Search Unity

How to convert any/this example shader of surface to vertex and fragment method?

Discussion in 'Shaders' started by cristian_ritter, Jun 3, 2013.

  1. cristian_ritter

    cristian_ritter

    Joined:
    Aug 11, 2011
    Posts:
    37
    How to convert any/this example shader of surface to vertex and fragment method?

    A example code:
    Code (csharp):
    1.  
    2. Shader "Nature/Terrain/Bumped Specular" {
    3. Properties {
    4.     _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
    5.     _Shininess ("Shininess", Range (0.03, 1)) = 0.078125
    6.  
    7.     // set by terrain engine
    8.     [HideInInspector] _Control ("Control (RGBA)", 2D) = "red" {}
    9.     [HideInInspector] _Splat3 ("Layer 3 (A)", 2D) = "white" {}
    10.     [HideInInspector] _Splat2 ("Layer 2 (B)", 2D) = "white" {}
    11.     [HideInInspector] _Splat1 ("Layer 1 (G)", 2D) = "white" {}
    12.     [HideInInspector] _Splat0 ("Layer 0 (R)", 2D) = "white" {}
    13.     [HideInInspector] _Normal3 ("Normal 3 (A)", 2D) = "bump" {}
    14.     [HideInInspector] _Normal2 ("Normal 2 (B)", 2D) = "bump" {}
    15.     [HideInInspector] _Normal1 ("Normal 1 (G)", 2D) = "bump" {}
    16.     [HideInInspector] _Normal0 ("Normal 0 (R)", 2D) = "bump" {}
    17.     // used in fallback on old cards  base map
    18.     [HideInInspector] _MainTex ("BaseMap (RGB)", 2D) = "white" {}
    19.     [HideInInspector] _Color ("Main Color", Color) = (1,1,1,1)
    20. }
    21.    
    22. SubShader {
    23.     Tags {
    24.         "SplatCount" = "4"
    25.         "Queue" = "Geometry-100"
    26.         "RenderType" = "Opaque"
    27.     }
    28. CGPROGRAM
    29. #pragma surface surf BlinnPhong vertex:vert
    30. #pragma target 3.0
    31.  
    32. void vert (inout appdata_full v)
    33. {
    34.     v.tangent.xyz = cross(v.normal, float3(0,0,1));
    35.     v.tangent.w = -1;
    36. }
    37.  
    38. struct Input {
    39.     float2 uv_Control : TEXCOORD0;
    40.     float2 uv_Splat0 : TEXCOORD1;
    41.     float2 uv_Splat1 : TEXCOORD2;
    42.     float2 uv_Splat2 : TEXCOORD3;
    43.     float2 uv_Splat3 : TEXCOORD4;
    44. };
    45.  
    46. sampler2D _Control;
    47. sampler2D _Splat0,_Splat1,_Splat2,_Splat3;
    48. sampler2D _Normal0,_Normal1,_Normal2,_Normal3;
    49. half _Shininess;
    50.  
    51. void surf (Input IN, inout SurfaceOutput o) {
    52.     fixed4 splat_control = tex2D (_Control, IN.uv_Control);
    53.     fixed4 col;
    54.     col  = splat_control.r * tex2D (_Splat0, IN.uv_Splat0);
    55.     col += splat_control.g * tex2D (_Splat1, IN.uv_Splat1);
    56.     col += splat_control.b * tex2D (_Splat2, IN.uv_Splat2);
    57.     col += splat_control.a * tex2D (_Splat3, IN.uv_Splat3);
    58.     o.Albedo = col.rgb;
    59.  
    60.     fixed4 nrm;
    61.     nrm  = splat_control.r * tex2D (_Normal0, IN.uv_Splat0);
    62.     nrm += splat_control.g * tex2D (_Normal1, IN.uv_Splat1);
    63.     nrm += splat_control.b * tex2D (_Normal2, IN.uv_Splat2);
    64.     nrm += splat_control.a * tex2D (_Normal3, IN.uv_Splat3);
    65.     // Sum of our four splat weights might not sum up to 1, in
    66.     // case of more than 4 total splat maps. Need to lerp towards
    67.     // "flat normal" in that case.
    68.     fixed splatSum = dot(splat_control, fixed4(1,1,1,1));
    69.     fixed4 flatNormal = fixed4(0.5,0.5,1,0.5); // this is "flat normal" in both DXT5nm and xyz*2-1 cases
    70.     nrm = lerp(flatNormal, nrm, splatSum);
    71.     o.Normal = UnpackNormal(nrm);
    72.  
    73.     o.Gloss = col.a * splatSum;
    74.     o.Specular = _Shininess;
    75.  
    76.     o.Alpha = 0.0;
    77. }
    78. ENDCG  
    79. }
    80.  
    81. Dependency "AddPassShader" = "Hidden/Nature/Terrain/Bumped Specular AddPass"
    82. Dependency "BaseMapShader" = "Specular"
    83.  
    84. Fallback "Nature/Terrain/Diffuse"
    85. }
    86.  
     
  2. RC-1290

    RC-1290

    Joined:
    Jul 2, 2012
    Posts:
    639
    By performing the lighting calculations in the vertex or fragment shader.

    The question is about a rather large topic, so I decided to limit my answer to the core question: "What is the difference between Surface shaders and regular Vertex and Fragment shaders?"
    Answer: Surface Shaders handle lighting for you.

    You can find more information in the documentation on Surface Shaders and Vertex/Fragment Shaders and on Aras's Blog
     
    Last edited: Jun 4, 2013
  3. Noisecrime

    Noisecrime

    Joined:
    Apr 7, 2010
    Posts:
    2,054
    and to take this advice further, by looking through all the CGIncludes from the built-in shader source, tracking how it integrates into the shader source you've posted and by adding 'pragma debug' to the shader then looking at the compiled shader source (in Unity select the shader, then click 'open compiled source' in the inspector.
     
  4. cristian_ritter

    cristian_ritter

    Joined:
    Aug 11, 2011
    Posts:
    37
    @RC-1290 and @noisecrime, thanks for replying!

    I need to convert the shaders to use a Tasharen Fog of War, in mobile. The code was done by a guy named @shiva.js in forum.

    I'll put here your explanation:
    I made it for something as diffuse and shaders that already has vertex and fragment shader

    Any idea to put this in surface shader?
     
    Last edited: Jun 4, 2013
  5. RC-1290

    RC-1290

    Joined:
    Jul 2, 2012
    Posts:
    639
    I'm having some difficulty understanding your post and what you want. If you get the impression I misunderstood you, you could try to ask someone to help you translate the post from your native language to English.

    ----

    If you want to apply the changes suggested by shiva.js, you can do that without converting from surface to vertex+fragment shader. You can indicate that a function should be called at the start of the vertex shader (called vertex modification function in the documentation), by adding "vertex: functionName" to the #pragma that mentions the surface shader
    For example:
    Code (csharp):
    1. #pragma surface surf BlinnPhong vertex:someVertexFunction
    There's an example in the Built-in Tree Bark shader.

    If this is confusing, I recommend taking time to learn Cg and shader programming in Unity. If you want someone else to do the work for you, you can wait and hope someone is kind enough to put the time and effort in, or hire someone.
     
    Last edited: Jun 4, 2013
  6. cristian_ritter

    cristian_ritter

    Joined:
    Aug 11, 2011
    Posts:
    37
    Sorry for my bad english :/ I understand the reading of English, but I'm not good at applying...
    I'll try to be more specific with my situation:

    ----------------------------------------------------------------------------------------------------------------------------------------------------------
    I downloaded the "Unity Built-in Shaders" to take a look, and applied the code sent by @shiva.js.
    I attached the code to each object on the scene, but the terrain uses "Nature/Terrain/Diffuse" shader and I need adapt code for this shader...
    I made some changes in the code, and now I have this:

    Code (csharp):
    1.  
    2. Shader "Mobile/Fog of War/Nature/Terrain/Diffuse" {
    3. Properties {
    4.     [HideInInspector] _Control ("Control (RGBA)", 2D) = "red" {}
    5.     [HideInInspector] _Splat3 ("Layer 3 (A)", 2D) = "white" {}
    6.     [HideInInspector] _Splat2 ("Layer 2 (B)", 2D) = "white" {}
    7.     [HideInInspector] _Splat1 ("Layer 1 (G)", 2D) = "white" {}
    8.     [HideInInspector] _Splat0 ("Layer 0 (R)", 2D) = "white" {}
    9.     // used in fallback on old cards  base map
    10.     [HideInInspector] _MainTex ("BaseMap (RGB)", 2D) = "white" {}
    11.     [HideInInspector] _Color ("Main Color", Color) = (1,1,1,1)
    12. }
    13.    
    14. SubShader {
    15.     Tags {
    16.         "SplatCount" = "4"
    17.         "Queue" = "Geometry-100"
    18.         "RenderType" = "Opaque"
    19.     }
    20.     Pass
    21.     {
    22.         CGPROGRAM
    23. //      #pragma surface surf Lambert
    24.        
    25.         struct Input {
    26.             float2 uv_Control : TEXCOORD0;
    27.             float2 uv_Splat0 : TEXCOORD1;
    28.             float2 uv_Splat1 : TEXCOORD2;
    29.             float2 uv_Splat2 : TEXCOORD3;
    30.             float2 uv_Splat3 : TEXCOORD4;
    31.         };
    32.        
    33.         sampler2D _Control;
    34.         sampler2D _Splat0,_Splat1,_Splat2,_Splat3;
    35.        
    36.         void surf (Input IN, inout SurfaceOutput o) {
    37.             fixed4 splat_control = tex2D (_Control, IN.uv_Control);
    38.             fixed3 col;
    39.             col  = splat_control.r * tex2D (_Splat0, IN.uv_Splat0).rgb;
    40.             col += splat_control.g * tex2D (_Splat1, IN.uv_Splat1).rgb;
    41.             col += splat_control.b * tex2D (_Splat2, IN.uv_Splat2).rgb;
    42.             col += splat_control.a * tex2D (_Splat3, IN.uv_Splat3).rgb;
    43.             o.Albedo = col;
    44.             o.Alpha = 0.0;
    45.         }
    46.         ENDCG
    47.     }
    48.    
    49.     Pass
    50.     {
    51.         CGPROGRAM
    52.         #pragma vertex vert_surf
    53.         #pragma fragment frag_surf
    54.        
    55.         #include "UnityCG.cginc"
    56.    
    57.         struct v2f_surf {
    58.             float4  pos : SV_POSITION;
    59.             float2  uv : TEXCOORD0;
    60.            
    61.             float2 fog : TEXCOORD2;
    62.         };
    63.        
    64.         float4 _Color;
    65.         sampler2D _MainTex;
    66.        
    67.         //begin regin FOG_OF_WAR
    68.         sampler2D _FogTex0;
    69.         sampler2D _FogTex1;
    70.         uniform float4 _Params;
    71.         uniform half4 _Unexplored;
    72.         uniform half4 _Explored;
    73.         //end regin
    74.        
    75.         float4 _MainTex_ST;
    76.        
    77.         v2f_surf vert_surf (appdata_full v) {
    78.             v2f_surf o;
    79.          
    80.             o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    81.             o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);
    82.            
    83.             float4 worldPos = mul (_Object2World, v.vertex);
    84.             o.fog.xy = worldPos.xz * _Params.z + _Params.xy;
    85.          
    86.             return o;
    87.         }
    88.        
    89.         half4 frag_surf (v2f_surf IN) : COLOR
    90.         {
    91.             half4 c = tex2D (_MainTex, IN.uv);
    92.            
    93.             half4 fog = lerp(tex2D(_FogTex0, IN.fog), tex2D(_FogTex1, IN.fog), _Params.w);
    94.             c= lerp(lerp(c * _Unexplored, c * _Explored, fog.g), c, fog.r);
    95.          
    96.             return c * _Color;
    97.         }
    98.         ENDCG
    99.     }
    100. }
    101.  
    102. Dependency "AddPassShader" = "Hidden/TerrainEngine/Splatmap/Lightmap-AddPass"
    103. Dependency "BaseMapShader" = "Diffuse"
    104.  
    105. Fallback "Mobile/Fog of War/Diffuse"
    106. }
    107.  
    as it was before:
    Code (csharp):
    1.  
    2. Shader "Nature/Terrain/Diffuse" {
    3. Properties {
    4.     [HideInInspector] _Control ("Control (RGBA)", 2D) = "red" {}
    5.     [HideInInspector] _Splat3 ("Layer 3 (A)", 2D) = "white" {}
    6.     [HideInInspector] _Splat2 ("Layer 2 (B)", 2D) = "white" {}
    7.     [HideInInspector] _Splat1 ("Layer 1 (G)", 2D) = "white" {}
    8.     [HideInInspector] _Splat0 ("Layer 0 (R)", 2D) = "white" {}
    9.     // used in fallback on old cards  base map
    10.     [HideInInspector] _MainTex ("BaseMap (RGB)", 2D) = "white" {}
    11.     [HideInInspector] _Color ("Main Color", Color) = (1,1,1,1)
    12. }
    13.    
    14. SubShader {
    15.     Tags {
    16.         "SplatCount" = "4"
    17.         "Queue" = "Geometry-100"
    18.         "RenderType" = "Opaque"
    19.     }
    20. CGPROGRAM
    21. #pragma surface surf Lambert
    22. struct Input {
    23.     float2 uv_Control : TEXCOORD0;
    24.     float2 uv_Splat0 : TEXCOORD1;
    25.     float2 uv_Splat1 : TEXCOORD2;
    26.     float2 uv_Splat2 : TEXCOORD3;
    27.     float2 uv_Splat3 : TEXCOORD4;
    28. };
    29.  
    30. sampler2D _Control;
    31. sampler2D _Splat0,_Splat1,_Splat2,_Splat3;
    32.  
    33. void surf (Input IN, inout SurfaceOutput o) {
    34.     fixed4 splat_control = tex2D (_Control, IN.uv_Control);
    35.     fixed3 col;
    36.     col  = splat_control.r * tex2D (_Splat0, IN.uv_Splat0).rgb;
    37.     col += splat_control.g * tex2D (_Splat1, IN.uv_Splat1).rgb;
    38.     col += splat_control.b * tex2D (_Splat2, IN.uv_Splat2).rgb;
    39.     col += splat_control.a * tex2D (_Splat3, IN.uv_Splat3).rgb;
    40.     o.Albedo = col;
    41.     o.Alpha = 0.0;
    42. }
    43. ENDCG  
    44. }
    45.  
    46. Dependency "AddPassShader" = "Hidden/TerrainEngine/Splatmap/Lightmap-AddPass"
    47. Dependency "BaseMapShader" = "Diffuse"
    48.  
    49. // Fallback to Diffuse
    50. Fallback "Diffuse"
    51. }
    52.  
    This is the working "Diffuse" code for vertex fragment by @shiva.js:
    Code (csharp):
    1.  
    2. // Unlit shader. Simplest possible textured shader.
    3. // - no lighting
    4. // - no lightmap support
    5. // - no per-material color
    6.  
    7. Shader "Mobile/Fog of War/Diffuse"
    8. {
    9.     Properties {
    10.         _Color ("Main Color", Color) = (1,1,1,1)
    11.         _MainTex ("Texture", 2D) = "white" { }
    12.     }
    13.     SubShader {
    14.         Pass {
    15.      
    16.         CGPROGRAM
    17.         #pragma vertex vert
    18.         #pragma fragment frag
    19.          
    20.         #include "UnityCG.cginc"
    21.          
    22.         float4 _Color;
    23.         sampler2D _MainTex;
    24.          
    25.         //begin regin FOG_OF_WAR
    26.         sampler2D _FogTex0;
    27.         sampler2D _FogTex1;
    28.         uniform float4 _Params;
    29.         uniform half4 _Unexplored;
    30.         uniform half4 _Explored;
    31.         //end regin
    32.          
    33.         struct v2f {
    34.             float4  pos : SV_POSITION;
    35.             float2  uv : TEXCOORD0;
    36.            
    37.             float2 fog : TEXCOORD2; // this is the new line to add
    38.         };
    39.          
    40.         float4 _MainTex_ST;
    41.          
    42.         v2f vert (appdata_base v)
    43.         {
    44.             v2f o;
    45.             o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    46.             o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);
    47.            
    48.             float4 worldPos = mul (_Object2World, v.vertex);
    49.             o.fog.xy = worldPos.xz * _Params.z + _Params.xy;
    50.            
    51.             return o;
    52.         }
    53.          
    54.         half4 frag (v2f i) : COLOR
    55.         {
    56.             half4 c = tex2D (_MainTex, i.uv);
    57.            
    58.             half4 fog = lerp(tex2D(_FogTex0, i.fog), tex2D(_FogTex1, i.fog), _Params.w);
    59.             c= lerp(lerp(c * _Unexplored, c * _Explored, fog.g), c, fog.r); // where c is the fixed4 that you will return
    60.            
    61.             return c * _Color;
    62.         }
    63.        
    64.         ENDCG
    65.         }
    66.     }
    67.     Fallback "Diffuse"
    68. }
    69.  
    ----------------------------------------------------------------------------------------------------------------------------------------------------------

    This is it, do you have any idea to solve that? (Especially in relation to the part of splats)
     
    Last edited: Jun 4, 2013
  7. RC-1290

    RC-1290

    Joined:
    Jul 2, 2012
    Posts:
    639
    Solve what exactly? Are you simply looking for someone to merge the functionality for you?

    Keep in mind that Surface Shaders create their own passes, so you can't place them inside other Pass blocks.
     
  8. sanjit8801681811

    sanjit8801681811

    Joined:
    Jan 11, 2016
    Posts:
    1
    there is any way to use lighting in vertex shader.
     
  9. robin-gallimard

    robin-gallimard

    Joined:
    Feb 2, 2015
    Posts:
    6