Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Steep Parallax Mapping

Discussion in 'Shaders' started by WGermany, Aug 20, 2013.

  1. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78
    Hello I have this shader that I'm trying to port into Unity, I need some help getting it to work, I don't know why its not working though. No errors are given so I tried to restart Unity and nothing really happened. The compiler says now though that "OUT" not being completely initialized but I don't see how.

    More Info:
    http://graphics.cs.brown.edu/games/SteepParallax/
    http://www.chandlerprall.com/2011/09/steep-parallax-shader/

    Code (csharp):
    1. Shader "Advanced/Steep Parrallax Occ Mapping"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Color", Color) = (0.5,0.5,0.5,1)
    6.         _MainTex("Base (RGB)", 2D) = "white" {}
    7.         _NormalMap("Normal Map", 2D) = "bump" {}
    8.         _Scale ("Normalmap Bumpiness", Range(0.0, 2.0)) = 0.04
    9.         _Shininess("Shininess", Range(0.0, 5.0)) = 1.5
    10.         _Shadow("Shadow On/Off - Set to 1 to Enable", Range(0.0, 1.0)) = 1.0
    11.     }
    12.         SubShader
    13.         {
    14.        
    15.        
    16.             Pass
    17.             {
    18.                
    19.             Tags {"RenderType" = "Opaque"}
    20.            
    21.                 CGPROGRAM
    22.                 #pragma vertex vert
    23.                 #pragma fragment frag
    24.                 #pragma target 4.0
    25.                
    26.                 //Samplers
    27.                 uniform sampler2D _MainTex;
    28.                 uniform sampler2D _NormalMap;
    29.                
    30.                 //Float4's
    31.                 uniform float4 _Color;
    32.                 uniform float4 _SpecColor;
    33.                
    34.                 //Floats
    35.                 uniform float _Scale;
    36.                 uniform float _Shininess;
    37.                 uniform float _Shadow;
    38.                
    39.                 //Pre-defined
    40.                 uniform float4 _LightColor0;
    41.  
    42.                 struct vertexInput
    43.                 {
    44.                     float4 vertex : POSITION;
    45.                     float3 normal : NORMAL;
    46.                     float4 texcoord : TEXCOORD0;
    47.                     float4 tangent : TANGENT;
    48.                 };
    49.                 //Output struct
    50.                 struct vertexOutput
    51.                 {
    52.                     float4 pos : SV_POSITION;
    53.                     float4 col : COLOR;
    54.                     float4 tex : TEXCOORD0;
    55.                     float3 posTangent : TEXCOORD1;
    56.                     float3 camTangent : TEXCOORD2;
    57.                     float3 lightTangent : TEXCOORD3;
    58.                     float3 normalDir : TEXCOORD4;
    59.                     float3 tangentDir : TEXCOORD5;
    60.                     float3 binormalDir : TEXCOORD6;
    61.                    
    62.                 };
    63.                 //Vertex shader
    64.                 vertexOutput vert(vertexInput IN)
    65.                 {
    66.                     vertexOutput OUT;
    67.  
    68.                     OUT.tex = IN.texcoord;
    69.                     OUT.pos = mul(UNITY_MATRIX_MVP, IN.vertex);
    70.                    
    71.                     float3 camPos = normalize(_WorldSpaceCameraPos.xyz - OUT.posTangent.xyz);
    72.                    
    73.                     // Find  normalize the plane's normal, tangent, and binormal vectors
    74.                     OUT.normalDir = normalize(IN.normal);
    75.                     OUT.tangentDir = normalize(IN.tangent).xyz;
    76.                     OUT.binormalDir = normalize(cross(OUT.normalDir, OUT.tangentDir) * IN.tangent.w );
    77.                    
    78.                     // Convert vertice, camera, and light vector positions into tangent space
    79.                     float3x3 tangentSpaceConverter = float3x3(OUT.tangentDir, OUT.binormalDir, OUT.normalDir);
    80.                    
    81.                     OUT.posTangent = mul(OUT.pos.xyz, tangentSpaceConverter);
    82.                     OUT.camTangent = mul(camPos, tangentSpaceConverter);
    83.                     OUT.lightTangent = mul(normalize(_WorldSpaceLightPos0.xyz), tangentSpaceConverter);
    84.                    
    85.                     return OUT;
    86.        
    87.                 }
    88.                 //Pixel shader
    89.                 float4 frag(vertexOutput i) : COLOR
    90.                 {
    91.                    
    92.                     //Steep Parallax
    93.                     float bumpScale = _Scale;
    94.                    
    95.                     //Normalize the other tangent space vectors
    96.                     float3 viewVector = normalize(i.camTangent - i.posTangent);
    97.                     float3 lightVector = normalize(i.lightTangent - i.posTangent);
    98.                    
    99.                     float3 tsE = normalize(i.camTangent);
    100.                    
    101.                     const float numSteps = 30.0f; // How many steps the UV ray tracing should take
    102.                     float height = 1.0;
    103.                     float step = 1.0 / numSteps;
    104.                    
    105.                     float2 offset = float2(0.0, 0.0);
    106.                     float4 NormalMap = tex2D(_NormalMap, offset);
    107.                    
    108.                     float2 delta = float2(-tsE.x, -tsE.y) * bumpScale / (tsE.z * numSteps);
    109.                    
    110.                     // find UV offset
    111.                     for (float i = 0.0f; i < numSteps; i++)
    112.                     {
    113.                          if (NormalMap.a < height) {
    114.                         height -= step;
    115.                         offset += delta;
    116.                         NormalMap = tex2D(_NormalMap, offset);
    117.                         } else {
    118.                             break;
    119.                         }
    120.                     }
    121.        
    122.                     float3 DiffuseTex = tex2D(_MainTex, offset).rgb;
    123.                     float3 NormalTex = tex2D(_NormalMap, offset).rgb * 2.0 - 1.0f;
    124.                    
    125.                     //N*L
    126.                     float NdotL = max(0.0f, dot(NormalTex.rgb, lightVector.xyz ) );
    127.                    
    128.                     //Calculate this pixel's lighting
    129.                     float nxDir = max(0.0, dot(NormalTex.rgb, lightVector.xyz));
    130.                     float specularPower = 0.0;
    131.                     float specularColor = _SpecColor;
    132.                     if(nxDir != 0.0)
    133.                     {
    134.                             float3 halfVector = normalize(lightVector + viewVector);
    135.                             float nxHalf = max(0.0, dot(NormalTex, halfVector));
    136.                             specularPower = pow(nxHalf, _Shininess);
    137.                     }
    138.                    
    139.                     float3 specular = specularColor * specularPower;
    140.                     float3 pixel_color = UNITY_LIGHTMODEL_AMBIENT + specular + (_Color.rgb * float3(nxDir,nxDir,nxDir) * DiffuseTex);
    141.                    
    142.                     //Find shadowing if enabled
    143.                     if (_Shadow == 1.0)
    144.                     {
    145.                    
    146.                         float2 shadow_offset = offset;
    147.                         float3 tsH = normalize(lightVector + tsE);
    148.                        
    149.                         float selfShadow = 0.0;
    150.                    
    151.                          if (NdotL > 0.0)
    152.                          {
    153.                              const float numShadowSteps = 10.0;
    154.                              step = 1.0 / numShadowSteps;
    155.                              delta = float2(lightVector.x, lightVector.y) * bumpScale / (numShadowSteps * lightVector.z);
    156.                    
    157.                              height = NormalMap.a + step * 0.1;
    158.                              
    159.                              for (float i = 0.0; i < numShadowSteps; i++)
    160.                              {
    161.                                 if (NormalMap.a < height  height < 1.0)
    162.                                 {
    163.                                     height += step;
    164.                                     shadow_offset += delta;
    165.                                     NormalMap = tex2D(_NormalMap, shadow_offset);
    166.                                 } else {
    167.                                     break;
    168.                                 }
    169.                             }
    170.                                     selfShadow = float(NormalMap.a < height);        
    171.                         }
    172.                    
    173.                         if (selfShadow == 0.0)
    174.                         {
    175.                             pixel_color *= 0.5;
    176.                         }
    177.                     }
    178.                    
    179.                    
    180.                     //if (offset.x < 0.0 || offset.x > 1.0 || offset.y < 0.0 || offset.y > 1.0)
    181.                     return float4(pixel_color, 1.0);
    182.                    
    183.                 }
    184.                
    185.                 ENDCG
    186.             }          
    187.                
    188.         }
    189.         //Fallbacks
    190.         //Fallback "VertexLit"
    191. }
     
  2. Dolkar

    Dolkar

    Joined:
    Jun 8, 2013
    Posts:
    576
    It's right... You forgot to set some value to OUT.col. (Or remove it altogether... it seems like you're not using it in the fragment shader.)
     
  3. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78
    Thanks Dolkar, you're a genius :)
     
  4. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78
    I've knocked it down to just one error (got rid of the implicit casting from floatx to floaty) but I'm not exactly sure why it won't compile, I've look at my other shaders and they work just fine not pulling all information into the fragment shader. Kinda stuck now :confused:

    Current Code:

    Code (csharp):
    1. Shader "Advanced/Steep Parrallax Occ Mapping"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Color", Color) = (0.5,0.5,0.5,1)
    6.         _MainTex("Base (RGB)", 2D) = "white" {}
    7.         _NormalMap("Normal Map", 2D) = "bump" {}
    8.         _Scale ("Normalmap Bumpiness", Range(0.0, 2.0)) = 0.04
    9.         _Shininess("Shininess", Range(0.0, 5.0)) = 1.5
    10.         _Shadow("Shadow On/Off - Set to 1 to Enable", Range(0.0, 1.0)) = 1.0
    11.     }
    12.         SubShader
    13.         {
    14.        
    15.        
    16.             Pass
    17.             {
    18.                
    19.             //Tags {"RenderType" = "Opaque"}
    20.            
    21.                 CGPROGRAM
    22.                 #pragma vertex vert
    23.                 #pragma fragment frag
    24.                 #pragma target 4.0
    25.                
    26.                 //Samplers
    27.                 uniform sampler2D _MainTex;
    28.                 uniform sampler2D _NormalMap;
    29.                
    30.                 //Float4's
    31.                 uniform float4 _Color;
    32.                 uniform float4 _SpecColor;
    33.                
    34.                 //Floats
    35.                 uniform float _Scale;
    36.                 uniform float _Shininess;
    37.                 uniform float _Shadow;
    38.                
    39.                 //Pre-defined
    40.                 uniform float4 _LightColor0;
    41.  
    42.                 struct vertexInput
    43.                 {
    44.                     float4 vertex : POSITION;
    45.                     float3 normal : NORMAL;
    46.                     float4 texcoord : TEXCOORD0;
    47.                     float4 tangent : TANGENT;
    48.                 };
    49.                 //Output struct
    50.                 struct vertexOutput
    51.                 {
    52.                     float4 pos : SV_POSITION;
    53.                     float4 tex : TEXCOORD0;
    54.                     float3 posTangent : TEXCOORD1;
    55.                     float3 camTangent : TEXCOORD2;
    56.                     float3 lightTangent : TEXCOORD3;
    57.                     float3 normalDir : TEXCOORD4;
    58.                     float3 tangentDir : TEXCOORD5;
    59.                     float3 binormalDir : TEXCOORD6;
    60.                    
    61.                 };
    62.                 //Vertex shader
    63.                 vertexOutput vert(vertexInput IN)
    64.                 {
    65.                     vertexOutput OUT;
    66.  
    67.                     OUT.tex = IN.texcoord;
    68.                     OUT.pos = mul(UNITY_MATRIX_MVP, IN.vertex);
    69.                    
    70.                     float3 camPos = normalize(_WorldSpaceCameraPos.xyz - OUT.posTangent.xyz);
    71.                    
    72.                     // Find  normalize the plane's normal, tangent, and binormal vectors
    73.                     OUT.normalDir = normalize(IN.normal);
    74.                     OUT.tangentDir = normalize(IN.tangent).xyz;
    75.                     OUT.binormalDir = normalize(cross(OUT.normalDir, OUT.tangentDir) * IN.tangent.w );
    76.                    
    77.                     // Convert vertice, camera, and light vector positions into tangent space
    78.                     float3x3 tangentSpaceConverter = float3x3(OUT.tangentDir, OUT.binormalDir, OUT.normalDir);
    79.                    
    80.                     OUT.posTangent = mul(OUT.pos.xyz, tangentSpaceConverter);
    81.                     OUT.camTangent = mul(camPos, tangentSpaceConverter);
    82.                     OUT.lightTangent = mul(normalize(_WorldSpaceLightPos0.xyz), tangentSpaceConverter);
    83.                    
    84.                     return OUT;
    85.        
    86.                 }
    87.                 //Pixel shader
    88.                 float4 frag(vertexOutput i) : COLOR
    89.                 {
    90.                    
    91.                     //Steep Parallax
    92.                     float bumpScale = _Scale;
    93.                    
    94.                     //Normalize the other tangent space vectors
    95.                     float3 viewVector = normalize(i.camTangent - i.posTangent);
    96.                     float3 lightVector = normalize(i.lightTangent - i.posTangent);
    97.                    
    98.                     float3 tsE = normalize(i.camTangent);
    99.                    
    100.                     const float numSteps = 30.0f; // How many steps the UV ray tracing should take
    101.                     float height = 1.0;
    102.                     float step = 1.0 / numSteps;
    103.                    
    104.                     float2 offset = i.tex.xy;
    105.                     float4 NormalMap = tex2D(_NormalMap, offset);
    106.                    
    107.                     float2 delta = float2(-tsE.x, -tsE.y) * bumpScale / (tsE.z * numSteps);
    108.                    
    109.                     // find UV offset
    110.                     for (float i = 0.0f; i < numSteps; i++)
    111.                     {
    112.                          if (NormalMap.a < height) {
    113.                         height -= step;
    114.                         offset += delta;
    115.                         NormalMap = tex2D(_NormalMap, offset);
    116.                         } else {
    117.                             break;
    118.                         }
    119.                     }
    120.        
    121.                     float3 DiffuseTex = tex2D(_MainTex, offset).rgb;
    122.                     float3 NormalTex = tex2D(_NormalMap, offset).rgb * 2.0 - 1.0f;
    123.                    
    124.                     //N*L
    125.                     float NdotL = max(0.0f, dot(NormalTex.rgb, lightVector.xyz ) );
    126.                    
    127.                     //Calculate this pixel's lighting
    128.                     float nxDir = max(0.0, dot(NormalTex.rgb, lightVector.xyz));
    129.                     float specularPower = 0.0;
    130.                     //float specularColor = _SpecColor;
    131.                     if(nxDir != 0.0)
    132.                     {
    133.                             float3 halfVector = normalize(lightVector + viewVector);
    134.                             float nxHalf = max(0.0, dot(NormalTex, halfVector));
    135.                             specularPower = pow(nxHalf, _Shininess);
    136.                     }
    137.                    
    138.                     float3 specular = specularPower;
    139.                     float3 pixel_color = UNITY_LIGHTMODEL_AMBIENT.xyz + specular + (_Color.rgb * float3(nxDir,nxDir,nxDir) * DiffuseTex);
    140.                    
    141.                     //Find shadowing if enabled
    142.                     if (_Shadow == 1.0)
    143.                     {
    144.                    
    145.                         float2 shadow_offset = offset;
    146.                         float3 tsH = normalize(lightVector + tsE);
    147.                        
    148.                         float selfShadow = 0.0;
    149.                    
    150.                          if (NdotL > 0.0)
    151.                          {
    152.                              const float numShadowSteps = 10.0;
    153.                              step = 1.0 / numShadowSteps;
    154.                              delta = float2(lightVector.x, lightVector.y) * bumpScale / (numShadowSteps * lightVector.z);
    155.                    
    156.                              height = NormalMap.a + step * 0.1;
    157.                              
    158.                              for (float i = 0.0; i < numShadowSteps; i++)
    159.                              {
    160.                                 if (NormalMap.a < height  height < 1.0)
    161.                                 {
    162.                                     height += step;
    163.                                     shadow_offset += delta;
    164.                                     NormalMap = tex2D(_NormalMap, shadow_offset);
    165.                                 } else {
    166.                                     break;
    167.                                 }
    168.                             }
    169.                                     selfShadow = float(NormalMap.a < height);        
    170.                         }
    171.                    
    172.                         if (selfShadow == 0.0)
    173.                         {
    174.                             pixel_color *= 0.5;
    175.                         }
    176.                     }
    177.                    
    178.                    
    179.                     //if (offset.x < 0.0 || offset.x > 1.0 || offset.y < 0.0 || offset.y > 1.0)
    180.                     return float4(pixel_color, 1.0);
    181.                    
    182.                 }
    183.                
    184.                 ENDCG
    185.             }          
    186.                
    187.         }
    188.         //Fallbacks
    189.         //Fallback "VertexLit"
    190. }
     
  5. Dolkar

    Dolkar

    Joined:
    Jun 8, 2013
    Posts:
    576
    It would be helpful if you posted the error as well.
     
  6. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78
    $error.png

    DX11 is enabled (because I'm using SM4.0)
    My GPU is a GTX 460 which is a DX11 SM5.0 graphics card
    The compiled shader doesn't tell me anything either.

    $error.png
     
    Last edited: Aug 20, 2013
  7. chronos78

    chronos78

    Joined:
    Dec 6, 2009
    Posts:
    154
    Pretty sure that out is a reserved word in cg. Have you try just using a different variable name instead. It shouldn't be an issue since you cased the spelling of "OUT" differently but it is something to try.
     
  8. Dolkar

    Dolkar

    Joined:
    Jun 8, 2013
    Posts:
    576
    camPos in your vertex shader is using an uninitialized value.

    No idea about the first error though... SM4.0 should work with DX11

    "out" is a reserved keyword, but "OUT" isn't... I'm using it myself.
     
  9. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78
    It compiles now but I don't get anything close too Steep Parallax Mapping, what am I supposed to return exactly gl_FragColor is like return right but how do I return the right value to get the right effect?

    Current code :

    Code (csharp):
    1. Shader "Advanced/Steep Parrallax Occ Mapping"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Color", Color) = (0.5,0.5,0.5,1)
    6.         _MainTex("Base (RGB)", 2D) = "white" {}
    7.         _NormalMap("Normal Map", 2D) = "bump" {}
    8.         _Scale ("Normalmap Bumpiness", Range(0.0, 2.0)) = 0.04
    9.         _Shininess("Shininess", Range(0.0, 5.0)) = 1.5
    10.         _Shadow("Shadow On/Off - Set to 1 to Enable", Range(0.0, 1.0)) = 1.0
    11.     }
    12.         SubShader
    13.         {
    14.        
    15.        
    16.             Pass
    17.             {
    18.                
    19.             Tags {"RenderType" = "Opaque"}
    20.            
    21.                 CGPROGRAM
    22.                 #pragma vertex vert
    23.                 #pragma fragment frag
    24.                 #pragma target 4.0
    25.                
    26.                 //Samplers
    27.                 uniform sampler2D _MainTex;
    28.                 uniform sampler2D _NormalMap;
    29.                
    30.                 //Float4's
    31.                 uniform float4 _Color;
    32.                 uniform float4 _SpecColor;
    33.                
    34.                 //Floats
    35.                 uniform float _Scale;
    36.                 uniform float _Shininess;
    37.                 uniform float _Shadow;
    38.                
    39.                 //Pre-defined
    40.                 uniform float4 _LightColor0;
    41.  
    42.                 struct vertexInput
    43.                 {
    44.                     float4 vertex : POSITION;
    45.                     float3 normal : NORMAL;
    46.                     float4 texcoord : TEXCOORD0;
    47.                     float4 tangent : TANGENT;
    48.                 };
    49.                 //Output struct
    50.                 struct vertexOutput
    51.                 {
    52.                     float4 pos : SV_POSITION;
    53.                     float4 tex : TEXCOORD0;
    54.                     float3 posTangent : TEXCOORD1;
    55.                     float3 camTangent : TEXCOORD2;
    56.                     float3 lightTangent : TEXCOORD3;
    57.                     float3 normalDir : TEXCOORD4;
    58.                     float3 tangentDir : TEXCOORD5;
    59.                     float3 binormalDir : TEXCOORD6;
    60.                    
    61.                 };
    62.                 //Vertex shader
    63.                 vertexOutput vert(vertexInput IN)
    64.                 {
    65.                     vertexOutput OUT;
    66.  
    67.                     OUT.tex = IN.texcoord;
    68.                     OUT.pos = mul(UNITY_MATRIX_MVP, IN.vertex);
    69.                    
    70.                     float3 camPos = normalize(_WorldSpaceCameraPos.xyz);
    71.                    
    72.                     // Find  normalize the plane's normal, tangent, and binormal vectors
    73.                     OUT.normalDir = normalize(IN.normal);
    74.                     OUT.tangentDir = normalize(IN.tangent).xyz;
    75.                     OUT.binormalDir = normalize(cross(OUT.normalDir, OUT.tangentDir) * IN.tangent.w );
    76.                    
    77.                     // Convert vertice, camera, and light vector positions into tangent space
    78.                     float3x3 tangentSpaceConverter = float3x3(OUT.tangentDir, OUT.binormalDir, OUT.normalDir);
    79.                    
    80.                     OUT.posTangent = mul(OUT.pos.xyz, tangentSpaceConverter);
    81.                     OUT.camTangent = mul(camPos, tangentSpaceConverter);
    82.                     OUT.lightTangent = mul(normalize(_WorldSpaceLightPos0.xyz), tangentSpaceConverter);
    83.                    
    84.                     return OUT;
    85.        
    86.                 }
    87.                 //Pixel shader
    88.                 float4 frag(vertexOutput i) : COLOR
    89.                 {
    90.                    
    91.                     //Steep Parallax
    92.                     float bumpScale = _Scale;
    93.                    
    94.                     //Normalize the other tangent space vectors
    95.                     float3 viewVector = normalize(i.camTangent - i.posTangent);
    96.                     float3 lightVector = normalize(i.lightTangent - i.posTangent);
    97.                    
    98.                     float3 tsE = normalize(i.camTangent);
    99.                    
    100.                     const float numSteps = 40.0f; // How many steps the UV ray tracing should take
    101.                     float height = 1.0;
    102.                     float step = 1.0 / numSteps;
    103.                    
    104.                     float2 offset = i.tex.xy;
    105.                     float4 NormalMap = tex2D(_NormalMap, offset);
    106.                    
    107.                     float2 delta = float2(-tsE.x, -tsE.y) * bumpScale / (tsE.z * numSteps);
    108.                    
    109.                     // find UV offset
    110.                     for (float i = 0.0f; i < numSteps; i++)
    111.                     {
    112.                          if (NormalMap.a < height) {
    113.                         height -= step;
    114.                         offset += delta;
    115.                         NormalMap = tex2D(_NormalMap, offset);
    116.                         } else {
    117.                             break;
    118.                         }
    119.                     }
    120.        
    121.                     float3 DiffuseTex = tex2D(_MainTex, offset).rgb;
    122.                     float3 NormalTex = tex2D(_NormalMap, offset).rgb * 2.0 - 1.0f;
    123.                    
    124.                     //N*L
    125.                     float NdotL = max(0.0f, dot(NormalTex.rgb, lightVector.xyz ) );
    126.                    
    127.                     //Calculate this pixel's lighting
    128.                     float nxDir = max(0.0, dot(NormalTex.rgb, lightVector.xyz));
    129.                     float specularPower = 0.0;
    130.                     //float specularColor = _SpecColor;
    131.                     if(nxDir != 0.0)
    132.                     {
    133.                             float3 halfVector = normalize(lightVector + viewVector);
    134.                             float nxHalf = max(0.0, dot(NormalTex, halfVector));
    135.                             specularPower = pow(nxHalf, _Shininess);
    136.                     }
    137.                    
    138.                     float3 specular = specularPower;
    139.                     float3 pixel_color = UNITY_LIGHTMODEL_AMBIENT.xyz + specular + float3(nxDir,nxDir,nxDir);
    140.                    
    141.                     //Find shadowing if enabled
    142.                     if (_Shadow == 1.0)
    143.                     {
    144.                    
    145.                         float2 shadow_offset = offset;
    146.                         float3 tsH = normalize(lightVector + tsE);
    147.                        
    148.                         float selfShadow = 0.0;
    149.                    
    150.                          if (NdotL > 0.0)
    151.                          {
    152.                              const float numShadowSteps = 10.0;
    153.                              step = 1.0 / numShadowSteps;
    154.                              delta = float2(lightVector.x, lightVector.y) * bumpScale / (numShadowSteps * lightVector.z);
    155.                    
    156.                              height = NormalMap.a + step * 0.1;
    157.                              
    158.                              for (float i = 0.0; i < numShadowSteps; i++)
    159.                              {
    160.                                 if (NormalMap.a < height  height < 1.0)
    161.                                 {
    162.                                     height += step;
    163.                                     shadow_offset += delta;
    164.                                     NormalMap = tex2D(_NormalMap, shadow_offset);
    165.                                 } else {
    166.                                     break;
    167.                                 }
    168.                             }
    169.                                     selfShadow = float(NormalMap.a < height);        
    170.                         }
    171.                    
    172.                         if (selfShadow == 0.0)
    173.                         {
    174.                             pixel_color *= 0.5;
    175.                         }
    176.                     }
    177.                    
    178.                    
    179.                     //if (offset.x < 0.0 || offset.x > 1.0 || offset.y < 0.0 || offset.y > 1.0)
    180.                     return float4(pixel_color, 1.0);
    181.                    
    182.                 }
    183.                
    184.                 ENDCG
    185.             }          
    186.                
    187.         }
    188.         //Fallbacks
    189.         //Fallback "VertexLit"
    190. }
    Picture Example:

    http://postimg.org/image/9rk4cjesx/full/
     

    Attached Files:

    Last edited: Aug 20, 2013
  10. Dolkar

    Dolkar

    Joined:
    Jun 8, 2013
    Posts:
    576
    You are returning the correct thing, but there can be problems elsewhere. Porting stuff like that is not easy... I suggest debugging it part by part, checking whether each variable contains what it should. If you copy-pasted the fragment shader, there's probably something wrong with the inputs, so I'd start there. From a brief look, I can see a few bugs: OUT.pos does NOT contain world space position. But you shouldn't work with world space at all! The normals, tangents and vertex positions are all in object space, but you're mixing them with world space camera and light positions.

    So, use IN.vertex for object space position, IN.normal and IN.tangent like you do now. You could also replace camera and light positions with _ObjectSpaceCameraPos and _ObjectSpaceLightPos0, buuut stuff is complicated. You are using directional light, which passes a direction instead of position to _ObjectSpaceLightPos0. Unity already has a fancy function to help you out with that, ObjSpaceLightDir(v). You can also safely move the vector computation to the vertex shader. To save you some frustration, it should look like this:

    Code (csharp):
    1.     //Output struct
    2.                 struct vertexOutput
    3.                 {
    4.                     float4 pos : SV_POSITION;
    5.                     float4 tex : TEXCOORD0;
    6.                     float3 camTangent : TEXCOORD1;
    7.                     float3 viewVector : TEXCOORD2;
    8.                     float3 lightVector : TEXCOORD3;
    9.                     float3 normalDir : TEXCOORD4;
    10.                     float3 tangentDir : TEXCOORD5;
    11.                     float3 binormalDir : TEXCOORD6;
    12.                    
    13.                 };
    14.                 //Vertex shader
    15.                 vertexOutput vert(vertexInput IN)
    16.                 {
    17.                     vertexOutput OUT;
    18.  
    19.                     OUT.tex = IN.texcoord;
    20.                     OUT.pos = mul(UNITY_MATRIX_MVP, IN.vertex);
    21.                    
    22.                     // Find  normalize the plane's normal, tangent, and binormal vectors
    23.                     OUT.normalDir = normalize(IN.normal);
    24.                     OUT.tangentDir = normalize(IN.tangent).xyz;
    25.                     OUT.binormalDir = normalize(cross(OUT.normalDir, OUT.tangentDir) * IN.tangent.w );
    26.                    
    27.                     // Convert vertice, camera, and light vector positions into tangent space
    28.                     float3x3 tangentSpaceConverter = float3x3(OUT.tangentDir, OUT.binormalDir, OUT.normalDir);
    29.                    
    30.                     OUT.camTangent = mul(tangentSpaceConverter, _ObjectSpaceCameraPos);
    31.                     OUT.viewVector = mul(tangentSpaceConverter, ObjSpaceViewDir(IN.vertex));
    32.                     OUT.lightVector = mul(tangentSpaceConverter, ObjSpaceLightDir(IN.vertex));
    33.                    
    34.                     return OUT;
    35.        
    36.                 }
    37.                 //Pixel shader
    38.                 float4 frag(vertexOutput i) : COLOR
    39.                 {
    40.                     //Steep Parallax
    41.                     float bumpScale = _Scale;
    42.                    
    43.                     //Normalize the other tangent space vectors
    44.                     float3 viewVector = normalize(i.viewVector);
    45.                     float3 lightVector = normalize(i.lightVector);
    46.                    
    47.                     float3 tsE = normalize(i.camTangent);
    48.  
    49.                     ...
    50.  
     
  11. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78
    Last edited: Aug 20, 2013