赞
踩
开启此篇章的原因: 现在都已经更新到 URP了,并且日常工作中也不会使用到Standard shader(工作中的shader都是自己人写的),之前了解过,也翻看过基本的standard shader 代码逻辑(尤其是PBR相关)。。。。
(1)之前在B站听大佬说:我认识的TA大佬,都把unity 内置的shader源码搂过一遍了。。。。。。 于是乎 我也想跟随大佬的脚步,认认真真的学习整理一遍,加深自己的记忆,也为以后忘记 迅速查找留下痕迹。。。
(2)最近由于工作需要,美术同学使用ASE 使用standard shader 连线做的shader… 需要翻译为普通的vf shader,。。。。。。于是乎,开启此系列:
此篇记录standardSurface shader 的基本结构
以及将standardSurface(后面简称 surface shader) 生成普通的vert frag shader (后面简称 vf shader)的代码:
在代码中有基本的结构注释,从 surface shader中声明的函数, 对应到 生成的 vf shader中的调用,体会达到的目的,更加深入的理解surface shader。
Shader "Custom/SurfaceShader01" { Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Albedo (RGB)", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM // // vertex: vert 第一步 // vert 在顶点着色器中调用: 负责初始化一个 v2f_surf 的结构体 // surf 第二步 // 对传递进来的描述物体外表面材质属性信息的 SurfaceOutput结构体进行赋值 ,并且返回 // BasicDiffuse 第三步 // 在第二步的处理后, 用第二步的表面片元信息, 用BasicDiffuse 进行光照计算 // final 第四步 // 在最后的颜色输出之前, 对颜色进行自定义的修改,按照final 函数进行处理,并且输出返回 #pragma surface surf BasicDiffuse vertex:vert finalcolor: final noforwardadd #pragma target 3.0 sampler2D _MainTex; float4 _Color; struct Input { float2 uv_MainTex; }; void vert(inout appdata_full v,out Input o) { o.uv_MainTex = v.texcoord.xy; } // 下面两行是GPU Instance 所需要的声明 ,现在可以忽略删除 // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader. // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing. // #pragma instancing_options assumeuniformscaling UNITY_INSTANCING_BUFFER_START(Props) // put more per-instance properties here // 声明改顶点是否位于视线域内,来判断这个顶点是否需要输出到frag中 UNITY_INSTANCING_BUFFER_END(Props) void surf (Input IN, inout SurfaceOutput o) { // 只用最简单的颜色输出 fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; o.Albedo = c.rgb; o.Alpha = c.a; } // 此处的 LightingBasicDiffuse 函数的名字由两部分组成: Lighting + BasicDiffuse // BasicDiffuse 即为上面#pragma中声明的的函数 inline float4 LightingBasicDiffuse(SurfaceOutput s,fixed3 lightDir,fixed atten) { float diffuse_term = saturate(dot(s.Normal,lightDir)); float4 col; col.rgb = s.Albedo.rgb * _LightColor0.rgb * diffuse_term; col.a = s.Alpha; return col; } void final(Input IN,SurfaceOutput o,inout fixed4 color) { color = fixed4(0,1,0,1); } ENDCG } FallBack "Diffuse" }
在点击“show generated code” 查看vf shader 生成的具体代码:
查找上面声明函数的对应关系和具体实现的效果!!!!!
Shader "Custom/SurfaceShader01" { Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Albedo (RGB)", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 200 // ------------------------------------------------------------ // Surface shader code generated out of a CGPROGRAM block: // ---- forward rendering base pass: Pass { Name "FORWARD" Tags { "LightMode" = "ForwardBase" } CGPROGRAM // compile directives #pragma vertex vert_surf #pragma fragment frag_surf #pragma target 3.0 #pragma multi_compile_instancing #pragma multi_compile_fog #pragma multi_compile_fwdbase #include "HLSLSupport.cginc" #include "UnityShaderVariables.cginc" #include "UnityShaderUtilities.cginc" // -------- variant for: <when no other keywords are defined> #if !defined(INSTANCING_ON) // Surface shader code generated based on: // vertex modifier: 'vert' // writes to per-pixel normal: no // writes to emission: no // writes to occlusion: no // needs world space reflection vector: no // needs world space normal vector: no // needs screen space position: no // needs world space position: no // needs view direction: no // needs world space view direction: no // needs world space position for lighting: no // needs world space view direction for lighting: no // needs world space view direction for lightmaps: no // needs vertex color: no // needs VFACE: no // passes tangent-to-world matrix to pixel shader: no // reads from normal: no // 1 texcoords actually used // float2 _MainTex #define UNITY_PASS_FORWARDBASE #include "UnityCG.cginc" #include "Lighting.cginc" #include "AutoLight.cginc" #define INTERNAL_DATA #define WorldReflectionVector(data,normal) data.worldRefl #define WorldNormalVector(data,normal) normal // Original surface shader snippet: #line 8 "" #ifdef DUMMY_PREPROCESSOR_TO_WORK_AROUND_HLSL_COMPILER_LINE_HANDLING #endif /* UNITY: Original start of shader */ // // vertex: vert 第一步 // vert 在顶点着色器中调用: 负责初始化一个 v2f_surf 的结构体 // surf 第二步 // 对传递进来的描述物体外表面材质属性信息的 SurfaceOutput结构体进行赋值 ,并且返回 // BasicDiffuse 第三步 // 在第二步的处理后, 用第二步的表面片元信息, 用BasicDiffuse 进行光照计算 // final 第四步 // 在最后的颜色输出之前, 对颜色进行自定义的修改,按照final 函数进行处理,并且输出返回 //#pragma surface surf BasicDiffuse vertex:vert finalcolor: final noforwardadd //#pragma target 3.0 sampler2D _MainTex; float4 _Color; struct Input { float2 uv_MainTex; }; void vert(inout appdata_full v,out Input o) { o.uv_MainTex = v.texcoord.xy; } // 下面两行是GPU Instance 所需要的声明 ,现在可以忽略删除 // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader. // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing. // //#pragma instancing_options assumeuniformscaling UNITY_INSTANCING_BUFFER_START(Props) // put more per-instance properties here // 声明改顶点是否位于视线域内,来判断这个顶点是否需要输出到frag中 UNITY_INSTANCING_BUFFER_END(Props) void surf (Input IN, inout SurfaceOutput o) { // 只用最简单的颜色输出 fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; o.Albedo = c.rgb; o.Alpha = c.a; } // 此处的 LightingBasicDiffuse 函数的名字由两部分组成: Lighting + BasicDiffuse // BasicDiffuse 即为上面#pragma中声明的的函数 inline float4 LightingBasicDiffuse(SurfaceOutput s,fixed3 lightDir,fixed atten) { float diffuse_term = saturate(dot(s.Normal,lightDir)); float4 col; col.rgb = s.Albedo.rgb * _LightColor0.rgb * diffuse_term; col.a = s.Alpha; return col; } void final(Input IN,SurfaceOutput o,inout fixed4 color) { color = fixed4(0,1,0,1); } // vertex-to-fragment interpolation data // no lightmaps: #ifndef LIGHTMAP_ON struct v2f_surf { UNITY_POSITION(pos); float2 pack0 : TEXCOORD0; // _MainTex float3 worldNormal : TEXCOORD1; float3 worldPos : TEXCOORD2; fixed3 vlight : TEXCOORD3; // ambient/SH/vertexlights UNITY_SHADOW_COORDS(4) UNITY_FOG_COORDS(5) #if SHADER_TARGET >= 30 float4 lmap : TEXCOORD6; #endif UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; #endif // with lightmaps: #ifdef LIGHTMAP_ON struct v2f_surf { UNITY_POSITION(pos); float2 pack0 : TEXCOORD0; // _MainTex float3 worldNormal : TEXCOORD1; float3 worldPos : TEXCOORD2; float4 lmap : TEXCOORD3; UNITY_SHADOW_COORDS(4) UNITY_FOG_COORDS(5) #ifdef DIRLIGHTMAP_COMBINED float3 tSpace0 : TEXCOORD6; float3 tSpace1 : TEXCOORD7; float3 tSpace2 : TEXCOORD8; #endif UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; #endif float4 _MainTex_ST; // vertex shader v2f_surf vert_surf (appdata_full v) { UNITY_SETUP_INSTANCE_ID(v); v2f_surf o; UNITY_INITIALIZE_OUTPUT(v2f_surf,o); UNITY_TRANSFER_INSTANCE_ID(v,o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); Input customInputData; vert (v, customInputData); o.pos = UnityObjectToClipPos(v.vertex); o.pack0.xy = TRANSFORM_TEX(v.texcoord, _MainTex); float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; float3 worldNormal = UnityObjectToWorldNormal(v.normal); #if defined(LIGHTMAP_ON) && defined(DIRLIGHTMAP_COMBINED) fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz); fixed tangentSign = v.tangent.w * unity_WorldTransformParams.w; fixed3 worldBinormal = cross(worldNormal, worldTangent) * tangentSign; #endif #if defined(LIGHTMAP_ON) && defined(DIRLIGHTMAP_COMBINED) o.tSpace0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x); o.tSpace1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y); o.tSpace2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z); #endif o.worldPos = worldPos; o.worldNormal = worldNormal; #ifdef DYNAMICLIGHTMAP_ON o.lmap.zw = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; #endif #ifdef LIGHTMAP_ON o.lmap.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw; #endif // SH/ambient and vertex lights #ifndef LIGHTMAP_ON #if UNITY_SHOULD_SAMPLE_SH && !UNITY_SAMPLE_FULL_SH_PER_PIXEL float3 shlight = ShadeSH9 (float4(worldNormal,1.0)); o.vlight = shlight; #else o.vlight = 0.0; #endif #ifdef VERTEXLIGHT_ON o.vlight += Shade4PointLights ( unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb, unity_4LightAtten0, worldPos, worldNormal ); #endif // VERTEXLIGHT_ON #endif // !LIGHTMAP_ON UNITY_TRANSFER_SHADOW(o,v.texcoord1.xy); // pass shadow coordinates to pixel shader UNITY_TRANSFER_FOG(o,o.pos); // pass fog coordinates to pixel shader return o; } // fragment shader fixed4 frag_surf (v2f_surf IN) : SV_Target { UNITY_SETUP_INSTANCE_ID(IN); // prepare and unpack data Input surfIN; UNITY_INITIALIZE_OUTPUT(Input,surfIN); surfIN.uv_MainTex.x = 1.0; surfIN.uv_MainTex = IN.pack0.xy; float3 worldPos = IN.worldPos; #ifndef USING_DIRECTIONAL_LIGHT fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos)); #else fixed3 lightDir = _WorldSpaceLightPos0.xyz; #endif #ifdef UNITY_COMPILER_HLSL SurfaceOutput o = (SurfaceOutput)0; #else SurfaceOutput o; #endif o.Albedo = 0.0; o.Emission = 0.0; o.Specular = 0.0; o.Alpha = 0.0; o.Gloss = 0.0; fixed3 normalWorldVertex = fixed3(0,0,1); o.Normal = IN.worldNormal; normalWorldVertex = IN.worldNormal; // call surface function surf (surfIN, o); // compute lighting & shadowing factor UNITY_LIGHT_ATTENUATION(atten, IN, worldPos) fixed4 c = 0; #ifndef LIGHTMAP_ON c.rgb += o.Albedo * IN.vlight; #endif // !LIGHTMAP_ON // lightmaps #ifdef LIGHTMAP_ON #if DIRLIGHTMAP_COMBINED // directional lightmaps fixed4 lmtex = UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.lmap.xy); half3 lm = DecodeLightmap(lmtex); #else // single lightmap fixed4 lmtex = UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.lmap.xy); fixed3 lm = DecodeLightmap (lmtex); #endif #endif // LIGHTMAP_ON // realtime lighting: call lighting function #ifndef LIGHTMAP_ON c += LightingBasicDiffuse (o, lightDir, atten); #else c.a = o.Alpha; #endif #ifdef LIGHTMAP_ON // combine lightmaps with realtime shadows #ifdef SHADOWS_SCREEN #if defined(UNITY_NO_RGBM) c.rgb += o.Albedo * min(lm, atten*2); #else c.rgb += o.Albedo * max(min(lm,(atten*2)*lmtex.rgb), lm*atten); #endif #else // SHADOWS_SCREEN c.rgb += o.Albedo * lm; #endif // SHADOWS_SCREEN #endif // LIGHTMAP_ON #ifdef DYNAMICLIGHTMAP_ON fixed4 dynlmtex = UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, IN.lmap.zw); c.rgb += o.Albedo * DecodeRealtimeLightmap (dynlmtex); #endif UNITY_APPLY_FOG(IN.fogCoord, c); // apply fog UNITY_OPAQUE_ALPHA(c.a); return c; } #endif // -------- variant for: INSTANCING_ON #if defined(INSTANCING_ON) // Surface shader code generated based on: // vertex modifier: 'vert' // writes to per-pixel normal: no // writes to emission: no // writes to occlusion: no // needs world space reflection vector: no // needs world space normal vector: no // needs screen space position: no // needs world space position: no // needs view direction: no // needs world space view direction: no // needs world space position for lighting: no // needs world space view direction for lighting: no // needs world space view direction for lightmaps: no // needs vertex color: no // needs VFACE: no // passes tangent-to-world matrix to pixel shader: no // reads from normal: no // 1 texcoords actually used // float2 _MainTex #define UNITY_PASS_FORWARDBASE #include "UnityCG.cginc" #include "Lighting.cginc" #include "AutoLight.cginc" #define INTERNAL_DATA #define WorldReflectionVector(data,normal) data.worldRefl #define WorldNormalVector(data,normal) normal // Original surface shader snippet: #line 8 "" #ifdef DUMMY_PREPROCESSOR_TO_WORK_AROUND_HLSL_COMPILER_LINE_HANDLING #endif /* UNITY: Original start of shader */ // // vertex: vert 第一步 // vert 在顶点着色器中调用: 负责初始化一个 v2f_surf 的结构体 // surf 第二步 // 对传递进来的描述物体外表面材质属性信息的 SurfaceOutput结构体进行赋值 ,并且返回 // BasicDiffuse 第三步 // 在第二步的处理后, 用第二步的表面片元信息, 用BasicDiffuse 进行光照计算 // final 第四步 // 在最后的颜色输出之前, 对颜色进行自定义的修改,按照final 函数进行处理,并且输出返回 //#pragma surface surf BasicDiffuse vertex:vert finalcolor: final noforwardadd //#pragma target 3.0 sampler2D _MainTex; float4 _Color; struct Input { float2 uv_MainTex; }; void vert(inout appdata_full v,out Input o) { o.uv_MainTex = v.texcoord.xy; } // 下面两行是GPU Instance 所需要的声明 ,现在可以忽略删除 // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader. // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing. // //#pragma instancing_options assumeuniformscaling UNITY_INSTANCING_BUFFER_START(Props) // put more per-instance properties here // 声明改顶点是否位于视线域内,来判断这个顶点是否需要输出到frag中 UNITY_INSTANCING_BUFFER_END(Props) void surf (Input IN, inout SurfaceOutput o) { // 只用最简单的颜色输出 fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; o.Albedo = c.rgb; o.Alpha = c.a; } // 此处的 LightingBasicDiffuse 函数的名字由两部分组成: Lighting + BasicDiffuse // BasicDiffuse 即为上面#pragma中声明的的函数 inline float4 LightingBasicDiffuse(SurfaceOutput s,fixed3 lightDir,fixed atten) { float diffuse_term = saturate(dot(s.Normal,lightDir)); float4 col; col.rgb = s.Albedo.rgb * _LightColor0.rgb * diffuse_term; col.a = s.Alpha; return col; } void final(Input IN,SurfaceOutput o,inout fixed4 color) { color = fixed4(0,1,0,1); } // vertex-to-fragment interpolation data // no lightmaps: #ifndef LIGHTMAP_ON struct v2f_surf { UNITY_POSITION(pos); float2 pack0 : TEXCOORD0; // _MainTex float3 worldNormal : TEXCOORD1; float3 worldPos : TEXCOORD2; fixed3 vlight : TEXCOORD3; // ambient/SH/vertexlights UNITY_SHADOW_COORDS(4) UNITY_FOG_COORDS(5) #if SHADER_TARGET >= 30 float4 lmap : TEXCOORD6; #endif UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; #endif // with lightmaps: #ifdef LIGHTMAP_ON struct v2f_surf { UNITY_POSITION(pos); float2 pack0 : TEXCOORD0; // _MainTex float3 worldNormal : TEXCOORD1; float3 worldPos : TEXCOORD2; float4 lmap : TEXCOORD3; UNITY_SHADOW_COORDS(4) UNITY_FOG_COORDS(5) #ifdef DIRLIGHTMAP_COMBINED float3 tSpace0 : TEXCOORD6; float3 tSpace1 : TEXCOORD7; float3 tSpace2 : TEXCOORD8; #endif UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; #endif float4 _MainTex_ST; // vertex shader v2f_surf vert_surf (appdata_full v) { UNITY_SETUP_INSTANCE_ID(v); v2f_surf o; UNITY_INITIALIZE_OUTPUT(v2f_surf,o); UNITY_TRANSFER_INSTANCE_ID(v,o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); Input customInputData; vert (v, customInputData); o.pos = UnityObjectToClipPos(v.vertex); o.pack0.xy = TRANSFORM_TEX(v.texcoord, _MainTex); float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; float3 worldNormal = UnityObjectToWorldNormal(v.normal); #if defined(LIGHTMAP_ON) && defined(DIRLIGHTMAP_COMBINED) fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz); fixed tangentSign = v.tangent.w * unity_WorldTransformParams.w; fixed3 worldBinormal = cross(worldNormal, worldTangent) * tangentSign; #endif #if defined(LIGHTMAP_ON) && defined(DIRLIGHTMAP_COMBINED) o.tSpace0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x); o.tSpace1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y); o.tSpace2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z); #endif o.worldPos = worldPos; o.worldNormal = worldNormal; #ifdef DYNAMICLIGHTMAP_ON o.lmap.zw = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; #endif #ifdef LIGHTMAP_ON o.lmap.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw; #endif // SH/ambient and vertex lights #ifndef LIGHTMAP_ON #if UNITY_SHOULD_SAMPLE_SH && !UNITY_SAMPLE_FULL_SH_PER_PIXEL float3 shlight = ShadeSH9 (float4(worldNormal,1.0)); o.vlight = shlight; #else o.vlight = 0.0; #endif #ifdef VERTEXLIGHT_ON o.vlight += Shade4PointLights ( unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb, unity_4LightAtten0, worldPos, worldNormal ); #endif // VERTEXLIGHT_ON #endif // !LIGHTMAP_ON UNITY_TRANSFER_SHADOW(o,v.texcoord1.xy); // pass shadow coordinates to pixel shader UNITY_TRANSFER_FOG(o,o.pos); // pass fog coordinates to pixel shader return o; } // fragment shader fixed4 frag_surf (v2f_surf IN) : SV_Target { UNITY_SETUP_INSTANCE_ID(IN); // prepare and unpack data Input surfIN; UNITY_INITIALIZE_OUTPUT(Input,surfIN); surfIN.uv_MainTex.x = 1.0; surfIN.uv_MainTex = IN.pack0.xy; float3 worldPos = IN.worldPos; #ifndef USING_DIRECTIONAL_LIGHT fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos)); #else fixed3 lightDir = _WorldSpaceLightPos0.xyz; #endif #ifdef UNITY_COMPILER_HLSL SurfaceOutput o = (SurfaceOutput)0; #else SurfaceOutput o; #endif o.Albedo = 0.0; o.Emission = 0.0; o.Specular = 0.0; o.Alpha = 0.0; o.Gloss = 0.0; fixed3 normalWorldVertex = fixed3(0,0,1); o.Normal = IN.worldNormal; normalWorldVertex = IN.worldNormal; // call surface function surf (surfIN, o); // compute lighting & shadowing factor UNITY_LIGHT_ATTENUATION(atten, IN, worldPos) fixed4 c = 0; #ifndef LIGHTMAP_ON c.rgb += o.Albedo * IN.vlight; #endif // !LIGHTMAP_ON // lightmaps #ifdef LIGHTMAP_ON #if DIRLIGHTMAP_COMBINED // directional lightmaps fixed4 lmtex = UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.lmap.xy); half3 lm = DecodeLightmap(lmtex); #else // single lightmap fixed4 lmtex = UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.lmap.xy); fixed3 lm = DecodeLightmap (lmtex); #endif #endif // LIGHTMAP_ON // realtime lighting: call lighting function #ifndef LIGHTMAP_ON c += LightingBasicDiffuse (o, lightDir, atten); #else c.a = o.Alpha; #endif #ifdef LIGHTMAP_ON // combine lightmaps with realtime shadows #ifdef SHADOWS_SCREEN #if defined(UNITY_NO_RGBM) c.rgb += o.Albedo * min(lm, atten*2); #else c.rgb += o.Albedo * max(min(lm,(atten*2)*lmtex.rgb), lm*atten); #endif #else // SHADOWS_SCREEN c.rgb += o.Albedo * lm; #endif // SHADOWS_SCREEN #endif // LIGHTMAP_ON #ifdef DYNAMICLIGHTMAP_ON fixed4 dynlmtex = UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, IN.lmap.zw); c.rgb += o.Albedo * DecodeRealtimeLightmap (dynlmtex); #endif UNITY_APPLY_FOG(IN.fogCoord, c); // apply fog UNITY_OPAQUE_ALPHA(c.a); return c; } #endif ENDCG } // ---- meta information extraction pass: Pass { Name "Meta" Tags { "LightMode" = "Meta" } Cull Off CGPROGRAM // compile directives #pragma vertex vert_surf #pragma fragment frag_surf #pragma target 3.0 #pragma multi_compile_instancing #pragma skip_variants FOG_LINEAR FOG_EXP FOG_EXP2 #pragma skip_variants INSTANCING_ON #pragma shader_feature EDITOR_VISUALIZATION #include "HLSLSupport.cginc" #include "UnityShaderVariables.cginc" #include "UnityShaderUtilities.cginc" // -------- variant for: <when no other keywords are defined> #if !defined(INSTANCING_ON) // Surface shader code generated based on: // vertex modifier: 'vert' // writes to per-pixel normal: no // writes to emission: no // writes to occlusion: no // needs world space reflection vector: no // needs world space normal vector: no // needs screen space position: no // needs world space position: no // needs view direction: no // needs world space view direction: no // needs world space position for lighting: no // needs world space view direction for lighting: no // needs world space view direction for lightmaps: no // needs vertex color: no // needs VFACE: no // passes tangent-to-world matrix to pixel shader: no // reads from normal: no // 1 texcoords actually used // float2 _MainTex #define UNITY_PASS_META #include "UnityCG.cginc" #include "Lighting.cginc" #define INTERNAL_DATA #define WorldReflectionVector(data,normal) data.worldRefl #define WorldNormalVector(data,normal) normal // Original surface shader snippet: #line 8 "" #ifdef DUMMY_PREPROCESSOR_TO_WORK_AROUND_HLSL_COMPILER_LINE_HANDLING #endif /* UNITY: Original start of shader */ // // vertex: vert 第一步 // vert 在顶点着色器中调用: 负责初始化一个 v2f_surf 的结构体 // surf 第二步 // 对传递进来的描述物体外表面材质属性信息的 SurfaceOutput结构体进行赋值 ,并且返回 // BasicDiffuse 第三步 // 在第二步的处理后, 用第二步的表面片元信息, 用BasicDiffuse 进行光照计算 // final 第四步 // 在最后的颜色输出之前, 对颜色进行自定义的修改,按照final 函数进行处理,并且输出返回 //#pragma surface surf BasicDiffuse vertex:vert finalcolor: final noforwardadd //#pragma target 3.0 sampler2D _MainTex; float4 _Color; struct Input { float2 uv_MainTex; }; void vert(inout appdata_full v,out Input o) { o.uv_MainTex = v.texcoord.xy; } // 下面两行是GPU Instance 所需要的声明 ,现在可以忽略删除 // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader. // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing. // //#pragma instancing_options assumeuniformscaling UNITY_INSTANCING_BUFFER_START(Props) // put more per-instance properties here // 声明改顶点是否位于视线域内,来判断这个顶点是否需要输出到frag中 UNITY_INSTANCING_BUFFER_END(Props) void surf (Input IN, inout SurfaceOutput o) { // 只用最简单的颜色输出 fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; o.Albedo = c.rgb; o.Alpha = c.a; } // 此处的 LightingBasicDiffuse 函数的名字由两部分组成: Lighting + BasicDiffuse // BasicDiffuse 即为上面#pragma中声明的的函数 inline float4 LightingBasicDiffuse(SurfaceOutput s,fixed3 lightDir,fixed atten) { float diffuse_term = saturate(dot(s.Normal,lightDir)); float4 col; col.rgb = s.Albedo.rgb * _LightColor0.rgb * diffuse_term; col.a = s.Alpha; return col; } void final(Input IN,SurfaceOutput o,inout fixed4 color) { color = fixed4(0,1,0,1); } #include "UnityMetaPass.cginc" // vertex-to-fragment interpolation data struct v2f_surf { UNITY_POSITION(pos); float2 pack0 : TEXCOORD0; // _MainTex UNITY_VERTEX_INPUT_INSTANCE_ID UNITY_VERTEX_OUTPUT_STEREO }; float4 _MainTex_ST; // vertex shader v2f_surf vert_surf (appdata_full v) { UNITY_SETUP_INSTANCE_ID(v); v2f_surf o; UNITY_INITIALIZE_OUTPUT(v2f_surf,o); UNITY_TRANSFER_INSTANCE_ID(v,o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); Input customInputData; vert (v, customInputData); o.pos = UnityMetaVertexPosition(v.vertex, v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST); o.pack0.xy = TRANSFORM_TEX(v.texcoord, _MainTex); float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz; float3 worldNormal = UnityObjectToWorldNormal(v.normal); return o; } // fragment shader fixed4 frag_surf (v2f_surf IN) : SV_Target { UNITY_SETUP_INSTANCE_ID(IN); // prepare and unpack data Input surfIN; UNITY_INITIALIZE_OUTPUT(Input,surfIN); surfIN.uv_MainTex.x = 1.0; surfIN.uv_MainTex = IN.pack0.xy; #ifdef UNITY_COMPILER_HLSL SurfaceOutput o = (SurfaceOutput)0; #else SurfaceOutput o; #endif o.Albedo = 0.0; o.Emission = 0.0; o.Specular = 0.0; o.Alpha = 0.0; o.Gloss = 0.0; fixed3 normalWorldVertex = fixed3(0,0,1); // call surface function surf (surfIN, o); UnityMetaInput metaIN; UNITY_INITIALIZE_OUTPUT(UnityMetaInput, metaIN); metaIN.Albedo = o.Albedo; metaIN.Emission = o.Emission; metaIN.SpecularColor = o.Specular; return UnityMetaFragment(metaIN); } #endif ENDCG } // ---- end of surface shader generated code #LINE 74 } FallBack "Diffuse" }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。