远离光源的物体投射的阴影

Gru*_*upa 3 opengl shadow

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

太阳系深度图:

在此输入图像描述

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

ybu*_*ill 6

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

使用 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);
}
Run Code Online (Sandbox Code Playgroud)

这里的0.0意思是完全阴影,1.0意思是完全没有阴影。、light和是太阳、月亮和碎片在非射影空间中的位置,而和是太阳occluder和月亮的半径。fragmentlight_radiusoccluder_radius

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

如果我将太阳的大小减小一半,我会得到以下结果:

  • 由于我不得不暂时搁置这个项目,所以我忘了告诉你你给了我多大的帮助。我是个新手,我花了相当多的时间试图为我的问题找到一个足够准确的解决方案。我知道也许您给了我一个看似微不足道的计算,但我只是想让您知道这对我来说是最有用的,我真的很感谢您抽出时间。 (2认同)