Three.js 从 WebGLRenderTarget 检索数据(水模拟) [英] Three.js Retrieve data from WebGLRenderTarget (water sim)

查看:89
本文介绍了Three.js 从 WebGLRenderTarget 检索数据(水模拟)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将此 (http://madebyevan.com/webgl-water/ ) 移植到三个.我想我已经接近了(现在只想要模拟,还不关心焦散/折射).我想让它与着色器一起工作以提升 GPU.

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

我正在努力从 WebGLRenderTarget(在我的示例中为 rtTexture)读取数据.在示例中,您将看到围绕中心点的 4 个顶点向上移位.这是正确的(在 1 个模拟步骤之后),因为它以中心点作为唯一的位移点开始.

如果我可以从 rtTexture 读回数据并每帧更新数据纹理 (buf1),那么模拟应该正确地设置动画.如何直接从 WebGLRenderTarget 读取数据?所有示例都演示了如何将数据发送到目标(呈现给它),而不是从中读取数据.还是我做错了?有些东西告诉我我必须处理多个纹理,并以某种方式来回交换,类似于 Evan 的做法.

TL;DR:如何在这样的调用后将数据从 WebGLRenderTarget 复制到 DataTexture:
<代码>//渲染到 rtTexture
renderer.render(sceneRTT, cameraRTT, rtTexture, true );

可能在 jsfiddle/gero3/UyGD8/9/找到了解决方案将进行调查并报告.

解决方案

好的,我想出了如何使用原生 webgl 调用读取数据:

//将第一个场景渲染成纹理renderer.render(sceneRTT, cameraRTT, rtTexture, true );//将渲染纹理读入缓冲区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.

这是最新的小提琴:http://jsfiddle.net/EqLL9/3/>

随着我的进步,我会保持更新.

现在效果很好.刚刚实现了法线,现在致力于环境反射和折射(再次纯粹通过着色器).http://relicweb.com/webgl/rt.html

I am trying to port this (http://madebyevan.com/webgl-water/‎) over to THREE. I think I'm getting close (just want the simulation for now, don't care about caustics/refraction yet). I'd like to get it working with shaders for the GPU boost.

Here's my current THREE setup using shaders: http://jsfiddle.net/EqLL9/2/ (the second smaller plane is for debugging what's currently in the WebGLRenderTarget)

What I'm struggling with is reading data back from the WebGLRenderTarget (rtTexture in my example). In the example you'll see the 4 vertices surrounding the center point are displaced upwards. This is correct (after 1 simulation step) as it starts with the center point being the only point of displacement.

If I could read the data back from the rtTexture and update the data texture (buf1) each frame, then the simulation should properly animate. How does one read the data directly from a WebGLRenderTarget? All the examples demonstrate how to send data TO the target (render to it), not read FROM it. Or am I doing it all wrong? Something's telling me I'll have to work with multiple textures and somehow swap back and forth similar to how Evan did it.

TL;DR: How can I copy data from a WebGLRenderTarget to a DataTexture after a call like this:
// render to rtTexture
renderer.render( sceneRTT, cameraRTT, rtTexture, true );

EDIT: May have found the solution at jsfiddle /gero3/UyGD8/9/ Will investigate and report back.

解决方案

Ok, I figured out how to read the data using native webgl calls:

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


The simulation now animates. However, it doesn't seem to be functioning properly (probably a dumb error I'm overlooking). It seems that the height values are never being damped and I'm not sure why. The data from buf1 is used in the fragment shader, which calculates the new height (red in RGBA), damps the value (multiplies by 0.99), then renders it to a texture. I then read this updated data from the texture back into buf1.

Here's the latest fiddle: http://jsfiddle.net/EqLL9/3/

I'll keep this updated as I progress along.

EDIT: Works great now. Just got normals implemented, and now working on environment reflection and refraction (again purely though shaders). http://relicweb.com/webgl/rt.html

这篇关于Three.js 从 WebGLRenderTarget 检索数据(水模拟)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