4 light normalmapping for animated meshes [C++/GLSL]

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
xirtamatrix
Posts: 219
Joined: Fri Feb 19, 2010 4:03 pm
Location: Estonia

Post by xirtamatrix »

wing64 wrote:Try this. :D

pixel program

Code: Select all

float4 fvAmbient;
float4 fvLight1Color; 
float4 fvLight2Color; 
float4 fvLight3Color; 
float4 fvLight4Color; 

float fSpecularPower; 
float fSpecularStrength; 
float fBumpStrength; 

sampler2D baseMap		: register(s0); 
sampler2D bumpMap		: register(s1); 

struct PS_INPUT
{	
	float2 Texcoord				: TEXCOORD0;
	float3 ViewDirection		: TEXCOORD1; 
	float3 LightDirection1		: TEXCOORD2; 
	float3 LightDirection2		: TEXCOORD3;
	float3 LightDirection3		: TEXCOORD4; 
	float3 LightDirection4		: TEXCOORD5; 
	float4 LightDistMultiplier  : TEXCOORD6;

};

float4 pixelMain( in PS_INPUT IN ) : COLOR
{
	float4 color = float4(0,0,0,0);

	float3  fvLightDirection1 = normalize( IN.LightDirection1 ); 
	float3  fvLightDirection2 = normalize( IN.LightDirection2 ); 
	float3  fvLightDirection3 = normalize( IN.LightDirection3 ); 
	float3  fvLightDirection4 = normalize( IN.LightDirection4 ); 

	float3  fvNormal         = tex2D( bumpMap, IN.Texcoord ).yxz; 
	fvNormal.xy*=2.0; 
	fvNormal.xy-=1.0; 

	fvNormal=(float3(0.0,0.0,1.0)-fvNormal)*fBumpStrength+fvNormal; 

	fvNormal=normalize(fvNormal); 

	float fNDotL1           = max(dot(fvNormal, fvLightDirection1),0.0)-0.1;  
	float fNDotL2           = max(dot(fvNormal, fvLightDirection2),0.0)-0.1;  
	float fNDotL3           = max(dot(fvNormal, fvLightDirection3),0.0)-0.1;  
	float fNDotL4           = max(dot(fvNormal, fvLightDirection4),0.0)-0.1;  

	float3  fvReflection1     = normalize( ( ( 2.0 * fvNormal )  ) - fvLightDirection1 );  
	float3  fvReflection2     = normalize( ( ( 2.0 * fvNormal )  ) - fvLightDirection2 );  
	float3  fvReflection3     = normalize( ( ( 2.0 * fvNormal )  ) - fvLightDirection3 );  
	float3  fvReflection4     = normalize( ( ( 2.0 * fvNormal )  ) - fvLightDirection4 );  

	float3  fvViewDirection  = normalize( IN.ViewDirection ); 

	float fRDotV1          = max( 0.0, dot( fvReflection1, fvViewDirection ) ); 
	float fRDotV2          = max( 0.0, dot( fvReflection2, fvViewDirection ) ); 
	float fRDotV3          = max( 0.0, dot( fvReflection3, fvViewDirection ) ); 
	float fRDotV4          = max( 0.0, dot( fvReflection4, fvViewDirection ) ); 

	float4  fvBaseColor      = tex2D( baseMap, IN.Texcoord ); 

	float4  fvTotalAmbient   = fvAmbient * fvBaseColor;  

	float4  fvTotalDiffuse   = fvLight1Color * fNDotL1* fvBaseColor*IN.LightDistMultiplier[0];  
	float4  fvTotalSpecular  = fNDotL1*fvLight1Color * ( pow( fRDotV1, fSpecularPower ) )*IN.LightDistMultiplier[0]; 

	fvTotalDiffuse   += fvLight2Color * fNDotL2* fvBaseColor*IN.LightDistMultiplier[1];  
	fvTotalSpecular  += fNDotL2*fvLight2Color * ( pow( fRDotV2, fSpecularPower ) )*IN.LightDistMultiplier[1];   

	fvTotalDiffuse   += fvLight3Color * fNDotL3* fvBaseColor*IN.LightDistMultiplier[2];  
	fvTotalSpecular  += fNDotL3*fvLight3Color * ( pow( fRDotV3, fSpecularPower ) )*IN.LightDistMultiplier[2];   

	fvTotalDiffuse   += fvLight4Color * fNDotL4* fvBaseColor*IN.LightDistMultiplier[3];  
	fvTotalSpecular  += fNDotL4*fvLight4Color * ( pow( fRDotV4, fSpecularPower ) )*IN.LightDistMultiplier[3];   

	color=( fvTotalAmbient + fvTotalDiffuse+ (fvTotalSpecular*fSpecularStrength)); 
	if(color.r>1.0){color.gb+=color.r-1.0;} 
	if(color.g>1.0){color.rb+=color.g-1.0;} 
	if(color.b>1.0){color.rg+=color.b-1.0;} 

	return color;
} 
Thank You Wing64, but has anyone managed to use this HLSL shader successfully? The pixel shader keeps giving me compile error

error: X4502: 'texcoord' reference exceeds valid range for this shader model

If tried changing to video::EPST_PS_2_0 but then it gives another error:
HLSL pixel shader compilation failed:
(79)error X5608: compiled shader code uses too many arithmetic instruction slots
(117). Max. allowed by the target (ps_2_0) is 64.
(1)error X5609: compiled shader code uses too many instruction slots
(119). Max. allowed by the target (ps_2_0) is 96.



Any help/ideas would be hugely appreciated!

/regards
to live, is natural; to die, is not!
Mel
Competition winner
Posts: 2292
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Post by Mel »

use Pixel Shader 3. This shader has too many instructions for anything less than Pixel Shader 3.

Also, in Irrlicht, the tangents and the binormals are on the texcoord1 and texcoord2 semantics in the vertex shader.
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
xirtamatrix
Posts: 219
Joined: Fri Feb 19, 2010 4:03 pm
Location: Estonia

Post by xirtamatrix »

Mel wrote:use Pixel Shader 3. This shader has too many instructions for anything less than Pixel Shader 3.
ah craps! That makes it unusable for me then :( I need to support at least Pixel Shader 2 and above.

So then, we have no way of normal-mapping on PS 2_0 right? Except for the provided 2-light material?
to live, is natural; to die, is not!
Mel
Competition winner
Posts: 2292
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Post by Mel »

You can try to remove some code to remove lights. But the point would be if you need really 4 dynamic lights with bumpmapping. Will there be actualy 4 lights moving constantly in your application all the time? You can obtain a similar detail using a diffuse environment map, and reducing the dynamic lights to a minimum, or else, using deferred rendering. Deferred rendering uses less instructions and supports an unlimited number of lights at constant rendering time at the cost of needing MRT support, and being unable to use alpha blending and MSAA. But it is posible to use it on Pixel shader 2.
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
Luben
Posts: 568
Joined: Sun Oct 09, 2005 10:12 am
Location: #irrlicht @freenode

Post by Luben »

There is also the alternative of doing multiple renderpasses, but it doesn't scale well.
Post Reply