Changing Shader Modes:Īn artist once pointed out to me that she can animate the shader type of a material, from Opaque to Transparent. A better but still not super maintainable one would be including your variant materials in the Resources folder, which always gets included in the build. So one not-so-great strat would be to include in your scene the material variations you’ll need in the build. So how do you swap shader types at runtime? (transparent to opaque, tessellated to not, etc) Solution 1: If you’re dealing with an _OFF _ON setup, then in addition to enabling, you also should DisableKeyword() for the _OFF one. Or rather, if you see the multiple keywords on the #pragma, the first one is the one used by default, and usually it would be a wildcard _ or a _NORMALMAP_OFF, before the _NORMALMAP or _NORMALMAP_ON. Same if you made a copy newMat.CopyPropertiesFromMaterial(oldMat), or just a newMat = new Material(Shader.Find("Standard")) programatically. itself to actually be swaped out on the GPU for another variant: myMaterial.EnableKeyword("_NORMALMAP"), or globally for every material: Shader.EnableKeyword("_NORMALMAP"). So you will need to also tell the Standard Shader or Uber Shader etc. When you’re working with the Standard or Uber shader, and remove a texture at runtime from C#, it’s the same, the shader just uses values of 0 when it samples that textue. If you write your own shader without a custom editor script, it will always include the calculations for the texture (and treat it as black if left empty). But this is because the Editor GUI C# script has noticed you left the texture slot empty. This means that if in your scene you have a material with the Standard Shader with a _NormalMap texture, and one without, 2 shader variants get created and are available at runtime. The CG in CGPROGRAM is real but is used as a middle language. This is why for example Unity shaders have “Surface Shaders” (which is Latin for “fake-shader”). Note: Normally the HLSL or CG you write in an engine is interpreted and compiled through a bunch of internal engine compiler layers and frameworks before it becomes “real” HLSL or “real” GLSL, Vulkan etc., according to the platform the build is for (pc/console etc). When you build the game, the engine goes through all your Materials and figures out what combination of settings they use, and parse and compile shader programs for each combination necessary. something else, or no else at all #endif #if defined(_NORMALMAP))įoo = tex2dlod ( _NormalMap, uvw ) //or bar = tex2D ( _NormalMap, uv ) //etc. the "_" is a wildcard for "OFF by default" // can also have #pragma compile_type _DO_STUFF_OFF _DO_STUFF_ON _DO_OTHER_STUFF // Replace "compile_type" with either "shader_feature" or "multi_compile". Shaders are text files that are typically full of compile time directives like this: 1ĬGPROGRAM #pragma compile_type _ _NORMALMAP //<- you define the keyword here Things to look for: SetKeyword, MaterialChanged, SetupMaterialWithBlendMode, Shader.EnableKeyword(), Shader.DisableKeyword(). If you examine StandardShaderGUI.cs ( get it here), you see that a whole bunch of stuff happens when you change a material setting. You want to create a material with any specific shader variant, programatically. You want to switch a shader from Opaque to Transparent at runtime. You have a material with like 5 textures, what happens if you remove some of them at runtime? Does it become more efficient? (with specifics for unit圓d and Standard, Uber, Custom shaders) Here’s a few high level scenarios you’d experience: I’ll briefly explain how shader programs are created and invoked under the hood, with shader variant compilation.
0 Comments
Leave a Reply. |