Skip to main content
GameDev.net gamedev.net
🔒 Locked

light shader

Started by giugio Jun 25, 2010 at 5:05 PM 1 replies 800+ views
Original Post
giugio
giugio
Hy.
I would create a light phong shader with more than one light in hlsl.
For each light , from 1 to 8 i must send to shader the position, direction , color ecc... via constant buffer.
I think to use a matrix for send to the shader what are the lights that are active
,and in the shader i have an if else chain for get the color of pixel for the corrispondent light and type of light.
Then I can disable/enable the light information , and send the information of the light to the shader only if exist(via costant buffer).

Is a good solution?
what advice to me if not?
thanks
Mathucub
Mathucub
This will work for DX9 and Shader Model 2+
[Based on ATI's http://developer.amd.com/media/gpu_assets/FixedFuncShader.pdf]

Make this into a .fx file that you also include in your c++.
You will need to make float3/float4 ADT's for C++.

#define LIGHT_TYPE_NONE	0#define LIGHT_TYPE_POINT	1#define LIGHT_TYPE_SPOT	2#define LIGHT_TYPE_DIRECTIONAL	3#define NUM_LIGHTS 8#define DIVIDE_BIAS 0.001struct CLight{  int iType;  float3 vPos;  float3 vDir;  float4 vAmbient;  float4 vDiffuse;  float4 vSpecular;  float fRange;  float3 vAttenuation; //1, D, D^2;  float3 vSpot;	//cos(theta/2), cos(phi/2), falloff};#ifndef __cplusplus// shader only codeint iLightDirIni;int iLightDirNum;int iLightPointIni;int iLightPointNum;int iLightSpotIni;int iLightSpotNum;CLight lights[NUM_LIGHTS];float4x4 matWorldViewProj : WORLDVIEWPROJ;float4x4 matWorldView	: WORLDVIEW;float4x4 matWorld	: WORLD;float4x4 matWorldViewIT;float4x4 matViewIT;struct VS_OUTPUT{  float4 Pos	: POSITION;  float4 Color	: COLOR0;  float4 ColorSpec	: COLOR1;  float4 Tex0	: TEXCOORD0;};struct COLOR_PAIR{  float4 Color	: COLOR0;  float4 ColorSpec	: COLOR1;};COLOR_PAIR DoDirLight(float3 Position, float3 N, float3 E, int i){   COLOR_PAIR OUT;   OUT.Diffuse = lights.Ambient;   OUT.Specular = 0;      float3 L = -normalize(lights.Direction); //light vector   float3 H = normalize(E + L); //half angle vector      //calculate the diffuse and specular contributions    float  diff = max(0 , dot(N,L));    float  spec = pow( max(0 , dot(N,H) ) , materialPower );      if (diff)   {		//output diffuse		OUT.Diffuse += lights.Diffuse * diff;	    		//output specular		OUT.Specular += lights.Specular * spec;   }      return OUT;}COLOR_PAIR DoPointLight(float3 Position, float3 N, float3 E, int i){   	COLOR_PAIR OUT;	OUT.Diffuse = lights.Ambient;	OUT.Specular = 0.0f;   	float3 PositionDelta = lights.Position-Position;	float  LD = length(PositionDelta);	float3 L  = PositionDelta/LD;	float  fAtten = 1.0f;	float  NdotL = dot(N,L);   	   	if (NdotL >= 0.0f)   	{   		// diffuse color		OUT.Diffuse += NdotL * lights.Diffuse;			// specular color    	        float3 H = normalize(E + L); //half angle vector		OUT.Specular = pow(max(0, dot(H, N)), materialPower) * lights.Specular;   	    	if(LD > (float)lights.Range)    	{    		fAtten = 0.0f;       	}    	else    	{       		fAtten *= 1.0f/((lights.Attenuation.x +        				   		lights.Attenuation.y*LD +        				   		lights.Attenuation.z*LD*LD)+DIVIDE_BIAS);    	}    	    	OUT.Diffuse *= fAtten;    	OUT.Specular *= fAtten;    }       return OUT;}COLOR_PAIR DoSpotLight(float3 Position, float3 N, float3 E, int i){	COLOR_PAIR OUT;	OUT.Diffuse = lights.Ambient;	OUT.Specular = 0.0f;      	float3 PositionDelta = lights.Position-Position;	float  LD = length(PositionDelta);	float3 L  = PositionDelta/LD;	float  fAttenSpot = 1.0f;	float NdotL = dot(N,L);     	if (NdotL >= 0.0f)    {  		// diffuse color		OUT.Diffuse += NdotL * lights.Diffuse;			// specular color	        float3 H = normalize(L + E);   //half vector	        OUT.Specular = pow(max(0, dot(H, N)), materialPower) * lights.Specular;	       	if(LD > (float)lights.Range)    	{    		fAttenSpot = 0.0f;       	}    	else    	{    		fAttenSpot *= 1.0f/((lights.Attenuation.x +        				   	lights.Attenuation.y*LD +        				   	lights.Attenuation.z*LD*LD)+DIVIDE_BIAS);       	}	        	//spot cone computation    	float3 L2 = -normalize(lights.Direction);    	float rho = dot(L, L2);    	    	fAttenSpot *= max(pow(saturate(rho - lights.Spot.y)/(lights.Spot.x - lights.Spot.y), lights.Spot.z), DIVIDE_BIAS);	    	OUT.Diffuse *= fAttenSpot;    	OUT.Specular *= fAttenSpot;   	}   	return OUT;}VS_OUTPUT vs_main (float4 vPosition : POSITION0,                                      float4 vPosition2 : POSITION1,                                      float3 vNormal	: NORMAL0,                                      float3 vNormal2	: NORMAL1,                                      float2 tc	: TEXCOORD0){  VS_OUTPUT Out = (VS_OUTPUT) 0;  vNormal = normalize(vNormal);  Out.Pos = mul(matWorldViewProj, vPosition);  float3 P = mul(matWorldView, vPosition); //position in view space  float3 N = mul((float3x3)matWorldViewIT, vNormal); //normal in view  float3 V = -normalize(P); //viewer  Out.Tex0 = tc;    //directional lights  for(int i = 0; i < iLightDirNum; i++)  {    COLOR_PAIR ColOut = DoDirLight(N, V, i+iLightDirIni);    Out.Color += ColOut.Color;     Out.ColorSpec += ColOut.ColorSpec;  }  //point lights  for(int i = 0; i < iLightPointNum; i++)  {    COLOR_PAIR ColOut = DoPointLight(vPosition, N, V,i+iLightPointIni);    Out.Color += ColOut.Color;    Out.ColorSpec += ColOut.ColorSpec;  }    //spot lights  for(int i = 0; i < iLightSpotNum; i++)  {    COLOR_PAIR ColOut = DoSpotLight(vPosition, N, V,i+iLightSpotIni);    Out.Color += ColOut.Color;    Out.ColorSpec += ColOut.ColorSpec; }  return Out;}technique vertex_lighting{  pass P0  {    VertexShader = compile vs_2_0 vs_main();   }}#endif


I didn't include a pixel shader... use whatever one you see fit.
If you change your vertex inputs/outputs, you can move the light loops into
the pixel shader and get per pixel lighting.

The tricky thing with this is that you need keep this data on the CPU and then
sort it by its light type before you upload it to the GPU. When you do your sort,
collect the data to set the indices for each type and count.
giugio
giugio
very thanks.
but how i can find articles like this?
under ati and under nvidia site?
can you post me some link.
by

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.