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. 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): var body = transform.Find("Body"); var bodyMaterial = body.GetComponent<Renderer>().material; foreach (var keyValue in maskDictionary) { bodyMaterial.SetFloat(keyValue.Key, Mathf.Clamp(keyValue.Value, 0f, 1f)); } 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.
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): 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): Shader "Custom/Standard Diffuse Masked Humanoid" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _MaskTex ("Mask", 2D) = "white" {} [Space(10)] [Toggle] _MaskHead("Mask Head", Float) = 0 [Toggle] _MaskTorso("Mask Torso", Float) = 0 [Toggle] _MaskArms("Mask Arms", Float) = 0 [Toggle] _MaskHands("Mask Hands", Float) = 0 [Toggle] _MaskHips("Mask Hips", Float) = 0 [Toggle] _MaskLegs("Mask Legs", Float) = 0 [Toggle] _MaskFeet("Mask Feet", Float) = 0 [Space(10)] _MaskHeadIndex("Head Mask Index", Range(0,1)) = 0.07 _MaskTorsoIndex("Torso Mask Index", Range(0,1)) = 0.16 _MaskArmsIndex("Arms Mask Index", Range(0,1)) = 0.35 _MaskHandsIndex("Hands Mask Index", Range(0,1)) = 0.5 _MaskHipsIndex("Hips Mask Index", Range(0,1)) = 0.26 _MaskLegsIndex("Legs Mask Index", Range(0,1)) = 0.615 _MaskFeetIndex("Feet Mask Index", Range(0,1)) = 0.66 _MaskThreshold("Mask Threshold", Range(0,1)) = 0.05 } SubShader { Tags { "Queue" = "AlphaTest" "RenderType" = "TransparentCutout" } Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma surface surf Standard alphatest:_Cutoff addshadow sampler2D _MainTex; sampler2D _MaskTex; fixed _MaskValue; fixed _MaskThreshold; float _MaskHead; float _MaskTorso; float _MaskArms; float _MaskHands; float _MaskHips; float _MaskLegs; float _MaskFeet; float _MaskHeadIndex; float _MaskTorsoIndex; float _MaskArmsIndex; float _MaskHandsIndex; float _MaskHipsIndex; float _MaskLegsIndex; float _MaskFeetIndex; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutputStandard o) { // read main texture fixed4 c = tex2D(_MainTex, IN.uv_MainTex); // read mask texture RED channel only fixed maskColor = tex2D(_MaskTex, IN.uv_MainTex).r; // // // check if maskColor is within threshold for mask index # and mask # is toggled on (toggled value is 1) fixed mask1 = abs(maskColor - _MaskHeadIndex) < _MaskThreshold ? _MaskHead : 0; fixed mask2 = abs(maskColor - _MaskTorsoIndex) < _MaskThreshold ? _MaskTorso : 0; fixed mask3 = abs(maskColor - _MaskArmsIndex) < _MaskThreshold ? _MaskArms : 0; fixed mask4 = abs(maskColor - _MaskHandsIndex) < _MaskThreshold ? _MaskHands : 0; fixed mask5 = abs(maskColor - _MaskHipsIndex) < _MaskThreshold ? _MaskHips : 0; fixed mask6 = abs(maskColor - _MaskLegsIndex) < _MaskThreshold ? _MaskLegs : 0; fixed mask7 = abs(maskColor - _MaskFeetIndex) < _MaskThreshold ? _MaskFeet : 0; // for now: just subtract from alpha if mask affects it c.a = c.a-mask1; c.a = c.a-mask2; c.a = c.a-mask3; c.a = c.a-mask4; c.a = c.a-mask5; c.a = c.a-mask6; c.a = c.a-mask7; // output color and alpha o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG } }
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): Shader "Shader Forge/SpriteDissolve" { Properties { _Slider_Dissolve ("Slider_Dissolve", Range(0, 1.5)) = 1.5 _Slider_Border ("Slider_Border", Color) = (1,0.7655173,0,1) _Slider_Transition ("Slider_Transition", Range(0, 0.2)) = 0.1083302 _0RED1GREEN2BLUE ("0 = RED // 1 = GREEN // 2= BLUE", Float ) = 0 _Texture2 ("Texture 2", 2D) = "white" {} _Texture1 ("Texture 1", 2D) = "white" {} [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0 } SubShader { Tags { "IgnoreProjector"="True" "Queue"="Transparent" "RenderType"="Transparent" "CanUseSpriteAtlas"="True" "PreviewType"="Plane" } Blend SrcAlpha OneMinusSrcAlpha Pass { Name "FORWARD" Tags { "LightMode"="ForwardBase" } Blend One OneMinusSrcAlpha Cull Off ZWrite Off CGPROGRAM #pragma vertex vert #pragma fragment frag #define UNITY_PASS_FORWARDBASE #pragma multi_compile _ PIXELSNAP_ON #include "UnityCG.cginc" #pragma multi_compile_fwdbase #pragma exclude_renderers gles3 metal d3d11_9x xbox360 xboxone ps3 ps4 psp2 #pragma target 3.0 uniform float _Slider_Dissolve; uniform float4 _Slider_Border; uniform float _Slider_Transition; uniform float _0RED1GREEN2BLUE; uniform sampler2D _Texture2; uniform float4 _Texture2_ST; uniform sampler2D _Texture1; uniform float4 _Texture1_ST; struct VertexInput { float4 vertex : POSITION; float2 texcoord0 : TEXCOORD0; }; struct VertexOutput { float4 pos : SV_POSITION; float2 uv0 : TEXCOORD0; }; VertexOutput vert (VertexInput v) { VertexOutput o = (VertexOutput)0; o.uv0 = v.texcoord0; o.pos = mul(UNITY_MATRIX_MVP, v.vertex ); #ifdef PIXELSNAP_ON o.pos = UnityPixelSnap(o.pos); #endif return o; } float4 frag(VertexOutput i, float facing : VFACE) : COLOR { float isFrontFace = ( facing >= 0 ? 1 : 0 ); float faceSign = ( facing >= 0 ? 1 : -1 ); ////// Lighting: ////// Emissive: float4 _Texture1_var = tex2D(_Texture1,TRANSFORM_TEX(i.uv0, _Texture1)); float4 _Texture2_var = tex2D(_Texture2,TRANSFORM_TEX(i.uv0, _Texture2)); float node_9964_if_leA = step(1.0,_0RED1GREEN2BLUE); float node_9964_if_leB = step(_0RED1GREEN2BLUE,1.0); 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))); float node_2567 = step(node_6089,_Slider_Dissolve); 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)); float3 finalColor = emissive; return fixed4(finalColor,1); } ENDCG } } FallBack "Diffuse" CustomEditor "ShaderForgeMaterialInspector" } If by luck you can help us, Thanks!