Hello everyone! I'm an atmospheric scientist working on radar data visualization software and have hit a bit of a snag with my move to DX10 and implementation of a geometry shader.
Here's an example of the interface, showing several different products from a mobile radar dataset. In the build shown, I precalculate the positions of all the gates (basically, radar pixels) in the dataset and pass that to the VShader and PShader for transformation to screen coordinates and coloration based on color tables. I recently implemented a GShader to expand my road layers so as to have them be more than one pixel wide, and want to implement a GShader for data so that I can dramatically decrease the memory load of a dataset (long-range radar datasets can consume >1GB of video memory... not great).
I initially wrote the whole shader implementation, but when it didn't work I backed way off and have just been trying to get the GShader to emit triangles that form a quad in the middle of each frame. In the input assembler stage, I'm passing the VShader two 2-byte integers: a beam index (to know which direction the antenna is pointing) and a gate index (range from radar). Below is my passthrough VShader (since all the actual geographical geometry is going to need to be calculated in the GShader stage). I put the "POSITION" semantic in VOut thinking that vertices without a defined position were getting culled, but that apparently is not the case. There's a few other radar-related fields in there (Value, FilterValue, SpecialValue) but I think we can safely ignore those, unless inclusion of them has pushed my vertex size over some limit and is the cause of my problems.
struct VOut
{
float4 Position : POSITION;
int2 GateRay : GATE_RAY;
float Value : VALUE;
float FilterValue : FILTER_VALUE;
int SpecialValue : SPECIAL_VALUE;
};
Texture2D<float> filterData : register(t0);
Texture2D<float> valueData : register(t1);
VOut VShader(int2 GateRay : POSITION)
{
VOut output;
output.Position = float4(0.5, 0.5, 0.5, 0.0);
output.GateRay = GateRay;
output.Value = valueData[output.GateRay];
output.FilterValue = filterData[output.GateRay];
if (output.Value == -1.#INF)
output.SpecialValue = 1;
else if (output.Value == 1.#INF)
output.SpecialValue = 2;
else
output.SpecialValue = 0;
return output;
}
My dummy GShader code is below. I am intentionally winding one triangle the wrong way - I do this during shader development so that if I screw up badly I can see at least half of my triangles. At this point, I'm just trying to get something to show onscreen. I don't see anything glaringly wrong with it, but I suppose if I did I would have fixed it. I adapted this code from the GShader that expands my GIS road lines into rectangles. Unlike this one, that GShader works.
struct PS_IN
{
float4 Position : SV_POSITION;
int2 GateRay : GATE_RAY;
float Value : VALUE;
float FilterValue : FILTER_VALUE;
int SpecialValue : SPECIAL_VALUE;
};
[maxvertexcount(6)]
void GShader(point VOut gin[1], inout TriangleStream<PS_IN> triStream)
{
PS_IN v[4];
v[0].Position = float4(-0.5, -0.5, 0.5, 0.0);
v[0].GateRay = int2(1, 1);
v[0].Value = 50.0;
v[0].FilterValue = 0.0;
v[0].SpecialValue = 0;
v[1].Position = float4(0.5, -0.5, 0.5, 0.0);
v[1].GateRay = int2(1, 1);
v[1].Value = 50.0;
v[1].FilterValue = 0.0;
v[1].SpecialValue = 0;
v[2].Position = float4(-0.5, 0.5, 0.5, 0.0);
v[2].GateRay = int2(1, 1);
v[2].Value = 50.0;
v[2].FilterValue = 0.0;
v[2].SpecialValue = 0;
v[3].Position = float4(0.5, 0.5, 0.5, 0.0);
v[3].GateRay = int2(1, 1);
v[3].Value = 50.0;
v[3].FilterValue = 0.0;
v[3].SpecialValue = 0;
triStream.Append(v[0]);
triStream.Append(v[3]);
triStream.Append(v[2]);
triStream.RestartStrip();
triStream.Append(v[0]);
triStream.Append(v[3]);
triStream.Append(v[1]);
triStream.RestartStrip();
}
Below is the dummy pixel shader I'm using. It should just color my triangles white. Normally I use a pixel shader compiled from HLSL code I generate from a user-defined color table - but in the interest of reducing sophistication in debugging, I'm using this dummy.
struct PS_IN
{
float4 Position : SV_POSITION;
int2 GateRay : GATE_RAY;
float Value : VALUE;
float FilterValue : FILTER_VALUE;
int SpecialValue : SPECIAL_VALUE;
};
float4 PShader(float4 Position : SV_POSITION, int2 GateRay : GATE_RAY, float Value : VALUE, float FilterValue : FILTER_VALUE, int SpecialValue : SPECIAL_VALUE) : SV_TARGET
{
return float4(1.0, 1.0, 1.0, 1.0);
}
Thanks in advance for the help!