I’m sorry that this topic is going more to the field of glsl, sice I have some problems with that too.
I prefer to write the sl code into a text file and then compile it runtime for allowing different extension versions to be used. My vertex shader compiles fine, but after compiling my fragment shader, cgCreateProgram causes my app to crash. If I intentionally type an invalid expression to the fragment shader, the compiler gives an error and does not crash my app. So it only crashes when the shader has compiled. Weird though. Here’s my function call:
Program = cgCreateProgram(Context, CG_SOURCE, (const char*)File.GetBuffer(),
Prof, NULL, NULL);
if( (Err = cgGetError())!=CG_NO_ERROR )
{
Con << cgGetErrorString(Err) << CEndl;
return false;
}
There’s some of my app specific stuff, but it should basically show what I’m doing. Context is created before calling this one and Prof is set to proper fragment shader profile. At least I think it is .
Apart from that, I’ve coded the tangent vector calculator, and to make sure it works I made my app to render the basis vectors on vertices. Here’s an image, so you could tell me if they look the way they should:
[http://koti.mbnet.fi/blender/poista/basis.jpg](http:// <a href=) " target=“_blank”> http://koti.mbnet.fi/blender/poista/basis.jpg
Red=tangent
Green=Vertex normal
Blue=Binormal
I can’t test my shaders before I can fix the crashing issue, so here’re my shaders. Maybe you could tell me any flaws they might have:
Vertex shader:
struct appin
{
float4 Position : POSITION;
float4 Normal : NORMAL;
float2 BaseUV : TEXCOORD0;
float4 Tangent : TEXCOORD1;
};
struct vertout
{
float4 HPosition : POSITION;
float2 BaseUV : TEXCOORD0;
float3 Color : COLOR;
};
vertout main(appin IN, uniform float4x4 ModelViewProj, uniform float4 LightVec)
{
vertout OUT;
OUT.HPosition = mul(ModelViewProj, IN.Position);
OUT.BaseUV = IN.BaseUV;
float3 BiNormal=normalize(cross(IN.Normal.xyz, IN.Tangent.xyz));
OUT.Color.x = dot(-LightVec, IN.Tangent);
OUT.Color.y = dot(-LightVec.xyz, BiNormal);
OUT.Color.z = dot(-LightVec, IN.Normal);
return OUT;
}
Fragment shader:
struct fragin
{
float2 BaseUV : TEXCOORD0;
float3 LightVec : COLOR; // Tangent space light vector
uniform sampler2D BaseTex : TEXUNIT0;
uniform sampler2D BumpTex : TEXUNIT1;
};
float3 main(fragin IN)
{
float3 BaseColor = tex2D(IN.BaseTex, IN.BaseUV).rgb;
float3 BumpVec = 2.0*(tex2D(IN.BumpTex, IN.BaseUV).rgb-0.5);
return BaseColor * saturate( dot(IN.LightVec, BumpVec) );
}
So I would have tangent pre-calculated and stored to second texture coordinates and the object space lightvector given as a uniform parameter before the mesh is rendered.