使用ThreeJS的WebGL中的水/镜像表面

时间:2013-02-23 22:23:45

标签: javascript three.js webgl mirror

我正在尝试使用Three.js在WebGL中制作水面。我想我将从一个镜子开始,因为我认为我知道如何添加位移以产生基本的连锁效果。

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

问题:首先,我找不到在ThreeJS翻转场景的方法。在OpenGL中你可以使用glScale并为-1添加-1,但我不认为这在WebGL(或它所基于的GLES)中是可行的。至少我在ThreeJS中找不到这样的东西。几何体有一个缩放参数,但场景没有。一种解决方案可能是在相机中更改.matrixWorldInverse,但我不确定如何做到这一点。有什么想法吗?

第二个障碍是削减/剔除飞机。同样,旧的方式是使用glClipPlane,但据我所知,即使在最新的OpenGL标准中也不支持,所以它也不在WebGL中。我在某处读到了你可以在顶点着色器中做到这一点,但是在ThreeJS中我只知道如何添加着色器作为材质,我需要在渲染到FBO时这样做。

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

我在互联网上找不到更多相关信息。很少有WebGL反射示例,唯一关闭的是here,它使用了一些“Oblique View Frustum”方法进行剔除。这真的是现在最好的方式吗?我们现在必须用软件编写代码(在CPU而不是GPU上运行),而不是一个函数?当然,ThreeJS中提供的立方体反射也不适用于飞机,所以是的,我试过了。 如果有人可以尽可能简单地说明如何做到这一点,我将非常感激。

3 个答案:

答案 0 :(得分:3)

检查this three.js example

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

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 );

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

这仅解决了问题的缩放部分。附加到Object3D的矩阵具有makeScale方法。