在 DirectX 11 中添加着色器的法线信息 - 法线在着色器中不可见
Adding normal information for the shader in DirectX 11 - normals not visible in shader?
我想为着色器添加法线贴图信息。我使用 DirectX 11 C++ SDK 中的教程 5 作为基础。
着色器创建的代码是(我只是为了确保我已经发布了所有重要信息,但我认为只有D3D11_INPUT_ELEMENT_DESC布局[]很重要):
// Compile the vertex shader
ID3DBlob* pVSBlob = NULL;
HRESULT hr = CompileShaderFromFile( strToWchart(vertexShaderFileName), "VS", "vs_4_0", &pVSBlob );
// Create the vertex shader
hr = device->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &vertexShader );
if( FAILED( hr ) )
{
pVSBlob->Release();
}
// Define the input layout
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 12, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
UINT numElements = ARRAYSIZE( layout );
// Create the input layout
hr = device->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(),
pVSBlob->GetBufferSize(), &*vertexLayout );
pVSBlob->Release();
// Set the input layout
context->IASetInputLayout( *vertexLayout );
// Compile the pixel shader
ID3DBlob* pPSBlob = NULL;
hr = CompileShaderFromFile( strToWchart(pixelShaderFileName), "PS", "ps_4_0", &pPSBlob );
// Create the pixel shader
hr = device->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &pixelShader );
pPSBlob->Release();
}
所以简单地D3D11_INPUT_ELEMENT_DESC我已将布局[]更改为(添加"正常"行):
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 12, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
比我在框创建方法中更改了几行:
// Create vertex buffer
SimpleVertex vertices[] =
{
{ XMFLOAT3( - halfSize.getX(), + halfSize.getY(), - halfSize.getZ() ), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( + halfSize.getX(), + halfSize.getY(), - halfSize.getZ() ), XMFLOAT4( 0.0f, 1.0f, 0.0f, 1.0f ), XMFLOAT4( 0.0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( + halfSize.getX(), + halfSize.getY(), + halfSize.getZ() ), XMFLOAT4( 0.0f, 1.0f, 1.0f, 1.0f ), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( - halfSize.getX(), + halfSize.getY(), + halfSize.getZ() ), XMFLOAT4( 1.0f, 0.0f, 0.0f, 1.0f ), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( - halfSize.getX(), - halfSize.getY(), - halfSize.getZ() ), XMFLOAT4( 1.0f, 0.0f, 1.0f, 1.0f ), XMFLOAT4( 0.0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( + halfSize.getX(), - halfSize.getY(), - halfSize.getZ() ), XMFLOAT4( 1.0f, 1.0f, 0.0f, 1.0f ), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( + halfSize.getX(), - halfSize.getY(), + halfSize.getZ() ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ), XMFLOAT4( 1.0f, 0.0f, 1.0f, 0.0f ) },
{ XMFLOAT3( - halfSize.getX(), - halfSize.getY(), + halfSize.getZ() ), XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ) },
};
所以所有行中的最后XMFLOAT4都是正常的(这些是错误的法线并不重要,现在我只想让它在顶点着色器中可见)。
我还更改了SimpleVertex:
struct SimpleVertex
{
XMFLOAT3 Pos;
XMFLOAT4 Color;
XMFLOAT4 Normal;
};
还有我的着色器来检查法线是否存在:
cbuffer ConstantBuffer : register( b0 )
{
matrix World;
matrix View;
matrix Projection;
}
struct VS_INPUT
{
float4 Pos : POSITION;
float4 Color : COLOR;
float4 Normal : NORMAL;
};
struct PS_INPUT
{
float4 Pos : SV_POSITION;
float4 Color : COLOR;
};
PS_INPUT VS( VS_INPUT input )
{
PS_INPUT output = (PS_INPUT)0;
output.Pos = mul( input.Pos, World );
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Color = input.Normal; //just to know if I have a normals
return output;
}
float4 PS( PS_INPUT input) : SV_Target
{
return input.Color;
}
但效果只是一个黑匣子(即使有输出。颜色 = 输入。正常)。
那么,问题出在哪里呢?我必须更改其他内容才能在着色器中获取法线信息?
看起来您的D3D11_INPUT_ELEMENT_DESC数组与您的顶点数据不匹配。试试这个:
// Define the input layout
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
法线的偏移量应包括"POSITION"(12 字节)和"COLOR"(16 字节,而不是 12)的偏移量。而且我不知道您为什么要为此设置输入槽。
我不知道
这是否是你的问题,但这里看起来有些不对劲:-
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 12, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }, };
颜色 r32g32b32a32 类型的条目大小为 16 字节,但这似乎不正确,我希望最后一行的 24 是 28。另外,您将输入插槽设置为12,我不太确定为什么?
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 如何在C++中从两个单独的for循环中添加两个数组
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 如何仅为一个函数添加延迟
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 如何将更多文件夹添加到c++include路径
- 如何将元素添加到数组的线程安全函数?
- QT通过C++添加映射QML项目
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 只能向C++添加一定数量的字符
- Qt和C++:将QLineEdit添加到QTabWidget中
- 将QIcon添加到QTableView单元格
- 在 DirectX 11 中添加更多 Texture2D 作为像素着色器资源时遇到问题
- 在 DirectX 11 中添加着色器的法线信息 - 法线在着色器中不可见
- 是否有可能在XAML/ c# Windows 8商店应用程序中添加单一的DirectX全屏页面?
- 如何在DirectX 10项目中添加for循环