Search Unity

Double Sided mobile Shader

Discussion in 'Shaders' started by AJ1006, Jul 2, 2015.

  1. AJ1006

    AJ1006

    Joined:
    Jan 6, 2014
    Posts:
    3
    We need some help, by creating a double sided mobile shader, with a normal and specular map.

    That is our current shader, it works in general, but not on all mobile devices. On some devices, the shader doesnt work and the mesh is just black. We use directional light in our scenes. If someone could help us out there, it would be great :)

    Shader "DoubleSiderShader" {
    Properties {
    _DiffuseBase ("Diffuse Base", 2D) = "white" {}
    _NormalMap ("Normal Map", 2D) = "bump" {}
    _Specular ("Specular", 2D) = "white" {}
    }
    SubShader {
    Tags {
    "RenderType"="Opaque"
    }
    Pass {
    Name "FORWARD"
    Tags {
    "LightMode"="ForwardBase"
    }
    Cull Off


    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    #define UNITY_PASS_FORWARDBASE
    #include "UnityCG.cginc"
    #include "AutoLight.cginc"
    #pragma multi_compile_fwdbase_fullshadows
    #pragma exclude_renderers xbox360 xboxone ps3 ps4 psp2
    #pragma target 2.0
    uniform float4 _LightColor0;
    uniform sampler2D _DiffuseBase; uniform float4 _DiffuseBase_ST;
    uniform sampler2D _NormalMap; uniform float4 _NormalMap_ST;
    uniform sampler2D _Specular; uniform float4 _Specular_ST;
    struct VertexInput {
    float4 vertex : POSITION;
    float3 normal : NORMAL;
    float4 tangent : TANGENT;
    float2 texcoord0 : TEXCOORD0;
    };
    struct VertexOutput {
    float4 pos : SV_POSITION;
    float2 uv0 : TEXCOORD0;
    float4 posWorld : TEXCOORD1;
    float3 normalDir : TEXCOORD2;
    float3 tangentDir : TEXCOORD3;
    float3 bitangentDir : TEXCOORD4;
    LIGHTING_COORDS(5,6)
    };
    VertexOutput vert (VertexInput v) {
    VertexOutput o = (VertexOutput)0;
    o.uv0 = v.texcoord0;
    o.normalDir = UnityObjectToWorldNormal(v.normal);
    o.tangentDir = normalize( mul( _Object2World, float4( v.tangent.xyz, 0.0 ) ).xyz );
    o.bitangentDir = normalize(cross(o.normalDir, o.tangentDir) * v.tangent.w);
    o.posWorld = mul(_Object2World, v.vertex);
    float3 lightColor = _LightColor0.rgb;
    o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    TRANSFER_VERTEX_TO_FRAGMENT(o)
    return o;
    }
    float4 frag(VertexOutput i) : COLOR {
    i.normalDir = normalize(i.normalDir);
    float3x3 tangentTransform = float3x3( i.tangentDir, i.bitangentDir, i.normalDir);
    /////// Vectors:
    float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
    float3 _NormalMap_var = UnpackNormal(tex2D(_NormalMap,TRANSFORM_TEX(i.uv0, _NormalMap)));
    float3 normalLocal = _NormalMap_var.rgb;
    float3 normalDirection = normalize(mul( normalLocal, tangentTransform )); // Perturbed normals

    float nSign = sign( dot( viewDirection, i.normalDir ) ); // Reverse normal if this is a backface
    i.normalDir *= nSign;
    normalDirection *= nSign;

    float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    float3 lightColor = _LightColor0.rgb;
    float3 halfDirection = normalize(viewDirection+lightDirection);
    ////// Lighting:
    float attenuation = LIGHT_ATTENUATION(i);
    float3 attenColor = attenuation * _LightColor0.xyz;
    ///////// Gloss:
    float gloss = 0.5;
    float specPow = exp2( gloss * 10.0+1.0);
    ////// Specular:
    float NdotL = max(0, dot( normalDirection, lightDirection ));
    float4 _Specular_var = tex2D(_Specular,TRANSFORM_TEX(i.uv0, _Specular));
    float3 specularColor = _Specular_var.rgb;
    float3 directSpecular = attenColor * pow(max(0,dot(halfDirection,normalDirection)),specPow)*specularColor;
    float3 specular = directSpecular;
    /////// Diffuse:
    NdotL = max(0.0,dot( normalDirection, lightDirection ));
    float3 directDiffuse = max( 0.0, NdotL) * attenColor;
    float3 indirectDiffuse = float3(0,0,0);
    indirectDiffuse += UNITY_LIGHTMODEL_AMBIENT.rgb; // Ambient Light
    float4 _DiffuseBase_var = tex2D(_DiffuseBase,TRANSFORM_TEX(i.uv0, _DiffuseBase));
    float3 diffuseColor = _DiffuseBase_var.rgb;
    float3 diffuse = (directDiffuse + indirectDiffuse) * diffuseColor;
    /// Final Color:
    float3 finalColor = diffuse + specular;
    return fixed4(finalColor,1);
    }
    ENDCG
    }
    Pass {
    Name "FORWARD_DELTA"
    Tags {
    "LightMode"="ForwardAdd"
    }
    Blend One One
    Cull Off


    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    #define UNITY_PASS_FORWARDADD
    #include "UnityCG.cginc"
    #include "AutoLight.cginc"
    #pragma multi_compile_fwdadd_fullshadows
    #pragma exclude_renderers xbox360 xboxone ps3 ps4 psp2
    #pragma target 2.0
    uniform float4 _LightColor0;
    uniform sampler2D _DiffuseBase; uniform float4 _DiffuseBase_ST;
    uniform sampler2D _NormalMap; uniform float4 _NormalMap_ST;
    uniform sampler2D _Specular; uniform float4 _Specular_ST;
    struct VertexInput {
    float4 vertex : POSITION;
    float3 normal : NORMAL;
    float4 tangent : TANGENT;
    float2 texcoord0 : TEXCOORD0;
    };
    struct VertexOutput {
    float4 pos : SV_POSITION;
    float2 uv0 : TEXCOORD0;
    float4 posWorld : TEXCOORD1;
    float3 normalDir : TEXCOORD2;
    float3 tangentDir : TEXCOORD3;
    float3 bitangentDir : TEXCOORD4;
    LIGHTING_COORDS(5,6)
    };
    VertexOutput vert (VertexInput v) {
    VertexOutput o = (VertexOutput)0;
    o.uv0 = v.texcoord0;
    o.normalDir = UnityObjectToWorldNormal(v.normal);
    o.tangentDir = normalize( mul( _Object2World, float4( v.tangent.xyz, 0.0 ) ).xyz );
    o.bitangentDir = normalize(cross(o.normalDir, o.tangentDir) * v.tangent.w);
    o.posWorld = mul(_Object2World, v.vertex);
    float3 lightColor = _LightColor0.rgb;
    o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    TRANSFER_VERTEX_TO_FRAGMENT(o)
    return o;
    }
    float4 frag(VertexOutput i) : COLOR {
    i.normalDir = normalize(i.normalDir);
    float3x3 tangentTransform = float3x3( i.tangentDir, i.bitangentDir, i.normalDir);
    /////// Vectors:
    float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
    float3 _NormalMap_var = UnpackNormal(tex2D(_NormalMap,TRANSFORM_TEX(i.uv0, _NormalMap)));
    float3 normalLocal = _NormalMap_var.rgb;
    float3 normalDirection = normalize(mul( normalLocal, tangentTransform )); // Perturbed normals

    float nSign = sign( dot( viewDirection, i.normalDir ) ); // Reverse normal if this is a backface
    i.normalDir *= nSign;
    normalDirection *= nSign;

    float3 lightDirection = normalize(lerp(_WorldSpaceLightPos0.xyz, _WorldSpaceLightPos0.xyz - i.posWorld.xyz,_WorldSpaceLightPos0.w));
    float3 lightColor = _LightColor0.rgb;
    float3 halfDirection = normalize(viewDirection+lightDirection);
    ////// Lighting:
    float attenuation = LIGHT_ATTENUATION(i);
    float3 attenColor = attenuation * _LightColor0.xyz;
    ///////// Gloss:
    float gloss = 0.5;
    float specPow = exp2( gloss * 10.0+1.0);
    ////// Specular:
    float NdotL = max(0, dot( normalDirection, lightDirection ));
    float4 _Specular_var = tex2D(_Specular,TRANSFORM_TEX(i.uv0, _Specular));
    float3 specularColor = _Specular_var.rgb;
    float3 directSpecular = attenColor * pow(max(0,dot(halfDirection,normalDirection)),specPow)*specularColor;
    float3 specular = directSpecular;
    /////// Diffuse:
    NdotL = max(0.0,dot( normalDirection, lightDirection ));
    float3 directDiffuse = max( 0.0, NdotL) * attenColor;
    float4 _DiffuseBase_var = tex2D(_DiffuseBase,TRANSFORM_TEX(i.uv0, _DiffuseBase));
    float3 diffuseColor = _DiffuseBase_var.rgb;
    float3 diffuse = directDiffuse * diffuseColor;
    /// Final Color:
    float3 finalColor = diffuse + specular;
    return fixed4(finalColor * 1,0);
    }
    ENDCG
    }
    }
    FallBack "Diffuse"
    CustomEditor "ShaderForgeMaterialInspector"
    }
     
  2. kilik128

    kilik128

    Joined:
    Jul 15, 2013
    Posts:
    909
    same with shader forge