Search code examples
shadercg

Why does passing vertex data to fragment shader fail on D3D but not OpenGL?


I'm working with a Cg shader that is supposed to pass some precalculated values from the vertex shader to the fragment shader in order to improve performance, but only OpenGL seems to be able to receive the data correctly. The only variable I can pass to the fragment shader in D3D seems to be the TEXCOORD0 semantic, which is bad, since I need to pass 6-7 different float4 params. I only use one texture, which is in TEXUNIT0.

The code looks something like this:

/* Vertex shader */
struct tex_coords
{
   float4 c00_01; 
   float4 c02_10;
   float2 c11; 
   float4 c12_20; 
   float4 c21_22; 
};

struct input
{
   float2 video_size;
   float2 texture_size;
   float2 output_size;
};

void main_vertex
(
   float4 position : POSITION,
   out float4 oPosition : POSITION,
   uniform float4x4 modelViewProj,

   float4 color : COLOR,
   out float4 oColor : COLOR,

   float2 tex : TEXCOORD,

   uniform input IN,
   out tex_coords coords
)
{
   oPosition = mul(modelViewProj, position);
   oColor = color;

   float2 texsize = IN.texture_size;
   float2 delta = 0.5 / texsize;
   float dx = delta.x;
   float dy = delta.y;

   coords = tex_coords (
      float4(tex + float2(-dx, -dy), tex + float2(-dx, 0)),
      float4(tex + float2(-dx, dy), tex + float2(0, -dy)),
      tex + float2(0, 0),
      float4(tex + float2(0, dy), tex + float2(dx, -dy)),
      float4(tex + float2(dx, 0), tex + float2(dx, dy))
   );
}

/* Fragment shader */
float4 main_fragment (in tex_coords co, uniform input IN, uniform sampler2D s0 : TEXUNIT0) : COLOR
{
   // Use texture lookups on the coordinates found in co.
}

Is there any reason this code should fail? I've tried binding all the variables in the struct to TEXCOORD1-through-5 semantics, but it fails on D3D. Works fine on OpenGL though.


Solution

  • This is a problem with Direct3D when using pre-transformed vertexes, thus bypassing the vertex shader entirely, which obviously causes problems in the fragment shader. Forcing the data to go through vertex shader should fix the problem.