Shader data flow questions

Two questions:

1. Is there any decent way to get a small chunk of data (4-8

bytes) from a vertex shader back to the CPU? I would only

do this in direct response to a mouse click, so it need not be fast,

just possible.

2. The MSDN reference materialhere would suggest that a variable declaredstatic

could carry information from one shader invocation to the next, so that

one could, for example, calculate a running min, max, or average of

some property over all vertices. But in practice it seems that my

static variable is zeroed afresh for every vertex.

Below are the bones of my test case. The CPU program is providing

each vertex with the "extra" variable, of which extra.x is a unique id

for each vertex, starting with 0.0 for the first, counting by 1.0 each

time. This information is demonstrably getting through.

However, reading the documentation would suggest that the line labelled

"HERE'S THE ACTION" should give me all vertices red. In fact, I

get only one red vertex, namely the first, suggesting that pickd is NOT

retaining a value.

Am I missing something really obvious? Should I be reading a

different reference? Is there one document somewhere that is The

Definitive Reference for HLSL?

[using DirectX 9 (June SDK), 6800

Ultra graphics card, Windows XP Pro, using D3DXCreateEffectFromFile to

set up the shader.]
uniform extern float4x4 gWVP;

OutputVS MyDemoVS(float3 posL : POSITION0, float2 extra : TEXCOORD0) {

static float pickd = 0;

if (extra.x == 0) pickd = 100; // reset picking algorithm, once per frame

OutputVS outVS = (OutputVS)0;

outVS.color.y = extra.x / 4000.0; // visually demonstrates that the ID is getting through

// Transform to homogeneous clip space:

outVS.posH = mul(float4(posL, 1.0f), gWVP);


if (pickd == 100) outVS.color = red; // HERE'S THE ACTION

return outVS;

}

[2128 byte] By [Sparklight] at [2007-12-25]
# 1

1. With Direct3D 9 there is no way to do this directly. But you can move the values forward to a pixel shader write them to a render target. Then you can use GetRenderTarget to read them back. Direct3D 10 will support this with the new Stream Out function.

2. The meaning of static is different here. If you write functions that are called from other functions all local variables in these are normally not persistent. If you use static the will hold the values if called multiple times for the same vertex/pixel. But they are not hold for the next vertex/pixel.

What you are trying to do? Maybe there is another solution.

RalfKornmann at 2007-8-31 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: Graphics...
# 2
What I'm trying to do: it would be very convenient, for my

purpose, to use a vertex shader for picking, given the 2D position of a

mouse click. The shader has the right information at the right

time to find the 2D proximity of the mouse to a vertex. I don't

even have to get the pick information back to the CPU to do some cool stuff. If I could find any way to carry information across vertices I could find the vertex with the minimum 2D distance to the mouse position.

So, is there any? Any class of variable at all that will be

shared among all vertices, that the shader can actually modify?

Sparklight at 2007-8-31 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: Graphics...
# 3

Well, there is no way to keep values persistent inside the shaders. A shader unit’s work with a SIMD approach it would be nearly impossible to build such a thing effective.

But I believe I have a possible solution for your problem.

If I understand you right you want to test if your vertex inputs match special criteria (set as shader constant). If it does you want to write some calculated values in a buffer that can later access from the CPU. Unfortunately there can be more than one positive match in the shader and you need to find the best.

You can try the following:

Make your check as before but set the sort criteria to the Z value. Than the Z-Buffer will find your best match for you. Make sure that you use Z values that macth your viewport settings.

RalfKornmann at 2007-8-31 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: Graphics...
# 4
This should be achievable with D3D9 queries... The only thing is that there can be a lag between the start of the request and the retrieval of the results... But then I assume it's already ok for you since you accepted to go with this kind of "gpu-side picking"...
WessamBahnassi at 2007-8-31 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,Game Technologies: Graphics...