如何在具有程序纹理的场景中反射 chrome 球体

How to reflect a chrome sphere in a scene with a procedural texture

我的场景背景是绘制海洋、熔岩层或其他类似背景的程序纹理。它也完全延伸到下方,就像您在立方体贴图中一样。如果我可以假设各个方向的视野都相同会更容易,但是如果有太阳,例如,你不能。

现在如果我想在中间放一个 chrome 球体,它会反射什么?球体看到的东西和主相机看到的一样吗?

假设渲染背景的成本很高,我不想每帧渲染多次。如果有帮助,我可以保存一份副本以在反思中使用。

有人可以提出一般方法吗?这是我的意思的程序纹理示例(这都在着色器中,除了四边形之外没有其他几何体):

https://www.shadertoy.com/view/XtS3DD

回答你的第一个问题:在现实世界中,你在球体中看到的反射取决于相机的位置和球体本身的位置。但是,在使用立方体贴图(最常见的方法)时,将两个位置都考虑在内对于移动球体来说成本过高,因为您必须在每一帧中重新渲染立方体贴图的所有六个面。因此,大多数游戏 "fake" 现实通过使用以原点(世界中的(0, 0, 0)-space)为中心的立方体贴图并仅将静态对象(树木等)渲染到立方体贴图。

由于您的背景完全是程序化的,因此您可以跳过创建立方体贴图纹理。如果您可以将程序背景纹理定义为从原点开始的方向(而不是位置!)的函数,那么您可以使用球体上每个点的法向量,加上球体的位置,再加上相机位置从背景纹理中进行采样。

这是它的公式,使用一些 glsl 伪代码:

vec3 N = normal vector for point on sphere
vec3 V = position of camera
vec3 S = position of point on sphere

vec3 ray = normalize(reflect(V-S,N));
// Reflect the vector pointing from the a point on the sphere to 
// the camera over the normal vector for the sphere.

vec4 color = proceduralBackgroundFunc(ray);

上面,color 是球体表面上点 S 的着色器的最终输出。

或者,您可以将背景预渲染为立方体纹理,然后像这样从中采样(仅更改上面的最后一行代码):

vec4 color = texture(cubeSample,ray);