x


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

more ▼

asked Mar 16, 2012 at 05:36 PM

ronronmx gravatar image

ronronmx
1k 317 236 262

(comments are locked)
10|3000 characters needed characters left

1 answer: sort voted first

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.

more ▼

answered Mar 29, 2012 at 07:33 PM

stramit gravatar image

stramit
35 1 1 2

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_SIMPLE IS_ADVANCED
 #pragma multi_compile LIGHTING_ON LIGHTING_OFF
Aug 02, 2013 at 05:19 PM porglezomp

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_SIMPLE 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_SIMPLE IS_ADVANCED" and then do "#pragma IS_SIMPLE IS_ADVANCE"? Just a little confused, sorry if this seems like a stupid question!

Mar 30, 2012 at 07:05 PM ronronmx
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x9510
x3190
x505
x183

asked: Mar 16, 2012 at 05:36 PM

Seen: 7612 times

Last Updated: Aug 02, 2013 at 05:29 PM