Javascript 使用ThreeJS在WebGL中创建水/镜像曲面

Javascript 使用ThreeJS在WebGL中创建水/镜像曲面,javascript,three.js,webgl,mirror,Javascript,Three.js,Webgl,Mirror,我正在尝试使用Three.js在WebGL中创建水面。我想我将从一个镜子开始,因为我想我知道如何添加位移来产生基本的涟漪效果 这就是我所知道的:反射通常是通过使用水平面作为消隐平面在FBO上渲染垂直(y轴)翻转的场景来实现的。然后,此FBO将用作水平面的纹理。使用置换贴图(或噪波纹理)可以置换图像并实现水效果 问题:首先,我找不到一种方法来将场景翻转成三个JS。在OpenGL中,您可以只使用glScale和put-1表示Y,但我认为在WebGL(或它所基于的GLE)中不可能做到这一点。至少我在3

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

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

问题:首先,我找不到一种方法来将场景翻转成三个JS。在OpenGL中,您可以只使用glScale和put-1表示Y,但我认为在WebGL(或它所基于的GLE)中不可能做到这一点。至少我在3J中没有发现这样的东西。几何体有一个比例参数,但场景没有。一个解决方案可能是改变相机中的.matrixWorldInverse,但我不确定如何才能做到这一点。有什么想法吗

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

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

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

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

您可以看到此演示文稿

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

请查看

开箱即用,直接从源代码开始:

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

在我看来,它看起来像一片海洋:)

小提琴只显示位移部分(折射),而我所有的任务都是缩放、剪裁和渲染到平面。不过,这次演讲看起来很有希望,所以我会研究一下。谢谢。场景是3.Object3D.prototype,所以它实际上也有缩放方法。但它似乎不起作用。我想这是因为摄影机也是场景的一部分,当我执行scene.scale.y时,摄影机也会翻转,所以最后我看不到任何差异(尽管灯光位置保持不变)。我试了一下camera.scale.y=-1,它确实翻转了所有的东西,不过光线还是停留在顶部,角度不对。我想我必须遍历所有场景。_对象并手动设置scale.y=-1。然后在渲染到FBO后再次执行该操作。你能给我举个例子说明你是如何做到的吗?我还是没法做到。我试过:“场景。矩阵。生成比例(1,-1,1);”和“场景.矩阵世界.makeScale(1,-1,1);scene.matrixWorld.matrixWorldNeedsUpdate=true;'它们似乎只是翻转了一些物体,但不是全部。我只想像在GL中一样翻转整个场景:'glPushMatrix();glScalef(1.,-1,1.)//呈现glpopatrib();'这在Three.js中似乎非常复杂。也许我可以直接在那里使用gl api。或者在场景对象中找到需要缩放的100个矩阵中的哪一个。这个主题目前正在讨论中,可能值得一看:)变量
waterNormals
?@GriffinM是什么。我不知道,从装货开始。不确定此waternormals纹理的确切用途。关于StackOverflow,你可以问一个单独的问题…@Wilt THREE.水似乎已经被清除了,有没有其他方法可以做到这一点?@GageHendyYaBoy在THREE.js网站上有三个例子:,和。这些示例的类不是库的一部分,但是可以找到