c++ - D3D11 : variable number of lights in HLSL

标签 c++ shader hlsl lighting direct3d11

我正在使用 C++ 和 Direct3D11 开发游戏引擎,现在我想向场景中添加可变数量的灯光。到目前为止,我设法添加和渲染了一些已知的并在着色器程序中编码的简单灯光。

在 shader.fx 中:

static const int LightsCount= 4;

struct NF3D_LIGHT
{
    // Members...
};

cbuffer Light : register(b5)
{
    NF3D_LIGHT light[LightsCount];
};

...

// And the pixel shader function:
float4 PS(PS_INPUT input) : SV_Target
{
    for(int i = 0; i < LightsCount; i++)
    {
        // Process each light and return the final pixel colour
    }
}

这很好用。但如果我尝试:

cbuffer LIGHTS_COUNT : register(b13)
{
    int LightsCount;
}

要使灯的数量根据游戏中发生的情况而变化,这是行不通的。我知道我可以在应用程序开始时给 LightsCount 一个很大的值并向数组添加灯光,但我发现这种方法复杂、固定且效率不高。

有人知道如何解决这个问题吗?提前谢谢你。

最佳答案

从着色器访问可变大小数组(具有运行时定义的大小)的一般问题可能会以不同的方式解决,具体取决于数组大小、数据更改频率和您的目标硬件。

我想到了几种技术:

  1. 如果您的数组很小,最简单的方法就是按照您的建议传递一个具有固定大小数组当前大小 的常量缓冲区。

  2. 几乎在任何硬件上都适用的方法是将数据写入纹理SampleLoad它来自着色器。您只能读取基本类型(floatfloat4 等),因此您需要对纹理实现适当的索引以读取复杂对象(结构)。

  3. 在 Shader Model 5 硬件上(以及一些 SM 4 上)你可以使用 UAV s 和 StructuredBuffer s 从缓冲区读取结构化数据。

  4. 如果您有涉及数组的非常复杂的计算,并且如果目标硬件允许您这样做,您可能希望将处理转移到计算着色器,甚至转移到 OpenCL 或 CUDA 内核。

    <

考虑到给定的问题,即经典光照,我会说我所见的 99% 都使用方法 1。无论如何,大多数时候一个场景中的灯光不会超过一打。

关于c++ - D3D11 : variable number of lights in HLSL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34456099/

相关文章:

c++ - 需要当前进程的 PID,getpid() 返回 -1

c++ - 为什么bool显示正确的位顺序,而直接输出移位运算结果却不正确?

c# - 在 Windows 7 Pro 32 位中生成 .tlb 文件

opengl - GLSL 全局变量

javascript - THREE.js 中的 Shadertoy

c++ - Direct3D 中具有雾问题的 HLSL 多纹理

wpf - 操作次数最少的排序算法

c++ - 如何使用 constexpr 逻辑?

math - pow(0, 2.2) 在 hlsl 像素着色器中给出 1?

c++ - 实时动态阴影来补充延迟着色?