庄懂的TA笔记(十九)<特效:顶点 平移+缩放+旋转+幽灵夜巡效果)>

news2024/12/27 12:38:55

 庄懂的TA笔记(十九)<特效:顶点 平移+缩放+旋转+幽灵夜巡效果)>

大纲:

效果展示:

正文:

一、顶点平移

1、代码实现:

1.1、声明移动范围,移动速度。

_MoveRange ("移动范围", range(0.0, 3.0)) = 1.0

_MoveSpeed ("移动速度", range(0.0, 3.0)) = 1.0

顶点shader中对,顶点位置做预处理xyz,用到的方法需要在外部声明。

// 声明常量 Π 的2 倍 =6.283185

#define TWO_PI 6.283185

这里的 TOW_PI常量,就是类似Π = 3.1415926这些公认的数值.

这里可以用 中间测试环节,测试 顶点动画方法:

vertex.y顶点的Y轴 加一个 移动范围,可以对顶点的移动范围做控制。

vertex.y += _MoveSpeed;

ok现在我们想让他自己上下起伏,就用到了正弦运动sin

 vertex.y +=  sin(_Time.z) * _MoveSpeed;

往期课程中,不同机型长时间运行会出现混乱的效果,所以这里要取余frac()但是取余后会出现顶点一抖一抖的状态,这是为什么呢?

这是因为曲线在运动到0.8的时候就取余了,然而我们需要他走完一个完整的三元函数波的进程

而上图中一个完整的曲线进程长度是多少呢是2倍的Π(3.1415926...)

所以这里就引出了我们需要 规定一个常量了

// 顶点动画方法

void Translation (inout float3 vertex) {

vertex.y += _MoveRange * sin(frac(_Time.z * _MoveSpeed) * TWO_PI);

}

2、核心代码分析:

回顾:

首先 时间 * 时间流动的速度 这样可以控制 动画快慢,

然后为了保证浮点精度对结果取余(frac)

然后让时间的流动,0-1的区间我们外面用的是一个sin函数,所以0-1是不行的,要让里面的值是6.283185. 所以要 *2Π,然后用周期性阔上,这样就开始做周期性波动。 得到周期性的波动后,我们想要控制他的波动范围,所以我们乘了一个范围的变量。这样我们就得到一个上下起伏的偏移值,是偏移值,不是Y轴的数值,我们要把偏移的数值,加到原有的Y轴上去,就完成了平移顶点动画的过程。

二、顶点缩放

示例代码:

Shader "AP01/L19/Translation" {
    Properties {
        _MainTex        ("RGB:颜色 A:透贴", 2d) = "gray"{}
        _Opacity        ("透明度", range(0, 1)) = 0.5
        _MoveRange      ("移动范围", range(0.0, 3.0)) = 1.0
        _MoveSpeed      ("移动速度", range(0.0, 3.0)) = 1.0
    }
    SubShader {
        Tags {
            "Queue"="Transparent"               // 调整渲染顺序
            "RenderType"="Transparent"          // 对应改为Cutout
            "ForceNoShadowCasting"="True"       // 关闭阴影投射
            "IgnoreProjector"="True"            // 不响应投射器
        }
        Pass {
            Name "FORWARD"
            Tags {
                "LightMode"="ForwardBase"
            }
            Blend One OneMinusSrcAlpha          // 修改混合方式One/SrcAlpha OneMinusSrcAlpha
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma target 3.0
            // 输入参数
            uniform sampler2D _MainTex; uniform float4 _MainTex_ST;
            uniform half _Opacity;
            uniform float _MoveRange;
            uniform float _MoveSpeed;
            // 输入结构
            struct VertexInput {
                float4 vertex : POSITION;       // 顶点位置 总是必要
                float2 uv : TEXCOORD0;          // UV信息 采样贴图用
            };
            // 输出结构
            struct VertexOutput {
                float4 pos : SV_POSITION;       // 顶点位置 总是必要
                float2 uv : TEXCOORD0;          // UV信息 采样贴图用
            };
            // 声明常量
            #define TWO_PI 6.283185
            // 顶点动画方法
            void Translation (inout float3 vertex) {
                vertex.y += _MoveRange * sin(frac(_Time.z * _MoveSpeed) * TWO_PI);
            }
            // 输入结构>>>顶点Shader>>>输出结构
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
                    Translation(v.vertex.xyz);
                    o.pos = UnityObjectToClipPos(v.vertex);    // 顶点位置 OS>CS
                    o.uv = TRANSFORM_TEX(v.uv, _MainTex);       // UV信息 支持TilingOffset
                return o;
            }
            // 输出结构>>>像素
            half4 frag(VertexOutput i) : COLOR {
                half4 var_MainTex = tex2D(_MainTex, i.uv);      // 采样贴图 RGB颜色 A透贴
                half3 finalRGB = var_MainTex.rgb;
                half opacity = var_MainTex.a * _Opacity;
                return half4(finalRGB * opacity, opacity);                // 返回值
            }
            ENDCG
        }
    }
}

 1、代码实现:

