本文共 9130 字,大约阅读时间需要 30 分钟。
卡通风格的渲染通常采用渐变纹理漫反射和分块的高光反射处理,能够在视觉上创造出生动的卡通效果。这种方法通过模拟光线反射和漫反射,赋予物体颜色和质感,使其更加生动且富有层次感。
轮廓线处理:
漫反射渐变纹理:
高光反射处理:
光照衰减与抗锯齿:
Shader "MilkShader/14/ToonShading" { Properties { _Color("Color Tint", Color) = (1,1,1,1) _MainTex("Main Tex", 2D) = "white" _Ramp("Ramp Texture", 2D) = "white" _Outline("Outline", Range(0,1)) = 0.1 _OutlineColor("Outline Color", Color) = (1,1,1,1) _Specular("Specular", Color) = (1,1,1,1) _SpecularScale("Specular Scale", Range(0, 0.1)) = 0.01 } SubShader { Tags {"RenderType"="Opaque" "Queue"="Geometry"} LOD 100 Pass { NAME "OUTLINE" Cull Front CGPROGRAM #pragma vertex vert #pragma fragment frag include "UnityCG.cginc" float _Outline; fixed4 _OutlineColor; struct a2v { float4 vertex : POSITION; float3 normal : NORMAL; }; struct v2f { float4 pos : SV_POSITION; }; v2f vert(a2v v) { v2f o; pos = mul(UNITY_MATRIX_MV, v.vertex); normal = mul(UNITY_MATRIX_IT_MV, v.normal); normal.z = -0.5; pos = pos + normalize(normal) * _Outline; o.pos = mul(UNITY_MATRIX_P, pos); return o; } float4 frag(v2f i) : SV_Target { return _OutlineColor.rgb; } ENDCG } Pass { Tags {"LightMode"="ForwardBase"} Cull Back CGPROGRAM include "UnityCG.cginc" include "Lighting.cginc" include "AutoLight.cginc" include "UnityShaderVariables.cginc" #pragma vertex vert #pragma fragment frag #pragma multi_compile_fwdbase sampler2D _MainTex; float4 _MainTex_ST; fixed4 _Color; sampler2D _Ramp; fixed4 _Specular; fixed _SpecularScale; struct a2v { float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; }; struct v2f { float4 pos : POSITION; float2 uv : TEXCOORD0; float3 worldNormal : TEXCOORD1; float3 worldPos : TEXCOORD2; SHADOW_COORDS(3) }; v2f vert(a2v v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); o.worldNormal = UnityObjectToWorldNormal(v.normal); o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; TRANSFER_SHADOW(o); return o; } float4 frag(v2f i) : SV_Target { fixed3 worldNormal = normalize(i.worldNormal); fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos)); fixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos)); fixed3 worldHalfDir = normalize(worldLightDir + worldViewDir); fixed4 c = tex2D(_MainTex, i.uv); fixed3 albedo = c.rgb * _Color.rgb; fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo; UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos); fixed diff = dot(worldNormal, worldLightDir); diff = (diff * 0.5 + 0.5) * atten; fixed3 diffuse = _LightColor0.rgb * albedo * tex2D(_Ramp, float2(diff, diff)).rgb; fixed spec = dot(worldNormal, worldHalfDir); fixed w = fwidth(spec) * 2.0; fixed3 specular = _Specular.rgb * lerp(0,1, smoothstep(-w,w,spec + _SpecularScale - 1)) * step(0.0001, _SpecularScale); return fixed4(ambient + diffuse + specular, 1.0); } ENDCG } } Fallback "Diffuse"}
素描风格的渲染通过多层纹理和线条处理,模拟手绘效果,赋予物体细腻的艺术感。这种方法通过层叠纹理和权重计算,生成丰富的纹理效果。
素描纹理层叠:
纹理权重计算:
颜色混合:
光照处理:
Shader "MilkShader/14/Hatching" { Properties { _Color("Color Tint", Color) = (1,1,1,1) _TileFactor("Tile Factor", Float) = 1 _Outline("Outline", Range(0,1)) = 0.1 _OutlineColor("Outline Color", Color) = (1,1,1,1) _Hatch0("Hatch 0", 2D) = "white" _Hatch1("Hatch 1", 2D) = "white" _Hatch2("Hatch 2", 2D) = "white" _Hatch3("Hatch 3", 2D) = "white" _Hatch4("Hatch 4", 2D) = "white" _Hatch5("Hatch 5", 2D) = "white" } SubShader { Tags {"RenderType"="Opaque" "Queue"="Geometry"} UsePass "MilkShader/14/ToonShading/OUTLINE" Pass { Tags {"LightMode"="ForwardBase"} CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fwdbase include "UnityCG.cginc" include "Lighting.cginc" include "AutoLight.cginc" include "UnityShaderVariables.cginc" fixed4 _Color; fixed _TileFactor; fixed _Outline; fixed4 _OutlineColor; sampler2D _Hatch0; sampler2D _Hatch1; sampler2D _Hatch2; sampler2D _Hatch3; sampler2D _Hatch4; sampler2D _Hatch5; struct appdata { float4 vertex : POSITION; float4 tangent : TANGENT; float2 texcoord : TEXCOORD0; float3 normal : NORMAL; }; struct v2f { float4 pos : POSITION; float2 uv : TEXCOORD0; fixed3 hatchWeight0 : TEXCOORD1; fixed3 hatchWeight1 : TEXCOORD2; float3 worldPos : TEXCOORD3; SHADOW_COORDS(4) }; v2f vert(appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord.xy * _TileFactor; fixed3 worldNormal = normalize(UnityObjectToWorldNormal(v.normal)); fixed3 worldLightDir = normalize(WorldSpaceLightDir(v.vertex)); fixed diff = max(0, dot(worldNormal, worldLightDir)); hatchFactor = diff * 7.0; o.hatchWeight0 = fixed3(0,0,0); o.hatchWeight1 = fixed3(0,0,0); if (hatchFactor > 6.0) { } else if (hatchFactor > 5.0) { o.hatchWeight0.x = hatchFactor - 5.0; } else if (hatchFactor > 4.0) { o.hatchWeight0.x = hatchFactor - 4.0; o.hatchWeight0.y = 1 - o.hatchWeight0.x; } else if (hatchFactor > 3.0) { o.hatchWeight0.y = hatchFactor - 3.0; o.hatchWeight0.z = 1 - o.hatchWeight0.y; } else if (hatchFactor > 2.0) { o.hatchWeight0.z = hatchFactor - 2.0; o.hatchWeight1.x = 1 - o.hatchWeight0.z; } else if (hatchFactor > 1.0) { o.hatchWeight1.x = hatchFactor - 1.0; o.hatchWeight1.y = 1 - o.hatchWeight1.x; } else { o.hatchWeight1.y = hatchFactor; o.hatchWeight1.z = 1 - o.hatchWeight1.y; } o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; TRANSFER_SHADOW(o); return o; } fixed4 frag(v2f i) : SV_Target { fixed4 hatchTex0 = tex2D(_Hatch0, i.uv) * i.hatchWeight0.x; fixed4 hatchTex1 = tex2D(_Hatch1, i.uv) * i.hatchWeight0.y; fixed4 hatchTex2 = tex2D(_Hatch2, i.uv) * i.hatchWeight0.z; fixed4 hatchTex3 = tex2D(_Hatch3, i.uv) * i.hatchWeight1.x; fixed4 hatchTex4 = tex2D(_Hatch4, i.uv) * i.hatchWeight1.y; fixed4 hatchTex5 = tex2D(_Hatch5, i.uv) * i.hatchWeight1.z; fixed4 whiteColor = fixed4(1,1,1,1) * (1 - i.hatchWeight0.x - i.hatchWeight0.y - i.hatchWeight0.z - i.hatchWeight1.x - i.hatchWeight1.y - i.hatchWeight1.z); fixed4 hatchColor = hatchTex0 + hatchTex1 + hatchTex2 + hatchTex3 + hatchTex4 + hatchTex5 + whiteColor; UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos); return fixed4(hatchColor.rgb * _Color.rgb * atten, 1.0); } ENDCG } } Fallback "Diffuse"}
平铺系数(_TileFactor)决定了纹理的密度。值越大,纹理线条越密集;值越小,纹理线条越稀疏。通过调整平铺系数,可以根据需求控制纹理的细腻程度。
卡通风格和素描风格渲染通过不同的纹理处理和光照模拟方法,分别实现了生动的卡通效果和细腻的素描效果。两种方法都结合了光照和纹理的精细控制,确保了视觉效果的自然和一致性。
转载地址:http://xhucz.baihongyu.com/