Search Unity

Unity shaders - specular lighting not reflecting properly

Discussion in 'Shaders' started by unity_ycAc5ynYwYxpFQ, May 27, 2020.

  1. unity_ycAc5ynYwYxpFQ

    unity_ycAc5ynYwYxpFQ

    Joined:
    Sep 17, 2017
    Posts:
    8
    Hi,

    I am trying to simulate specular light reflecting from a planet's surface.

    The problem I came across is that we can see a glossy spot on the side of the planet that is facing away from the sun.




    I tried inverting the lights direction when calculating the dot product, but that causes another problem: it inverts the side of the planets that are lit.






    Here is my code. Can you guys help me out?

    [ICODE]
    [code=CSharp]Shader "Unlit/planetShader"
    {
    Properties
    {
    _PlanetColor("Main color",Color) = (1,1,1,1)
    _SpecularGlossStrength("Specular gloss strength",float) = 1
    }
    SubShader
    {
    Tags { "RenderType"="Opaque" }
    LOD 100

    Pass
    {
    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag


    #include "UnityCG.cginc"

    struct VertexInput
    {
    float4 vertex : POSITION;
    float3 normal : NORMAL;
    };

    struct VertexOutput
    {
    float4 vertex : SV_POSITION;
    float3 normal : TEXCOORD0;
    float3 worldPos : TEXCOORD1;
    };

    // Declare variables here
    float4 _PlanetColor;
    Vector _SunPosition;
    float _SpecularGlossStrength;

    VertexOutput vert (VertexInput input)
    {
    VertexOutput output;
    output.vertex =UnityObjectToClipPos(input.vertex);
    output.worldPos = mul(unity_ObjectToWorld,input.vertex);

    //output.uv = TRANSFORM_TEX(vertexInput.uv, _MainTex);

    output.normal = mul(unity_ObjectToWorld, input.normal);



    return output;
    }

    fixed4 frag (VertexOutput output) : SV_Target
    {
    // Diffuse light
    // Based on planet position relative to the sun

    float3 lightDir = normalize(_SunPosition - output.worldPos);

    //float3 lightDir = normalize(float3(1,1,1));

    float diffuseLightFallOff = max(.2,dot(lightDir, normalize(output.normal)));

    float3 sunColor = float3(1, 1, 0);

    float3 compositeColor = _PlanetColor + sunColor/2;

    float3 diffuseLight = compositeColor * diffuseLightFallOff;


    // Specular light
    float3 camToFragDir = normalize(_WorldSpaceCameraPos - output.worldPos);

    float3 camToFragDirReflect = reflect(normalize(output.normal), camToFragDir);

    float specularFallOff = max(0,dot(-lightDir, camToFragDirReflect));

    specularFallOff = pow(specularFallOff, _SpecularGlossStrength);


    // Combining lights and colors

    float3 finalColor = (diffuseLight + specularFallOff) * compositeColor;


    return float4(finalColor,1);
    }
    ENDCG
    }
    }
    }[/code]
    [/ICODE]