当前位置:   article > 正文

Unity 内置Surface着色器转换到vert/frag着色器_unity 表面着色器 翻译成顶点着色器

unity 表面着色器 翻译成顶点着色器

本文出发点在于,从shader可视化工具制作的shader导出的表面着色器,需要进行重写!

从编辑器中导出的着色器,很多事表面着色器,表面着色器是unity提供的一种更高层的封装,虽然降低了shader入门的难度,但是这种shader,会包含大量的变体,里面的逻辑由于封装而无法被开发者控制,所以,需要将表面着色器转换为顶点片元着色器;前提:需要在一定程度上了解表面着色器,如果不了解,推荐可以简单看一下官方文档,或《Unity Shader入门精要》- 17章;

可以选择直接重写,但有时,如果想要完整复现导出的surface着色器,可以通过先将其转换为顶点片元着色器,然后移除不必要的代码,再根据其顶点片元着色器来理解它究竟真正做了什么工作;

随便新建一个表面着色器,然后转换为顶点片元着色器,及时是一个简单的lamber模型,我们可以看到会生成上千行代码,并带来很多变体;

我们的剔除工作就是根据不必要的变体关键字来去除,首先是移除不必要的pass,可以搜索pass关键字,然后将第一个pass之后的全部移除,他们通常是不必要的;然后只关心一个pass,可以看到它根据不同的宏定义了不同的结构体和片元着色器,根据ifdef和ifndef等可以去除;最后得到一个只有一个顶点和片元着色器的pass,去尝试着理解这个pass里做了什么;当然,剔除的时候要关注材质效果是否发生了变化,如果发生了变化,那说明删除的代码是受到影响的;

