Sign in to follow this  
1hod0afop

Dynamic Shaders? Please give me an idea

Recommended Posts

Hi I'm quite new to D3D programmable pipeline and wanna learn. What I'm thinking is : how can I implement dynamic shaders? In fixed function pipeline, I usally disabled lights which are far enough from the object to ignore. i.e. I have always rendered each object with different set of lights. I did it for other effects also, such as specular light maps, environment maps, etc. (I think everyone does so) Now I'm wondering how to implement that features with programmable pipeline. Can you give me an idea please? And also I'd like to know: - Cost of creating shaders, i.e. cost of calling IDirect3DDevice9::CreateVertexShader() and CreatePixelShader() functions. (let's say I have compiled shader code already) - Cost of changing shaders. Thanks in advance [Edited by - 1hod0afop on July 3, 2008 12:47:37 AM]

Share this post


Link to post
Share on other sites

Well, you could implement multiple lights in your HLSL shader, using constant arrays to hold the information and providing a constant indicating the number of active lights. Then your could gather the number of active lights per object, set their properties on the effect and loop over them. Something like this:



#define MaxLights 10

float3 LightDirections[MaxLights];
float4 LightColors[MaxLights];
int LightCount;

...

float4 lightAccum = AmbientColor;

for(int i = 0; i < LightCount; i++)
{
lightAccum += max(dot(input.Normal, -LightDirections[i]), 0) * LightColors[i];
}




An alternative would be to use deferred shading, but that typically requires quite a bit of redesign to your rendering code. As for the cost of those specific operations, Tom's DX FAQ contains various estimates and a wealth of other information.

Share this post


Link to post
Share on other sites
As a modification of reimgius' approach, you could create multiple techniques, each for a different distance-based LOD. Then you can use the same shader source, but hardcode the number of lights with a parameter to avoid runtime looping:

#define MAX_LIGHTS 10
float3 LightDirections[MAX_LIGHTS];
float4 LightColors[MAX_LIGHTS];

VS_OUTPUT VSMain(VS_INPUT In, uniform int nLights)
{
for (int i = 0; i < nLights; i++)
{
...
}
}

technique LOD0 {
pass p0 {
VertexShader = compile vs_3_0 VSMain(10);
}
}

technique LOD1 {
pass p0 {
VertexShader = compile vs_3_0 VSMain(5);
}
}
// etc.


You could also create different LOD meshes for your objects, and then in the model file specify different shaders as materials for those meshes. So picking the right LOD mesh will also use the shader using less lights.

Share this post


Link to post
Share on other sites
Thanks. Much more helpful than I expected :) Actually I'm porting my game engine into programmable pipeline and it seems more difficult than I thought ^^
Hope to get many help from here ;)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this