Search Unity

Shader not processing property block changes right away

Discussion in 'Shaders' started by Riderfan, Nov 4, 2016.

  1. Riderfan

    Riderfan

    Joined:
    Jan 10, 2013
    Posts:
    514
    I'm using PropertyBlocks to change values inside a shader at various points in the game. I can pause the game and look at the material on the object in the inspector, look at the values for the shader properties and see that they've been updated and are correct, but the shader isn't actually using them.

    After a few moments though, something kicks in and the shaders DO start using the new values. It just not starting when I've told them too.

    Is there some sort of 'shader refresh' that I need to call to get these to take right away?

    This is the call I make from within the game to change the values in the shader;
    Code (CSharp):
    1.  
    2. mProps.SetFloat("_CurrentRow", _Row);  //_Row is a value passed in
    3. mProps.SetFloat("_StartFrame", Random.Range(1, MAXFRAMES)); //We want to start at a random frame between 1 and MaxFrames(5).
    4. mMesh.SetPropertyBlock(mProps);
    5.  
    and this is the full shader;

    Code (CSharp):
    1.  
    2. Shader "CanuckPlay/Instanced Vert Shader"
    3. {
    4.     Properties
    5.     {
    6.         _Color("Color", Color) = (1, 1, 1, 1)
    7.         _MainTex("Base (RGB) Trans (A)", 2D) = "white" {}
    8.         _Cutoff("Alpha cutoff", Range(0,1)) = 0.15
    9.         _Cells("X= Columns, Y=Rows, Z=Speed", Vector) = (8, 5, 10, 0)
    10.         _CurrentRow("Current Row", float) = 1.0
    11.         _StartFrame("Start Frame", float) = 1.0
    12.     }
    13.     SubShader
    14.     {
    15.         Tags{ "Queue" = "AlphaTest" "IgnoreProjector" = "True" "RenderType" = "TransparentCutout" "LightMode" = "ForwardBase" }
    16.         LOD 100
    17.         //Cull Off
    18.  
    19.         Pass
    20.         {
    21.             CGPROGRAM
    22.             #pragma vertex vert
    23.             #pragma fragment frag
    24.             #pragma target 3.0
    25.             #pragma multi_compile_instancing
    26.             #include "UnityCG.cginc"
    27.             #include "UnityLightingCommon.cginc" // for _LightColor0
    28.             #pragma multi_compile_fwdbase
    29.             #include "AutoLight.cginc"
    30.  
    31.             struct appdata_t
    32.             {
    33.                 UNITY_INSTANCE_ID
    34.                 float4 vertex : POSITION;
    35.                 float3 normal : NORMAL;
    36.                 float3 color : COLOR0;
    37.                 float2 texcoord : TEXCOORD0;
    38.                 float2 localpos : TEXCOORD1; // local vertex position. makes it easier because static batched meshes dont have local verts anymore
    39.                 float2 frameindex : TEXCOORD2; // x=frameindex, y=unused
    40.             };
    41.  
    42.             struct v2f
    43.             {
    44.                 UNITY_INSTANCE_ID
    45.                 float4 pos : SV_POSITION;
    46.                 fixed4 diff : COLOR0; //Diffuse lighting color
    47.                 float2 texcoord : TEXCOORD0;
    48.                 float3 color : TEXCOORD1;
    49.                 float3 lightDir : TEXCOORD2;
    50.                 float3 normal : TEXCOORD3;
    51.                 LIGHTING_COORDS(4, 5)
    52.             };
    53.  
    54.             sampler2D _MainTex;
    55.             float4 _MainTex_ST;
    56.             fixed _Cutoff;
    57.             float4 _Cells;
    58.  
    59.             UNITY_INSTANCING_CBUFFER_START(MyProperties)
    60.                 UNITY_DEFINE_INSTANCED_PROP(fixed4, _Color)
    61.                 UNITY_DEFINE_INSTANCED_PROP(float, _CurrentRow)
    62.                 UNITY_DEFINE_INSTANCED_PROP(float, _StartFrame)
    63.             UNITY_INSTANCING_CBUFFER_END
    64.  
    65.             // rotate always towards camera
    66.             void Billboard(inout appdata_t v)
    67.             {
    68.                 const float3 local = float3(v.localpos.x, v.localpos.y, 0); // this is the quad verts as generated by MakeMesh.cs in the localPos list.
    69.                 const float3 offset = v.vertex.xyz - local;
    70.  
    71.                 const float3 upVector = half3(0, 1, 0);
    72.                 const float3 forwardVector = UNITY_MATRIX_IT_MV[2].xyz; // camera forward
    73.                 const float3 rightVector = normalize(cross(forwardVector, upVector));
    74.  
    75.                 float3 position = 0;
    76.                 position += local.x * rightVector;
    77.                 position += local.y * upVector;
    78.                 position += local.z * forwardVector;
    79.  
    80.                 v.vertex = float4(offset + position, 1);
    81.                 v.normal = forwardVector;
    82.             }
    83.  
    84.             // moves the sprite sheet from left to right restricted to a single row specified by _CurrentRow.
    85.             void AnimateUV(appdata_t v, inout v2f o)
    86.             {
    87.                 float frame = UNITY_ACCESS_INSTANCED_PROP(_StartFrame) + floor(_Time.g * _Cells.z); //Advance the frame number
    88.  
    89.                 o.texcoord.x += fmod(frame, _Cells.x); //Update the columns based on time per frame
    90.                 o.texcoord.y += fmod(UNITY_ACCESS_INSTANCED_PROP(_CurrentRow), _Cells.y); //Keep to the specified row.
    91.                 o.texcoord /= _Cells.xy;
    92.             }
    93.  
    94.             v2f vert(appdata_t v)
    95.             {
    96.                 v2f o;
    97.                 UNITY_INITIALIZE_OUTPUT(v2f, o);
    98.  
    99.                 UNITY_SETUP_INSTANCE_ID(v);
    100.                 UNITY_TRANSFER_INSTANCE_ID(v, o);
    101.  
    102.                 Billboard(v);
    103.  
    104.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    105.                 o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
    106.  
    107.                 AnimateUV(v, o);
    108.  
    109.                 o.lightDir = normalize(ObjSpaceLightDir(v.vertex));
    110.                 o.normal = normalize(v.normal).xyz;
    111.  
    112.                 TRANSFER_VERTEX_TO_FRAGMENT(o);
    113.  
    114.                 return o;
    115.             }
    116.  
    117.             fixed4 frag(v2f i) : SV_Target
    118.             {
    119.                 float3 L = normalize(i.lightDir);
    120.                 float3 N = normalize(i.normal);
    121.  
    122.                 float attenuation = LIGHT_ATTENUATION(i) * 0.75;
    123.                 float4 ambient = UNITY_LIGHTMODEL_AMBIENT * 0.5;
    124.  
    125.                 float NdotL = saturate(dot(N, L));
    126.                 float4 diffuseTerm = NdotL * _LightColor0 * UNITY_ACCESS_INSTANCED_PROP(_Color) * attenuation;
    127.  
    128.                 float4 diffuse = tex2D(_MainTex, i.texcoord);
    129.                 clip(diffuse.a - _Cutoff); //Deal with alpha.
    130.  
    131.                 float4 finalColor = (ambient + diffuseTerm) * diffuse;
    132.  
    133.                 return finalColor;
    134.             }
    135.             ENDCG
    136.         }
    137.     }
    138.     Fallback "VertexLit" //This is required because the shadow 'finalize' is handled in existing shaders, so use the simpliest one possible.
    139. }
    140.  
    thanks in advance.
     
  2. Riderfan

    Riderfan

    Joined:
    Jan 10, 2013
    Posts:
    514
    Can someone from the Unity Dev site chime in on this? I can't seem to get these properties to update when told to and I'm wondering if this a known bug?

    thanks
     
  3. _Amael_

    _Amael_

    Joined:
    Aug 20, 2012
    Posts:
    19
    Late reply, but it looks like your shader is missing the [PerRendererData] tags:

    Code (CSharp):
    1.  
    2. Shader "CanuckPlay/Instanced Vert Shader"
    3. {
    4.     Properties
    5.     {
    6.         _Color("Color", Color) = (1, 1, 1, 1)
    7.         _MainTex("Base (RGB) Trans (A)", 2D) = "white" {}
    8.         _Cutoff("Alpha cutoff", Range(0,1)) = 0.15
    9.         _Cells("X= Columns, Y=Rows, Z=Speed", Vector) = (8, 5, 10, 0)
    10.         [PerRendererData]_CurrentRow("Current Row", float) = 1.0
    11.         [PerRendererData]_StartFrame("Start Frame", float) = 1.0
    12.     }
    13. }
    14.  
    If the material property blocks are working correctly, you won't be able to use the inspector to see the values of the material (the material will say "MaterialPropertyBlock is used to modify these values")