开发者

Screen-space square looking distorted in PIX

开发者 https://www.devze.com 2023-03-31 05:26 出处:网络
I have a simple function that creates a square that covers the entire screen, I use it for applying post-processing effects, however as far as I can tell it has been the cause of countless errors.

I have a simple function that creates a square that covers the entire screen, I use it for applying post-processing effects, however as far as I can tell it has been the cause of countless errors.

When I run my code in PIX I get the following mesh, but the square should be straight and covering the screen, shouldn't it?

Screen-space square looking distorted in PIX

My vertex shader does no transformation and simply passes position information to the pixel shader.

The function that creates the square is as follows:

private void InitializeGeometry()
    {
        meshes = new Dictionary<Vector3, Mesh>();
        //build array of vertices for one square
        ppVertex[] vertexes = new ppVertex[4];
        //vertexes[0].Position = new Vector3(-1f, -1f, 0.25f);

        vertexes[0].Position = new Vector3(-1, -1, 1f);
        vertexes[1].Position = new Vector3(-1, 1, 1f);
        vertexes[2].Position = new Vector3(1, -1, 1f);
        vertexes[3].Position = new Vector3(1, 1, 1f);

        vertexes[0].TexCoords = new Vector2(0, 0);
        vertexes[1].TexCoords = new Vector2(0, 1);
        vertexes[2].TexCoords = new Vector2(1, 0);
        vertexes[3].TexCoords = new Vector2(1, 1);

        //build index array for the vertices to build a quad from two triangles
        short[] indexes = { 0, 1, 2, 1, 3, 2 };

        //create the data stream to push the vertex data into the buffer
        DataStream vertices = new DataStream(Marshal.SizeOf(typeof(Vertex)) * 4, true, true);
        //load the data stream
        vertices.WriteRange(vertexes);
        //reset the data position
        vertices.Position = 0;

        //create the data stream to push the index data into the buffer
        DataStream indices = new DataStream(sizeof(short) * 6, true, true);
        //load the data stream
        indices.WriteRange(indexes);
        //reset the data position
        indices.Position = 0;

        //create the mesh object
        Mesh mesh = new Mesh();

        //create the description of the vertex buffer
        D3D.BufferDescription vbd = new BufferDescription();
        vbd.BindFlags = D3D.BindFlags.VertexBuffer;
        vbd.CpuAccessFlags = D3D.CpuAccessFlags.None;
        vbd开发者_StackOverflow社区.OptionFlags = ResourceOptionFlags.None;
        vbd.SizeInBytes = Marshal.SizeOf(typeof(Vertex)) * 4;
        vbd.Usage = ResourceUsage.Default;
        //create and assign the vertex buffer to the mesh, filling it with data
        mesh.VertexBuffer = new D3D.Buffer(device, vertices, vbd);

        //create the description of the index buffer
        D3D.BufferDescription ibd = new BufferDescription();
        ibd.BindFlags = D3D.BindFlags.IndexBuffer;
        ibd.CpuAccessFlags = D3D.CpuAccessFlags.None;
        ibd.OptionFlags = ResourceOptionFlags.None;
        ibd.SizeInBytes = sizeof(short) * 6;
        ibd.Usage = ResourceUsage.Default;
        //create and assign the index buffer to the mesh, filling it with data
        mesh.IndexBuffer = new D3D.Buffer(device, indices, ibd);

        //get vertex and index counts
        mesh.vertices = vertexes.GetLength(0);
        mesh.indices = indexes.Length;

        //close the data streams
        indices.Close();
        vertices.Close();

        meshes.Add(new Vector3(0), mesh);
    }

and when I render the square:

private void DrawScene()
    {
        lock (meshes)
        {
            foreach (Mesh mesh in meshes.Values)
            {
                if (mesh.indices > 0)
                {
                    try
                    {
                        //if (camera.SphereInFrustum(mesh.BoundingSphere, sphereRadius))
                        //{
                            context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(mesh.VertexBuffer, Marshal.SizeOf(typeof(Vertex)), 0));
                            context.InputAssembler.SetIndexBuffer(mesh.IndexBuffer, Format.R16_UInt, 0);
                            context.DrawIndexed(mesh.indices, 0, 0);
                        //}
                    }
                    catch (Exception err)
                    {
                        MessageBox.Show(err.Message);
                    }
                }
            }
        }
    }

EDIT: I've added the vertex shader being run

cbuffer EveryFrame : register(cb0)
{
    float3 diffuseColor : packoffset(c0);
    float3 lightdir : packoffset(c1);
};

cbuffer EveryMotion : register(cb1)
{
    float4x4 WorldViewProjection : packoffset(c0);
    float4x4 LightWorldViewProjection : packoffset(c4);
};

struct VS_IN
{
    float3 position : POSITION;
    float3 normal : NORMAL;
    float4 col : TEXCOORD;
};

struct PS_IN
{
    float4 position : SV_POSITION;
    float4 col : TEXCOORD;
    float3 normal : NORMAL;
};

PS_IN VS(VS_IN input)
{
    PS_IN output;
    output.position = float4(input.position,1);
    output.col = input.col;
    output.normal = input.normal;
    return output;
}

Here's PIX's vertex output.

PreVS:

Screen-space square looking distorted in PIX

PostVS:

Screen-space square looking distorted in PIX

And here's the dissassembly PIX generated when I chose to debug vertex 0

//
// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
//
//
//
// Input signature:
//
// Name             Index   Mask Register SysValue Format   Used
// ---------------- ----- ------ -------- -------- ------ ------
// POSITION             0   xyz         0     NONE  float   xyz 
// NORMAL               0   xyz         1     NONE  float   xyz 
// TEXCOORD             0   xyzw        2     NONE  float       
//
//
// Output signature:
//
// Name             Index   Mask Register SysValue Format   Used
// ---------------- ----- ------ -------- -------- ------ ------
// SV_POSITION          0   xyzw        0      POS  float   xyzw
// TEXCOORD             0   xyzw        1     NONE  float   xyzw
// NORMAL               0   xyz         2     NONE  float   xyz 
//
vs_4_0
dcl_input v0.xyz
dcl_input v1.xyz
dcl_output_siv  o0.xyzw , position
dcl_output o1.xyzw
dcl_output o2.xyz
mov o0.xyz, v0.xyzx
mov o0.w, l(1.000000)
mov o1.xyzw, l(1.000000, 1.000000, 1.000000, 1.000000)
mov o2.xyz, v1.xyzx
ret 
// Approximately 5 instruction slots used

I've also added the input assembler:

private void SetPPInputAssembler(Shader shader)
        {
            InputElement[] elements = new[] {
                new InputElement("POSITION",0,Format.R32G32B32_Float,0),
                new InputElement("NORMAL",0,Format.R32G32B32_Float,12,0),
                new InputElement("TEXCOORD",0,Format.R32G32_Float,24,0),
            };

            InputLayout layout = new InputLayout(device, shader.InputSignature, elements);

            context.InputAssembler.InputLayout = layout;
            context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
        }


Obviously your vertex input positions don't match the values you want to give in.

For the first vertex the values look good until the z-coordinate of the texture coordinates. You are defining a Vector2D in your program Vertex-struct, but a Vector4D in the Vertexshader Vertex-struct and things get mixed up.

just change VS_IN to this:

struct VS_IN
{
    float3 position : POSITION;
    float3 normal : NORMAL;
    float2 col : TEXCOORD; // float2 instead of float4
};

I'm not sure though if you really want to have colors or rather texcoords. If you really want to have colors float4 would be right, but then you had to change

vertexes[0].TexCoords = new Vector2(0, 0);

into

vertexes[0].TexCoords = new Vector4(0, 0, 0, 0);

Either way, one of those variables is misnamed and probably the reason for the confusion.

0

精彩评论

暂无评论...
验证码 换一张
取 消