最终可以得到一个简易版本,如下是一个简单的lambert模型:

  1. // Upgrade NOTE: replaced 'defined FOG_COMBINED_WITH_WORLD_POS' with 'defined (FOG_COMBINED_WITH_WORLD_POS)'
  2. Shader "SurfaceTest/Surf2Vert" {
  3. Properties {
  4. _MainTex ("Texture", 2D) = "white" {}
  5. _Color ("Main Color", Color) = (1,1,1,1)
  6. }
  7. SubShader {
  8. Tags { "RenderType" = "Opaque" }
  9. // ------------------------------------------------------------
  10. // Surface shader code generated out of a CGPROGRAM block:
  11. // ---- forward rendering base pass:
  12. Pass {
  13. Name "FORWARD"
  14. Tags { "LightMode" = "ForwardBase" }
  15. CGPROGRAM
  16. // compile directives
  17. #pragma vertex vert_surf
  18. #pragma fragment frag_surf
  19. #pragma multi_compile_instancing
  20. #pragma multi_compile_fog
  21. #pragma multi_compile_fwdbase
  22. #include "HLSLSupport.cginc"
  23. #define UNITY_INSTANCED_LOD_FADE
  24. #define UNITY_INSTANCED_SH
  25. #define UNITY_INSTANCED_LIGHTMAPSTS
  26. #include "UnityShaderVariables.cginc"
  27. #include "UnityShaderUtilities.cginc"
  28. // -------- variant for: <when no other keywords are defined>
  29. #if !defined(INSTANCING_ON)
  30. #include "UnityCG.cginc"
  31. #include "Lighting.cginc"
  32. #include "AutoLight.cginc"
  33. #define INTERNAL_DATA
  34. #define WorldReflectionVector(data,normal) data.worldRefl
  35. #define WorldNormalVector(data,normal) normal
  36. half4 LightingSimpleLambert (SurfaceOutput s, half3 lightDir, half atten) {
  37. half NdotL = dot (s.Normal, lightDir);
  38. half4 c;
  39. c.rgb = s.Albedo * _LightColor0.rgb * max(0, NdotL);
  40. c.a = s.Alpha;
  41. return c;
  42. // return fixed4(0,0,0,1);
  43. }
  44. struct Input {
  45. float2 uv_MainTex;
  46. };
  47. sampler2D _MainTex;
  48. fixed4 _Color;
  49. void surf (Input IN, inout SurfaceOutput o) {
  50. o.Albedo = tex2D(_MainTex, IN.uv_MainTex) * _Color;
  51. // o.Albedo = fixed4(0,1,0,1);
  52. }
  53. // high-precision fragment shader registers:
  54. #ifndef UNITY_HALF_PRECISION_FRAGMENT_SHADER_REGISTERS
  55. struct v2f_surf {
  56. UNITY_POSITION(pos);
  57. float2 pack0 : TEXCOORD0; // _MainTex
  58. float3 worldNormal : TEXCOORD1;
  59. float3 worldPos : TEXCOORD2;
  60. fixed3 vlight : TEXCOORD3; // ambient/SH/vertexlights
  61. UNITY_FOG_COORDS(4)
  62. UNITY_SHADOW_COORDS(5)
  63. #if SHADER_TARGET >= 30
  64. float4 lmap : TEXCOORD6;
  65. #endif
  66. UNITY_VERTEX_INPUT_INSTANCE_ID
  67. UNITY_VERTEX_OUTPUT_STEREO
  68. };
  69. #endif
  70. // with lightmaps:
  71. float4 _MainTex_ST;
  72. // vertex shader
  73. v2f_surf vert_surf (appdata_full v) {
  74. // UNITY_SETUP_INSTANCE_ID(v);
  75. v2f_surf o;
  76. // UNITY_INITIALIZE_OUTPUT(v2f_surf,o);
  77. // UNITY_TRANSFER_INSTANCE_ID(v,o);
  78. // UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  79. o.pos = UnityObjectToClipPos(v.vertex);
  80. o.pack0.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
  81. float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
  82. float3 worldNormal = UnityObjectToWorldNormal(v.normal);
  83. o.worldPos.xyz = worldPos;
  84. o.worldNormal = worldNormal;
  85. // SH/ambient and vertex lights
  86. #ifndef LIGHTMAP_ON
  87. #if UNITY_SHOULD_SAMPLE_SH && !UNITY_SAMPLE_FULL_SH_PER_PIXEL
  88. float3 shlight = ShadeSH9 (float4(worldNormal,1.0));
  89. o.vlight = shlight;
  90. #else
  91. o.vlight = 0.0;
  92. #endif
  93. #endif // !LIGHTMAP_ON
  94. // UNITY_TRANSFER_LIGHTING(o,v.texcoord1.xy); // pass shadow and, possibly, light cookie coordinates to pixel shader
  95. // #ifdef FOG_COMBINED_WITH_TSPACE
  96. // UNITY_TRANSFER_FOG_COMBINED_WITH_TSPACE(o,o.pos); // pass fog coordinates to pixel shader
  97. // #elif defined (FOG_COMBINED_WITH_WORLD_POS)
  98. // UNITY_TRANSFER_FOG_COMBINED_WITH_WORLD_POS(o,o.pos); // pass fog coordinates to pixel shader
  99. // #else
  100. // UNITY_TRANSFER_FOG(o,o.pos); // pass fog coordinates to pixel shader
  101. // #endif
  102. return o;
  103. }
  104. // fragment shader
  105. fixed4 frag_surf (v2f_surf IN) : SV_Target {
  106. UNITY_SETUP_INSTANCE_ID(IN);
  107. // prepare and unpack data
  108. Input surfIN;
  109. UNITY_INITIALIZE_OUTPUT(Input,surfIN);
  110. surfIN.uv_MainTex.x = 1.0;
  111. surfIN.uv_MainTex = IN.pack0.xy;
  112. float3 worldPos = IN.worldPos.xyz;
  113. #ifndef USING_DIRECTIONAL_LIGHT
  114. fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));
  115. #else
  116. fixed3 lightDir = _WorldSpaceLightPos0.xyz;
  117. #endif
  118. #ifdef UNITY_COMPILER_HLSL
  119. SurfaceOutput o = (SurfaceOutput)0;
  120. #else
  121. SurfaceOutput o;
  122. #endif
  123. o.Albedo = 0.0;
  124. o.Emission = 0.0;
  125. o.Specular = 0.0;
  126. o.Alpha = 0.0;
  127. o.Gloss = 0.0;
  128. fixed3 normalWorldVertex = fixed3(0,0,1);
  129. // return fixed4(0.5* normalize(IN.worldNormal)+0.5, 1);
  130. o.Normal = IN.worldNormal;
  131. normalWorldVertex = IN.worldNormal;
  132. surf (surfIN, o);
  133. UNITY_LIGHT_ATTENUATION(atten, IN, worldPos)
  134. fixed4 c = 0;
  135. #ifndef LIGHTMAP_ON
  136. c.rgb += o.Albedo * IN.vlight;
  137. #endif
  138. #ifndef LIGHTMAP_ON
  139. c += LightingSimpleLambert (o, lightDir, atten);
  140. // return c;
  141. #else
  142. c.a = o.Alpha;
  143. #endif
  144. UNITY_APPLY_FOG(_unity_fogCoord, c); // apply fog
  145. UNITY_OPAQUE_ALPHA(c.a);
  146. return c;
  147. }
  148. #endif
  149. ENDCG
  150. }
  151. }
  152. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/107822
推荐阅读
相关标签
  

闽ICP备14008679号