Search Unity

Debugging shaders in Visual Studio

Discussion in 'Shaders' started by fromPaxtaobod, Mar 4, 2015.

  1. fromPaxtaobod

    fromPaxtaobod

    Joined:
    Dec 2, 2014
    Posts:
    5
    Hello. I optimize my shader in Visual Studio and I can not understand one thing. Why operator "if" doesn't work? Screenshot attached.
    Code (CSharp):
    1. Shader "TexturingByMask" {
    2.     Properties {
    3.         _Color ("Diffuse Material Color", Color) = (1,1,1,1)
    4.         _SpecColor ("Specular Material Color", Color) = (1,1,1,1)
    5.         _Shininess ("Shininess", Range(1, 20)) = 10
    6.         _Mask1 ("Mask1 (RGBA)", 2D) = "red" {}
    7.         _Mask2 ("Mask2 (RGBA)", 2D) = "red" {}
    8.         _Texture1 ("Diffuse atlas", 2D) = "white" {}
    9.         _BumpMap1 ("Normal map atlas", 2D) = "white" {}
    10.         }
    11.    SubShader {
    12.       Pass {      
    13.           Tags { "LightMode" = "ForwardBase" }
    14.          CGPROGRAM
    15.          #pragma vertex vert
    16.          #pragma fragment frag
    17.           #pragma enable_d3d11_debug_symbols
    18.           #include "UnityCG.cginc"
    19.          
    20.         sampler2D _Mask1, _Mask2;
    21.         sampler2D _Texture1;
    22.         sampler2D _BumpMap1;
    23.        
    24.         uniform float4 _LightColor0;
    25.         uniform float4 _Color;
    26.         uniform float4 _SpecColor;
    27.         uniform float _Shininess;
    28.        
    29.          struct vertexInput {
    30.             float4 vertex : POSITION;
    31.             float2 texcoord : TEXCOORD0;
    32.             float3 normal : NORMAL;
    33.             float4 tangent : TANGENT;
    34.          };
    35.        
    36.          struct vertexOutput {
    37.             float4 pos : SV_POSITION;
    38.             float2 texcoord : TEXCOORD0;
    39.             float4 tangent : TEXCOORD5;
    40.             float4 posWorld : TEXCOORD1;
    41.             float3 tangentWorld : TEXCOORD2;
    42.             float3 normalWorld : TEXCOORD3;
    43.             float3 binormalWorld : TEXCOORD4;
    44.          };
    45.          vertexOutput vert(vertexInput input)
    46.          {
    47.             vertexOutput output;
    48.             output.texcoord = input.texcoord;
    49.             output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
    50.            
    51.             float4x4 modelMatrix = _Object2World;
    52.             float4x4 modelMatrixInverse = _World2Object;
    53.             // unity_Scale.w is unnecessary
    54.  
    55.             output.tangentWorld = normalize(mul(modelMatrix, float4(input.tangent.xyz, 0.0)).xyz);
    56.             output.normalWorld = normalize(mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    57.             output.binormalWorld = normalize(cross(output.normalWorld, output.tangentWorld) * input.tangent.w); // tangent.w is specific to Unity
    58.             output.posWorld = mul(modelMatrix, input.vertex);
    59.            
    60.             return output;
    61.          }
    62.          float4 frag(vertexOutput input) : COLOR // fragment shader
    63.          {
    64.             fixed4 output;
    65.  
    66.             float4 mask1 = tex2D (_Mask1, input.texcoord);
    67.             fixed4 mask2 = tex2D (_Mask2, input.texcoord);
    68.  
    69.             fixed3 texColor = 0.0;
    70.             fixed4 encodedNormal = 0.0;
    71.            
    72.             half border = 0.00390625; // 16/4096;
    73.  
    74.             // 1
    75.             if (mask1.r != 0.0f)
    76.             {
    77.                 half2 uv;
    78.                 uv.x = input.texcoord.x*(0.25f - border*2) + border;
    79.                 uv.y = input.texcoord.y*(0.25f - border*2) + border;
    80.                
    81.                 texColor += mask1.r * tex2D (_Texture1, uv);
    82.                 encodedNormal += mask1.r * tex2D(_BumpMap1, uv);
    83.             }
    84.  
    85.             // 2
    86.             if (mask1.g != 0.0)
    87.             {
    88.                 half2 uv;
    89.                 uv.x = input.texcoord.x*(0.25f - border*2) + 0.25f + border;
    90.                 uv.y = input.texcoord.y*(0.25f - border*2) + border;
    91.                
    92.                 texColor += mask1.g * tex2D (_Texture1, uv);
    93.                 encodedNormal += mask1.g * tex2D(_BumpMap1, uv);
    94.             }
    95.  
    96.             // 3
    97.             if (mask1.b != 0.0)
    98.             {
    99.                 half2 uv;
    100.                 uv.x = input.texcoord.x*(0.25f - border*2) + 0.50f + border;
    101.                 uv.y = input.texcoord.y*(0.25f - border*2) + border;
    102.                
    103.                 texColor += mask1.b * tex2D (_Texture1, uv);
    104.                 encodedNormal += mask1.b * tex2D(_BumpMap1, uv);
    105.             }
    106.  
    107.             // 4
    108.             if (mask1.a != 0.0)
    109.             {
    110.                 half2 uv;
    111.                 uv.x = input.texcoord.x*(0.25f - border*2) + 0.75f + border;
    112.                 uv.y = input.texcoord.y*(0.25f - border*2) + border;
    113.                
    114.                 texColor += mask1.a * tex2D (_Texture1, uv);
    115.                 encodedNormal += mask1.a * tex2D(_BumpMap1, uv);
    116.             }
    117.  
    118.             // 5
    119.             if (mask2.r != 0.0f)
    120.             {
    121.                 half2 uv;
    122.                 uv.x = input.texcoord.x*(0.25f - border*2) + border;
    123.                 uv.y = input.texcoord.y*(0.25f - border*2) + 0.25f + border;
    124.                
    125.                 texColor += mask2.r * tex2D (_Texture1, uv);
    126.                 encodedNormal += mask2.r * tex2D(_BumpMap1, uv);
    127.             }
    128.  
    129.             // 6
    130.             if (mask2.g != 0.0f)
    131.             {
    132.                 half2 uv;
    133.                 uv.x = input.texcoord.x*(0.25f - border*2) + 0.25f + border;
    134.                 uv.y = input.texcoord.y*(0.25f - border*2) + 0.25f + border;
    135.                
    136.                 texColor += mask2.g * tex2D (_Texture1, uv);
    137.                 encodedNormal += mask2.g * tex2D(_BumpMap1, uv);
    138.             }
    139.  
    140.             // 7
    141.             if (mask2.b != 0.0f)
    142.             {
    143.                 half2 uv;
    144.                 uv.x = input.texcoord.x*(0.25f - border*2) + 0.50f + border;
    145.                 uv.y = input.texcoord.y*(0.25f - border*2) + 0.25f + border;
    146.                
    147.                 texColor += mask2.b * tex2D (_Texture1, uv);
    148.                 encodedNormal += mask2.b * tex2D(_BumpMap1, uv);
    149.             }
    150.  
    151.             // 8
    152.             if (mask2.a != 0.0f)
    153.             {
    154.                 half2 uv;
    155.                 uv.x = input.texcoord.x*(0.25f - border*2) + 0.75f + border;
    156.                 uv.y = input.texcoord.y*(0.25f - border*2) + 0.25f + border;
    157.                
    158.                 texColor += mask2.a * tex2D (_Texture1, uv);
    159.                 encodedNormal += mask2.a * tex2D(_BumpMap1, uv);
    160.             }
    161.            
    162.             ///////////////
    163.             // Light
    164.             ///////////////
    165.             fixed3 ambientLighting;
    166.             fixed3 localCoords;
    167.             fixed3 normalDirection;
    168.             fixed3 diffuseReflection;
    169.             fixed3 specularReflection;
    170.             fixed3x3 local2WorldTranspose = fixed3x3(input.tangentWorld, input.binormalWorld, input.normalWorld);
    171.             fixed3 viewDirection = normalize(_WorldSpaceCameraPos - input.posWorld.xyz);
    172.             fixed3 lightDirection;
    173.             fixed attenuation;
    174.             attenuation = 1.0; // no attenuation
    175.             lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    176.            
    177.             fixed splatSum = dot(mask1 + mask2, fixed4(1,1,1,1));
    178.             fixed4 flatNormal = fixed4(0.5,0.5,1,0.5); // this is "flat normal" in both DXT5nm and xyz*2-1 cases
    179.             encodedNormal = lerp(flatNormal, encodedNormal, splatSum);
    180.            
    181.             ambientLighting = UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb * texColor;
    182.            
    183.             // Bumped Diffuse
    184.             localCoords = fixed3(2.0 * encodedNormal.a - 1.0, 2.0 * encodedNormal.g - 1.0, 0.0);
    185.             //localCoords.z = sqrt(1.0 - dot(localCoords, localCoords));
    186.             localCoords.z = 1.0 - 0.5 * dot(localCoords, localCoords);
    187.             normalDirection = normalize(mul(localCoords, local2WorldTranspose));
    188.             diffuseReflection = attenuation * _LightColor0.rgb * texColor * _Color.rgb * max(0.0, dot(normalDirection, lightDirection));
    189.            
    190.             // Specular Light
    191.             if (dot(normalDirection, lightDirection) < 0.0)
    192.                specularReflection = fixed3(0.0, 0.0, 0.0);
    193.             else
    194.                specularReflection = attenuation * _LightColor0.rgb * _SpecColor.rgb * pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), _Shininess);
    195.              
    196.             output = fixed4(ambientLighting + diffuseReflection + specularReflection, 1.0);
    197.  
    198.             return output;
    199.          }
    200.          ENDCG
    201.         }
    202.    }
    203. }
     

    Attached Files:

  2. ilya_ca

    ilya_ca

    Joined:
    Nov 19, 2011
    Posts:
    274
    There are two issues with your code:
    1. It's incorrect to compare floating-point numbers with the equality operator (due to a possible loss of precision). With floating point numbers you cannot guarantee that 0 == 0. 0 may be equal to 0.00001, and then your comparison will fail. It's recommended to use the following form instead: if (a >= threshold), for example: if (a >= 0.00001)
    2. What you actually end up doing is making your shader much slower. Branching (using if statements) is very heavy on GPU (as opposed to CPU). You will gain a lot of performance by getting rid of the if statements. In your code you have 8 if statements, which will make your shader run very slow.
     
  3. fromPaxtaobod

    fromPaxtaobod

    Joined:
    Dec 2, 2014
    Posts:
    5
    ilya_ca thank you, I look into the matter, branching on the GPU works very differently