If anyone could help or point me to the right place to ask, that would be great.
Code: Select all
//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
float4x4 mTransWorld; // Transposed world matrix
float4x4 mWorldViewProj; // World * View * Projection transformation
float4x4 mInvWorld; // Inverted world matrix
float4x4 mInvWorldViewProj; // Inverted WorldViewProj
// Vertex shader output structure
struct VS_OUTPUT
{
float4 fPosition : POSITION; // fake position to satisfy compiler
float3 Normal : COLOR0; // the Normal, store in COLOR0 semantic
float2 TexCoord : TEXCOORD0; // tex coords
float4 wPosition : TEXCOORD1; // world position
float4 vPosition : TEXCOORD2; // vertex position
};
VS_OUTPUT vertexMain( in float4 vPosition : POSITION,
in float3 vNormal : NORMAL,
float2 texCoord : TEXCOORD0 )
{
VS_OUTPUT Output;
// transform position to clip space
Output.vPosition = mul(vPosition, mWorldViewProj);
// transform normal
float3 normal = mul(float4(vNormal,0.0), mInvWorld);
// renormalize normal
Output.Normal = normalize(normal);
// position in world coodinates
Output.wPosition = mul(mTransWorld, vPosition);
Output.TexCoord = texCoord;
Output.fPosition = Output.vPosition;
return Output;
}
// material attributes, because it doesn't work, to define it from the irrlicht API and to find it in gl_FrontMaterial
#define SHININESS 18
#define WITH_NORMALMAP_GREEN_UP
#define WITH_NORMALMAP
#define MAX_LIGHTS 8
// Pixel shader output structure
struct PS_OUTPUT
{
float4 RGBColor : COLOR0; // Pixel color
};
struct LightSource
{
float4 position;
float4 diffuse;
float4 specular;
};
sampler2D diffusemap;
sampler2D specularmap;
sampler2D normalmap;
sampler2D emitmap;
//float4 color;
float3x3 cotangent_frame(float3 N, float3 p, float2 uv)
{
// get edge vectors of the pixel triangle
float3 dp1 = ddx(p);
float3 dp2 = ddy(p);
float3 duv1 = ddx(float3(uv, 0));
float3 duv2 = ddy(float3(uv, 0));
// solve the linear system
float3 dp2perp = cross(dp2, N);
float3 dp1perp = cross(N, dp1);
float3 T = dp2perp * duv1.x + dp1perp * duv2.x;
float3 B = dp2perp * duv1.y + dp1perp * duv2.y;
// construct a scale-invariant frame
float invmax = rsqrt(max(dot(T,T), dot(B,B)));
return float3x3(T * invmax, B * invmax, N);
}
// assume N, the interpolated vertex normal and V, the view vector (eye to vertex)
float3 perturb_normal(float3 N, float3 V, float2 texcoord)
{
// the normalmap pixels are in [0,1] interval, we needs [-1, 1]
float3 map = tex2D(normalmap, texcoord).xyz*2 -1;
#ifdef WITH_NORMALMAP_UNSIGNED
map = map * 255./127. - 128./127.;
#endif
#ifdef WITH_NORMALMAP_2CHANNEL
map.z = sqrt(1. - dot(map.xy, map.xy));
#endif
#ifdef WITH_NORMALMAP_GREEN_UP
map.y = -map.y;
#endif
float3x3 TBN = cotangent_frame(N, V, texcoord);
//return normalize(TBN * map);
return normalize(mul(map, TBN));
}
LightSource gl_LightSource[MAX_LIGHTS];
float LightCount;
float4 pixelMain( float3 Normal : COLOR0,
float2 TexCoord : TEXCOORD0,
float4 wPosition : TEXCOORD1,
float4 vPosition : TEXCOORD2) :COLOR
{
PS_OUTPUT Output;
float4 diffuse = float4(0,0,0,0);
float4 specular = float4(0,0,0,0);
float4 color = float4(1.0, 1.0, 1.0, 1.0);
#ifdef WITH_NORMALMAP
float3 n = perturb_normal(Normal, wPosition, TexCoord);
#define NORMAL n
#else
#define NORMAL Normal
#endif
float3 lv;
float quadraticAttenuation;
for (int i=0; i<LightCount; i++)
{
//Divide by 5 to give lights more range
lv = (float3)((gl_LightSource[i].position - wPosition) / 5);
quadraticAttenuation = 1 / pow(length(lv), 2);
// max() is used to disallow negative values (that makes an other light at opposed direction)
diffuse += max(0, dot(normalize(lv), NORMAL))
* quadraticAttenuation * gl_LightSource[i].diffuse;
// changing 8 value changes the scale of the specular effect, there is currently a problem by replacing it by gl_FrontMaterial.shininess (shininess is to 0)
specular += pow(max(0, dot(normalize(lv), normalize(reflect(wPosition, NORMAL)))), SHININESS)
* quadraticAttenuation * gl_LightSource[i].specular;
}
Output.RGBColor = (
diffuse * tex2D(diffusemap, TexCoord)
+ specular * tex2D(specularmap, TexCoord)
) + tex2D(emitmap, TexCoord) * color;
return Output.RGBColor;
}