2

我正在尝试使用 Three.js 在 WebGL 中制作水面。我想我会从一面镜子开始,因为我想我知道如何添加位移来制作基本的涟漪效果。

这就是我所知道的:反射通常是通过使用水面作为剔除平面在 FBO 上渲染垂直(y 轴)翻转的场景来实现的。然后这个 FBO 被用作水平面的纹理。使用置换贴图(或噪声纹理)可以置换图像并实现水效果。

问题:首先,我找不到在 ThreeJS 中翻转场景的方法。在 OpenGL 中,您可以只使用 glScale 并将 -1 表示为 Y,但我认为这在 WebGL(或它所基于的 GLES)中是不可能的。至少我在 ThreeJS 中没有发现这样的东西。几何有一个比例参数,但场景没有。一种解决方案可能是更改 Camera 中的 .matrixWorldInverse,但我不确定如何做到这一点。有任何想法吗?

第二个障碍是裁剪/剔除平面。同样,旧方法是使用 glClipPlane,但据我所知,即使在最新的 OpenGL 标准中也不支持它,所以它也不在 WebGL 中。我在某处读到你可以在顶点着色器中做到这一点,但在 ThreeJS 中我只知道如何将着色器添加为材质,并且在渲染到 FBO 期间我需要它。

第三,使用正确的纹理坐标将 FBO 渲染到水平面,所以我认为基本上是从相机位置投影。

我在互联网上找不到更多关于此的信息。WebGL 反射示例很少,唯一接近的就是这里,它使用了一些“斜视截头体”方法进行剔除。这真的是当今最好的方法吗?我们现在必须在软件中自己编写代码而不是一个函数(在 CPU 而不是 GPU 上运行)?当然,ThreeJS 中提供的立方体反射也不适用于平面,所以是的,我试过了。如果有人可以尽可能简单地举例说明如何做到这一点,我将不胜感激。

4

3 回答 3

4

查看这个 three.js 示例

开箱即用,直接从源头开始:

water = new THREE.Water( renderer, camera, scene, {
    textureWidth: 512, 
    textureHeight: 512,
    waterNormals: waterNormals,
    alpha:  1.0,
    sunDirection: light.position.clone().normalize(),
    sunColor: 0xffffff,
    waterColor: 0x001e0f,
    distortionScale: 50.0,
} );


mirrorMesh = new THREE.Mesh(
    new THREE.PlaneBufferGeometry( parameters.width * 500, parameters.height * 500 ),
    water.material
);

mirrorMesh.add( water );
mirrorMesh.rotation.x = - Math.PI * 0.5;
scene.add( mirrorMesh );

对我来说似乎像一片海洋:)

于 2015-01-20T15:04:07.667 回答
2

您可以查看此演示文稿 http://29a.ch/slides/2012/webglwater/

这个小提琴可能对你有用 jsfiddle.net/ahmedadel/44tjE

于 2013-02-24T08:57:58.577 回答
0

这仅解决了您问题的扩展部分。附加到 Object3D 的矩阵有一个 makeScale 方法。

于 2013-02-23T23:23:27.483 回答