Question

I have began to create some shaders for my university group project however I have ran into a bit of a snag with my water shader. I am trying to create one which utilises two overlapping normal maps.

Whilst everything looks okay in the editor, when I then publish to the webplayer, the scene looks like its unlit.

Heres my code for the shader:

//
// Filename : WaterShader.shader
// Version : 2.0
// Date : 1st March 2014
//

Shader "Flight/WaterShader/2.0"
{
    // Set up variables so we can access them in inspector mode
    Properties
    {   
        // Variable to control the colour tint
        _Color ("Base Color", Color) = (1, 1, 1, 1)

        // Variables for specular
        _SpecularColor ("Specular Color", Color) = (1, 1, 1, 1)
        _SpecularAmount ("Shininess", Float) = 10

        // Variable for setting the base texture
        _MainTex ("Water Texture", 2D) = "white" { }

        // Variables to set the normal map 1
        _BumpMapA ("Normal Map", 2D) = "bump" { }
        _BumpDepthA ("Depth", Range(0.25, 10.0)) = 1 
        // Variables to set the normal map 2
        _BumpMapB ("Normal Map", 2D) = "bump" { }
        _BumpDepthB ("Depth", Range(0.25, 10.0)) = 1 
    }

    SubShader
    {
        pass
        {
            Tags { "RenderType" = "Opaque" }
            Lighting On

            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag
            #pragma exclude_renderers flash

            // Variables
            sampler2D _MainTex;
            float4 _MainTex_ST;

            sampler2D _BumpMapA;
            float4 _BumpMapA_ST;
            float _BumpDepthA;

            sampler2D _BumpMapB;
            float4 _BumpMapB_ST;
            float _BumpDepthB;

            float4 _Color;
            float4 _SpecularColor;
            float _SpecularAmount;
            float4 _LightColor0;

            struct vertexInput
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 texcoord : TEXCOORD0;
                float4 tangent : TANGENT;
            };

            struct vertexOutput
            {
                float4 pos : SV_POSITION;
                float4 tex : TEXCOORD0;
                float4 posWorld : TEXCOORD1;
                float3 normalWorld : TEXCOORD2;
                float3 tangentWorld : TEXCOORD3;
                float3 binormalWorld : TEXCOORD4;
            };

            vertexOutput vert(vertexInput input)
            {
                vertexOutput output;

                output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
                output.tex = input.texcoord;
                output.posWorld = mul(_Object2World, input.vertex);

                output.normalWorld = normalize( mul( float4( input.normal, 0.0f ), _World2Object ).xyz );
                output.tangentWorld = normalize( mul( _Object2World, input.tangent ).xyz );
                output.binormalWorld = normalize( cross( output.normalWorld, output.tangentWorld) * input.tangent.w );

                return output;
            }

            float4 frag(vertexOutput input) : COLOR
            {
                // Set up variables
                float3 viewDirection;
                float3 lightDirection;
                float3 normalDirection;

                float lightIntensity;

                float4 normalColorA;
                float4 normalColorB;
                float4 normalColor;

                float3 normalLocalA;
                float3 normalLocalB;
                float3 normalLocal;

                float3x3 normalWorld;

                float4 textureColor;
                float3 diffuseColor;
                float3 specularColor;
                float3 lightColor;
                float4 finalColor;

                // Begin calculations

                // Calculate the angle we are looking at the pixel
                viewDirection = normalize(_WorldSpaceCameraPos.xyz - input.posWorld.xyz );

                if(_WorldSpaceLightPos0.w == 0.0) 
                {
                    lightIntensity = 1.0;
                    lightDirection = normalize(_WorldSpaceLightPos0.xyz);
                }
                else
                {
                    float3 fragmentToLightSource = _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
                    float distance = length(fragmentToLightSource);
                    lightIntensity = 1.0 / distance;
                    lightDirection = normalize(fragmentToLightSource);
                }

                // Sample the textures
                textureColor = tex2D(_MainTex, input.tex.xy * _MainTex_ST.xy + _MainTex_ST.zw);
                normalColorA = tex2D(_BumpMapA, input.tex.xy * _BumpMapA_ST.xy + _BumpMapA_ST.zw);
                normalColorB = tex2D(_BumpMapB, input.tex.xy * _BumpMapB_ST.xy + _BumpMapB_ST.zw);

                // Expand the normals and set the intensity of the normal map
                normalLocalA = float3(2.0 * normalColorA.ag - float2(1.0, 1.0), 0.0);
                normalLocalA.z = _BumpDepthA;

                normalLocalB = float3(2.0 * normalColorB.ag - float2(1.0, 1.0), 0.0);
                normalLocalB.z = _BumpDepthB;

                // Combine the two normals  
                normalLocal = normalize(normalLocalA + normalLocalB);


                // Calculate the normal in the world
                normalWorld = float3x3( input.tangentWorld, input.binormalWorld, input.normalWorld );
                normalDirection = normalize( mul( normalLocal, normalWorld ) );

                // Calculate lighting
                diffuseColor = lightIntensity * _LightColor0.xyz * saturate( dot(normalDirection, lightDirection) );
                specularColor = diffuseColor * _SpecularColor.xyz * pow( saturate( dot( reflect(-lightDirection, normalDirection), viewDirection) ), _SpecularAmount );

                // Combine lighting
                lightColor = UNITY_LIGHTMODEL_AMBIENT.xyz + diffuseColor + specularColor;

                // Apply lighting to the texture color
                textureColor = float4( textureColor.xyz * lightColor * _Color.xyz, 1.0);

                return textureColor;
            }

            ENDCG
        }
    } 
    FallBack "Specular"
}

In the editor it looks like this:

Editor Mode

Where as in the webplayer it looks like this:

Webplayer

Anyone able to help me see where I have gone wrong? :)

Was it helpful?

Solution

You need a separate pass of pixel light in the scene for the web player. Replace your current SubShader Parameters with

SubShader
{
    Tags {"RenderType" = "Opaque"}    
    Pass 
    {
        Tags {"LightMode" = "ForwardAdd"}    
    }  
    Pass
    {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #pragma exclude_renderers flash
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top