Квадрат экранного пространства выглядит искаженным в PIX - PullRequest
0 голосов
/ 29 августа 2011

У меня есть простая функция, которая создает квадрат, покрывающий весь экран, я использую его для применения эффектов постобработки, однако, насколько я могу судить, это стало причиной бесчисленных ошибок.

Когда я запускаю свой код в PIX, я получаю следующую сетку, но квадрат должен быть прямым и покрывать экран, не так ли?

Mesh information from PIX capture

Мой вершинный шейдер не выполняет преобразованиеи просто передает информацию о положении в пиксельный шейдер.

Функция, которая создает квадрат, выглядит следующим образом:

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.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);
    }

и при рендеринге квадрата:

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);
                    }
                }
            }
        }
    }

РЕДАКТИРОВАТЬ: Я добавил запускаемый вершинный шейдер

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;
}

Вот вывод вершин PIX.

PreVS:

preVS

PostVS:

postVS

А вот PIX дизассемблирования, сгенерированный, когда я решил отладить вершину 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

Я также добавил входной ассемблер:

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;
        }

1 Ответ

3 голосов
/ 06 сентября 2011

Очевидно, что ваши входные позиции вершин не соответствуют значениям, которые вы хотите задать.

Для первой вершины значения выглядят хорошо до координаты z текстурных координат.Вы определяете Vector2D в своей программе Vertex-struct, но Vector4D в Vertexshader Vertex-struct и все перемешивается.

просто измените VS_IN на это:

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

I 'Я не уверен, что если вы действительно хотите иметь цвета или, вернее, texcoords.Если вы действительно хотите иметь цвета, float4 был бы правильным, но тогда вам пришлось бы поменять

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

на

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

В любом случае, одна из этих переменных названа неправильно и, вероятно, причиназа путаницу.

...