0
\$\begingroup\$

I'm trying to create a super simple no frills off-screen process... I have the device, I can export the texture to Image... etc... I'm having one heck of a time just getting a simple Triangle Strip to display an image so I can run pixel shaders on it... I have found examples and even have the Direct3D cookbook.. However, I don't need all the camera functions and so on... I can't seem strip out the unnecessary bits and still have it work... please help...

I just need a super simple quad renderer that aligns to the renderer target...

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Do I understand correctly that you're trying to set up a "blit"? ie. You have a single quad made up of two triangles, and the corners of the quad should map to the corners of the render target, so your shader is invoked once for every pixel in the render target - does that describe your scenario? \$\endgroup\$ – DMGregory Jan 30 '17 at 17:08
  • \$\begingroup\$ That sounds pretty close to what I'm looking for... basically setup a Triangle Strip to renderer image as texture on so pixel shader can be applied... \$\endgroup\$ – user96556 Jan 30 '17 at 17:20
  • \$\begingroup\$ Do you think you can help me out? because I seem to be missing something... I'm sure it is something small and trivial... but I appear to be missing it never the less... \$\endgroup\$ – user96556 Jan 30 '17 at 17:50
  • 1
    \$\begingroup\$ I'm not fluent in SharpDX, but I'm sure other users can help there. Here I just wanted to ensure the question was clear so others can give you the help you need. \$\endgroup\$ – DMGregory Jan 30 '17 at 17:59
1
\$\begingroup\$

This is a vertex shader which will draw a full screen triangle without a vertex buffer:

// This function will create the triangle
inline void FullScreenTriangle(in uint vertexID, out float4 pos, out float2 tex)
{
    FullScreenTriangle(vertexID, pos);

    tex.x = (float)(vertexID / 2)*2.0f;
    tex.y = 1.0f - (float)(vertexID % 2)*2.0f;
}

// This is the vertex structure that the vertex shader will emit and the pixel shader will receive:
struct VertexToPixelPostProcess
{
    float4 pos              : SV_POSITION;
    float2 tex              : TEXCOORD0;
};

// This is the vertex shader itself:
VertexToPixelPostProcess main(uint vI : SV_VERTEXID)
{
    VertexToPixelPostProcess Out;

    FullScreenTriangle(vI, Out.pos, Out.tex);

    return Out;
}

This will cover the entire screen and your pixel shader will receive texture coordinates which will map (0,0) to the upper left corner of the screen and (1,1) to the bottom right corner.

You need to call Draw(3,0) from your API to draw this to the screen.

This also requires a few graphics state setups. You should set a null input layout, set a null vertex buffer, set the primitive topology to trianglelist, set an appropriate blend state, disable depth/stencil tests and keep the backface culling in mind (you could disable backface culling to render at all times).

You should have a rendertarget bound when drawing.

UPDATE: If you specifically need a quad, then it is still achievable in a very similar way without vertex buffers. This simple vertex shader will create a quad for you:

struct VertextoPixel
{
    float4 pos              : SV_POSITION;
    float2 tex              : TEXCOORD0;
};

VertextoPixel main(uint vI : SV_VERTEXID)
{
    VertextoPixel Out = (VertextoPixel)0;

    // This vertex shader generates a trianglestrip like this:
    //  1--2
    //    /
    //   /
    //  3--4
    Out.tex = float2(vI % 2, vI % 4 / 2);

    Out.pos = float4(Out.tex * 2 - 1, 0, 1);

    return Out;
}

Call it with Draw(4,0) and a trianglestrip primitive topology.

UPDATE2: Your texture sampling pixel shader then could look something like this:

// Also bind the texture from the API side:
Texture2D myTexture:register(t0);
// If you don't bind a sampler from the API side, a default sampler will be used
SamplerState mySampler:register(s0);

float4 main(VertextoPixel input) : SV_Target
{
  return myTexture.Sample(mySampler, input.tex); // outputs the textured quad
}

If you still can not render it, then enable the debug layer when creating your graphics device, or use a graphics debugger like Nvidia Nsight, AMD GPU Perfstudio, PIX for Windows or Intel's Graphics Performance Analizer.

Good luck!

\$\endgroup\$
8
  • \$\begingroup\$ Forgive me, this produces a triangle? I need a quad (rectangle)... this may just be a terminology thing here... \$\endgroup\$ – user96556 Jan 30 '17 at 18:03
  • \$\begingroup\$ Yes, but a triangle can also be used to render to an off screen render target, and it is more efficient. \$\endgroup\$ – János Turánszki Jan 30 '17 at 18:40
  • \$\begingroup\$ I guess I'm not following you on that... Here is what i'm thinking... Triangle strip with 4 vertex entries.. \$\endgroup\$ – user96556 Jan 30 '17 at 18:46
  • \$\begingroup\$ OK, from your question I thought that you want to have some sort of screen-filling geometry to render to a render target. Nevertheless, the last paragraph still applies, you can debug graphics applications quite easily nowadays. Also I've updated my answer! :) \$\endgroup\$ – János Turánszki Jan 30 '17 at 19:16
  • \$\begingroup\$ Ok, what you have provided is advanced for me. So forgive me, how do I apply the texture(The Image to be processed) without reference to the vertices? I have n layers to process using the "Compensation.fx"... I just need a very good understanding of this method... pixel or compute shaders will need to run on this as well. I thank you for you help! \$\endgroup\$ – user96556 Jan 30 '17 at 22:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.