Coding Style
Initial stages of programming - low level shaders API:
The following function is a C++ Win32 example of a camera matrix. I wrote this function while taking the first shaders course.
m44 ActualCustomMathClass::camera( vertex target, vertex camPos )
{
m44 out;
// Look = CameraTarget - CameraPosition
vertex vLook;
vLook.x = target.x - camPos.x;
vLook.y = target.y - camPos.y;
vLook.z = target.z - camPos.z;
vLook.w = 0;
vLook = normalize( vLook );
// WorldUp values - Default WorldUp values to (0, 1, 0, 0)
vertex worldUp;
worldUp.x = 0;
worldUp.y = 1;
worldUp.z = 0;
worldUp.w = 0;
// Right = WorldUp X Look
vertex vRight;
vRight = crossProduct( worldUp, vLook );
vRight = normalize( vRight );
// Up = Look X Right
vertex vUp;
vUp = crossProduct( vLook, vRight );
vUp = normalize( vUp );
// Translation = -(CameraPosition dot Component)
vertex trans;
trans.x = -(dotProduct( camPos, vRight ));
trans.y = -(dotProduct( camPos, vUp ));
trans.z = -(dotProduct( camPos, vLook ));
// Matrix Layout
// Right.x Up.x Look.x 0
// Right.y Up.y Look.y 0
// Right.z Up.z Look.z 0
// Translation.x Translation.y Translation.z 1
out.m[0][0] = vRight.x; out.m[0][1] = vUp.x; out.m[0][2] = vLook.x; out.m[0][3] = 0;
out.m[1][0] = vRight.y; out.m[1][1] = vUp.y; out.m[1][2] = vLook.y; out.m[1][3] = 0;
out.m[2][0] = vRight.z; out.m[2][1] = vUp.z; out.m[2][2] = vLook.z; out.m[2][3] = 0;
out.m[3][0] = trans.x; out.m[3][1] = trans.y; out.m[3][2] = trans.z; out.m[3][3] = 1;
return out;
}
|
HLSL (High Level Shaders Language):
For my shaders demo, I created a total of 6 shaders. One of the shaders was Glass shader. Here is the FX file portion of its code.
//--------------------------------------------------------------------------------------------
// Globals
//--------------------------------------------------------------------------------------------
float4x4 m_WorldMatrix;
float4x4 m_CameraMatrix;
float4x4 m_ProjectionMatrix;
float3 m_Light; // Light Position in World Space
float3 m_Camera;
texture m_BaseTexture;
texture m_EffectTexture;
texture m_EnvironmentTexture;
// Base Texture can be applied but not being used for glass
sampler2D BaseTexture = sampler_state
{
Texture = <m_BaseTexture>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
};
// A Normal Texture can be applied optionally
sampler2D EffectTexture = sampler_state
{
Texture = <m_EffectTexture>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
};
// Reflection of the environment is applied using the preloaded environment cube texture
samplerCUBE EnvironmentTexture = sampler_state
{
Texture = <m_EnvironmentTexture>>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
};
//--------------------------------------------------------------------------------------------
// Vertex shader input and output structure
//--------------------------------------------------------------------------------------------
struct VS_INPUT
{
float3 Position : POSITION;
float3 Normal : NORMAL;
float2 Tex0 : TEXCOORD0;
float3 Tangent : TANGENT;
float3 Binormal : BINORMAL;
};
struct VS_OUTPUT
{
float4 Position : POSITION;
float2 Tex0 : TEXCOORD0;
float3 TangentCamera : TEXCOORD1;
float3 TangentLight : TEXCOORD2;
};
//--------------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------------
VS_OUTPUT VtxShader( VS_INPUT In )
{
VS_OUTPUT Out;
// Position XForm
In.Position = mul(float4(In.Position, 1), (float4x3)m_WorldMatrix);
float3 tempPos = In.Position;
float3 P = In.Position.xyz;
In.Position = mul(float4(In.Position, 1), (float4x3)m_CameraMatrix);
Out.Position = mul(float4(In.Position, 1), m_ProjectionMatrix);
// Transforming Normal, Tangent, and Binormal vectors to World space
float3 N = normalize(mul(In.Normal, (float4x3)m_WorldMatrix));
float3 T = normalize(mul(In.Tangent, (float4x3)m_WorldMatrix));
float3 B = normalize(mul(In.Binormal, (float4x3)m_WorldMatrix));
// Inverse Tangent-Space Matrix:
// T.x B.x N.x
// T.y B.y N.y
// T.z B.z N.z
float3x3 tangentMatrix = float3x3(B,T,N); // B,T,N is the correct format for float3x3()
// Pass Thrus: Transform camera and light to Tangent-Space for output
Out.TangentCamera = mul( tangentMatrix, normalize(tempPos - m_Camera) );
Out.TangentLight = mul( tangentMatrix, normalize(tempPos - m_Light) );
Out.Tex0 = In.Tex0;
return Out;
}
//--------------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------------
float4 PixShader(VS_OUTPUT In) : COLOR
{
// Assign a dark gray color to the object
float4 baseColour = float4( 0.25, 0.25, 0.25, 1.0 );
// Create a normal out of the effect texture
// This is an optional step since the normals in this case are not being used
float3 normal = tex2D(EffectTexture, In.Tex0);
// Bring the normal value from between (-1 and 1) to (0 and 1)
normal = normal * 2 - 1;
normal = normalize( normal );
// Diffuse Lighting Calculation - Intensity * (Normal * -TangentLight)
float diffuse = 1.0f * (dot(normal, normalize(-In.TangentLight)));
baseColour *= max(0.1, diffuse);
// Specular Lighting Calculation (Optional Use)
float3 R = reflect(In.TangentLight, normal);
R = normalize(R);
float spec = dot(R, normalize(-In.TangentCamera));
spec = saturate(spec);
spec = pow(spec, 1000.0f);
// Environment Map
float3 RV = reflect(normalize(-In.TangentCamera), normal);
float4 environmentColor = texCUBE( EnvironmentTexture, RV );
return float4((baseColour + (environmentColor * 0.2) + (spec * 3.0f)).rgb, 0.5f);
}
//--------------------------------------------------------------------------------------------
// Set Shader
//--------------------------------------------------------------------------------------------
technique SetShaders
{
pass P0
{
VertexShader = compile vs_2_0 VtxShader();
PixelShader = compile ps_2_0 PixShader();
}
}
|
|