如何使用程序纹理反映场景中的chrome球体

时间:2015-09-19 21:18:18

标签: opengl direct3d

我的场景背景是绘制海洋,熔岩地板或某些其他背景的程序纹理。它完全延伸到下面,就像你在立方体贴图中一样。如果我可以假设视图在所有方向上都相同会更容易,但是如果有太阳,那么你就不能。

现在,如果我想在中间放置一个镀铬球体,它会反映出什么?球体看起来和主相机一样吗?

假设渲染背景很昂贵,而且我不想每帧多次这样做。如果有帮助,我可以保存副本以用于反射。

有人可以提出一般方法吗?这是我所说的程序纹理的一个例子(这是在着色器中,除了四边形之外没有几何):

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

1 个答案:

答案 0 :(得分:1)

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

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

以下是使用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);