Jump to content
  • Advertisement
Sign in to follow this  
Kaloux

Lights and hardware vertex processing

This topic is 3930 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi ! When I enable hardware vertex processing and use my own vertex shader, lights are no longer applied (models are no more self shadowed). Is there something I missed in the API ? Or am I obliged to make my own pixel shader, taking care of light calculations by myself ? What would be the use of D3DLIGHT9 then ? (I really miss a good tutorial on this subject. All I find is either too complex or too abstract) Thanks in advance.

Share this post


Link to post
Share on other sites
Advertisement
enabling vertex processing means that you will have to replace the full working of the transform and lighting pipeline. That means you have to several things in shaders, including transformation, lighting and shadowing.

what i don't understand is that models are no more self shadowed? I haven't been following the t&l anymore lately, but in my memory self shadowing wasn't even supported in the t&l hardware.

in the documentation of DX9/10 (latest sdk), there's an article about replacing the existing T&L, but it requires a 'newer' video card with good shader support i think.

Share this post


Link to post
Share on other sites
Well, by self shadowing, I meant normal darkening. In the real world, it's a kind of shadow :)

Anyway...
Sadly, you confirmed my thoughts. Do you know a place where I could find pre-build shaders that I could work on ?
If none, then I'd have just a question :
I'd have to pass all the lights in the pixel shader. As far as I know, you can't transfer a C++ struct directly into the shader program. So the solution would be to create several arrays in the pixel shader :

    // General
int xLightType[MAX_LIGHT_NBR];
float3 xLightColor[MAX_LIGHT_NBR];
// Spot and point lights
float3 xLightPos[MAX_LIGHT_NBR];
float3 xLightAttenFactors[MAX_LIGHT_NBR];
float xLightRange[MAX_LIGHT_NBR];
// Spot and directionnal lights
float3 xLightDirection[MAX_LIGHT_NBR];
// Spot lights
float2 xLightCones[MAX_LIGHT_NBR];
float xLightFallof[MAX_LIGHT_NBR];



... and then update them in the main program when needed ?
I could also calculate everything in the main program and change the color of my vertice.
What'd be best ?

Share this post


Link to post
Share on other sites
You mention both vertex and pixel shaders so it's not clear whether just vertex lighting would suffice.

You wouldn't need a pixel shader routine to do just vertex shading.

Share this post


Link to post
Share on other sites
The standard D3D fixed function lighting is per vertex, so you wouldn't need to write a pixel shader. You will need to add lighting to your vertex shader though.

Share this post


Link to post
Share on other sites
Wow, awesome posts guys and well done on helping Kaloux,
Kaloux, at the very least, your vertex shader should transform the vertices to give them a position in world space. You can however then additionally specify a lighting model (light your vertices).

I hope this helps.
Take care.

Share this post


Link to post
Share on other sites
Ok thanks for these infos, I didn't thought I could do it in the vertex shader !

I've tried using the arrays I described in my previous post and I just can't get it to work properly...
In fact, I use a "for" loop to iterate through my arrays and calculate lighting, but weird things are happening.

Here is my code, I'll explain what's wrong just after :

// Vertex shader input structure
struct VS_INPUT
{
float4 Position : POSITION;
float2 Texture : TEXCOORD0;
float3 Normal : NORMAL;
};

// Vertex shader output structure
struct VS_OUTPUT
{
float4 Position : POSITION;
float2 Texture : TEXCOORD0;
float3 Normal : TEXCOORD1;
float4 Color : COLOR0;
};

// Global variables
float4x4 mWorldViewProj;

/// LIGHTS
// Light types
int LIGHT_POINT = 1;
int LIGHT_SPOT = 2;
int LIGHT_DIRECTIONAL = 3;
// General
int mLightNbr;
int mLightType[128];
float4 mLightColor[128];
// Spot and point lights
float4 mLightPos[128];
float4 mLightAttenFactors[128];
float mLightRange[128];
// Spot and directionnal lights
float4 mLightDirection[128];
// Spot lights
float mLightConeIn[128];
float mLightConeOut[128];
float mLightFallof[128];

float4 Light_PointDiffuse(float3 VertPos, float3 VertNorm, float3 LightPos,
float4 LightColor, float4 LightAttenuation, float LightRange)
{
float3 LightDir = LightPos - VertPos;
float Dist = length(LightDir);
if (Dist < LightRange)
{
float DistAttn = saturate(1 / (LightAttenuation.x +
LightAttenuation.y * Dist +
LightAttenuation.z * Dist * Dist));

float AngleAttn = saturate(dot(VertNorm, LightDir));

return LightColor * DistAttn * AngleAttn;
}
else
return float4(1, 1, 1, 1);
}

// Name: Simple Vertex Shader
// Type: Vertex shader
// Desc: Vertex transformation and texture coord pass-through
//
VS_OUTPUT main( in VS_INPUT Input )
{
VS_OUTPUT Output; //create an output vertex

float3 Position3D = Input.Position;
Output.Position = mul(Input.Position, mWorldViewProj); //apply vertex transformation
Output.Texture = Input.Texture; //copy original texcoords.
Output.Normal = Input.Normal;
Output.Color[0] = 1.0f;
Output.Color[1] = 1.0f;
Output.Color[2] = 1.0f;
Output.Color[3] = 1.0f;

if (mLightNbr != 0)
{
for (int i = 0; i < mLightNbr; i++)
{
if (mLightType == 1) // Point light
{
Output.Color *= Light_PointDiffuse(Position3D, Input.Normal, mLightPos, mLightColor, mLightAttenFactors, mLightRange);
}
}
}

return Output; //return output vertex
}


Maybe 128 is a bit too much :)
Anyway, if I use this shader, everything is plain black. However, if I replace :
Output.Color *= Light_PointDiffuse(Position3D, Input.Normal, mLightPos, mLightColor, mLightAttenFactors, mLightRange);

...by :
Output.Color *= Light_PointDiffuse(Position3D, Input.Normal, mLightPos[0], mLightColor[0], mLightAttenFactors[0], mLightRange[0]);

... it works !

I made some tests and checked that the loop is executed only once in both cases (I have only one light in my scene).
Am I doing something wrong with the loop ?

Something else that annoys me is that the following code doesn't work as expected :
if (mLightType == LIGHT_POINT)
...

That's why I replaced "LIGHT_POINT" by "1" in my code, and it worked. Strange...

Share this post


Link to post
Share on other sites

Hi,

Actually you can use structs in HLSL (instead of those numerous arrays), and as far as I remember, they even map quite well to C++ structures. Need to verify that.

Good luck!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!