- Home /
How to make keywords per material works properly (not in Editor)
Hi,
Basically here's my problem : I load an .obj object in Unity with a custom parser that is supposed to set keyword "BUMP" or "NO_BUMP" to my shader for each material depending on whether a bump texture comes along with this material (not all of my materials have necessarily bump).
But no matter what the bump texture value could be I always end up with my shader be executed with the BUMP keyword value set...
In the Obj parser/loader I have this :
mat = new Material(Shader.Find("Lectra/FragmentProg-Transparent"));
if ( mat.HasProperty("_BumpMap") && bumpTexture != null )
{
Texture2D newBump = Bump.NormalMapVG(bumpTexture, bumpDepth);
mat.SetTexture("_BumpMap", newBump);
mat.SetTextureScale("_BumpMap", new Vector2(bumpScaleX, bumpScaleY));
var keywords = new List<string> { "BUMP" };
mat.shaderKeywords = keywords.ToArray();
}
else
{
mat.SetTexture("_BumpMap", null);
var keywords = new List<string> { "NO_BUMP" };
mat.shaderKeywords = keywords.ToArray ();
}
And in my shader I have this :
Pass {
Tags { "LightMode" = "ForwardBase" }
Cull Off
//zWrite Off
Blend SrcAlpha OneMinusSrcAlpha
//AlphaTest Greater [_Cutoff]
CGPROGRAM
#pragma multi_compile BUMP NO_BUMP
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
//user defined variables
uniform fixed4 _Color;
uniform sampler2D _MainTex;
uniform half4 _MainTex_ST;
uniform sampler2D _BumpMap;
uniform half4 _BumpMap_ST;
uniform fixed _BumpDepth;
uniform half _MyShininess;
//base input structs
struct vertexInput
{
half4 vertex : POSITION;
half3 normal : NORMAL;
fixed4 texcoord : TEXCOORD0;
#if BUMP
half3 tangent : TANGENT;
#endif
};
struct vertexOutput
{
half4 pos : SV_POSITION;
fixed4 tex : TEXCOORD1;
fixed3 normalDir : TEXCOORD2;
fixed3 viewDir : TEXCOORD3;
fixed3 lightDir : TEXCOORD4;
half3 vlight : TEXCOORD5;
#if BUMP
fixed3 tangentDir : TEXCOORD6;
fixed3 binormalDir : TEXCOORD7;
#endif
};
//vertex function
vertexOutput vert(vertexInput v)
{
vertexOutput o;
half3 posWorld = mul(_Object2World, v.vertex);
// Vectors
o.normalDir = normalize(mul(_Object2World, float4(v.normal, 0.0)).xyz);
#if BUMP
o.tangentDir = normalize( mul(_Object2World, float4(v.tangent, 0.0)).xyz );
o.binormalDir = normalize( cross(o.tangentDir, o.normalDir) );
#endif
o.lightDir = normalize(_WorldSpaceLightPos0.xyz);
o.viewDir = normalize(_WorldSpaceCameraPos.xyz - posWorld.xyz);
// Vertex light probes
o.vlight = ShadeSH9(float4(o.normalDir, 1.0));
// Coordinates
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.tex = v.texcoord;
return o;
}
//fragment function
fixed4 frag(vertexOutput i) : COLOR
{
//lighting
fixed ambiantAtten = 0.01;
fixed diffuseAtten = 2.0;
fixed specularAtten = 0.4;
fixed3 normalDirection;
#if BUMP
fixed4 texNm = tex2D(_BumpMap, _BumpMap_ST.xy * i.tex.xy + _BumpMap_ST.zw);
fixed3 localCoords = fixed3(2.0 * texNm.ag - fixed2(1.0, 1.0), 0.0);
localCoords.z = _BumpDepth;
fixed3x3 local2WorldTranspose = fixed3x3(
i.tangentDir,
i.binormalDir,
i.normalDir
);
normalDirection = normalize ( mul ( localCoords, local2WorldTranspose ) );
#else
normalDirection = i.normalDir;
#endif
fixed nDotL = dot(normalDirection, i.lightDir);
fixed3 diffuseReflection = _Color *_LightColor0.rgb * saturate(nDotL);
fixed3 specularReflection;
if (nDotL < 0.0)
// light source on the wrong side?
{
specularReflection = float3(0.0, 0.0, 0.0);
// no specular reflection
}
else
{
// light source on the right side
specularReflection = specularAtten *_LightColor0.rgb * _SpecColor * pow ( saturate ( dot( reflect( -i.lightDir, normalDirection ), i.viewDir ) ), _MyShininess );
//specularReflection = diffuseReflection * pow ( saturate ( dot( reflect( -i.lightDir, i.normalDir ), i.viewDir ) ), _MyShininess );
}
fixed3 lightFinal = ambiantAtten * UNITY_LIGHTMODEL_AMBIENT + diffuseAtten * diffuseReflection + specularReflection;
fixed4 tex = tex2D(_MainTex, _MainTex_ST.xy * i.tex.xy + _MainTex_ST.zw);
fixed3 finalColor = lightFinal * tex.rgb + i.vlight * tex.rgb;
fixed finalAlpha = tex.a * _Color.a ;
return fixed4(finalColor, finalAlpha);
}
ENDCG
}
From what I've read on the topic I think I use the keyword per material properly but I may be missing something here...
If someone could point it out that'd be greatly appreciated !
Thanks in advance,
I don't see any problems, but -1 for not cutting the code down to the essentials.