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

Face's Normal direction (Without accounting normal map!)

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

  1. Annihlator

    Annihlator

    Joined:
    Oct 15, 2012
    Posts:
    378
    Greetings, i'm trying to use wether a normal is facing in an upwards position or not to further define of the shaders functions, but so far i only managed to face the normal direction INCLUDING any used normal maps, i want to use the function without any of the normal map's data taken into account.

    Currently i'm using the following function in my surf shader:
    Code (csharp):
    1. float TestValue = 0.5+(dot(WorldNormalVector(IN, o.Normal), _TestDirection.xyz))/2;
    2. TestValue = smoothstep(0.5,1,TestValue);
    _Testdirection is a float4 with value (0.0,1.0,0.0,0.0)

    So the only problem i have now is that the code uses the resulting normal including applied normal map, i want the value without the normal map.

    Hope someone can help me out on this one! Thanks!
     
    Last edited: Jun 6, 2013
  2. cician

    cician

    Joined:
    Dec 10, 2012
    Posts:
    233
  3. Annihlator

    Annihlator

    Joined:
    Oct 15, 2012
    Posts:
    378
    aye, it's a surface shader.

    I tried using your example as follows:
    Code (csharp):
    1. float TestValue = 0.5+(dot(IN.worldNormal, _TestDirection.xyz))/2;
    but now the returned value somehow always is 0 :(

    Currently the preview of the shader looks like this;

    I want the same result, only excluded the normal map. so basically what it'd look like on a sphere that wouldn't be using the normalmap (however i need my normalmap, but for other purposes then this calculation)
     
  4. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    This is the code to get the world normal of the flat-shaded model in a surface shader.
    Code (csharp):
    1. WorldNormalVector(IN, float3(0,0,1))
    Or you could set up a custom vertex shader in your surface shader to work that out and then pass that value through to the fragment shader (probably a bit cheaper to calculate).
    In vert:
    Code (csharp):
    1. float3 normalW = mul((float3x3)_Object2World, v.normal);
    In surf:
    Code (csharp):
    1. normalW = normalize(normalW);
     
  5. Annihlator

    Annihlator

    Joined:
    Oct 15, 2012
    Posts:
    378
    Thanks Farfarer! after a bit of rummaging i managed to get the vertex function working!

    I'm putting the result of the test/debug version of the shader (purely for seeing the result value) online;
    Code (csharp):
    1.  
    2. Shader "Custom/FaceDirectionTester" {
    3.     Properties {
    4.         _MainTex ("Base (RGB)", 2D) = "white" {}
    5.         _Bump ("Bump", 2D) = "bump" {}
    6.         _BaseColor ("Base Color", Color) = (0.0,0.0,0.0,1.0)
    7.         _TestColor ("Test Color", Color) = (1.0,1.0,1.0,1.0)
    8.         _TestDirection ("Testing Direction", Vector) = (0,1,0)
    9.         _TestFactor ("Test Angle Hardness", Range(0,975) ) = 0.95
    10.        
    11.     }
    12.     SubShader {
    13.         Tags { "RenderType"="Opaque" }
    14.         LOD 200
    15.        
    16.         CGPROGRAM
    17.         #pragma surface surf BlinnPhong vertex:myvert
    18.         #include "UnityCG.cginc"
    19.  
    20.         sampler2D _Bump;
    21.         float4 _BaseColor;
    22.         float4 _TestColor;
    23.         float4 _TestDirection;
    24.         float _TestFactor
    25.  
    26.         struct Input {
    27.             float2 uv_Bump;
    28.             float3 normalW;
    29.             INTERNAL_DATA
    30.         };
    31.        
    32.         void myvert (inout appdata_full v, out Input data){
    33.             UNITY_INITIALIZE_OUTPUT(Input,data);
    34.             data.normalW = mul((float3x3)_Object2World, v.normal);
    35.         }
    36.  
    37.         void surf (Input IN, inout SurfaceOutput o) {
    38.             o.Normal = UnpackNormal (tex2D (_Bump, IN.uv_Bump));
    39.             float TestValue = 0.5+(dot(normalize(IN.normalW), _TestDirection.xyz))/2;
    40.             half4 result = 0;
    41.             o.Albedo = 0;
    42.             result = smoothstep(_TestFactor,1,TestValue);
    43.             o.Emission = result.rgb;
    44.             o.Alpha = 0;
    45.         }
    46.         ENDCG
    47.     }
    48.     FallBack "Diffuse"
    49. }
    50.  
    Who knows, maybe someone else will have another use for it in the future :)
     
    Last edited: Jun 7, 2013
    Head-Trip likes this.