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

Add normal map in vertex shader

Discussion in 'Shaders' started by 5c4r3cr0w, Sep 24, 2019.

  1. 5c4r3cr0w

    5c4r3cr0w

    Joined:
    Mar 8, 2016
    Posts:
    35
    Hello Everyone!

    I am new to shader programming. I am trying to create a vertex shader which looks metallic/specular. I found this shader by exploring tutorials here and added diffuse map and specular map to it. I am working on it for quite a while to add normal maps(with no success). Currently it doesn't support normal map. Any suggestion and help regarding this is very appreciated.

    Here is what my code looks like:
    Code (CSharp):
    1. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
    2.  
    3. Shader "Custom/op-VertLit" {
    4.    Properties {
    5.        _MainTex("Diffuse Map",2D)="white"{}
    6.        _Specular("Occlusion",2D)="white"{}
    7.        _Bump("Normal",2D)="white"{}
    8.       _Color ("Diffuse Material Color", Color) = (1,1,1,1)
    9.       _SpecColor ("Specular Material Color", Color) = (1,1,1,1)
    10.       _AlphaX ("Roughness in Brush Direction", Float) = 1.0
    11.       _AlphaY ("Roughness orthogonal to Brush Direction", Float) = 1.0
    12.       _Cutoff("Cutoff",Range(-0.01,1.01))=1.0
    13.    }
    14.    SubShader {
    15.       Pass {  
    16.          Tags { "LightMode" = "ForwardBase" }
    17.             // pass for ambient light and first light source
    18.          CGPROGRAM
    19.          #pragma vertex vert
    20.          #pragma fragment frag
    21.          #include "UnityCG.cginc"
    22.          uniform float4 _LightColor0;
    23.             // color of light source (from "Lighting.cginc")
    24.          // User-specified properties
    25.          uniform float4 _Color;
    26.          uniform float4 _SpecColor;
    27.          uniform float _AlphaX;
    28.          uniform float _AlphaY;
    29.        
    30.          sampler2D _MainTex;
    31.          sampler2D _Specular;
    32.          sampler2D _Bump;
    33.          half _Cutoff;
    34.  
    35.          struct vertexInput {
    36.             float4 vertex : POSITION;
    37.             float3 normal : NORMAL;
    38.             float4 tangent : TANGENT;
    39.             float2 uv : TEXCOORD0;
    40.          };
    41.          struct vertexOutput {
    42.             float4 pos : SV_POSITION;
    43.             float4 posWorld : TEXCOORD0;
    44.  
    45.             float3 viewDir : TEXCOORD1;
    46.              
    47.             float3 normalDir : TEXCOORD2;
    48.              
    49.             float3 tangentDir : TEXCOORD3;
    50.              
    51.             float2 uv: TEXCOORD4;
    52.          };
    53.          vertexOutput vert(vertexInput input)
    54.          {
    55.             vertexOutput output;
    56.             float4x4 modelMatrix = unity_ObjectToWorld;
    57.             float4x4 modelMatrixInverse = unity_WorldToObject;
    58.             output.uv = input.uv;
    59.             output.posWorld = mul(modelMatrix, input.vertex);
    60.             output.viewDir = normalize(_WorldSpaceCameraPos - output.posWorld.xyz);
    61.              
    62.             output.normalDir = normalize(mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    63.              
    64.             output.tangentDir = normalize(mul(modelMatrix, float4(input.tangent.xyz, 0.0)).xyz);
    65.        
    66.             output.pos = UnityObjectToClipPos(input.vertex);
    67.             return output;
    68.          }
    69.          float4 frag(vertexOutput input) : COLOR
    70.          {
    71.             float3 lightDirection;
    72.             float attenuation;
    73.             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    74.             {
    75.                attenuation = 1.0; // no attenuation
    76.                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    77.             }
    78.             else // point or spot light
    79.             {
    80.                float3 vertexToLightSource = _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    81.                float distance = length(vertexToLightSource);
    82.                attenuation = 1.0 / distance; // linear attenuation
    83.                lightDirection = normalize(vertexToLightSource);
    84.             }
    85.             float3 halfwayVector = normalize(lightDirection + input.viewDir);
    86.              
    87.             float3 binormalDirection = cross(input.normalDir, input.tangentDir);
    88.              
    89.             float dotLN = dot(lightDirection, input.normalDir);
    90.                // compute this dot product only once
    91.             float4 spec =tex2D(_Specular,input.uv);
    92.             float4 tex = tex2D(_MainTex, input.uv);
    93.             float4 bump = tex2D(_Bump,input.uv);
    94.  
    95.  
    96.             float3 ambientLighting = UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb * spec.rgb ;
    97.              
    98.             float3 diffuseReflection =
    99.                attenuation * _LightColor0.rgb * _Color.rgb
    100.                * max(0.0, dotLN) * tex ;
    101.             float3 specularReflection;
    102.             if (dotLN < 0.0) // light source on the wrong side?
    103.             {
    104.                specularReflection = float3(0.0, 0.0, 0.0);
    105.                   // no specular reflection
    106.             }
    107.             else // light source on the right side
    108.             {
    109.                float dotHN = dot(halfwayVector, input.normalDir);
    110.                float dotVN = dot(input.viewDir, input.normalDir);
    111.                float dotHTAlphaX =
    112.                   dot(halfwayVector, input.tangentDir) / _AlphaX;
    113.                float dotHBAlphaY = dot(halfwayVector,
    114.                   binormalDirection) / _AlphaY;
    115.                specularReflection =
    116.                   attenuation * _LightColor0.rgb * _SpecColor.rgb
    117.                   * sqrt(max(0.0, dotLN / dotVN))
    118.                   * exp(-2.0 * (dotHTAlphaX * dotHTAlphaX
    119.                   + dotHBAlphaY * dotHBAlphaY) / (1.0 + dotHN));
    120.             }
    121.            
    122.             clip(tex.a-_Cutoff);
    123.             return float4(ambientLighting + diffuseReflection
    124.                + specularReflection, 1.0);
    125.          }
    126.          ENDCG
    127.       }
    128.  
    129.    }
    130.    Fallback "Specular"
    131. }
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
  3. TheSirRolfe

    TheSirRolfe

    Joined:
    Dec 8, 2021
    Posts:
    2