Hello All,
I cobbled together a shader from some code on the net. It can do multiple lights, diffuse+specuar shading, transparancy, and color and normal textures. I was planning on using it as a base to add the effects I need. The shader works fine as is and compiles without error in shader model 2.0. The problem I have is that if I add additional code, it puts me over the instruction limit for shader model 2. Attempting to uncomment the “#pragma target 3.0” to use shader model 3.0 (after adding additional code) gives me the error that “No subshaders can run on this graphics card.” I have been pulling my hair out for tens of hours over this, searching for a solution everywhere. The problem appears on multiple DirectX 11 computers. Can someone point me in the right direction?
Thanks!
Edit: Another error I am getting is “D3D shader assembly failed with: (5): error X2000: syntax error : unexpected token ‘#’”
// main code from http://cgcookie.com/unity/lessons/09c-debug-and-optimize-practical/
// cookie stuff from http://en.wikibooks.org/wiki/Cg_Programming/Unity/Cookies
Shader "RiftShader/NormalShader" {
// _Name ( "Displayed Name", type ) = default value [{options}]
Properties {
_Color ("Diffuse Material Color", Color) = (1.0, 1.0, 1.0, 1.0)
_SpecColor ("Specular Material Color", Color) = (1.0, 1.0, 1.0, 1.0)
_Shininess ("Specular Power", Float) = 10.0
_RimColor ("Rim Color", Color) = (1.0, 1.0, 1.0, 1.0)
_RimPower ("Rim Power", Range(0.1, 10.0)) = 3.0
_MainTex ("Diffuse Texture", 2D) = "white" {}
_BumpMap ("Normal Texture", 2D) = "bump" {}
_BumpDepth ("Bump Depth", Range(0.0, 1.0)) = 1.0
}
SubShader {
// this render queue is rendered after Geometry and AlphaTest, in back-to-front order.
// Anything alpha-blended (i.e. shaders that don't write to depth buffer) should go here (glass, particle effects)
Tags {"Queue" = "Transparent" }
// object that is rendered using this subshader will never cast shadows. This is mostly useful when you are using
// shader replacement on transparent objects and you do not wont to inherit a shadow pass from another subshader
Tags {"ForceNoShadowCasting" = "True" }
// object that uses this shader will not be affected by Projectors. This is mostly useful on semitransparent
// objects, because there is no good way for Projectors to affect them
Tags {"IgnoreProjector" = "True" }
// shader is potentially going to output semi-transparent or transparent pixels
Tags {"RenderType" = "Transparent" }
LOD 400
Alphatest Greater 0 ZWrite Off ColorMask RGB
GrabPass{ }
Pass {
// ForwardBase: ambient, main directional light and vertex/SH lights
// ambient light, first pixel light, and 4 vertex lights
Tags { "LightMode"="ForwardBase" }
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
//#pragma target 3.0
//#pragma only_renderers d3d11
#pragma exclude_renderers flash
#pragma vertex vert
#pragma fragment frag
//user defined variables
uniform sampler2D _MainTex;
uniform half4 _MainTex_ST;
uniform sampler2D _BumpMap;
uniform half4 _BumpMap_ST;
uniform fixed4 _Color;
uniform fixed4 _SpecColor;
uniform fixed4 _RimColor;
uniform half _Shininess;
uniform half _RimPower;
uniform fixed _BumpDepth;
//unity defined variables
uniform half4 _LightColor0; // color of light source
uniform float4x4 _LightMatrix0; // transformation from world to light source
uniform sampler2D _LightTexture0; // cookie alpha texture map
//base input structs
struct vertexInput{
half4 vertex : POSITION;
half3 normal : NORMAL;
half4 texcoord : TEXCOORD0;
half4 tangent : TANGENT;
};
struct vertexOutput{
half4 pos : SV_POSITION;
half4 tex : TEXCOORD0;
fixed4 lightDirection : TEXCOORD1;
fixed3 viewDirection : TEXCOORD2;
fixed3 normalWorld : TEXCOORD3;
fixed3 tangentWorld : TEXCOORD4;
fixed3 binormalWorld : TEXCOORD5;
half4 posLight : TEXCOORD6; // position in light space
};
//vertex shader
vertexOutput vert(vertexInput v){
vertexOutput o;
o.normalWorld = normalize( mul( half4( v.normal, 0.0 ), _World2Object ).xyz );
o.tangentWorld = normalize ( mul( _Object2World, v.tangent ).xyz );
o.binormalWorld = normalize ( cross(o.normalWorld, o.tangentWorld) * v.tangent.w );
half4 posWorld = mul(_Object2World, v.vertex);
o.posLight = mul(_LightMatrix0, posWorld);
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.tex = v.texcoord;
o.viewDirection = normalize( _WorldSpaceCameraPos.xyz - posWorld.xyz );
half3 fragmentToLightSource = _WorldSpaceLightPos0.xyz - posWorld.xyz;
// if _WorldSpaceLightPos0.w == 0 then we have a directional light, otherwise we have a point or spotlight
// for a directional light, atten = 1.0 and lightDirection = _WorldSpaceLightPos0.xzy
// for point or spot, atten = 1.0 / distance (linear attenuation)
// and lightDirection = fragmentToLightSource
o.lightDirection = fixed4(
normalize( lerp( _WorldSpaceLightPos0.xyz , fragmentToLightSource, _WorldSpaceLightPos0.w )),
lerp(1.0, 1.0/length(fragmentToLightSource), _WorldSpaceLightPos0.w )
);
return o;
}
//fragment shader
fixed4 frag(vertexOutput i) : COLOR
{
//Texture Maps
fixed4 tex = tex2D(_MainTex, i.tex.xy * _MainTex_ST.xy + _MainTex_ST.zw);
fixed4 texN = tex2D(_BumpMap, i.tex.xy * _BumpMap_ST.xy + _BumpMap_ST.zw);
//unpack Normal function
fixed3 localCoords = fixed3(2.0 * texN.ag - fixed2(1.0, 1.0), _BumpDepth);
//normal transpose matrix
fixed3x3 local2WorldTranspose = fixed3x3(
i.tangentWorld,
i.binormalWorld,
i.normalWorld
);
//calculate normal direction
fixed3 normalDirection = normalize( mul( localCoords, local2WorldTranspose ) );
//Lighting
fixed nDotL = max(0.0, dot(normalDirection, i.lightDirection.xyz));
fixed3 ambientLighting = UNITY_LIGHTMODEL_AMBIENT.xyz * _Color.xyz;
fixed3 diffuseReflection = _LightColor0.xyz * _Color.xyz * nDotL;
// fixed3 diffuseReflection = i.lightDirection.w * _LightColor0.xyz * nDotL;
fixed3 specularReflection = _LightColor0.xyz * _SpecColor.a * _SpecColor.xyz * pow(max(0.0, dot(reflect(-i.lightDirection.xyz, normalDirection), i.viewDirection)), _Shininess);
//Rim Lighting
fixed rim = 1 - max(0.0, dot(i.viewDirection, normalDirection));
fixed3 rimLighting = _RimColor.a * _RimColor.xyz * _LightColor0.xyz * nDotL * pow( rim, _RimPower );
fixed3 lightFinal = ambientLighting + diffuseReflection + specularReflection + rimLighting;
return fixed4(tex.xyz * lightFinal, _Color.a);
}
ENDCG
} //pass
Pass {
// FrowardAdd : additive per-pixel lights are applied, one pass per light
// do not add ambient, texture, emission, or surface color in again
// unless there are more than one directional light sources without cookies,
// we can assume that all directional light sources in this pass have cookies
Tags { "LightMode"="ForwardAdd" }
ZWrite Off Blend One One Fog { Color (0,0,0,0) }
Blend SrcAlpha One
//Blend One One
CGPROGRAM
//#pragma target 3.0
//#pragma only_renderers d3d11
#pragma exclude_renderers flash
#pragma vertex vert
#pragma fragment frag
//user defined variables
uniform sampler2D _MainTex;
uniform half4 _MainTex_ST;
uniform sampler2D _BumpMap;
uniform half4 _BumpMap_ST;
uniform fixed4 _Color;
uniform fixed4 _SpecColor;
uniform fixed4 _RimColor;
uniform half _Shininess;
uniform half _RimPower;
uniform fixed _BumpDepth;
//unity defined variables
uniform half4 _LightColor0;
uniform float4x4 _LightMatrix0; // transformation from world to light source
uniform sampler2D _LightTexture0; // cookie alpha texture map
//base input structs
struct vertexInput{
half4 vertex : POSITION;
half3 normal : NORMAL;
half4 texcoord : TEXCOORD0;
half4 tangent : TANGENT;
};
struct vertexOutput{
half4 pos : SV_POSITION;
half4 tex : TEXCOORD0;
fixed4 lightDirection : TEXCOORD1;
fixed3 viewDirection : TEXCOORD2;
fixed3 normalWorld : TEXCOORD3;
fixed3 tangentWorld : TEXCOORD4;
fixed3 binormalWorld : TEXCOORD5;
half4 posLight : TEXCOORD6; // position in light space
};
//vertex shader
vertexOutput vert(vertexInput v){
vertexOutput o;
o.normalWorld = normalize( mul( half4( v.normal, 0.0 ), _World2Object ).xyz );
o.tangentWorld = normalize ( mul( _Object2World, v.tangent ).xyz );
o.binormalWorld = normalize ( cross(o.normalWorld, o.tangentWorld) * v.tangent.w );
half4 posWorld = mul(_Object2World, v.vertex);
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.tex = v.texcoord;
o.posLight = mul(_LightMatrix0, posWorld);
o.viewDirection = normalize( _WorldSpaceCameraPos.xyz - posWorld.xyz );
half3 fragmentToLightSource = _WorldSpaceLightPos0.xyz - posWorld.xyz;
o.lightDirection = fixed4(
normalize( lerp(_WorldSpaceLightPos0.xyz , fragmentToLightSource, _WorldSpaceLightPos0.w) ),
lerp(1.0, 1.0/length(fragmentToLightSource), _WorldSpaceLightPos0.w)
);
return o;
}
//fragment shader
fixed4 frag(vertexOutput i) : COLOR
{
//Texture Maps
fixed4 texN = tex2D(_BumpMap, i.tex.xy * _BumpMap_ST.xy + _BumpMap_ST.zw);
fixed dirLightAlpha = tex2D(_LightTexture0, i.posLight.xy).a; // can we move to vert shader?
fixed spotLightAlpha = tex2D(_LightTexture0, i.posLight.xy / i.posLight.w + fixed2(0.5, 0.5)).a;
//unpack Normal function
fixed3 localCoords = fixed3(2.0 * texN.ag - fixed2(1.0, 1.0), _BumpDepth);
//normal transpose matrix
fixed3x3 local2WorldTranspose = fixed3x3(
i.tangentWorld,
i.binormalWorld,
i.normalWorld
);
//calculate normal direction
fixed3 normalDirection = normalize( mul( localCoords, local2WorldTranspose ) );
//Lighting
fixed nDotL = max(0.0, dot(normalDirection, i.lightDirection.xyz));
fixed3 diffuseReflection = i.lightDirection.w * _LightColor0.xyz * _Color.xyz * nDotL;
fixed3 specularReflection = _LightColor0.xyz * _SpecColor.a * _SpecColor.xyz * pow(max(0.0, dot(reflect(-i.lightDirection.xyz, normalDirection), i.viewDirection)), _Shininess);
//Rim Lighting
fixed rim = 1 - max(0.0, dot(i.viewDirection, normalDirection));
fixed3 rimLighting = _RimColor.a * _RimColor.xyz * _LightColor0.xyz * nDotL * pow( rim, _RimPower );
// cookie attenuation
// if _WorldSpaceLightPos0.w == 0 then we have a directional light
// and atten = dirLightAlpha
// else if _LightMatrix0[3][3] == 1 then we have a spotlight
// and atten = spotLightAlpha
fixed cookieAttenuation = lerp(dirLightAlpha, lerp(spotLightAlpha, 1.0, _LightMatrix0[3][3]), _WorldSpaceLightPos0.w);
fixed3 lightFinal = diffuseReflection + specularReflection + rimLighting;
return fixed4(cookieAttenuation * lightFinal, _Color.a);
}
ENDCG
} //pass
}
// Comment out fallback shader for testing - will make object show up as pink if there is an error.
//FallBack "Diffuse"
}