繁体   English   中英

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

[英]What is the correct way to set global parameters in hlsl shader?

在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 ++代码fe中设置这些全局值? 我是否应该创建另一个着色器,该着色器仅设置可以像这样作为缓冲区访问的这些值?

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

务必注意常量变量打包规则 此结构不会有问题,但是在某些情况下,您可能需要在C ++结构中添加额外的填充,以说明着色器cbuffers打包数据的事实,以至于由于c ++的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 );

现在,将常量缓冲区绑定到您的顶点着色器:

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM