Unity CG着色器实战
卡通风格先一个Pass只渲染背面黑色沿法线膨胀做轮廓线效果正式渲染Pass漫反射采样一个逐渐变暗的纹理做出硬边明暗。高光反射和一个阈值比较大于则直接显示高光颜色。Shader My/Toon { Properties { _Color (Color, Color) (1,1,1,1) _SpeColor(SpeColor,Color)(1,1,1,1) _SpecThreshold(SpecThreshold,Range(0.1,1))1 _MainTex(MainTex,2D)white{} _ShadeTex(ShadeTex,2D)white{} _OutlineWidth(OutlineWidth,Range(0.001,0.1))0.01 _OutlineCol(OutlineColor,Color)(0,0,0,1) [Enum(UnityEngine.Rendering.CullMode)]_Cull(Cull,Float)0 } SubShader { Tags { RenderTypeTransparentCutoutQueueAlphaTest} LOD 100 Pass{ Name Outline Cull Front CGPROGRAM #pragma vertex vert #pragma fragment frag #include UnityCG.cginc struct v2f { float4 vertex: SV_POSITION; }; float _OutlineWidth; fixed4 _OutlineCol; v2f vert(appdata_base v){ v2f o; v.vertex.xyz normalize(v.normal)* _OutlineWidth; o.vertex UnityObjectToClipPos(v.vertex); return o; } fixed4 frag(v2f i): SV_Target{ return _OutlineCol; } ENDCG } Pass { Name Main Tags{LightMode ForwardBase} Cull [_Cull] Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fwdbase #include UnityCG.cginc #include Lighting.cginc #include AutoLight.cginc struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; float2 uv:TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; float2 uv:TEXCOORD0; float3 worldPos: TEXCOORD1; float3 worldNormal: TEXCOORD2; float3 viewDir: TEXCOORD3; float3 lightDir: TEXCOORD4; SHADOW_COORDS(5) }; fixed4 _Color; fixed4 _SpeColor; float _SpecThreshold; sampler2D _MainTex; float4 _MainTex_ST; sampler2D _ShadeTex; v2f vert (appdata v) { v2f o; o.pos UnityObjectToClipPos(v.vertex); o.worldNormalnormalize(UnityObjectToWorldNormal(v.normal)); o.lightDir-normalize(_WorldSpaceLightPos0.xyz); o.worldPosmul(unity_ObjectToWorld,v.vertex); o.viewDirnormalize(_WorldSpaceCameraPos-o.worldPos); TRANSFER_SHADOW(o); o.uvv.uv; return o; } fixed4 frag (v2f i) : SV_Target { fixed4 texColtex2D(_MainTex,i.uv); //漫反射 float3 lightPosnormalize(_WorldSpaceLightPos0.xyz); fixed diffdot(i.worldNormal,lightPos)*0.50.5; UNITY_LIGHT_ATTENUATION(atten,i,i.worldPos); diff*atten; fixed4 shadeColtex2D(_ShadeTex,float2(diff,0)); //高光 float3 reflDirreflect(i.lightDir,i.worldNormal); float specstep(_SpecThreshold ,dot(reflDir,i.viewDir)); fixed3 color_Color.rgb* texCol.rgb*(UNITY_LIGHTMODEL_AMBIENT shadeCol) _SpeColor.rgb* spec; return fixed4(color,texCol.a); //return UNITY_LIGHTMODEL_AMBIENT; } ENDCG } } Fallback Diffuse }脸的下部有点黑可以加一个漫反射明暗到渐变贴图u的系数控制漫反射变黑的阈值。消融效果Shader My/Melt { Properties { _MainTex (Texture, 2D) white {} _NoiseTex(NoiseTex,2D){} _EdgeTex(EdgeTex,2D){} _EdgeWidth(EdgeWidth,Range(0,1))0.01 _MeltThre(MeltThreshold,Range(0,1))0 } SubShader { Tags { RenderTypeOpaque } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include UnityCG.cginc struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; sampler2D _NoiseTex; sampler2D _EdgeTex; fixed _EdgeWidth; fixed _MeltThre; v2f vert (appdata_base v) { v2f o; o.vertex UnityObjectToClipPos(v.vertex); o.uv TRANSFORM_TEX(v.texcoord, _MainTex); return o; } fixed4 frag (v2f i) : SV_Target { fixed no tex2D(_NoiseTex,i.uv); clip(no- _MeltThre); //噪声离阈值的差小于edge宽度时开始显示边缘 //把差值相对于edge宽度的比例转换到0-1用于采样贴图 fixed edgeU1- smoothstep(0,_EdgeWidth,no- _MeltThre); fixed4 edgeCol tex2D(_EdgeTex,fixed2(edgeU,0.5)); fixed4 col tex2D(_MainTex, i.uv); return lerp(col, edgeCol,edgeU); } ENDCG } } }水面Shader My/Water { Properties{ _MainTex(MainTex,2D){} _NormalTex(NormalTex,2D){} _Cube(Cubemap,Cube){} _Distortion(Distortion,Range(0,1))0 _XSpeed(XSpeed,Range(-0.1,0.1))0.01 _YSpeed(YSpeed,Range(-0.1,0.1))0.01 _Fresnel(Fresnel,Range(0,1))1 } SubShader{ Tags{RenderTypeOpaqueQueueTransparent} GrabPass{} Pass{ Tags{LightModeForwardBase} CGPROGRAM #pragma vertex vert #pragma fragment frag #include UnityCG.cginc #include Lighting.cginc sampler2D _MainTex; float4 _MainTex_ST; sampler2D _NormalTex; float4 _NormalTex_ST; samplerCUBE _Cube; sampler2D _GrabTexture;//GrabPass捕获的图像默认名 float _Distortion; fixed _XSpeed; fixed _YSpeed; float _Fresnel; struct v2f { float4 pos:SV_POSITION; float4 grabPos:TEXCOORD0; float4 uv:TEXCOORD1; float4 TtoW0: TEXCOORD3; float4 TtoW1: TEXCOORD4; float4 TtoW2: TEXCOORD5; }; v2f vert(appdata_full v){ v2f o; o.pos UnityObjectToClipPos(v.vertex); o.grabPos ComputeScreenPos(o.pos); o.uv.xyv.texcoord.xy* _MainTex_ST.xy _MainTex_ST.zw; o.uv.zwv.texcoord.xy* _NormalTex_ST.xy _NormalTex_ST.zw; float3 worldNormal UnityObjectToWorldNormal(v.normal); fixed3 worldPosmul(unity_ObjectToWorld,v.vertex).xyz; // float3 worldTan UnityObjectToWorldDir(v.tangent); float3 worldBinormal cross(normalize(worldTan),normalize(worldNormal))*v.tangent.w; o.TtoW0float4(worldTan.x,worldBinormal.x,worldNormal.x,worldPos.x); o.TtoW1float4(worldTan.y,worldBinormal.y,worldNormal.y,worldPos.y); o.TtoW2float4(worldTan.z,worldBinormal.z,worldNormal.z,worldPos.z); return o; } fixed4 frag(v2f i):SV_Target{ float3 worldPosfloat3(i.TtoW0.w,i.TtoW1.w,i.TtoW2.w); fixed3 viewDir normalize(UnityWorldSpaceViewDir(worldPos)); //float4 normal tex2D(_NormalTex,i.uv.zw); ////法线贴图的法线在切线空间 //float3 tanNormalUnpackNormal(normal); float2 speed _Time.y*float2( _XSpeed,_YSpeed); float4 packNormal tex2D(_NormalTex,i.uv.zw speed); fixed3 bump1 UnpackNormal(packNormal).rgb; packNormal tex2D(_NormalTex,i.uv.zw- speed); fixed3 bump2 UnpackNormal(packNormal).rgb; fixed3 bump normalize( bump1bump2); ////法线贴图的法线在世界 float3 worldNormal float3(dot(i.TtoW0.xyz, bump), dot(i.TtoW1.xyz, bump), dot(i.TtoW2.xyz, bump)); fixed3 albedo tex2D(_MainTex, i.uv.xy); float3 refl reflect(-viewDir,worldNormal); //兰伯特 //fixed3 lambertColor _LightColor0.rgb * albedo.rgb * max(0, dot(worldNormal, normalize(_WorldSpaceLightPos0.xyz))); //半角向量 //float3 halfA normalize(normalize(viewDir) normalize(_WorldSpaceLightPos0.xyz)); //高光反射 //fixed3 specularColor _LightColor0.rgb* pow(max(0, dot(worldNormal, halfA)), _SpecularNum); fixed4 reflCol texCUBE(_Cube,refl)*tex2D(_MainTex,i.uv); float2 offset bump.xy*_Distortion; i.grabPos.xy offset*i.grabPos.z i.grabPos.xy; fixed2 screenUV(i.grabPos.xyoffset)/i.grabPos.w; fixed4 grabCol tex2D(_GrabTexture,screenUV); fixed fresnel _Fresnel(1- _Fresnel)* pow((1-dot(normalize(viewDir),normalize(worldNormal))),5); float4 colorreflCol*(1-fresnel)grabCol*fresnel; return color; } ENDCG } } }
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2413687.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!