- Home /
Using custom keywords in cg shaders
I need to use custom keywords in my cg shader, but so far I can't get them working. I looked at the Water4 shader and scripts - since it uses custom keywords - and tried to setup my files the same way, but so far I can't get it to work.
Here's my shader( my custom keyword is in the "surf" function ):
Shader "SRShaders/Bumped Specular (1 Directional Light)" {
Properties {
_Shininess ("Shininess", Range (0.03, 1)) = 0.078125
_MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
_BumpMap ("Normalmap", 2D) = "bump" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 250
CGPROGRAM
#pragma surface surf MobileBlinnPhong exclude_path:prepass nolightmap noforwardadd halfasview novertexlights
inline fixed4 LightingMobileBlinnPhong (SurfaceOutput s, fixed3 lightDir, fixed3 halfDir, fixed atten)
{
fixed diff = max (0, dot (s.Normal, lightDir));
fixed nh = max (0, dot (s.Normal, halfDir));
fixed spec = pow (nh, s.Specular*128) * s.Gloss;
fixed4 c;
c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * spec) * (atten*2);
c.a = 0.0;
return c;
}
sampler2D _MainTex;
sampler2D _BumpMap;
half _Shininess;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = tex.rgb;
#ifdef IS_SIMPLE // My custom keyword
o.Albedo *= 4;
#endif
o.Gloss = tex.a;
o.Alpha = tex.a;
o.Specular = _Shininess;
o.Normal = UnpackNormal (tex2D(_BumpMap, IN.uv_MainTex));
}
ENDCG
}
FallBack "Mobile/VertexLit"
}
And here's my script:
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class ShaderManager : MonoBehaviour {
// Store the camera
public Camera cam;
public Texture2D tex;
// Before the object gets rendered
public void OnWillRenderObject ( ) {
cam = Camera.current;
if( !cam )
return;
Shader shader = renderer.sharedMaterial.shader;
}
void OnEnable() {
Shader.EnableKeyword("IS_SIMPLE"); // My custom keyword
}
void OnDisable() {
Shader.DisableKeyword("IS_SIMPLE"); // My custom keyword
}
}
I should mention that the script is NOT in the same folder as the shader, and that I am not using Unity Pro. I'm using Unity 3.5 iPhone basic.
I can't find any documentation on this issue, so I need a shader guru's help hehe :)
Thanks in advance!
Stephane
Answer by stramit · Mar 29, 2012 at 07:33 PM
Hi you will notice that the water shader does this at the start:
#pragma multi_compile WATER_REFRACTIVE WATER_REFLECTIVE WATER_SIMPLE
What this is saying is that the compiler needs to generate a permutation of the shader for each of those defines. There will be 3 combinations generated. One each for WATER_REFLECTIVE, WATER_REFRACTIVE, and WATER_SIMPLE.
The shader compiler is very explicit about the permutations it generates. So if you have multiple flags that you want on / off use multiple multi_compile pragmas.
Doing:
#pragma IS_SIMPLE IS_ADVANCED
#pragma LIGHTING_ON LIGHTING_OFF
Will generate these permutations:
IS_SIMPLE LIGHTING_ON
IS_SIMPLE LIGHTING_OFF
IS_ADVANCED LIGHTING_ON
IS_ADVANCED LIGHTING_OFF
You do not need to use a given flag.
In your example you would do:
#pragma IS_SIMPLE IS_ADVANCED
This would generate two permutations, one with IS_SIMPLE set one with IS_ADVANCED set. You don't need to use IS_ADVANCED.
Let me know if you have any further troubles.
Thanks for the answer stramit! I am not home right now so I can't give it a try, but I will tonight when I get home. Quick question: when you say "Doing: #pragma IS_SI$$anonymous$$PLE IS_ADVANCED #pragma LIGHTING_ON LIGHTING_OFF", how come it's not "#pragma multi_compile"? Do i need to define first "#pragma multi-compile IS_SI$$anonymous$$PLE IS_ADVANCED" and then do "#pragma IS_SI$$anonymous$$PLE IS_ADVANCE"? Just a little confused, sorry if this seems like a stupid question!
Just ran into this problem, helping out anyone who comes along here. You need to put multi_compile on all your pragmas. So that would be:
#pragma multi_compile IS_SI$$anonymous$$PLE IS_ADVANCED
#pragma multi_compile LIGHTING_ON LIGHTING_OFF
If you need only one keyword, you can use #pragma multi_compile SO$$anonymous$$ETHING_ON _
(notice the 2nd arg)
Your answer
Follow this Question
Related Questions
Flat Shading / No Vertex Interpolation 2 Answers
Access to svPosition in fragment shader 1 Answer
Material doesn't have a color property '_Color' 4 Answers
Shaders problems after moving to URP 0 Answers