Search Unity

Setting the normal map scale (intensity) through code only works on editor, not in the build.

Discussion in 'Shaders' started by Black_Demon, Mar 16, 2016.

  1. Black_Demon

    Black_Demon

    Joined:
    Jul 12, 2014
    Posts:
    12
    Hi, I'm using the next code to set the normal map intensity at the begining:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class MyScript : MonoBehaviour
    5. {
    6.     // The material is placed in the assets folder and attached here from Inspector
    7.     public Material materialBody;
    8.  
    9.     void Awake()
    10.     {
    11.         materialBody.SetFloat("_BumpScale", 0.3f);
    12.         materialBody.EnableKeyword("_NORMALMAP");
    13.         materialBody.renderQueue = 3000;
    14.     }
    15. }
    When I hit play I can see the material changes properly in the Inspector and also in the Scene view I see a 30% intensity.

    The problem is that it only works on the editor, but when I make the build (Android) and install it in my phone it just doesn't work, the normal map appears at full intensity.

    I'm using the Standard material and only has a normal map assigned, no heightmap or others.

    I also saw this post http://docs.unity3d.com/Manual/MaterialsAccessingViaScript.html but I can figure out what am I doing wrong. Somebody facing the same problem?
     
  2. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    I think it's only supported in shader model 3.0+
     
    Black_Demon likes this.
  3. Black_Demon

    Black_Demon

    Joined:
    Jul 12, 2014
    Posts:
    12
    Hi @Farfarer thanks for your hint, I found my phone have only OpenGL2.0, so I borrow my friend's phone to do some tests, it is a Galaxy S6 with OpenGl 3.1 and shader level 5.0. I configured the player settings like this: playersettings.jpg
    This way all the textures are exported to work with OpenGL 3.0+
    I built my app with this settings and installed both in my Opengl2.0 phone and my friend's Opengl3.0 phone, and indeed in mine I see all my 3d models without textures (they appear in fuchsia color) while in my friend's I can see all the textures properly, anyways the changes to the intensity of the normal map are not working yet, it continues showing at 100% intensity all the time.

    Is there something I'm missing? Maybe this is not the proper way to export to OpenGL3.0? Maybe I need to change something in the shader's import settings or create a custom shader? I really feel lost now, hope someone can help me.
     
  4. Black_Demon

    Black_Demon

    Joined:
    Jul 12, 2014
    Posts:
    12
    I also made a custom shader from the Standard shader code, and set it to export to opengl3.0, as follows:

    Code (CSharp):
    1. Shader "Standard2"
    2. {
    3.     Properties
    4.     {
    5.         _Color("Color", Color) = (1,1,1,1)
    6.         _MainTex("Albedo", 2D) = "white" {}
    7.  
    8.         _Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
    9.  
    10.         _Glossiness("Smoothness", Range(0.0, 1.0)) = 0.5
    11.         [Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0
    12.         _MetallicGlossMap("Metallic", 2D) = "white" {}
    13.  
    14.         _BumpScale("Scale", Float) = 1.0
    15.         _BumpMap("Normal Map", 2D) = "bump" {}
    16.  
    17.         _Parallax("Height Scale", Range(0.005, 0.08)) = 0.02
    18.         _ParallaxMap("Height Map", 2D) = "black" {}
    19.  
    20.         _OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0
    21.         _OcclusionMap("Occlusion", 2D) = "white" {}
    22.  
    23.         _EmissionColor("Color", Color) = (0,0,0)
    24.         _EmissionMap("Emission", 2D) = "white" {}
    25.  
    26.         _DetailMask("Detail Mask", 2D) = "white" {}
    27.  
    28.         _DetailAlbedoMap("Detail Albedo x2", 2D) = "grey" {}
    29.         _DetailNormalMapScale("Scale", Float) = 1.0
    30.         _DetailNormalMap("Normal Map", 2D) = "bump" {}
    31.  
    32.         [Enum(UV0,0,UV1,1)] _UVSec("UV Set for secondary textures", Float) = 0
    33.  
    34.  
    35.             // Blending state
    36.             [HideInInspector] _Mode("__mode", Float) = 0.0
    37.             [HideInInspector] _SrcBlend("__src", Float) = 1.0
    38.             [HideInInspector] _DstBlend("__dst", Float) = 0.0
    39.             [HideInInspector] _ZWrite("__zw", Float) = 1.0
    40.     }
    41.  
    42.         CGINCLUDE
    43. #define UNITY_SETUP_BRDF_INPUT MetallicSetup
    44.             ENDCG
    45.  
    46.             SubShader
    47.         {
    48.             Tags { "RenderType" = "Opaque" "PerformanceChecks" = "False" }
    49.             LOD 300
    50.  
    51.  
    52.             // ------------------------------------------------------------------
    53.             //  Base forward pass (directional light, emission, lightmaps, ...)
    54.             Pass
    55.             {
    56.                 Name "FORWARD"
    57.                 Tags { "LightMode" = "ForwardBase" }
    58.  
    59.                 Blend[_SrcBlend][_DstBlend]
    60.                 ZWrite[_ZWrite]
    61.  
    62.                 CGPROGRAM
    63.                 #pragma target es3.0
    64.             // TEMPORARY: GLES2.0 temporarily disabled to prevent errors spam on devices without textureCubeLodEXT
    65.             //#pragma exclude_renderers gles
    66.  
    67.             // -------------------------------------
    68.  
    69.             #pragma shader_feature _NORMALMAP
    70.             #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    71.             #pragma shader_feature _EMISSION
    72.             #pragma shader_feature _METALLICGLOSSMAP
    73.             #pragma shader_feature ___ _DETAIL_MULX2
    74.             #pragma shader_feature _PARALLAXMAP
    75.  
    76.             #pragma multi_compile_fwdbase
    77.             #pragma multi_compile_fog
    78.  
    79.             #pragma vertex vertBase
    80.             #pragma fragment fragBase
    81.             #include "UnityStandardCoreForward.cginc"
    82.  
    83.             ENDCG
    84.         }
    85.             // ------------------------------------------------------------------
    86.             //  Additive forward pass (one light per pass)
    87.             Pass
    88.             {
    89.                 Name "FORWARD_DELTA"
    90.                 Tags { "LightMode" = "ForwardAdd" }
    91.                 Blend[_SrcBlend] One
    92.                 Fog { Color(0,0,0,0) } // in additive pass fog should be black
    93.                 ZWrite Off
    94.                 ZTest LEqual
    95.  
    96.                 CGPROGRAM
    97.                 #pragma target es3.0
    98.             // GLES2.0 temporarily disabled to prevent errors spam on devices without textureCubeLodEXT
    99.             //#pragma exclude_renderers gles
    100.  
    101.             // -------------------------------------
    102.  
    103.  
    104.             #pragma shader_feature _NORMALMAP
    105.             #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    106.             #pragma shader_feature _METALLICGLOSSMAP
    107.             #pragma shader_feature ___ _DETAIL_MULX2
    108.             #pragma shader_feature _PARALLAXMAP
    109.  
    110.             #pragma multi_compile_fwdadd_fullshadows
    111.             #pragma multi_compile_fog
    112.  
    113.             #pragma vertex vertAdd
    114.             #pragma fragment fragAdd
    115.             #include "UnityStandardCoreForward.cginc"
    116.  
    117.             ENDCG
    118.         }
    119.             // ------------------------------------------------------------------
    120.             //  Shadow rendering pass
    121.             Pass {
    122.                 Name "ShadowCaster"
    123.                 Tags { "LightMode" = "ShadowCaster" }
    124.  
    125.                 ZWrite On ZTest LEqual
    126.  
    127.                 CGPROGRAM
    128.                 #pragma target es3.0
    129.             // TEMPORARY: GLES2.0 temporarily disabled to prevent errors spam on devices without textureCubeLodEXT
    130.             //#pragma exclude_renderers gles
    131.  
    132.             // -------------------------------------
    133.  
    134.  
    135.             #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    136.             #pragma multi_compile_shadowcaster
    137.  
    138.             #pragma vertex vertShadowCaster
    139.             #pragma fragment fragShadowCaster
    140.  
    141.             #include "UnityStandardShadow.cginc"
    142.  
    143.             ENDCG
    144.         }
    145.             // ------------------------------------------------------------------
    146.             //  Deferred pass
    147.             Pass
    148.             {
    149.                 Name "DEFERRED"
    150.                 Tags { "LightMode" = "Deferred" }
    151.  
    152.                 CGPROGRAM
    153.                 #pragma target es3.0
    154.             // TEMPORARY: GLES2.0 temporarily disabled to prevent errors spam on devices without textureCubeLodEXT
    155.             //#pragma exclude_renderers nomrt gles
    156.  
    157.  
    158.             // -------------------------------------
    159.  
    160.             #pragma shader_feature _NORMALMAP
    161.             #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    162.             #pragma shader_feature _EMISSION
    163.             #pragma shader_feature _METALLICGLOSSMAP
    164.             #pragma shader_feature ___ _DETAIL_MULX2
    165.             #pragma shader_feature _PARALLAXMAP
    166.  
    167.             #pragma multi_compile ___ UNITY_HDR_ON
    168.             #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
    169.             #pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE
    170.             #pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON
    171.  
    172.             #pragma vertex vertDeferred
    173.             #pragma fragment fragDeferred
    174.  
    175.             #include "UnityStandardCore.cginc"
    176.  
    177.             ENDCG
    178.         }
    179.  
    180.             // ------------------------------------------------------------------
    181.             // Extracts information for lightmapping, GI (emission, albedo, ...)
    182.             // This pass it not used during regular rendering.
    183.             Pass
    184.             {
    185.                 Name "META"
    186.                 Tags { "LightMode" = "Meta" }
    187.  
    188.                 Cull Off
    189.  
    190.                 CGPROGRAM
    191.                 #pragma vertex vert_meta
    192.                 #pragma fragment frag_meta
    193.  
    194.                 #pragma shader_feature _EMISSION
    195.                 #pragma shader_feature _METALLICGLOSSMAP
    196.                 #pragma shader_feature ___ _DETAIL_MULX2
    197.  
    198.                 #include "UnityStandardMeta.cginc"
    199.                 ENDCG
    200.             }
    201.         }
    202.  
    203.             SubShader
    204.         {
    205.             Tags { "RenderType" = "Opaque" "PerformanceChecks" = "False" }
    206.             LOD 150
    207.  
    208.             // ------------------------------------------------------------------
    209.             //  Base forward pass (directional light, emission, lightmaps, ...)
    210.             Pass
    211.             {
    212.                 Name "FORWARD"
    213.                 Tags { "LightMode" = "ForwardBase" }
    214.  
    215.                 Blend[_SrcBlend][_DstBlend]
    216.                 ZWrite[_ZWrite]
    217.  
    218.                 CGPROGRAM
    219.                 #pragma target es3.0
    220.  
    221.                 #pragma shader_feature _NORMALMAP
    222.                 #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    223.                 #pragma shader_feature _EMISSION
    224.                 #pragma shader_feature _METALLICGLOSSMAP
    225.                 #pragma shader_feature ___ _DETAIL_MULX2
    226.             // SM2.0: NOT SUPPORTED shader_feature _PARALLAXMAP
    227.  
    228.             #pragma skip_variants SHADOWS_SOFT DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE
    229.  
    230.             #pragma multi_compile_fwdbase
    231.             #pragma multi_compile_fog
    232.  
    233.             #pragma vertex vertBase
    234.             #pragma fragment fragBase
    235.             #include "UnityStandardCoreForward.cginc"
    236.  
    237.             ENDCG
    238.         }
    239.             // ------------------------------------------------------------------
    240.             //  Additive forward pass (one light per pass)
    241.             Pass
    242.             {
    243.                 Name "FORWARD_DELTA"
    244.                 Tags { "LightMode" = "ForwardAdd" }
    245.                 Blend[_SrcBlend] One
    246.                 Fog { Color(0,0,0,0) } // in additive pass fog should be black
    247.                 ZWrite Off
    248.                 ZTest LEqual
    249.  
    250.                 CGPROGRAM
    251.                 #pragma target es3.0
    252.  
    253.                 #pragma shader_feature _NORMALMAP
    254.                 #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    255.                 #pragma shader_feature _METALLICGLOSSMAP
    256.                 #pragma shader_feature ___ _DETAIL_MULX2
    257.             // SM2.0: NOT SUPPORTED shader_feature _PARALLAXMAP
    258.             #pragma skip_variants SHADOWS_SOFT
    259.  
    260.             #pragma multi_compile_fwdadd_fullshadows
    261.             #pragma multi_compile_fog
    262.  
    263.             #pragma vertex vertAdd
    264.             #pragma fragment fragAdd
    265.             #include "UnityStandardCoreForward.cginc"
    266.  
    267.             ENDCG
    268.         }
    269.             // ------------------------------------------------------------------
    270.             //  Shadow rendering pass
    271.             Pass {
    272.                 Name "ShadowCaster"
    273.                 Tags { "LightMode" = "ShadowCaster" }
    274.  
    275.                 ZWrite On ZTest LEqual
    276.  
    277.                 CGPROGRAM
    278.                 #pragma target es3.0
    279.  
    280.                 #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    281.                 #pragma skip_variants SHADOWS_SOFT
    282.                 #pragma multi_compile_shadowcaster
    283.  
    284.                 #pragma vertex vertShadowCaster
    285.                 #pragma fragment fragShadowCaster
    286.  
    287.                 #include "UnityStandardShadow.cginc"
    288.  
    289.                 ENDCG
    290.             }
    291.  
    292.             // ------------------------------------------------------------------
    293.             // Extracts information for lightmapping, GI (emission, albedo, ...)
    294.             // This pass it not used during regular rendering.
    295.             Pass
    296.             {
    297.                 Name "META"
    298.                 Tags { "LightMode" = "Meta" }
    299.  
    300.                 Cull Off
    301.  
    302.                 CGPROGRAM
    303.                 #pragma vertex vert_meta
    304.                 #pragma fragment frag_meta
    305.  
    306.                 #pragma shader_feature _EMISSION
    307.                 #pragma shader_feature _METALLICGLOSSMAP
    308.                 #pragma shader_feature ___ _DETAIL_MULX2
    309.  
    310.                 #include "UnityStandardMeta.cginc"
    311.                 ENDCG
    312.             }
    313.         }
    314.  
    315.  
    316.             FallBack "VertexLit"
    317.             CustomEditor "StandardShaderGUI"
    318. }
    319.  
    I basicly set the shader level target (#pragma target es3.0), this modified shader didn't work either, now I'm guessing this feature of setting a normal map's intensity is not working yet on mobile, maybe it is under development? Can anyone confim this please? I'm using the last stable version of Unity (5.3.4f1).
     
    aliozan7 likes this.
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    An important requirement for bump scale beyond shader model 3.0 is DXTC support.

    The bit of code that's important is in UnityStandardUtils.cginc, specifically the UnpackScaleNormal function, and how normal maps are stored on mobile vs other platforms.

    For desktop and consoles textures are compressed using DXTC (DirectX Texture Compression), specifically DXT1 or DXT5, and normal maps are stored as what's referred to as DXT5nm, which is just a normal DXT5 texture with the normal map's red channel stored in the alpha and the blue channel removed. The blue, or z value, is reconstructed from the red and green and this step makes scaling the normals fairly easy to add.

    For mobile it's assumed DXTC isn't supported, and for most platforms this is true, so instead normal maps are stored as is. Since it doesn't reconstruct the z supporting scaling would add a bunch of additional math that isn't otherwise needed.

    Now that function in question looks like this:
    Code (CSharp):
    1. half3 UnpackScaleNormal(half4 packednormal, half bumpScale)
    2. {
    3.     #if defined(UNITY_NO_DXT5nm)
    4.         return packednormal.xyz * 2 - 1;
    5.     #else
    6.         half3 normal;
    7.         normal.xy = (packednormal.wy * 2 - 1);
    8.         #if (SHADER_TARGET >= 30)
    9.             // SM2.0: instruction count limitation
    10.             // SM2.0: normal scaler is not supported
    11.             normal.xy *= bumpScale;
    12.         #endif
    13.         normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));
    14.         return normal;
    15.     #endif
    16. }
    There is indeed a test for if the shader target is 3.0 or higher (SHADER_TARGET >= 30), and #pragma target es3.0 actually sets SHADER_TARGET to 35 so would pass that test ... but it never gets to that code because the platform you're running on (The Galaxy S6 w/ a Mali GPU) doesn't support DXTC so instead the function just returns texture's values "straight" and skips the bump scale.

    If you wanted to implement this on your own using a custom standard surface shader it wouldn't be too hard, but modifying the Standard.shader itself is going to be a bit more than just setting a #pragma someplace. You might be able to get away with putting a modified UnityStandardUtils.cginc in the same folder as your Standard2.shader and modifying the UnpackScaleNormal function there.

    Code (CSharp):
    1. half3 UnpackScaleNormal(half4 packednormal, half bumpScale)
    2. {
    3.     #if defined(UNITY_NO_DXT5nm)
    4.         half3 normal = packednormal.xyz * 2 - 1;
    5.         #if (SHADER_TARGET >= 30)
    6.             normal.xy *= bumpScale;
    7.             normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));
    8.         #endif
    9.         return normal;
    10.     #else
    11.         half3 normal;
    12.         normal.xy = (packednormal.wy * 2 - 1);
    13.         #if (SHADER_TARGET >= 30)
    14.             // SM2.0: instruction count limitation
    15.             // SM2.0: normal scaler is not supported
    16.             normal.xy *= bumpScale;
    17.         #endif
    18.         normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));
    19.         return normal;
    20.     #endif
    21. }
     
    Last edited: Apr 13, 2016
  6. Black_Demon

    Black_Demon

    Joined:
    Jul 12, 2014
    Posts:
    12
    Hi @bgolus that did the trick! I really appreciate your help and the additional information, I'm a begginer in shaders programming and find this very useful, thank you so much.:)