gpt4 book ai didi

opengl - 具有深度立方体贴图的全向阴影贴图

转载 作者:行者123 更新时间:2023-12-02 04:37:26 24 4
gpt4 key购买 nike

我正在使用全向点光源。我已经使用立方体贴图纹理作为 6 个帧缓冲区的颜色附件来实现阴影贴图,并对其每个像素中的光到片段距离进行编码。

现在,如果可能的话,我想以这种方式更改我的实现:

  • 1) 将深度立方体贴图纹理附加到我的帧缓冲区的深度缓冲区,而不是颜色。
  • 2)仅渲染深度,在此 channel 中不写入颜色
  • 3)在主 channel 中,从立方体贴图纹理中读取深度,将其转换为距离,并检查当前片段是否被光线遮挡。

当将深度值从立方体贴图转换回距离时,我的问题出现了。我使用光到片段向量(在世界空间中)来获取立方体贴图中的深度值。此时,我不知道正在使用六个面中的哪一个,也不知道哪些 2D 纹理坐标与我正在读取的深度值相匹配。那么如何将深度值转换为距离呢?

这里是我的代码片段来说明:

深度纹理:

glGenTextures(1, &TextureHandle);
glBindTexture(GL_TEXTURE_CUBE_MAP, TextureHandle);
for (int i = 0; i < 6; ++i)
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT,
Width, Height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

帧缓冲区构造:

for (int i = 0; i < 6; ++i)
{
glGenFramebuffers(1, &FBO->FrameBufferID);
glBindFramebuffer(GL_FRAMEBUFFER, FBO->FrameBufferID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, TextureHandle, 0);
glDrawBuffer(GL_NONE);
}

我正在尝试编写的片段着色器来实现我的代码:

float ComputeShadowFactor(samplerCubeShadow ShadowCubeMap, vec3 VertToLightWS)
{
float ShadowVec = texture(ShadowCubeMap, vec4(VertToLightWS, 1.0));
ShadowVec = DepthValueToDistance(ShadowVec);
if (ShadowVec * ShadowVec > dot(VertToLightWS, VertToLightWS))
return 1.0;

return 0.0;
}

DepthValueToDistance 函数是我的实际问题。

最佳答案

因此,解决方案是将光到片段矢量转换为深度值,而不是将从立方体贴图读取的深度转换为距离。

这是修改后的着色器代码:

float VectorToDepthValue(vec3 Vec)
{
vec3 AbsVec = abs(Vec);
float LocalZcomp = max(AbsVec.x, max(AbsVec.y, AbsVec.z));

const float f = 2048.0;
const float n = 1.0;
float NormZComp = (f+n) / (f-n) - (2*f*n)/(f-n)/LocalZcomp;
return (NormZComp + 1.0) * 0.5;
}

float ComputeShadowFactor(samplerCubeShadow ShadowCubeMap, vec3 VertToLightWS)
{
float ShadowVec = texture(ShadowCubeMap, vec4(VertToLightWS, 1.0));
if (ShadowVec + 0.0001 > VectorToDepthValue(VertToLightWS))
return 1.0;

return 0.0;
}

关于VectorToDepthValue(vec3 Vec)的说明:

LocalZComp 对应于立方体贴图的匹配视锥体中给定 Vec 的 Z 分量。它实际上是 Vec 的最大组件(例如,如果 Vec.y 是最大组件,我们将查看立方体贴图的 Y+ 或 Y- 面)。

如果你看看这个wikipedia article ,您将在之后理解数学(为了便于理解,我将其保留为正式形式),它只需将 LocalZComp 转换为标准化 Z 值(在 [-1..1] 之间),然后将其映射到 [0..1],这是深度缓冲区值的实际范围。 (假设你没有改变它)。 nf 是用于生成立方体贴图的平截头体的近值和远值。

ComputeShadowFactor 然后只需将立方体贴图的深度值与从片段到光源向量(此处名为 VertToLightWS)计算出的深度值进行比较,同时添加一个小的深度偏差(问题中缺少),如果片段未被光遮挡,则返回 1。

关于opengl - 具有深度立方体贴图的全向阴影贴图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10786951/

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