1、AB为模板,改名,并追加面板参数。

_MainTex ("RGB:颜色 A:透贴", 2d) = "gray"{}

_Opacity ("透明度", range(0, 1)) = 0.5

_ScaleRange ("缩放范围", range(0.0, 0.5)) = 0.2

_ScaleSpeed ("缩放速度", range(0.0, 3.0)) = 1.0

和顶点位置变化相似,只是前缀变成了缩放。

 

2、和顶点shader一样,在做一般操作之前对顶点信息做一个修改。

和上个案例相比,一个是名字变了,另一个是 内容变了,因为对平移的修改是 偏移 + 到Y轴上去,

缩放,一般是用 ,我们算出他 缩放的比例,例如缩放原先大小的 120%,或者70%,我们把这样的假设区间,做一个周期性的变化,再把它乘上去,平移是( + ), 缩放是( * ) ,这个是两者不同的地方。

// 顶点动画方法

void Scaling (inout float3 vertex) {

vertex.y *= _ScaleRange * sin(frac(_Time.z * _ScaleSpeed) * TWO_PI);

}

//输入结构:

Scaling(v.vertex.xyz);

这个时候可以输出测试看下效果:

这是为什么呢,因为代码平移中,只对Y轴做了操作,现在缩放要对XYZ都做操作,(xyz都做操作就不需要.xyz了,也可以省略)这时,修改xyz后,我们可以继续输出看下。

vertex.xyz *= _ScaleRange * sin(frac(_Time.z * _ScaleSpeed) * TWO_PI);

这个时候我们发现,现在虽然有了缩放,但是他取了负向的值,我们不想让他有负的,不想让他在0的缩放比例上来回浮动,因为在0的区间上,他可能会取正数,也可能取负数,我们希望他在原有大小基础上做浮动,在100%的大小上做浮动,那么这个改变也很简单,我们有个基础值,100%那就1嘛,在加上波动值,这个事情就完事儿了。

vertex.xyz *= 1.0 + _ScaleRange * sin(frac(_Time.z * _ScaleSpeed) * TWO_PI);

2、核心代码分析:

 三、顶点旋转

1、代码实现:

1、AB做为模板。

2、声明旋转参数:

_RotateRange ("旋转范围", range(0.0, 45.0)) = 20.0

_RotateSpeed ("旋转速度", range(0.0, 3.0)) = 1.0

3、声明常量2Π;

4、顶点动画方法:

这里的 思路是分两步走计算偏移量的,归到计算偏移量应用偏移量的,归到应用偏移量

那些部分是 计算偏移量呢?首先我们要知道对旋转来说,偏移量意味着什么?

对平移来说,他的偏移量距离

对旋转来说,他的偏移量角度

//计算偏移量

所以我们要把偏移的角度计算出来,他的偏移量还是动态的需要加上_Time.

角度 = 旋转范围 * 正弦(取余*(Time.z * 旋转速度) * 2Π);

角度= 旋转范围 * -1到1的动态数值

float angleY = _RotateRange * sin(frac(_Time.z * _RotateSpeed) * TWO_PI);


应用偏移量:

角度转成弧度,是为了方便后面三角函数的运算,因为三角函数取的弧度不是角度

float radY = radians(angleY); //角度转弧度

