gpt4 book ai didi

Three.js使用framebuffer作为纹理

转载 作者:行者123 更新时间:2023-12-02 13:36:49 25 4
gpt4 key购买 nike

我在 Three.js 中使用 canvas 元素中的图像作为纹理,使用 JavaScript 在 Canvas 上执行图像操作,然后在纹理上调用 needUpdate()。这可行,但速度很慢。

我想在片段着色器中执行图像计算。我发现了很多几乎的例子:

编辑:这是另一个:

据我了解,理想情况下,我能够使用自己的片段着色器创建一个新的帧缓冲区对象,自行渲染它,并将其输出用作另一种 Material 的片段着色器的纹理统一。这可能吗?

编辑2:看起来我可能会问类似的问题:Shader Materials and GL Framebuffers in THREE.js ...尽管问题似乎尚未解决。

最佳答案

上面列出的

渲染到纹理渲染到另一个场景是同一件事,并且是您想要的技术。解释一下:

在 vanilla WebGL 中,执行此类操作的方式是从头开始创建帧缓冲区对象 (FBO),将纹理绑定(bind)到它,然后使用您选择的着色器渲染它。不涉及“场景”和“相机”等概念,这是一个复杂的过程。这是一个例子:

http://learningwebgl.com/blog/?p=1786

但这也恰好是 Three.js 在使用它来渲染带有相机的场景时所做的事情:渲染器输出到帧缓冲区,在其基本用法中直接输出到屏幕。因此,如果您指示它渲染到新的 WebGLRenderTarget,则可以使用相机看到的任何内容作为第二种 Material 的输入纹理。所有复杂的事情仍在发生,但在幕后,这就是 Three.js 的美妙之处。 :)

所以:要复制包含单个渲染纹理的 FBO 的 WebGL 设置,如评论中所述,只需创建一个包含正交相机和单个平面的新场景,该场景的 Material 使用所需的纹理,然后渲染到使用自定义着色器的新 WebGLRenderTarget:

// new render-to-texture scene
myScene = new THREE.Scene();

// you may need to modify these parameters
var renderTargetParams = {
minFilter:THREE.LinearFilter,
stencilBuffer:false,
depthBuffer:false
};

myImage = THREE.ImageUtils.loadTexture( 'path/to/texture.png',
new THREE.UVMapping(), function() { myCallbackFunction(); } );

imageWidth = myImage.image.width;
imageHeight = myImage.image.height;

// create buffer
myTexture = new THREE.WebGLRenderTarget( width, height, renderTargetParams );

// custom RTT materials
myUniforms = {
colorMap: { type: "t", value: myImage },
};
myTextureMat = new THREE.ShaderMaterial({
uniforms: myUniforms,
vertexShader: document.getElementById( 'my_custom_vs' ).textContent,
fragmentShader: document.getElementById( 'my_custom_fs' ).textContent
});

// Setup render-to-texture scene
myCamera = new THREE.OrthographicCamera( imageWidth / - 2,
imageWidth / 2,
imageHeight / 2,
imageHeight / - 2, -10000, 10000 );

var myTextureGeo = new THREE.PlaneGeometry( imageWidth, imageHeight );
myTextureMesh = new THREE.Mesh( myTextureGeo, myTextureMat );
myTextureMesh.position.z = -100;
myScene.add( myTextureMesh );

renderer.render( myScene, myCamera, myTexture, true );

渲染新场景后,myTexture 将可用作主场景中另一种 Material 的纹理。请注意,您可能希望使用 loadTexture() 调用中的回调函数触发第一个 render,这样在源图像加载之前它不会尝试渲染.

关于Three.js使用framebuffer作为纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21533757/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com