这个想法: 使用本机WebGL帧缓冲创建一个renderTexture,以便能够使用" WEBGL_draw_buffers"并输出多个附件(COLOR_ATTACHMENT0_WEBGL,COLOR_ATTACHMENT1_WEBGL,COLOR_ATTACHMENT2_WEBGL,...)
glFragData[0] = ...
glFragData[1] = ...
glFragData[2] = ...
glFragData[3] = ...
然后,尝试使用绑定到帧缓冲区的这些附加的本机WebGL texture2D更新一些THREE.DataTextures。
使用WEBGL_draw_buffers扩展程序,我的本机帧缓冲区一切正常......但我找不到更新threejs纹理的方法。我通过查看Threejs如何处理WebGLRenderTarget尝试了很多东西......但没有任何工作......没有办法用原生WebGL Texture2D更新THREE.Texture。
我不想使用WebGLRenderTarget,因为只有一个COLOR_ATTACHMENT并且它不支持" WEBGL_draw_buffers"延期。 也许将来处理这个会很好;)
知道如何实现这个目标吗?
这就是我在代码方面的意思:
var scene;
var camera;
var renderer;
var debugMaterial;
var posTextureOut;
function init()
{
// create a data texture + generate a gl.Texture2D for it
posTextureOut = new THREE.DataTexture(posTextureData, rttSize, rttSize, THREE.RGBAFormat, THREE.FloatType);
posTextureOut.__webglTexture = gl.createTexture();
posTextureOut.__webglInit = true;
posTextureOut.needsUpdate = true;
// create a framebuffer and bind posTextureOut.__webglTexture to it
rttFramebuffer = gl.createFramebuffer();
renderFrameBuffer = gl.createRenderbuffer();
gl.bindTexture(gl.TEXTURE_2D, posTextureOut.__webglTexture);
//gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, rttSize, rttSize, 0, gl.RGBA, gl.FLOAT, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, rttFramebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, ext.COLOR_ATTACHMENT0_WEBGL, gl.TEXTURE_2D, posTextureOut.__webglTexture, 0);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.bindTexture(gl.TEXTURE_2D, null);
// Bind RenderBuffer to FrameBuffer Depth and Stencil attachment
gl.bindFramebuffer(gl.FRAMEBUFFER, rttFramebuffer);
gl.bindRenderbuffer(gl.RENDERBUFFER, renderFrameBuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, rttSize, rttSize );
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, renderFrameBuffer );
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
// create material with classic vert/frag shaders + posTextureOut as mainTexture
debugMaterial = new THREE.ShaderMaterial({
uniforms:
{
texture: { type: "t", value: posTextureOut }
},
vertexShader: shaderLoader.GetData("simulVert"),
fragmentShader: shaderLoader.GetData("simulFrag"),
transparent: true,
needsUpdate: true
});
var geometry = new THREE.PlaneGeometry( 128, 128, 8, 8 );
plane = new THREE.Mesh( geometry, debugMaterial );
scene.add( plane );
}
function render()
{
gl.bindFramebuffer(gl.FRAMEBUFFER, rttFramebuffer);
// Draw some stuff width gl.drawArrays or gl.drawElements
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
// ... find a way to update posTextureOut width the native texture2D from the framebuffer
renderer.resetGLState(); // errors in renderer if this is not called (??)
renderer.render(scene, camera);
}
如果我这样做,我会让它部分工作:
function render()
{
gl.bindFramebuffer(gl.FRAMEBUFFER, rttFramebuffer);
// Draw some stuff width gl.drawArrays or gl.drawElements
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
renderer.resetGLState();
gl.bindTexture(gl.TEXTURE_2D, posTextureOut.__webglTexture);
renderer.render(scene, camera);
gl.bindTexture(gl.TEXTURE_2D, null);
}
但它并不真正适合ThreeJS渲染器管道,我无法控制使用哪个activeTexture,无论gl.activeTexture(gl.TEXTURE0)gl.TEXTURE1,gl.TEXTURE2是否在之前传递结合。
我真的想从我的网格材质中使用自定义帧缓冲区的内容更新我的posTextureOut(THREE.DataTexture)。
听起来像THREE.Textures没有考虑对其__webglTexture的任何更改。
由于
Q值。
答案 0 :(得分:1)
好的,我想我找到了为什么我无法使用texture2D参考更新THREE.Texture。
要使用gl.createTexture()设置THREE.Texture,我通过谷歌搜索找到了这个:
posTextureOut = new THREE.DataTexture(posTextureData, rttSize, rttSize, THREE.RGBAFormat, THREE.FloatType);
posTextureOut.__webglTexture = gl.createTexture();
posTextureOut.__webglInit = true;
posTextureOut.needsUpdate = true;
然后,如果你想将这个纹理绑定到一个原生的framebuffer并在其上做一些原生的webgl东西,你可以这样做:
gl.bindFramebuffer(gl.FRAMEBUFFER, rttFramebuffer);
...
ext.drawBuffersWEBGL([ext.COLOR_ATTACHMENT0_WEBGL, ext.COLOR_ATTACHMENT1_WEBGL]);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, posTextureOut.__webglTexture);
...
...
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
使用此修改过的posTextureOut .__ webglTexture更新了THREE.Texture的问题
使用needsUpdate = true对我没有帮助,并且由于纹理绑定到THREE.WebGLRenderer而导致很多错误。
通过查看源代码,我发现了问题。 在THREE.WebGLRenderer中,this.setTexture方法如下所示:
this.setTexture = function ( texture, slot ) {
var textureProperties = properties.get( texture );
if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
var image = texture.image;
if ( image === undefined ) {
console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );
return;
}
if ( image.complete === false ) {
console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );
return;
}
uploadTexture( textureProperties, texture, slot );
return;
}
state.activeTexture( _gl.TEXTURE0 + slot );
state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
};
this.uploadTexture方法正在执行此操作:
function uploadTexture( textureProperties, texture, slot ) {
if ( textureProperties.__webglInit === undefined ) {
textureProperties.__webglInit = true;
texture.addEventListener( 'dispose', onTextureDispose );
textureProperties.__webglTexture = _gl.createTexture();
_infoMemory.textures ++;
}
此时,textureProperties .__ webglInit始终未定义,即使它之前被强制。相同的前面textureProperties .__ webglTexture ...总是未定义。
我通过强制this.setTexture来修复此问题,以查看纹理并查看此比例是否有任何更改...否则,渲染器不会考虑它。
以下是我添加的两行:
this.setTexture = function ( texture, slot ) {
var textureProperties = properties.get( texture );
if (texture.__webglInit != undefined) textureProperties.__webglInit = texture.__webglInit;
if (texture.__webglTexture != undefined) textureProperties.__webglTexture = texture.__webglTexture;
if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
var image = texture.image;
....
现在一切正常......我可以在原生WebGL中处理THREE.Texture __webglTexture:)