下面的是计算 sin 和 cos 值,会用sincos()这个方法把参数一起求出来。

float sinY, cosY = 0;

sincos(radY, sinY, cosY);

//sincos(radY,输入Y,输出Y)

vertex.xz = float2(

vertex.x * cosY - vertex.z * sinY,

vertex.x * sinY + vertex.z * cosY);

// 顶点动画方法

void Rotation (inout float3 vertex) {

//此为计算偏移量的代码

float angleY = _RotateRange * sin(frac(_Time.z * _RotateSpeed) * TWO_PI);

//以下为应用偏移量的代码

float radY = radians(angleY); //角度转弧度

float sinY, cosY = 0;

sincos(radY, sinY, cosY);

vertex.xz = float2(

vertex.x * cosY - vertex.z * sinY,

vertex.x * sinY + vertex.z * cosY

);

2、核心代码分析:

ok那么上述的内容,为什么能让顶点做旋转呢?

我们详细讲一下原理:

前置知识:就是向量的 加减法 。

假设有一个向量a 和 b, a 是从A 指到B 的向量

b是从A指到D的向量

那a + b 和 a - b 分别是什么呢?

今天的知识,只需要知道 a + b 和 a - b就可以了。

A+B 相当于 把 A B 平移到 D C的位置,这样就围成一个平行四边形。

那a+b等于什么呢?

a+b等于 A指向C的这条 向量。 相当于两个向量求和的话,就是把他拼成平行四边形,平行四边形对角一连线,就是他们的和,他们另外的一个对角,就是他们的差。

现在我们的模型是沿Y轴旋转,沿Y轴旋转,相当于Y轴是没有变化的,变化的只有 x,z轴。

然后旋转一个θ(角度)后,就旋转到红色标注的点上了,我们已知原始点 是x,z,旋转θ角度之后,问,红色的这个坐标点是多少?

如果我们知道这个坐标值,跟旋转角θ之间的对应关系,方程列出来,那么我们的代码就可以写了。

我们第一步怎么来咧?

先把黑色的这个点,理解为一个向量,从原点指向黑点的一个向量,这个向量的值,也是他的坐标值。

然后把这个向量值根据x轴,y轴。原始的向量,等于 x 和 y相加。

这两个向量,也同样旋转Θ角度之后,就变成了红色的向量,那么,红色的xy相加就等于红色原点的位置,因为我们可以视为,整个坐标系旋转了一个θ角,然后就变成了下图的样子了,之前是个长方形,旋转之后也是个长方形,我们现在要 求 红色原点的位置,那我们知道 红色的 x轴和红色的y轴就可以了。那么红色x,y怎么求?

首先看红色x轴上,x轴的长度,虽然红色线现在是斜线,但是点的横向移动是不改变他的长度的。这里引入三角函数的一些知识。cos = 邻边 / 斜边。 求那个角,就按照下图 套公式即可。

那么 红色的x轴的位置就是,(x*cosθ , x * sinθ)

红色的z轴的位置就是,(-z * sinθ , z * cosθ)

现在 两个红色分量加在一起 求出 红点位置了

( x * cosθ - z * sinθ , x * sinθ + z * cos θ )

示例代码:

Shader "AP01/L19/Rotation" {
    Properties {
        _MainTex        ("RGB:颜色 A:透贴", 2d) = "gray"{}
        _Opacity        ("透明度", range(0, 1)) = 0.5
        _RotateRange    ("旋转范围", range(0.0, 45.0)) = 20.0
        _RotateSpeed    ("旋转速度", range(0.0, 3.0)) = 1.0
    }
    SubShader {
        Tags {
            "Queue"="Transparent"               // 调整渲染顺序
            "RenderType"="Transparent"          // 对应改为Cutout
            "ForceNoShadowCasting"="True"       // 关闭阴影投射
            "IgnoreProjector"="True"            // 不响应投射器
        }
        Pass {
            Name "FORWARD"
            Tags {
                "LightMode"="ForwardBase"
            }
            Blend One OneMinusSrcAlpha          // 修改混合方式One/SrcAlpha OneMinusSrcAlpha
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma target 3.0
            // 输入参数
            uniform sampler2D _MainTex; uniform float4 _MainTex_ST;
            uniform half _Opacity;
            uniform float _RotateRange;
            uniform float _RotateSpeed;
            // 输入结构
            struct VertexInput {
                float4 vertex : POSITION;       // 顶点位置 总是必要
                float2 uv : TEXCOORD0;          // UV信息 采样贴图用
            };
            // 输出结构
            struct VertexOutput {
                float4 pos : SV_POSITION;       // 顶点位置 总是必要
                float2 uv : TEXCOORD0;          // UV信息 采样贴图用
            };
            // 声明常量
            #define TWO_PI 6.283185
            // 顶点动画方法
            void Rotation (inout float3 vertex) {
                float angleY = _RotateRange * sin(frac(_Time.z * _RotateSpeed) * TWO_PI);
                float radY = radians(angleY);
                float sinY, cosY = 0;
                sincos(radY, sinY, cosY);
                vertex.xz = float2(
                    vertex.x * cosY - vertex.z * sinY,
                    vertex.x * sinY + vertex.z * cosY
                );
            }
            // 输入结构>>>顶点Shader>>>输出结构
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
                    Rotation(v.vertex.xyz);
                    o.pos = UnityObjectToClipPos(v.vertex);    // 顶点位置 OS>CS
                    o.uv = TRANSFORM_TEX(v.uv, _MainTex);       // UV信息 支持TilingOffset
                return o;
            }
            // 输出结构>>>像素
            half4 frag(VertexOutput i) : COLOR {
                half4 var_MainTex = tex2D(_MainTex, i.uv);      // 采样贴图 RGB颜色 A透贴
                half3 finalRGB = var_MainTex.rgb;
                half opacity = var_MainTex.a * _Opacity;
                return half4(finalRGB * opacity, opacity);                // 返回值
            }
            ENDCG
        }
    }
}

四、幽灵夜巡(综合)

1、代码实现:

对模型做一个处理,去maya或者blende做定点色刷制。

这里没刷蓝色,是因为,黑色部分 实际上是 红色通道的反向。就可以少占用一个通道。

maya中顶点颜色绘制位置: 网格显示>>绘制顶点颜色工具

PS:注意 这里顶点色 添加中,色彩一定要是 纯色,否则会出现问题。

 1、参数追加:

_MainTex ("RGB:颜色 A:透贴", 2d) = "gray"{}

_Opacity ("透明度", range(0, 1)) = 0.5

_ScaleParams ("天使圈缩放 X:强度 Y:速度 Z:校正", vector) = (0.2, 1.0, 4.5, 0.0)

_SwingXParams ("X轴扭动 X:强度 Y:速度 Z:波长", vector) = (1.0, 3.0, 1.0, 0.0)

_SwingZParams ("Z轴扭动 X:强度 Y:速度 Z:波长", vector) = (1.0, 3.0, 1.0, 0.0)

_SwingYParams ("Y轴起伏 X:强度 Y:速度 Z:滞后", vector) = (1.0, 3.0, 0.3, 0.0)

_ShakeYParams ("Y轴摇头 X:强度 Y:速度 Z:滞后", vector) = (20.0, 3.0, 0.3, 0.0)

2、输入输出结构 追加顶点色:

struct vertexInput{

float4 vertex : POSITION;

float4 color : COLOR;

float4 uv : TEXCOORD0;

}

struct vertexOutplut {

float4 vertex : POSITION;

float4 color : COLOR;

float4 uv : TEXCOORD0;

}

因为我们为模型刷 了 顶点色彩做动画遮罩,所以需要在输入结构声明 。至于输出结构中也声明定点色,是因为案例中 的光环 做了闪烁效果处理,所以输出结构,我们依然输出了顶点色。

这里的定点色闪烁也是 用了 参数传入,在传出的方式来实现的。

1、缩放天使圈

//顶点动画方法:

float scale = _ScaleParams.x * color.g * sim(frac (_Time.z * _ScaleParams.y) * TWO_PI );

vertex .xyz * = 1 + scale;

vertex.y -=_ScaleParams.z * scale;

2、幽灵摆动

