gpt4 book ai didi

opengl - 远离光源的物体转换的阴影

转载 作者:行者123 更新时间:2023-12-04 01:46:23 26 4
gpt4 key购买 nike

我对远离光源的物体转换的阴影有疑问。我正在使用深度图方法在我的太阳系模拟中渲染阴影。太阳是一个点光源,我想观察月亮在地球上的影子。但是由于月球相对于它与太阳之间的距离来说是一个非常小的物体,并且由于深度图分辨率有限,因此在渲染深度立方体贴图纹理时会忽略月球和地球的存在。

太阳系深度图:

enter image description here

你可以看到,即使夸大了月球的大小,它在深度立方体贴图上也只留下了很小的足迹。对于这么大的月亮, eclipse 确实有效,但一旦我将月亮缩小到实际大小,它就不再在深度图中呈现,因此,不再考虑阴影计算。我使用的是 4096 X 4096 纹理。有没有办法解决这个问题,还是我的方法注定要失败?任何帮助将不胜感激。

最佳答案

有一个重要的观察结果:当你近距离观察地球时,你可能并不关心火星上的阴影。因此,与其使用立方体贴图对整个太阳系进行阴影贴图,不如使用平面阴影贴图仅覆盖近地区域。

使用 4096x4096 深度图和 384000 公里的月球距离,您将获得每纹素约 100 公里的分辨率,并且月亮将在阴影贴图上占据半径约 20 纹素的圆盘。

但是,还有更好的方法。由于行星和卫星大致呈球形并且数量很少,因此您可以简单地对每个片段进行射线-球面相交来计算阴影。可以计算月球和太阳圆盘之间的交点角面积,以获得实时的本影/半影渲染。这是一个近似着色器中阴影因子的函数:

float soft_shadow(vec3 light, float light_radius,
vec3 occluder, float occluder_radius, vec3 fragment)
{
vec3 v0 = light - fragment;
vec3 v1 = occluder - fragment;

float R0 = length(v0);
float R1 = length(v1);

float a0 = light_radius/R0;
float a1 = occluder_radius/R1;

float a = length(cross(v0, v1))/(R0*R1);
a = smoothstep(a0 - a1, a0 + a1, a);
return 1 - (1 - a)*pow(a1/a0, 2);
}

这里0.0表示全阴影,1.0表示完全没有阴影。 lightoccluderfragment是太阳、月亮和碎片在非投影空间,而 light_radiusoccluder_radius 是太阳和月亮的半径。

对于实际尺寸,此代码为我提供了这些图像:

如果我将太阳的大小减小一半,我会得到这些:

关于opengl - 远离光源的物体转换的阴影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55102900/

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