我正在尝试使用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中提供的立方体反射也不适用于飞机,所以是的,我试过了。 如果有人可以尽可能简单地说明如何做到这一点,我将非常感激。
答案 0 :(得分:3)
开箱即用,直接从源头开始使用:
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方法。