javascript 使用 ThreeJS 的 WebGL 中的水/镜面
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15046449/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Water/Mirrored surface in WebGL using ThreeJS
提问by user1214513
I am trying to make a water surface in WebGL using Three.js. I think I will start with just a mirror as I think I know how to add displacement to make basic ripple effects.
我正在尝试使用 Three.js 在 WebGL 中制作水面。我想我会从一面镜子开始,因为我想我知道如何添加位移来制作基本的涟漪效果。
This is what I know:Reflection is usually made by rendering a vertically (y-axis) flipped scene on a FBO using the water plane as a culling plane. Then this FBO is used as a texture for the water plane. Using a displacement map (or a noise texture) the image can be displaced and a water effect achieved.
这就是我所知道的:反射通常是通过使用水面作为剔除平面在 FBO 上渲染垂直(y 轴)翻转场景来实现的。然后这个 FBO 被用作水平面的纹理。使用置换贴图(或噪声纹理)可以置换图像并实现水效果。
The problems:First off, I can't find a way to flip the scene in ThreeJS. In OpenGL you can just use glScale and put -1 for Y, but I don't think this is possible in WebGL (or GLES on which it is based). At least I found no such thing in ThreeJS. There is a scale parameter for geometry, but there is none for scene. One solution could be changing the .matrixWorldInverse in Camera, but I am not sure how I could do that. Any ideas?
问题:首先,我找不到在 ThreeJS 中翻转场景的方法。在 OpenGL 中,您可以只使用 glScale 并为 Y 设置 -1,但我认为这在 WebGL(或它所基于的 GLES)中是不可能的。至少我在 ThreeJS 中没有发现这样的东西。几何体有一个比例参数,但场景没有。一种解决方案可能是更改 Camera 中的 .matrixWorldInverse,但我不确定如何做到这一点。有任何想法吗?
The second hurdle is clipping/culling plane. Again, the old way was using glClipPlane, but its not supported even in the newest OpenGL standard as far as I know, so its also not in WebGL. I read somewhere that you can do that in vertex shader, but in ThreeJS I only know how to add shaders as materials and I need this during the render to FBO.
第二个障碍是裁剪/剔除平面。同样,旧方法是使用 glClipPlane,但据我所知,即使在最新的 OpenGL 标准中也不支持它,所以它也不在 WebGL 中。我在某处读到你可以在顶点着色器中做到这一点,但在 ThreeJS 中我只知道如何将着色器添加为材质,并且在渲染到 FBO 期间我需要这个。
And third, rendering the FBO to water plane with correct texture coordinates, so I think basically projecting from the camera position.
第三,将 FBO 渲染到具有正确纹理坐标的水面,所以我认为基本上是从相机位置投影。
I can't find any more information on this on the internet. There are very few WebGL reflection examples and the only thing close was here, and it used some "Oblique View Frustum" method for culling. Is this really the best way to do it nowadays? Instead of one function we now must code this ourselves in software (to be ran on CPU not GPU)? Also cube reflections provided in ThreeJS of course is not applicable for a plane, so yes, I tried those. If someone can make as easy as possible example on how to do this I would greatly appreciate it.
我在互联网上找不到关于此的更多信息。WebGL 反射示例很少,唯一接近的是here,它使用了一些“斜视锥体”方法进行剔除。这真的是当今最好的方法吗?我们现在必须在软件中自己编写代码而不是一个函数(在 CPU 上而不是 GPU 上运行)?ThreeJS 中提供的立方体反射当然不适用于平面,所以是的,我尝试了这些。如果有人可以尽可能简单地举例说明如何做到这一点,我将不胜感激。
回答by Wilt
Check this three.js exampleout.
Out of the box and ready to use, straight from the source:
开箱即用,直接来自源头:
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 );
Seems to look like an ocean to me :)
对我来说似乎是一片海洋:)
回答by Ahmed Hussein
You can see this presentation http://29a.ch/slides/2012/webglwater/
你可以看到这个演示 http://29a.ch/slides/2012/webglwater/
and this fiddle may be useful for you jsfiddle.net/ahmedadel/44tjE
这个小提琴可能对你有用 jsfiddle.net/ahmedadel/44tjE
回答by gaitat
This only addresses the scaling part of your question. The matrix that is attached to the Object3D has a makeScale method.
这仅解决了您问题的缩放部分。附加到 Object3D 的矩阵有一个 makeScale 方法。