Проблема с пиксельным шейдером 3D-графики SlimDX

Я работаю над простым 3D-приложением, которое будет рисовать куб с помощью SlimDX. В настоящее время он должен рисовать один треугольник на экране, но вместо этого ничего не делает.

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

Я установил для cullmode значение none, но он по-прежнему отказывается запускать пиксельный шейдер. Вот код, который инициализирует матрицы проекции и представления.

        m_ProjectionMatrix = Matrix.PerspectiveFovLH(0.7853982f, //1.570796f, // this is 90 degrees in radians
                                                     (float) m_Form.Width / (float) m_Form.Height,
                                                     m_Viewport.MinZ,
                                                     m_Viewport.MaxZ);

        m_ViewMatrix = Matrix.LookAtLH(new Vector3(3, 1, -10),
                                       new Vector3(0, 0, 0),
                                       new Vector3(0, 1, 0));

Сам треугольник расположен в начале координат, так как я не применил к нему никакого перевода. Вот данные вершины, которые хранятся в пользовательской структуре вершины. Пока я использую только данные о местоположении, пока не решу эту проблему. Затем я буду возиться с другими значениями, которые я добавил. Но вот данные вершины:

    Vertex[] vertexData =
    {
        new Vertex() { Position = new Vector4(-1.0f, 1.0f, 0.0f, 0.0f), Color = new Color4(1.0f, 0.0f, 0.0f, 1.0f), TexCoord = new Vector2(0, 0) },
        new Vertex() { Position = new Vector4(1.0f, 1.0f, 0.0f, 0.0f), Color = new Color4(1.0f, 0.0f, 1.0f, 0.0f), TexCoord = new Vector2(1, 0) },
        new Vertex() { Position = new Vector4(0.0f, -1.0f, 0.0f, 0.0f), Color = new Color4(1.0f, 1.0f, 0.0f, 0.0f), TexCoord = new Vector2(0.5f, 1) },
    };

А вот код шейдера:

cbuffer cbPerResize : register( b0 )
{
    matrix Projection;
};

cbuffer cbPerFrame : register( b1 )
{
    matrix View;
};

cbuffer cbPerObject : register( b2 )
{
    matrix World;
};


Texture2D ObjTexture;
SamplerState ObjSamplerState;


//--------------------------------------------------------------------------------------
struct VS_INPUT
{
    float4 Pos : POSITION;
    float4 Color : COLOR;
    float2 TexCoord: TEXCOORD;
};

struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float4 Color : COLOR;
    float2 TexCoord: TEXCOORD;
};






PS_INPUT Vertex_Shader( VS_INPUT input )
{
    PS_INPUT output = (PS_INPUT) 0;

    output.Color = input.Color;
    output.TexCoord = input.TexCoord;

    output.Pos = mul( input.Pos, World );
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );

    return output;
}

float4 Pixel_Shader_Color(PS_INPUT input) : SV_TARGET
{
    return float4(0.0f, 0.0f, 1.0f, 1.0f);   
}

Вот код рисования в моем методе RenderScene(). Мировая матрица для куба в настоящее время является просто единичной матрицей:

    // Clear the screen before we draw the next frame.
    m_DeviceContext.ClearRenderTargetView(m_RenderTargetView, m_ClearColor);


    // Send the cube's world matrix to the changes per object constant buffer.
    m_DataStream.Position = 0;
    m_DataStream.Write(Matrix.Transpose(m_CubeWorldMatrix));
    m_DataStream.Position = 0;
    m_Device.ImmediateContext.UpdateSubresource(new DataBox(0, 0, m_DataStream),
                                                m_CbChangesPerObject,
                                                0);


    // Draw the triangle that we created in our vertex buffer.
    m_DeviceContext.Draw(3, 0);


    // Present the frame we just rendered to the user.
    m_SwapChain.Present(0,
                        PresentFlags.None);

Вот выходные данные этапа InputAssembler. Значение вершины кажется странным.

# Visual Studio - VsPix
# Version: 11
# Vertex shader mesh
#
# Generated data
# object insideShape
g insideShape
v -Infinity Infinity NaN
v Infinity Infinity NaN
v NaN -Infinity NaN
f 1 2 3

Это одна из тех очень раздражающих проблем, которые вы просто не можете решить. И по моему опыту, эти типы ошибок обычно вызываются чем-то очень маленьким... лол

Я проверил буферы констант, и похоже, что они устанавливаются правильно. Я в тупике... Что происходит? Любая помощь приветствуется!


person Mike F.    schedule 17.11.2013    source источник


Ответы (1)


Судя по тому, что вы используете m_Viewport.MinZ и m_Viewport.MaxZ в качестве ближней/дальней плоскости для матрицы проекции.

В окне просмотра они обычно равны 0->1, но значения в матрице проекции другие, поэтому, если вы установите MaxZ = 1 в своей проекции, ваш треугольник будет обрезан (поскольку ваш взгляд на z равен -10).

Попробуйте установить проекцию на ближнюю = 0,5 и дальнюю = 200 (примерно так).

РЕДАКТИРОВАТЬ: Также я заметил, что ваша позиция вершины -1.0f, 1.0f, 0.0f, 0.0f

Последний компонент должен быть 1.0f

person mrvux    schedule 18.11.2013
comment
Я изменил проекцию ближе к 0,5 и далеко к 200, но все равно делает то же самое. Пиксельный шейдер по-прежнему не работает. :( - person Mike F.; 18.11.2013
comment
Это может быть намеком на проблему. Если я нажму на этап ассемблера ввода в графическом отладчике, я увижу, что он выводит, и я добавил это в пост выше. Строки Vertex в этом выводе полны бесконечностей и значений NaN, что кажется неправильным. - person Mike F.; 18.11.2013
comment
Что, если вы установите для всех своих матриц идентичность? - person mrvux; 18.11.2013
comment
Я попробовал это (установил идентичность матриц вида и проекции), и в результате все окно заполнено синим цветом. Даже когда я перемещаю положение камеры по оси Z обратно на -1000. Таким образом, пиксельный шейдер явно запущен. Но это не треугольник. ржу не могу - person Mike F.; 18.11.2013
comment
ЭТО БЫЛО! Я изменил компонент w каждой вершины на 1.0f. Теперь я вижу синий перевернутый треугольник на экране! Благодаря тонну! - person Mike F.; 18.11.2013