[英]Sending 2D and 3D shadowmaps to shaders
我正在尝试为我的简单引擎实现阴影贴图,我发现我应该将全向阴影贴图(点光源的立方体贴图)与二维贴图(方向灯和聚光灯)结合起来。
我的统一块看起来像这样:
#define MAX_LIGHTS 128
//...
struct Light
{
//light data...
};
//...
layout (std140) uniform Lights
{
int lightCount; //how many lights were passed into the shader (from 0 to MAX_LIGHTS)
Light lights[MAX_LIGHTS];
};
我有两个问题要问你。
采样器对象成本高吗? 以下代码是否适用于多个灯?
sampler2D shadowMaps2D[MAX_LIGHTS]; samplerCube shadowCubemaps[MAX_LIGHTS]; //... if (lights[index].type == POINT_LIGHT) CalculateShadow(shadowCubemaps[lights[index].shadowMapNr]); else CalculateShadow(shadowMaps2D[lights[index].shadowMapNr]);
只有lightCount数量的对象会实际填充纹理。 我们遇到了很多未定义的采样器,我认为这会导致一些问题。
如果我理解正确,我不能在统一块中声明采样器。 那么,每次阴影贴图更新时,我真的被迫循环遍历所有着色器并更新采样器吗? 这是浪费时间!
采样器对象成本高吗?
这个问题有点误导,因为 GLSL 中的sampler
数据类型只是引用纹理单元的不透明句柄。 代价高昂的是实际的采样操作。 此外,特定阴影阶段的纹理单元数量是有限的。 该规范仅保证 16 个。由于您不能为不同的采样器类型重复使用相同的单元,这会将您的MAX_LIGHTS
限制为仅 8 个。
然而,很少需要采样器阵列。 相反,您可以使用数组 textures ,这将允许您将所有阴影贴图(每种纹理类型)存储在单个纹理对象中,并且您只需要一个采样器。
说了这么多我还是觉得你的光数是完全不现实的。 即使在最快的 GPU 上,实时应用 128 个阴影贴图也行不通……
如果我理解正确,我不能在统一块中声明采样器。
正确的。
那么,每次阴影贴图更新时,我真的被迫循环遍历所有着色器并更新采样器吗? 这是浪费时间!
不。仅当您要从中采样的纹理单元的索引发生变化(理想情况下永远不会)时,才需要更新采样器制服。 不是当绑定不同的纹理时,也不是当某些纹理内容更改时。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.