Shader 效果与算法解释
遮罩的用法
遮罩用来控制某些个区域显示 其他的不显示
例如
_SpecularMask 遮罩图
_FireTex 火焰效果图
fixed3 emissionCol = (tex2D(_SpecularMask,IN.uv_MainTex) * tex2D(_FireTex,moveUv) * (_FireScale * (_SinTime.z + _FireSinScale))).rgb;
其中 遮罩图 上下边为黑色(0),在颜色乘法运算也就不会显示火焰效果
AlphaTest 与 AlphaBlend
alphatest 是 透明度测试,通过a的值控制那些区域显示 反之不显示 (也就是不完全透明)
alphaBlend 是 透明度混合,也就是完全透明的物体 与 不透明物体 混合着色 (也就是 完全透明)
行列变化算法
// 这里是计算行和列的数量
float timeNum = floor(_Time.y * _Speed);
float row = floor(timeNum / _HorAmount);
float colume = timeNum - row * _HorAmount;
// 对uv进行偏移 ,这里行是偏移y 列是偏移x,y的偏移相反
half2 uv = i.uv + half2(colume,-row);
// 然后对uv进行缩放 , 达到只取一个图片的效果
uv.x /= _HorAmount;
uv.y /= _VerAmount;
fixed4 col = tex2D(_MainTex, uv);
这里的colume计算是根据 timeNum的大小 决定的,但是他有一个周期性质,也就是从1-HorAmount ~ 1-HorAmount 这样的一个周期
所以 需要用timeNum减去上一个周期的大小,得到当前周期的值,例如 当 HorAmount = 4 ,timeNum = 7 时 colume的值应该为3 == 7 - (7/4 * 4) == timeNum - row * _HorAmount;
法线贴图 双向采样 算法
float4 waterTexOffset1 = tex2D(_WaterNormalTex,IN.uv_WaterNormalTex + float2(_WaterSpeed * _Time.y,0));
float4 waterTexOffset2 = tex2D(_WaterNormalTex,float2(1-IN.uv_WaterNormalTex.y,IN.uv_WaterNormalTex.x) + float2(_WaterSpeed * _Time.y,0));
float4 waterTexOffset = (waterTexOffset1 + waterTexOffset2)/2;
float3 waterNormal = UnpackNormal(waterTexOffset);
法线贴图 双向采样 四次算法
这里第二次双向采样 是基于第一次才采样的结果也就是对于 扰动的幅度增加
float4 waterTexOffset1 = tex2D(_WaterNormalTex,IN.uv_WaterNormalTex + float2(_WaterSpeed * _Time.x,0));
float4 waterTexOffset2 = tex2D(_WaterNormalTex,float2(1-IN.uv_WaterNormalTex.y,IN.uv_WaterNormalTex.x) + float2(_WaterSpeed * _Time.x,0));
float4 waterTexOffset = (waterTexOffset1 + waterTexOffset2)/2;
float3 waterNormal = UnpackNormal(waterTexOffset);
float2 waterNormalOffset = waterNormal.xy * _WaterNormalRefract;
waterTexOffset1 = tex2D(_WaterNormalTex,IN.uv_WaterNormalTex + float2(_WaterSpeed * _Time.x,0) + waterNormalOffset);
waterTexOffset2 = tex2D(_WaterNormalTex,float2(1-IN.uv_WaterNormalTex.y,IN.uv_WaterNormalTex.x) + waterNormalOffset + float2(_WaterSpeed * _Time.x,0));
float3 waterNormal = UnpackNormal((waterTexOffset1 + waterTexOffset2)/2);