Three.js 从 WebGLRenderTarget(水模拟)中检索数据

8
我正在尝试将此内容(http://madebyevan.com/webgl-water/)移植到THREE。我认为我已经接近成功了(现在只想要模拟,暂时不关心焦散/折射)。我希望使用着色器让它与GPU加速配合使用。

这是我目前使用着色器的THREE设置:http://jsfiddle.net/EqLL9/2/ (第二个较小的平面用于调试WebGLRenderTarget中当前的内容)

我遇到的问题是从WebGLRenderTarget(我的示例中的rtTexture)读取数据。在示例中,您会看到围绕中心点的4个顶点向上位移。这是正确的(经过1个模拟步骤后),因为它从中心点开始是唯一的位移点。

如果我能从rtTexture中读取数据并在每一帧更新数据纹理(buf1),那么模拟应该可以正确地进行动画。如何直接从WebGLRenderTarget中读取数据?所有的示例都演示了如何将数据发送到目标(渲染到它),而不是从中读取。或者我做错了什么?有些东西告诉我,我将不得不使用多个纹理,并以某种方式交替切换,类似于Evan所做的方式。
简而言之:在像这样的调用之后,我该如何将数据从WebGLRenderTarget复制到DataTexture:
// render to rtTexture
renderer.render( sceneRTT, cameraRTT, rtTexture, true );
编辑:可能已经在jsfiddle /gero3/UyGD8/9/找到解决方案。将进行调查并报告回来。
1个回答

10

好的,我已经找到了使用本地WebGL调用读取数据的方法:

// Render first scene into texture
renderer.render( sceneRTT, cameraRTT, rtTexture, true );

// read render texture into buffer
var gl = renderer.getContext();
gl.readPixels( 0, 0, simRes, simRes, gl.RGBA, gl.UNSIGNED_BYTE, buf1.image.data );
buf1.needsUpdate = true;


模拟现在有动画效果了。但它似乎没有正常运行(可能是我忽视的愚蠢错误)。似乎高度值从未被阻尼,我不确定原因。buf1中的数据用于片元着色器中,该片元着色器计算新高度(RGBA中的红色),阻尼值(乘以0.99),然后将其呈现到纹理中。然后我从纹理中读取更新后的数据回到buf1中。

这里是最新的jsfiddle链接:http://jsfiddle.net/EqLL9/3/

我会随着进展而不断更新。

编辑:现在非常好用。刚刚实现了法线,并且正在处理环境反射和折射(仅通过着色器)。http://relicweb.com/webgl/rt.html


2
好的,模拟已经修复。我没有使用双WebGLRenderTargets实现双缓冲。最新链接为:http://jsfiddle.net/EqLL9/4/。 - relicweb
1
很好。这里有另一个在three.js框架内实现GPGPU的例子:http://jabtunes.com/labs/3d/gpuflocking/webgl_gpgpu_flocking3.html - WestLangley
@WestLangley 谢谢你,看起来很酷。我已经更新了我的模拟,并将其放在我的主站点上(仍然是一个重度的WIP):http://relicweb.com/webgl/rt.html - relicweb
这可能会有所帮助:threejs.org/examples/webgl_postprocessing_godrays.html 接受不完全令人满意的答案将导致问题的浏览量较低,因为每个人都会认为一切都很好。 - Dragan Okanovic
我正在研究与我的水相似的模拟。就像你的情况一样,阻尼不起作用。双缓冲如何解决阻尼问题? - punitjajodia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接