2013-02-27 2 views
0

Я пишу приложение, которое отображает графику на экране. Приложение может переключаться между графическими модулями Direct3D9 и Direct3D10 (я писал DLL, которые обертывают как D3D9, так и D3D10). При попытке визуализации тестовой сетки (тор, который поставляется в виде сетки в D3DX9 и в библиотеке DXUT, вы можете найти в образцах DirectX10), модуль Direct3D10 ведет себя довольно странно. Вот что я получаю.Странная визуализация с Direct3D10

D3D9: Torus rendered by D3D9 module.

D3D10: Torus rendered by D3D10 module

мнение, проекция и мировые матрицы являются одинаковыми для обоих случаев. Единственное, что отличается, это код инициализации устройства и файлы эффектов HLSL (для простоты я применяю только окружающие цвета и не использую расширенное освещение, текстурирование и т. Д.). Может ли это быть из-за неправильной инициализации устройства или из-за плохих шейдеров? Я был бы признателен за любой намек. Я могу отправить любую часть кода по запросу.

Парень в игре Dev StackExchange предположил, что это, вероятно, из-за транспонированной матрицы проекции. Я попытался заменить порядок, в котором матрицы умножаются в файле шейдера, я пробовал почти каждую перестановку, которую я мог бы получить, но на экране не было прав.

Заранее спасибо. EDIT: Вот файл .fx. Вы можете игнорировать PS, там ничего интересного не происходит.

//Basic ambient light shader with no textures 
matrix World; 
matrix View; 
matrix Projection; 
float4 AmbientColor : AMBIENT = float4(1.0, 1.0, 1.0, 1.0); 
float AmbientIntensity = 1.0; 

struct VS_OUTPUT 
{ 
    float4 Position : SV_POSITION; // vertex position 
    float4 Color : COLOR0; // vertex color  
}; 

RasterizerState rsWireframe { FillMode = WireFrame; }; 

VS_OUTPUT RenderSceneVS(float4 vPos : POSITION) 
{ 
    VS_OUTPUT output; 
    matrix WorldProjView = mul(World, mul(View, Projection)); 
    vPos = mul(vPos, WorldProjView);   
    output.Position = vPos; 
    output.Color.rgb = AmbientColor * AmbientIntensity; 
    output.Color.a = AmbientColor.a; 

    return output; 
} 

struct PS_OUTPUT 
{ 
    float4 RGBColor : SV_Target; // Pixel color 
}; 

PS_OUTPUT RenderScenePS(VS_OUTPUT In) 
{ 
    PS_OUTPUT output; 
    output.RGBColor = In.Color; 
    return output; 
} 

technique10 Ambient 
{ 
    pass P0 
    { 
     SetRasterizerState(rsWireframe); 
     SetVertexShader(CompileShader(vs_4_0, RenderSceneVS())); 
      SetGeometryShader(NULL); 
      SetPixelShader(CompileShader(ps_4_0, RenderScenePS()));    
    } 
} 
+0

Не могли бы вы разместить код шейдера? Это очень поможет. Кроме того, «Транспонировано» не означает порядок умножения. Это означает, что формируется матрица: http://en.wikipedia.org/wiki/Row-major_order – Stardidi

+0

Я попытался использовать параметр флага шейдера, чтобы изменить порядок матриц от столбца к майору строки, что не помогло ни , –

+0

Эти проблемы с матрицами - это такая боль, с которой приходится иметь дело, попробуйте установить свою матрицу World и View в Identity.Если это не исправить, очевидно, что проблема в том, как вы создаете матрицу Projection. (Возможно, опубликуйте эту строку кода) – Stardidi

ответ

2

Убедитесь, что ваш vPos.w = 1.0f. Если это не так, умножение матрицы будет диким и создаст странные результаты.

1

Не уверен, что вызывает эту проблему, но вы можете проверить следующее:

  • убедитесь, что постоянные буферы с tranformation матрицами «инициализируется с чем-то», а не какая-то фигня данных
  • если вы используете normal/tangent в вашем буфере вершин также убедитесь, что вы не помещаете некоторые данные мусора там (за вершину), но это скорее вызовет проблему с текстурированием
  • убедитесь, что ваше описание вершинного макета соответствует вводу в vertexshader (.hlsl) , иногда даже если он не соответствует, он просто компилируется и запускается, но показывая некоторую неожиданную сетку.
  • Я понятия не имею, как он в DX9, но, может быть, есть что-то с координатами, умножив г в буфере вершин на в некоторой матрице преобразования на -1 может помочь

Edit: Это может быть также хорошей идеей просто поместить некоторую простую сетку в буфер, например, куб (треугольник ровный) и проверить, правильно ли он рисуется.

+0

Сетка генерируется образцом DXUT, который поставляется с DirectX SDK. Поэтому у меня нет большого контроля над этим. –

+0

Вы должны убедиться, что ваша сетка не содержит больше информации, чем просто POSITION. На самом деле поцарапать это, это просто создаст действительно странную сетку. – Stardidi

0

Вам необходимо перенести свои матрицы, прежде чем устанавливать их как константы шейдеров. Если вы используете xnamath, используйте функцию XMMatrixTranspose() в каждой из миров, матриц просмотра и проекции, прежде чем устанавливать их в свой постоянный буфер.

Смежные вопросы