10.Gameplay and Screen Effects
-
老电影效果
-
Sepia tone 棕褐色调 通过叠加颜色获得 fixed lum = dot (fixed3(0.299, 0.587, 0.114), renderTex.rgb);
fixed4 finalColor = lum + lerp(_SepiaColor, _SepiaColor + fixed4(0.1f,0.1f,0.1f,1.0f), _RandomValue);
finalColor = pow(finalColor, _Contrast);
-
Vignette effect 晕影效果 也是通过叠加图片获得的 fixed4 vignetteTex = tex2D(_VignetteTex, i.uv);
finalColor = lerp(finalColor, finalColor * vignetteTex, _VignetteAmount);
-
Dust and scratches 脏迹和划痕 虽然更加复杂,但依旧是叠加图片获得的,只是增加了uv的滚动 half2 scratchesUV = half2(i.uv.x + (_RandomValue * _SinTime.z * _ScratchesXSpeed), i.uv.y + (_Time.x * _ScratchesYSpeed));
fixed4 scratchesTex = tex2D(_ScratchesTex, scratchesUV);
finalColor.rgb *= lerp(scratchesTex, constantWhite, (_RandomValue));
half2 dustUV = half2(i.uv.x + (_RandomValue * (_SinTime.z * _dustXSpeed)), i.uv.y + (_RandomValue * (_SinTime.z * _dustYSpeed)));
fixed4 dustTex = tex2D(_DustTex, dustUV);
finalColor.rgb *= lerp(dustTex.rgb, constantWhite, (_RandomValue * _SinTime.z));
-
夜视效果 仍旧是图片叠加 //失真算法,对当前UV值变换
float2 barrelDistortion(float2 coord)
{
float2 h = coord.xy - float2(0.5, 0.5);
float r2 = h.x * h.x + h.y * h.y;
float f = 1.0 + r2 * (_distortion * sqrt(r2));
return f * _scale * h + 0.5;
}
fixed4 frag(v2f_img i) : COLOR
{
//取失真后的uv值
half2 distortedUV = barrelDistortion(i.uv);
//采样
fixed4 renderTex = tex2D(_MainTex, distortedUV);
fixed4 vignetteTex = tex2D(_VignetteTex, i.uv);
//采样扫描线图片
half2 scanLinesUV = half2(i.uv.x * _ScanLineTileAmount, i.uv.y * _ScanLineTileAmount);
fixed4 scanLineTex = tex2D(_ScanLineTex, scanLinesUV);
//采样噪声图片
half2 noiseUV = half2(i.uv.x + (_RandomValue * _SinTime.z * _NoiseXSpeed), i.uv.y + (_Time.x * _NoiseYSpeed));
fixed4 noiseTex = tex2D(_NoiseTex, noiseUV);
//叠加夜视颜色色调
fixed lum = dot (fixed3(0.299, 0.587, 0.114), renderTex.rgb);
lum += _Brightness;
fixed4 finalColor = (lum *2) + _NightVisionColor;
//叠加在一起
finalColor = pow(finalColor, _Contrast);
finalColor *= vignetteTex;
finalColor *= scanLineTex * noiseTex;
return finalColor;
}
11.Advanced Shading Techniques
-
使用UnityCG.cginc文件中的函数 文件位于Editor\Data\CGIncludes文件夹下 -
Luminance函数(在UnityCG.cginc中定义): 函数定义(返回灰度值): inline half Luminance(half3 rgb) { return dot(rgb, unity_ColorSpaceLuminance.rgb); } 其中,unity_ColorSpaceLuminance也在此文件中定义 #define unity_ColorSpaceLuminance half4(0.22, 0.707, 0.071, 0.0) -
使用自定义的CGInclude文件(头文件)
- 创建MyCGInclude.cginc文件
- 在文件中实现函数
- 在shader中使用#include “MyCGInclude.cginc”
- 调用文件中的函数
-
毛皮着色器
-
首先新建一个pass,它将在顶点函数中创建一个稍大一些的模型(同时考虑了重力) void vert (inout appdata_full v)
{
fixed3 direction = lerp(v.normal, _Gravity * _GravityStrength + v.normal * (1-_GravityStrength), FUR_MULTIPLIER);
v.vertex.xyz += direction * _FurLength * FUR_MULTIPLIER * v.color.a;
}
-
它的表面着色器负责判断哪些像素应该被显示或隐藏(同时考虑了观察角度) void surf (Input IN, inout SurfaceOutputStandard o) {
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = step(lerp(_Cutoff,_CutoffEnd,FUR_MULTIPLIER), c.a);
float alpha = 1 - (FUR_MULTIPLIER * FUR_MULTIPLIER);
alpha += dot(IN.viewDir, o.Normal) - _EdgeFade;
o.Alpha *= alpha;
}
-
在普通表面着色器CGEND之后,添加多个该pass,越多则越真实 -
这种方法非常耗时 -
向着色器传数组(实现HeatMap)
-
C#部分:material.SetVectorArray("_Properties", properties); -
shader部分:uniform float2 _Properties[20]; -
heatMap实现方法:通过传入的position数组中点的位置和半径累计热度值h,再根据h绘制上颜色 half4 frag(vertOutput output) : COLOR
{
half h = 0;
for (int i = 0; i < _Points_Length; i++)
{
half di = distance(output.worldPos, _Points[i].xyz);
half ri = _Properties[i].x;
half hi = 1- saturate(di / ri);
h += hi * _Properties[i].y;
}
h = saturate(h);
half4 color = tex2D(_HeatTex, fixed2(h, 0));
return color;
}
-
性能瓶颈:对于每个像素,都需要执行这个循环
|