Vertex Shaders, Again

Started by
11 comments, last by Draigan 22 years ago
Previously with Direct3D, if I wanted a directional light and say a spotlight, I just enabled the two lights, send the geometry and voila! Now that I''ve started my move to vertex shaders, how exactly do I accomplish the same sort of thing? Do I have to write a new vertex shader for every combination of lights that I want to apply. Say I have an object that receives a directional light, is spherically mapped and a spotlight may or may not be on the object. Do I have to make 2 vertex shaders - one for the situation without the spotlight and one for with?
Advertisement
quote:
Do I have to write a new vertex shader for every combination of lights that I want to apply.


In DX8.x, yes!

Although in many situations you could write the shader so that it always applied both lights, then simply modulate the output of each light by a constant - that way you have a sort of dimmer switch for each light. Depends how many vertices you''re passing and how much you''d save by removing a light.

nVidia and ATI also have solutions to this which link "fragments" of shaders together (sort of like a macro programming language) - so you write a bit of code to do a transform, another bit to do a point light, and another bit to do a directional light. Their solutions then join the fragments together on demand when you need a new shader. Take a look on their websites for: ATI ATILLA and nVidia NVLink

In a future version of D3D its been proposed that there will be subroutine and branch support for vertex shaders...

--
Simon O''Connor
Creative Asylum Ltd
www.creative-asylum.com

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

I have a question.

My GeForce 2 handles the hardware TnL, but, if I use vertex shaders the code will run in the CPU, isn''t it?

Is there any method to use vertex shader and perform the TnL in hardware?

Thanks in advance
IDirect3DDevice8::SetVertexShader

uses built in TnL pipeline instead of your own shader if you pass it FVF flags instead of a shader handle. see the documentation
But if I want to do a simple vertex shader for vertex tweening, which method should I use?

Locking a vertex buffer and interpolate the vertex, or use a vertex shader?. The first method can be better in a GeForce 2 card, that use Tnl. But the other can be better in the other cards, that support hardware vertex shaders, or don''t support it (D3D optimizes the code for the CPU)

I''m correct?

Thanks
You need different rendering paths for different video cards Adso. Do it one way for a GF2 and another way for GF3, GF4.
Why is the VS instruction set missing condition and branch instuctions. It makes the code very inflexible (ie, dynamic number of lights).
If I use the D3DX Effects for the vertex shaders and I choose to implement the fixed-function vertex shader in there to automatically transform, does it use hardware?
quote:Original post by JonnyBoy
Why is the VS instruction set missing condition and branch instuctions. It makes the code very inflexible (ie, dynamic number of lights).


1. By imposing this limitation, an implementation is able to perform parallel vertex processing. For example if you have a CPU with SSE and use D3D software vertex processing, it will transform and light *4* vertices at a time (SIMD with the data in the buffer swizzled into SoA format). The same goes for hardware. Allowing arbitrary *conditional* branches would break this ability!

2. You can do conditional code in a vertex shader with the min, max, sge, slt instructions. The idea is to nullify the results of any parts you don''t want such as set the output of any light you don''t want to black. Obviously it means redundant instructions are executed. An alternative is to make a new shader for each permutation - if you''re transforming a lot of vertices with varied numbers of lights, this could in fact be faster than any conditionals.

3. Another current solution to the permutation problem is to use NVLink from nVidia or ATILLA from ATI which are both linkers for fragments of vertex shader code which can be used at runtime.

4. In the provisional 2.0 shader spec which is coming in DX9 (and was previewed at Meltdown), there are some nice things on the way including: SUBROUTINES and LOOPS which should solve almost all cases where you''d like a conditional branch. For example for a variable number of lights you''d simply make the loop counter use a constant which specified the number of active lights.
However to use 2.0 shaders in hardware you''ll need hardware capable of doing them (i.e. nothing currently publically available will ever do them).


--
Simon O''Connor
Creative Asylum Ltd
www.creative-asylum.com

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Where can I find the specs for the 1.4 and 2.0 vertex shaders? In the DirectX 8.1 SDK covers only up to the 1.1 version.

And, anybody knows a fast method of normalizing a vector in vertex shader?

Thanks

This topic is closed to new replies.

Advertisement