gpt4 book ai didi

c++ - 在 hlsl 着色器中设置全局参数的正确方法是什么?

转载 作者:行者123 更新时间:2023-11-30 01:51:05 25 4
gpt4 key购买 nike

在 hlsl 着色器中设置全局参数的正确方法是什么?如果我有以下全局参数:

float4x4 World;
float4x4 View;
float4x4 Projection;

我在顶点着色器中使用它们:

void VertexShaderFunction( in float4 inputPosition : POSITION, in float4 colorIn : COLOR, out float4 posOut : SV_POSITION, out float4 colorOut : COLOUR)
{
//Set values for output
float4 worldPosition = mul(inputPosition, World);
float4 viewPosition = mul(worldPosition, View);
float4 position = mul(viewPosition, Projection);


posOut = position;
colorOut = colorIn;
}

然后如何从 C++ 代码 f.e. 设置这些全局值?什么时候移动相机?我是否应该创建另一个着色器,它只设置这些我可以像这样作为缓冲区访问的值?

void SetProjectionMatrix(float4x4 inputMatrix : MATRIX){
Projection = inputMatrix;
}

请告诉我实现此目标的正确方法是什么。

最佳答案

首先,在您的着色器中,您需要将矩阵放入常量缓冲区中:

cbuffer CameraBuffer : register( b0 ) {
float4x4 World;
float4x4 View;
float4x4 Projection;
}

如果您不声明常量缓冲区,它们会为您创建,但最好显式声明它们并按更新频率对它们进行分组。例如,将每帧更新的所有常量和仅设置一次的所有常量组合在一起。这允许您只更新需要更新的常量,而无需向 GPU 发送额外数据。

即使它们在这个 cbuffer 结构中,它们在您的着色器中仍然以相同的方式访问。

在您的 C++ 代码中,您需要声明一个类似的结构来存储您的矩阵:

struct CameraConstants {
XMFLOAT4X4 world;
XMFLOAT4X4 view;
XMFLOAT4X4 projection;
};

注意 packing rules for constant variables 非常重要.此结构不会有问题,但在某些情况下,您可能需要向 C++ 结构添加额外的填充,以说明着色器 cbuffers 打包数据的事实,以便它不会跨越 16 字节边界,这是由于 16 字节的性质GPU 寄存器。

在初始化期间,您还需要创建一个常量缓冲区。该过程与顶点缓冲区相同,只是您需要使用以下标志来声明可由 CPU 写入的常量缓冲区:

cbDesc.Usage = D3D11_USAGE_DYNAMIC;
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;

无论何时更新矩阵,都需要将它们上传到 GPU。为此,您将常量缓冲区映射到 CPU,并复制 CameraConstants 结构:

D3D11_MAPPED_SUBRESOURCE resource;
m_deviceContext->Map( cameraCbuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource );
memcpy( resource.pData, cameraConstants, sizeof( CameraConstants ) );
m_deviceContext->Unmap( cameraCbuffer, 0 );

现在只需将常量缓冲区绑定(bind)到您的顶点着色器:

m_deviceContext->VSSetConstantBuffers( 0, 1, &cameraCbuffer );

请注意,第一个参数映射到您在着色器 cbuffer 声明中使用的寄存器(在本例中为 b0)。

还有一点,hlsl 中的矩阵默认是主要列。如果您的矩阵在 C++ 中是行主要的(可能),那么您需要在发送到 GPU 之前转置它们,或者在着色器中将您的矩阵声明为 row_major

查看 DirectX 示例以获得所有这些的一些源代码:https://code.msdn.microsoft.com/windowsdesktop/Direct3D-Tutorial-Win32-829979ef

关于c++ - 在 hlsl 着色器中设置全局参数的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26571743/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com