这里的公式,也很眼熟, X轴摆动=x轴范围*(速度*正弦运动 + )*2Π;

float swingX = _SwingXParms.x * sin((_Time.z * _SwingXParams.y + vertex.z * _SwingXParams.z) * TWO_PI);

这里如果不加小尾巴的会直接整体横向平移,而不是摆动。

那么这里的小尾巴_SwingXParams.y + vertex.z是什么意思呢?

小尾巴和什么相关,和顶点信息的Y坐标相关,也就是和模型的高度是相关的,且模型Y轴上不同顶点的高度也是不一样的,除非是个饼,所以在不同的高度,顶点信息也是不一样的。

这个时候Y轴顶点不一样,再把它作用在sin的参数里面,最终得出的sin值也是不一样的。

不一样如何体现呢?

他会沿Y轴方向做 正弦波,也就是从上到下 的S形。

float swingZ = _SwingXParms.x * sin((_Time.z * _SwingXParams.y + vertex.y * _SwingXParams.z) * TWO_PI);

vertex.xz+=float2 (swingX,swingZ) * color.r; //xz轴位移 * 红遮罩 = 红区域摆动。

3、摇头+圈滞后

//计算偏移量:计算弧度

弧度 =弧度 * ( 1-color.g红色反向遮罩 ) sin(frac(时间 *速度 - 旋转滞后 )*2Π);

float radY = radians(_ShakeYParams.x) * (1.0 - color.r) *

sin(frac(_Time.z * _ShakeYParams.y - color.g * _ShakeYParams.z) * TWO_PI);

这里的小尾巴是什么意思呢?实际上是滞后效果。

那么怎么滞后原理是什么呢?

通过原本的旋转时间,在 减去 红色遮罩区域中的一个延迟时间。

就是时间 减去了一个值.

_Time.z * _ShakeYParams.y - color.g * _ShakeYParams.z;

//应用偏移量:应用弧度

float sinY, cosY = 0;

sincos(radY, sinY, cosY);

vertex.xz = float2(

vertex.x * cosY - vertex.z * sinY,

vertex.x * sinY + vertex.z * cosY

);

4、幽灵起伏:

//计算偏移量

Y起伏参数=起伏范围*sin(frac(时间*速度 - 滞后)*2Π);

float swingY = _SwingYParams.x *

sin(frac(_Time.z * _SwingYParams.y - color.g * _SwingYParams.z) * TWO_PI);

//应用偏移量

vertex.y += swingY;

5、处理顶点色

需要想好在像素shader中应用 顶点色 。(跳转到: 输出结构>>像素下)

那么为了配合像素shader的应用使用,我们要怎么构造从顶点输出的RGB呢?

首先 声明一个亮度,对天使圈之外的亮度,他恒定保持为1, 在天使圈的范围亮度是提高的,也是带闪烁的。

亮度基础值是1对吧,因为身子是占的绝大多数,天使圈占的是小部分,然后他应该加上某个东西,因为天使圈是要提亮的也就是 1+color.g 乘 亮度倍数和 闪烁(scale是1到-1的波动值)

lightness = 亮度1 + 红遮罩 * 1 + scale * 2 ;

float lightness = 1.0 + color.g * 1.0 + scale * 2.0;

color = float3(lightness, lightness, lightness);

来到输入输出结构

输入结构下:

AnimGhost(v.vertex.xyz,v.color.rgb); //修改了v.vertex.xyz顶点位置,和定点色v.color.rbg

输出结构>>像素下:

首先我们用顶点色干嘛呢?我们用途是说把天使圈提亮并闪烁。

天使圈在像素shader的最终输出是什么呢?

是finalRGB把,所以让 var_MainTex.rgb * i.color.RGB就完事了。

float3 finalRGB = var_MainTex.rgb * i.color.rgb; //定点色的亮度,传给 finalRGB的像素颜色中。

2、核心代码分析:

示例代码:

Shader "AP01/L19/AnimGhost" {
    Properties {
        _MainTex        ("RGB:颜色 A:透贴", 2d) = "gray"{}
        _Opacity        ("透明度", range(0, 1)) = 0.5 
        _ScaleParams    ("天使圈缩放 X:强度 Y:速度 Z:校正", vector) = (0.2, 1.0, 4.5, 0.0)
        _SwingXParams   ("X轴扭动 X:强度 Y:速度 Z:波长", vector) = (1.0, 3.0, 1.0, 0.0)
        _SwingZParams   ("Z轴扭动 X:强度 Y:速度 Z:波长", vector) = (1.0, 3.0, 1.0, 0.0)
        _SwingYParams   ("Y轴起伏 X:强度 Y:速度 Z:滞后", vector) = (1.0, 3.0, 0.3, 0.0)
        _ShakeYParams   ("Y轴摇头 X:强度 Y:速度 Z:滞后", vector) = (20.0, 3.0, 0.3, 0.0)
    }
    SubShader {
        Tags {
            "Queue"="Transparent"               // 调整渲染顺序
            "RenderType"="Transparent"          // 对应改为Cutout
            "ForceNoShadowCasting"="True"       // 关闭阴影投射
            "IgnoreProjector"="True"            // 不响应投射器
        }
        Pass {
            Name "FORWARD"
            Tags {
                "LightMode"="ForwardBase"
            }
            Blend One OneMinusSrcAlpha          // 修改混合方式One/SrcAlpha OneMinusSrcAlpha
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma target 3.0
            // 输入参数
            uniform sampler2D _MainTex; uniform float4 _MainTex_ST;
            uniform half _Opacity;
            uniform float4 _ScaleParams;
            uniform float3 _SwingXParams;
            uniform float3 _SwingZParams;
            uniform float3 _SwingYParams;
            uniform float3 _ShakeYParams;
            // 输入结构
            struct VertexInput {
                float4 vertex : POSITION;       // 顶点位置 总是必要
                float2 uv : TEXCOORD0;          // UV信息 采样贴图用
                float4 color : COLOR;           // 顶点色 遮罩用
            };
            // 输出结构
            struct VertexOutput {
                float4 pos : SV_POSITION;       // 顶点位置 总是必要
                float2 uv : TEXCOORD0;          // UV信息 采样贴图用
                float4 color : COLOR;
            };
            // 声明常量
            #define TWO_PI 6.283185
            // 顶点动画方法
            void AnimGhost (inout float3 vertex, inout float3 color) {
                // 缩放天使圈
                float scale = _ScaleParams.x * color.g * sin(frac(_Time.z * _ScaleParams.y) * TWO_PI);
                vertex.xyz *= 1.0 + scale;
                vertex.y -=  _ScaleParams.z * scale;
                // 幽灵摆动
                float swingX = _SwingXParams.x * sin(frac(_Time.z * _SwingXParams.y + vertex.y * _SwingXParams.z) * TWO_PI);
                float swingZ = _SwingZParams.x * sin(frac(_Time.z * _SwingZParams.y + vertex.y * _SwingZParams.z) * TWO_PI);
                vertex.xz += float2(swingX, swingZ) * color.r;
                // 幽灵摇头
                float radY = radians(_ShakeYParams.x) * (1.0 - color.r) * sin(frac(_Time.z * _ShakeYParams.y - color.g * _ShakeYParams.z) * TWO_PI);
                float sinY, cosY = 0;
                sincos(radY, sinY, cosY);
                vertex.xz = float2(
                    vertex.x * cosY - vertex.z * sinY,
                    vertex.x * sinY + vertex.z * cosY
                );
                // 幽灵起伏
                float swingY = _SwingYParams.x * sin(frac(_Time.z * _SwingYParams.y - color.g * _SwingYParams.z) * TWO_PI);
                vertex.y += swingY;
                // 处理顶点色
                float lightness = 1.0 + color.g * 1.0 + scale * 2.0;
                color = float3(lightness, lightness, lightness);
            }
            // 输入结构>>>顶点Shader>>>输出结构
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
                    AnimGhost(v.vertex.xyz, v.color.rgb);
                    o.pos = UnityObjectToClipPos(v.vertex);    // 顶点位置 OS>CS
                    o.uv = TRANSFORM_TEX(v.uv, _MainTex);       // UV信息 支持TilingOffset
                    o.color = v.color;
                return o;
            }
            // 输出结构>>>像素
            half4 frag(VertexOutput i) : COLOR {
                half4 var_MainTex = tex2D(_MainTex, i.uv);      // 采样贴图 RGB颜色 A透贴
                half3 finalRGB = var_MainTex.rgb * i.color.rgb;
                half opacity = var_MainTex.a * _Opacity;
                return half4(finalRGB * opacity, opacity);                // 返回值
            }
            ENDCG
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/835906.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

‘<>‘ cannot be used with anonymous classes

‘&#xff1c;&#xff1e;‘ cannot be used with anonymous classes <>不能与匿名类一起使用 Description Resource Path Location Type <> cannot be used with anonymous classes SearchHitSupport.java /spring-data-elasticsearch/src/main/java/org/spri…

QWidget样式

1、设置边框样式&#xff1a; QWidget {font-family:Microsoft YaHei UI;background:#ffffff;/*border:3px solid rgba(207, 209, 208, 170);设置整体边框*/border-bottom: 3px solid rgba(207, 209, 208, 170);/*设置底部边框*/border-top: 3px solid rgba(207, 209, 208, 1…

谷歌云 | 电子商务 | 如何更好地管理客户身份以支持最佳的用户体验

【本文由Cloud Ace整理发布。Cloud Ace是谷歌云全球战略合作伙伴&#xff0c;拥有 300 多名工程师&#xff0c;也是谷歌最高级别合作伙伴&#xff0c;多次获得 Google Cloud 合作伙伴奖。作为谷歌托管服务商&#xff0c;我们提供谷歌云、谷歌地图、谷歌办公套件、谷歌云认证培训…

docker创建镜像并上传云端服务器

docker创建镜像并上传云端服务器 docker容器与镜像的关系1.基本镜像相关文件创建1.1 创建dockerfile文件1.2.创建do.sh文件1.3 创建upload_server_api.py文件1.4 创建upload_server_webui.py文件1.5 文件保存位置 2. 创建镜像操作2.1 创建镜像2.3 创建容器2.2 进入环境容器2.3 …

leetcode----JavaScript 详情题解(4)

目录 2722. 根据 ID 合并两个数组 2723. 添加两个 Promise 对象 2724. 排序方式 2725. 间隔取消 2726. 使用方法链的计算器 2727. 判断对象是否为空 2624. 蜗牛排序 2694. 事件发射器 2722. 根据 ID 合并两个数组 现给定两个数组 arr1 和 arr2 &#xff0c;返回一个新…

Flink 系列四 Flink 运行时架构

目录 前言 介绍 1、程序结构 1.1、Source 1.2、Transformation 1.3、Sink 1.4、数据流 2、Flink运行时组件 2.1、Dispatcher 2.2、JobManager 2.3、TaskManager 2.4、ResourceManager 3、任务提交流程 3.1、standalone 模式 3.2、yarn 模式 4、任务调度原理 4…

AI智慧安监视频监控汇聚平台EasyCVR调用接口出现跨域现象该如何解决?

视频监控汇聚EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有GB28181、RTSP/Onvif、RTMP等&#xff0c;以及厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等&#xff0c;能对外分发RTSP、RTMP、FLV、HLS、WebRTC等格式的视…

Scrum敏捷开发流程图怎么画?

1. 什么是Scrum敏捷开发流程图&#xff1f; Scrum敏捷开发流程图是一种可视化工具&#xff0c;用于形象地描述Scrum敏捷开发方法中的工作流程和活动。Scrum敏捷开发流程图展示了项目从需求收集到产品交付的整个开发过程&#xff0c;帮助团队理解和跟踪项目进展&#xff0c;促…

vue使用FullCalendar插件实现日历会议预约功能

目录 1. vue 项目使用npm安装插件 2. vue 页面代码&#xff08;直接复制粘贴可用&#xff09; 3. vue FullCalendar的内置函数以及配置 前言&#xff1a;此案例是用FullCalendar插件做一个会议日程预约功能&#xff0c;此功能可查看自己的日程安排会议信息等...... FullC…

国产化车载智能座舱方案引领新时代

车载智能座舱是一项集成了多种技术的复杂工程&#xff0c;包括大量的硬件设备、大数据分析、实时交互、用户体验和技术创新研发等。由于涉及的技术领域繁多&#xff0c;智能座舱技术在实际应用中面临很多技术壁垒&#xff0c;如硬件性能、互联互通、集成性、数据采集、存储、处…

Flink正常消费一段时间后,大量反压,看着像卡住了,但又没有报错。

文章目录 前言一、原因分析二、解决方案 前言 前面我也有提到&#xff0c;发现flink运行一段时间后&#xff0c;不再继续消费的问题。这个问题困扰了我非常久&#xff0c;一开始也很迷茫。又因为比较忙&#xff0c;所以一直没有时间能够去寻找答案&#xff0c;只是通过每天重启…

智慧医院该啥样?白皮书给你答案

注意&#xff1a;案例数据均为虚拟数据 随着云计算、大数据、物联网、区块链、新一代互联网通信等新技术的不断发展,“新基建”的不断升级,新医改的不断深化,智慧医院成为我国医院现代化建设的重要发展方向。 党的十八大以来&#xff0c;数字经济更是上升为国家战略&#xff…

运动式蓝牙耳机哪种好、口碑最好的运动蓝牙耳机

为了保持身体健康&#xff0c;许多人在闲暇时选择进行一些日常运动。其中&#xff0c;很多人喜欢在运动时戴上耳机&#xff0c;让身体随着音乐的节奏运动&#xff0c;希望能够增强运动效果。正因如此&#xff0c;市场上涌现了许多优秀的运动耳机品牌&#xff0c;它们推出了一系…

人脸识别场景下Faiss大规模向量检测性能测试评估分析

在前面的两篇博文中&#xff0c;主要是考虑基于之前以往的人脸识别项目经历结合最近使用到的faiss来构建更加高效的检索系统&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a; 《基于facenetfaiss开发构建人脸识别系统》 Facenet算法的优点&#xff1a;高准确率&#…

MQTT协议详解「概念、特性、版本及作用」

MQTT&#xff08;Message Queuing Telemetry Transport&#xff0c;消息队列遥测传输&#xff09;是ISO标准下基于发布/订阅方式的轻量级消息协议。MQTT通常使用TCP / IP&#xff08;传输控制协议/Internet协议&#xff09;作为其传输&#xff0c;但也可以使用其他双向传输。MQ…

vue、uniapp直传阿里云文档

前端实现文件上传到oss&#xff08;阿里云&#xff09;适用于vue、react、uni-app&#xff0c;获取视频第一帧图片 用户获取oss配置信息将文件上传到阿里云&#xff0c;保证了安全性和减轻服务器负担。一般文件资源很多直接上传到服务器会加重服务器负担此时可以选择上传到oss&…

【C++】开源:sqlite3数据库配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍sqlite3数据库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下…

【Autolayout自动布局介绍 Objective-C语言】

一、好,我们开始介绍Autolayout 1.什么事Autolayout 好,那么,接下来,我们介绍一下这个Autolayout Autolayout,就是“自动布局” 那么,自动布局,它就是专门用来做UI界面的 那么,UI界面,我们为了适应不同屏幕,要进行自动布局, 所以要使用Autolayout 这个Autolayou…

物理机是什么?有什么优势?可以上堡垒机吗?

你知道物理机是什么&#xff1f;有什么优势&#xff1f;可以上堡垒机吗&#xff1f;今天我们就来简单聊聊。 物理机是什么&#xff1f; 物理机是相对于虚拟机而言的对实体计算机的称呼。物理机提供给虚拟机以硬件环境&#xff0c;有时也称为“寄主”或“宿主”。 物理机有什么…

C# Blazor 学习笔记(11):路由跳转和信息传值

文章目录 前言路由跳转测试用例路由传参/路由约束 前言 Blazor对路由跳转进行了封装。 ASP.NET Core Blazor 路由和导航 NavigationManager 类 本文的主要内容就是全局的跳转 路由跳转 路由跳转就要用到NavigationManager 类。 其实最常用的还是NavigateTo这个跳转函数 测…