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; }
-
性能瓶颈:对于每个像素,都需要执行这个循环
-