Dynamic Shaders? Please give me an idea
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]
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 10float3 LightDirections[MaxLights];float4 LightColors[MaxLights];int LightCount;...float4 lightAccum = AmbientColor;for(int i = 0; i < LightCount; i++){ lightAccum += max(dot(input.Normal, -LightDirections), 0) * LightColors;}
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.
Thanks very much! I was looking at shader assembly languages only. Sorry for stupid post, I'm a n00b here.
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:
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.
#define MAX_LIGHTS 10float3 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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement