Search Unity

Material Isn't Updating When Using SetFloat

Discussion in 'Shaders' started by tomglenn, May 8, 2018.

  1. tomglenn

    tomglenn

    Joined:
    Aug 3, 2015
    Posts:
    28
    I've created a shader based on the Unity Standard Shader which uses Transparent Cutout and a mask texture that allows me to dynamically mask areas of my Humanoid mesh at run time (Head, Torso, Arms etc).

    This works brilliantly in the editor, as shown below.
    upload_2018-5-8_21-10-23.png

    It also works great at run time, if I modify the toggles in the inspector.

    However, if I try and update it at runtime through a script as below:

    Code (CSharp):
    1.         var body = transform.Find("Body");
    2.         var bodyMaterial = body.GetComponent<Renderer>().material;
    3.  
    4.         foreach (var keyValue in maskDictionary)
    5.         {
    6.             bodyMaterial.SetFloat(keyValue.Key, Mathf.Clamp(keyValue.Value, 0f, 1f));
    7.         }
    8.  
    9.         bodyMaterial.EnableKeyword("_ALPHATEST_ON");
    Nothing happens, until I click on my Scene view (While the game is still running) and click on my players Body gameobject. As soon as I do that, the mesh updates and the parts I wish to mask actually get masked....

    I've searched all over and all I can find are posts about requiring the EnableKeyword() call when using Standard shaders, which as you can see I am already doing.

    Any help is much appreciated.
     
  2. tomglenn

    tomglenn

    Joined:
    Aug 3, 2015
    Posts:
    28
    UPDATE:
    After lots of messing about, closing and reopening unity between tests (once you opened the inspector, it worked every time until closing unity!) I finally fixed the issue.

    I added the following line to my Shader

    Code (CSharp):
    1. Blend SrcAlpha OneMinusSrcAlpha
    In the end I didn't need to mess about with any calls to EnableKeyword() etc.
    Just simply calling SetFloat() worked.

    For anyone interested, here is my full shader.
    Props go to mgear over at this post for the ground work. https://forum.unity.com/threads/special-mask-texture-problem.506864/

    Code (CSharp):
    1. Shader "Custom/Standard Diffuse Masked Humanoid"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Base (RGB)", 2D) = "white" {}
    6.         _MaskTex ("Mask", 2D) = "white" {}
    7.  
    8.         [Space(10)]
    9.         [Toggle] _MaskHead("Mask Head", Float) = 0
    10.         [Toggle] _MaskTorso("Mask Torso", Float) = 0
    11.         [Toggle] _MaskArms("Mask Arms", Float) = 0
    12.         [Toggle] _MaskHands("Mask Hands", Float) = 0
    13.         [Toggle] _MaskHips("Mask Hips", Float) = 0
    14.         [Toggle] _MaskLegs("Mask Legs", Float) = 0
    15.         [Toggle] _MaskFeet("Mask Feet", Float) = 0
    16.         [Space(10)]
    17.         _MaskHeadIndex("Head Mask Index", Range(0,1)) = 0.07
    18.         _MaskTorsoIndex("Torso Mask Index", Range(0,1)) = 0.16
    19.         _MaskArmsIndex("Arms Mask Index", Range(0,1)) = 0.35
    20.         _MaskHandsIndex("Hands Mask Index", Range(0,1)) = 0.5
    21.         _MaskHipsIndex("Hips Mask Index", Range(0,1)) = 0.26
    22.         _MaskLegsIndex("Legs Mask Index", Range(0,1)) = 0.615
    23.         _MaskFeetIndex("Feet Mask Index", Range(0,1)) = 0.66
    24.         _MaskThreshold("Mask Threshold", Range(0,1)) = 0.05
    25.     }
    26.     SubShader
    27.     {
    28.         Tags
    29.         {
    30.             "Queue" = "AlphaTest"
    31.             "RenderType" = "TransparentCutout"
    32.         }
    33.  
    34.         Blend SrcAlpha OneMinusSrcAlpha
    35.  
    36.         CGPROGRAM
    37.         #pragma surface surf Standard alphatest:_Cutoff addshadow
    38.         sampler2D _MainTex;
    39.         sampler2D _MaskTex;
    40.         fixed _MaskValue;
    41.         fixed _MaskThreshold;
    42.         float _MaskHead;
    43.         float _MaskTorso;
    44.         float _MaskArms;
    45.         float _MaskHands;
    46.         float _MaskHips;
    47.         float _MaskLegs;
    48.         float _MaskFeet;
    49.         float _MaskHeadIndex;
    50.         float _MaskTorsoIndex;
    51.         float _MaskArmsIndex;
    52.         float _MaskHandsIndex;
    53.         float _MaskHipsIndex;
    54.         float _MaskLegsIndex;
    55.         float _MaskFeetIndex;
    56.         struct Input
    57.         {
    58.             float2 uv_MainTex;
    59.         };
    60.         void surf (Input IN, inout SurfaceOutputStandard o)
    61.         {
    62.             // read main texture
    63.             fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
    64.  
    65.             // read mask texture RED channel only
    66.             fixed maskColor = tex2D(_MaskTex, IN.uv_MainTex).r;
    67.             // // // check if maskColor is within threshold for mask index # and mask # is toggled on (toggled value is 1)
    68.             fixed mask1 = abs(maskColor - _MaskHeadIndex) < _MaskThreshold ? _MaskHead : 0;
    69.             fixed mask2 = abs(maskColor - _MaskTorsoIndex) < _MaskThreshold ? _MaskTorso : 0;
    70.             fixed mask3 = abs(maskColor - _MaskArmsIndex) < _MaskThreshold ? _MaskArms : 0;
    71.             fixed mask4 = abs(maskColor - _MaskHandsIndex) < _MaskThreshold ? _MaskHands : 0;
    72.             fixed mask5 = abs(maskColor - _MaskHipsIndex) < _MaskThreshold ? _MaskHips : 0;
    73.             fixed mask6 = abs(maskColor - _MaskLegsIndex) < _MaskThreshold ? _MaskLegs : 0;
    74.             fixed mask7 = abs(maskColor - _MaskFeetIndex) < _MaskThreshold ? _MaskFeet : 0;
    75.             // for now: just subtract from alpha if mask affects it
    76.             c.a = c.a-mask1;
    77.             c.a = c.a-mask2;
    78.             c.a = c.a-mask3;
    79.             c.a = c.a-mask4;
    80.             c.a = c.a-mask5;
    81.             c.a = c.a-mask6;
    82.             c.a = c.a-mask7;
    83.             // output color and alpha
    84.             o.Albedo = c.rgb;
    85.             o.Alpha = c.a;
    86.         }
    87.         ENDCG
    88.     }
    89. }
    90.  
     
  3. Tahitij

    Tahitij

    Joined:
    Aug 19, 2015
    Posts:
    1
    Hi @tomglenn!

    It appears we got the same problem:
    https://gamedev.stackexchange.com/q...-a-materials-shader-in-an-image-unity-5-2-0f3
    https://answers.unity.com/questions/1549807/how-to-play-a-shader-in-an-image-unity-520f3.html

    We tried your solution but without success here our shader:

    Code (CSharp):
    1. Shader "Shader Forge/SpriteDissolve" {
    2.     Properties {
    3.         _Slider_Dissolve ("Slider_Dissolve", Range(0, 1.5)) = 1.5
    4.         _Slider_Border ("Slider_Border", Color) = (1,0.7655173,0,1)
    5.         _Slider_Transition ("Slider_Transition", Range(0, 0.2)) = 0.1083302
    6.         _0RED1GREEN2BLUE ("0 = RED // 1 = GREEN // 2= BLUE", Float ) = 0
    7.         _Texture2 ("Texture 2", 2D) = "white" {}
    8.         _Texture1 ("Texture 1", 2D) = "white" {}
    9.         [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
    10.     }
    11.     SubShader {
    12.         Tags {
    13.             "IgnoreProjector"="True"
    14.             "Queue"="Transparent"
    15.             "RenderType"="Transparent"
    16.             "CanUseSpriteAtlas"="True"
    17.             "PreviewType"="Plane"
    18.         }
    19.        
    20.         Blend SrcAlpha OneMinusSrcAlpha
    21.        
    22.         Pass {
    23.             Name "FORWARD"
    24.             Tags {
    25.                 "LightMode"="ForwardBase"
    26.             }
    27.            
    28.             Blend One OneMinusSrcAlpha
    29.             Cull Off
    30.             ZWrite Off
    31.            
    32.             CGPROGRAM
    33.             #pragma vertex vert
    34.             #pragma fragment frag
    35.             #define UNITY_PASS_FORWARDBASE
    36.             #pragma multi_compile _ PIXELSNAP_ON
    37.             #include "UnityCG.cginc"
    38.             #pragma multi_compile_fwdbase
    39.             #pragma exclude_renderers gles3 metal d3d11_9x xbox360 xboxone ps3 ps4 psp2
    40.             #pragma target 3.0
    41.             uniform float _Slider_Dissolve;
    42.             uniform float4 _Slider_Border;
    43.             uniform float _Slider_Transition;
    44.             uniform float _0RED1GREEN2BLUE;
    45.             uniform sampler2D _Texture2; uniform float4 _Texture2_ST;
    46.             uniform sampler2D _Texture1; uniform float4 _Texture1_ST;
    47.             struct VertexInput {
    48.                 float4 vertex : POSITION;
    49.                 float2 texcoord0 : TEXCOORD0;
    50.             };
    51.             struct VertexOutput {
    52.                 float4 pos : SV_POSITION;
    53.                 float2 uv0 : TEXCOORD0;
    54.             };
    55.             VertexOutput vert (VertexInput v) {
    56.                 VertexOutput o = (VertexOutput)0;
    57.                 o.uv0 = v.texcoord0;
    58.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex );
    59.                 #ifdef PIXELSNAP_ON
    60.                     o.pos = UnityPixelSnap(o.pos);
    61.                 #endif
    62.                 return o;
    63.             }
    64.             float4 frag(VertexOutput i, float facing : VFACE) : COLOR {
    65.                 float isFrontFace = ( facing >= 0 ? 1 : 0 );
    66.                 float faceSign = ( facing >= 0 ? 1 : -1 );
    67. ////// Lighting:
    68. ////// Emissive:
    69.                 float4 _Texture1_var = tex2D(_Texture1,TRANSFORM_TEX(i.uv0, _Texture1));
    70.                 float4 _Texture2_var = tex2D(_Texture2,TRANSFORM_TEX(i.uv0, _Texture2));
    71.                 float node_9964_if_leA = step(1.0,_0RED1GREEN2BLUE);
    72.                 float node_9964_if_leB = step(_0RED1GREEN2BLUE,1.0);
    73.                 float node_6089 = (lerp((node_9964_if_leA*_Texture1_var.b)+(node_9964_if_leB*_Texture1_var.r),_Texture1_var.g,node_9964_if_leA*node_9964_if_leB)*length((1.0 - i.uv0)));
    74.                 float node_2567 = step(node_6089,_Slider_Dissolve);
    75.                 float3 emissive = lerp(lerp(_Texture1_var.rgb,_Texture2_var.rgb,node_2567),_Slider_Border.rgb,(node_2567*step(_Slider_Dissolve,(node_6089+_Slider_Transition))*0.1));
    76.                 float3 finalColor = emissive;
    77.                 return fixed4(finalColor,1);
    78.             }
    79.             ENDCG
    80.         }
    81.     }
    82.     FallBack "Diffuse"
    83.     CustomEditor "ShaderForgeMaterialInspector"
    84. }
    If by luck you can help us,
    Thanks!