问题
I'm trying to use an FBO in a material in THREE.js. I have a GPU-based fluid simulation which outputs its final visualisation to a framebuffer object, which I would like to use to texture a mesh. Here's my simple fragment shader:
varying vec2 vUv;
uniform sampler2D tDiffuse;
void main() {
gl_FragColor = texture2D( tDiffuse, vUv );
}
I am then trying to use a simple THREE.ShaderMaterial:
var material = new THREE.ShaderMaterial( {
uniforms: { tDiffuse: { type: "t", value: outputFBO } },
//other stuff... which shaders to use etc
} );
But my mesh just appears black, albeit with no errors to the console. If I use the same shader and shader material, but supply the result of THREE.ImageUtils.loadTexture("someImageOrOther") as the uniform to the shader, it renders correctly, so I assume the problem is with my FBO. Is there some convenient way of converting from an FBO to a Texture2D in WebGL?
EDIT:
After some more experimentation it would appear that this isn't the problem. If I pass the FBO to a different shader I wrote that just outputs the texture to the screen then it displays fine. Could my material appear black because of something like lighting/normals?
EDIT 2:
The UVs and normals are coming straight from THREE, so I don't think it can be that. Part of the problem is that most shader errors aren't reported so I have difficulty in that regard. If I could just map the WebGLTexture somehow that would make everything easier, perhaps like this
var newMaterial = new THREE.MeshLambertMaterial({ map : outputFBO.texture });
but of course that doesn't work. I haven't been able to find any documentation that suggests THREE can read directly from WebGLTextures.
回答1:
By poking a little into the sources of WebGLRenderer (look at https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLRenderer.js#L6643 and after), you may try to create a three js texture with a dummy picture, then change the data member __webglTexture
of this texture by putting your own webgltexture.
Also, you may need to set to true
the __webglInit
data member of the texture object so that init code is not executed (because then __webglTexture
is overwritten by a call to _gl.createTexture();
)
回答2:
If you don't mind using the Three.js data structures, here's how you do it:
Three.js use framebuffer as texture
来源:https://stackoverflow.com/questions/15641914/shader-materials-and-gl-framebuffers-in-three-js