发布网友 发布时间:2024-09-28 01:16
共1个回答
热心网友 时间:2024-09-29 15:50
下图是多渲染目标的效果:
预备知识WebGLRenderTarget什么是渲染目标?渲染目标是一种缓冲区。这个缓冲区用于缓存在显卡将图形显示在显示屏之前所执行的一些操作得到的绘图数据。
通常我们处理什么数据呢?
constimage={width:width,height:height,depth:1};this.texture=newTexture(image,options.mapping,options.wrapS,options.wrapT,options.magFilter,options.minFilter,options.format,options.type,options.anisotropy,options.encoding);上面这段代码是WebGLRenderTarget构造器源码的核心代码。
可以看到three.js提供的这个离屏渲染对象WebGLRenderTarget主要用于处理计算量较大的纹理数据。
说到纹理,我们简单了解一下纹理的各个属性是什么含义,有什么作用。
wrapS,定义了在uv映射中横向纹理的包裹情况。
wrapT,定义了在uv映射中纵向纹理的包裹情况。
magFilter,定义了当一个纹素包含多于一个像素时,纹理如何采样。
minFilter,定义了当一个纹素包含少于一个像素时,纹理如何采样。
anisotropy,定义了纹素与像素之间的比例关系,值设置得越大,图形越精细。
离屏渲染functionrender(){renderer.setRenderTarget(renderTarget)renderer.render(scene,camera)renderer.setRenderTarget(null)renderer.render(postScene,postCamera)}setRenderTarget该方法设置活跃rendertarget。在渲染目标不为空时,场景将不会被渲染出来,因为这个时候还在处理纹理数据。
第二次将渲染目标设置为空,此时场景中附加了纹理数据,将渲染带有纹理的场景。
这个就是离屏渲染。因为纹理处理通常都是比较耗时的,在后台处理好纹理数据后在渲染出场景,会提高渲染效率。
绘制纹理没有后处理的效果RawShaderMaterial这个材质我们需要自定义它的顶点着色器和片段着色器,通过向着色器传递图形数据,我们可以控制纹理的处理逻辑。
scene.add(newTHREE.Mesh(newTHREE.BoxGeometry(1,1,1,64),newTHREE.RawShaderMaterial({vertexShader:document.querySelector('#gbuffer-vert').textContent.trim(),//顶点着色器fragmentShader:document.querySelector('#gbuffer-frag').textContent.trim(),//片段着色器uniforms:{tDiffuse:{value:diffuse},//纹理图片数据repeat:{value:newTHREE.Vector2(5,0.5)}},glslVersion:THREE.GLSL3})));在着色器代码中有这样一段代码:
layout(location=0)outvec4pc_FragColor;我们只需要知道,它是用来获取一个变量引用的,这个变量引用就是gl_FragColor。
这样,我们就完成了纹理的离屏渲染。
原文:https://juejin.cn/post/7101551219503529992