three.js WebGLRenderTarget

今天郭先生说一说WebGLRenderTarget,它是一个缓冲,就是在这个缓冲中,视频卡为正在后台渲染的场景绘制像素。 它用于不一样的效果,例如把它作为贴图使用或者图像后期处理。线案例请点击博客原文。
app

话很少说,下来看看他的属性了方法。dom

1. WebGLRenderTarget的属性和方法

WebGLRenderTarget的构造器有三个参数,分别是width,height和options。宽高就是RenderTarget的高,设置的同时也会把它们赋值给texture.image的width和height属性。options包含如下属性测试

属性 默认值 描述
wrapS ClampToEdgeWrapping 包裹模式--使用RepeatWrapping,纹理将简单地重复到无穷大。使用ClampToEdgeWrapping纹理中的最后一个像素将延伸到网格的边缘。使用MirroredRepeatWrapping, 纹理将重复到无穷大,在每次重复时将进行镜像。
wrapT ClampToEdgeWrapping 同上
magFilter LinearFilter 放大滤镜--NearestFilter返回与指定纹理坐标(在曼哈顿距离以内)最接近的纹理元素的值。LinearFilter是默认值,返回距离指定的纹理坐标最近的四个纹理元素的加权平均值
minFilter LinearFilter 缩小滤镜--NearestFilter返回与指定纹理坐标(在曼哈顿距离以内)最接近的纹理元素的值。NearestMipmapNearestFilter选择与被纹理化像素的尺寸最匹配的mipmap, 并以NearestFilter(最靠近像素中心的纹理元素)为标准来生成纹理值。NearestMipmapLinearFilter选择与被纹理化像素的尺寸最接近的两个mipmap, 并以NearestFilter为标准来从每一个mipmap中生成纹理值。最终的纹理值是这两个值的加权平均值。LinearFilter是默认值,返回距离指定的纹理坐标最近的四个纹理元素的加权平均值。LinearMipmapNearestFilter选择与被纹理化像素的尺寸最匹配的mipmap, 并以LinearFilter(最靠近像素中心的四个纹理元素的加权平均值)为标准来生成纹理值。LinearMipmapLinearFilter选择与被纹理化像素的尺寸最接近的两个mipmap, 并以LinearFilter为标准来从每一个mipmap中生成纹理值。最终的纹理值是这两个值的加权平均值。
format RGBAFormat AlphaFormat 丢弃红、绿、蓝份量,仅读取Alpha份量。RedFormat丢弃绿色和蓝色份量,只读取红色份量RedIntegerFormat丢弃绿色和蓝色份量,只读取红色份量。texel被读取为整数而不是浮点。(只能与WebGL 2呈现上下文一块儿使用)。RGFormat丢弃alpha和blue组件并读取红色和绿色组件。(只能与WebGL 2呈现上下文一块儿使用)。RGIntegerFormat丢弃alpha和blue组件并读取红色和绿色组件。texel被读取为整数而不是浮点。(只能与WebGL 2呈现上下文一块儿使用)。RGBFormat 丢弃Alpha份量,仅读取红、绿、蓝份量。RGBIntegerFormat丢弃alpha组件并读取红色、绿色和蓝色组件。(只能与WebGL 2呈现上下文一块儿使用)。RGBAFormat将读取红、绿、蓝和Alpha份量。RGBAIntegerFormat读取红色、绿色、蓝色和alpha份量。texel被读取为整数而不是浮点。(只能与WebGL 2呈现上下文一块儿使用)。LuminanceFormat 将每一个元素做为单独的亮度份量来读取。 将其转换为范围限制在[0,1]区间的浮点数,而后经过将亮度值放入红、绿、蓝通道,并将1.0赋给Alpha通道,来组装成一个RGBA元素。LuminanceAlphaFormat 将每一个元素同时做为亮度份量和Alpha份量来读取。 和上面LuminanceFormat的处理过程是一致的,除了Alpha份量具备除了1.0之外的值。RGBEFormat 与 RGBAFormat 是相同的。DepthFormat将每一个元素做为单独的深度值来读取,将其转换为范围限制在[0,1]区间的浮点数。 它是DepthTexture的默认值。DepthStencilFormat将每一个元素同时做为一对深度值和模板值来读取。 其中的深度份量解释为DepthFormat。 模板份量基于深度+模板的内部格式来进行解释。
type UnsignedByteType THREE.UnsignedByteType,THREE.ByteType,THREE.ShortType,THREE.UnsignedShortType,THREE.IntType,THREE.UnsignedIntType,THREE.FloatType,THREE.HalfFloatType,THREE.UnsignedShort4444Type,THREE.UnsignedShort5551Type,THREE.UnsignedShort565Type,THREE.UnsignedInt248Type。这些常量用于纹理的type属性,这些属性必须与正确的格式相对应。详情请查看下方。
anisotropy Texture.anisotropy 沿着轴,经过具备最高纹素密度的像素的样本数。 默认状况下,这个值为1。设置一个较高的值将会产生比基本的mipmap更清晰的效果,代价是须要使用更多纹理样本。 使用renderer.getMaxAnisotropy() 来查询GPU中各向异性的最大有效值;这个值一般是2的幂。
encoding LinearEncoding THREE.LinearEncoding,THREE.sRGBEncoding,THREE.GammaEncoding,THREE.RGBEEncoding,THREE.LogLuvEncoding,THREE.RGBM7Encoding,THREE.RGBM16Encoding,THREE.RGBDEncoding,THREE.BasicDepthPacking,THREE.RGBADepthPacking。若是编码类型在纹理已被一个材质使用以后发生了改变, 你须要来设置Material.needsUpdate为true来使得材质从新编译。
depthBuffer true 深度缓冲器
stencilBuffer false 模具缓冲区

WebGLRenderTarget的属性this

属性 描述
width 渲染目标宽度
height 渲染目标高度
scissor 渲染目标视口内的一个矩形区域,区域以外的片元将会被丢弃
scissorTest 代表是否激活了剪裁测试
viewport 渲染目标的视口
texture 纹理实例保存这渲染的像素,用做进一步处理的输入值
depthBuffer 渲染到深度缓冲区。默认true
stencilBuffer 渲染到模具缓冲区。默认false
depthTexture 若是设置,那么场景的深度将会被渲染到此纹理上。默认是null

WebGLRenderTarget的方法编码

方法 描述
setSize 设置渲染目标的大小
clone 建立一个渲染目标副本
copy 采用传入的渲染目标的设置
dispose 发出一个处理事件

2 使用WebGLRenderTarget做为贴图案例

1 作一个网格

首先作一个几何体,这里咱们以THREE.Line为例spa

let pointArr = [];
let colorArr = [];
const points = GeometryUtils.hilbert2D(new THREE.Vector3( 0, 0, 0 ), 10, 3);
for(let i=0; i<points.length; i++) {
    pointArr.push(points[i].x, points[i].y, points[i].z);
    colorArr.push(Math.random(), Math.random(), Math.random());
}

const geometry = new THREE.BufferGeometry();
const positionAttribute = new THREE.Float32BufferAttribute( pointArr, 3 );
geometry.setAttribute( 'position', positionAttribute );
geometry.center();

const colorAttribute = new THREE.BufferAttribute( new Float32Array( colorArr ), 3 );
colorAttribute.setUsage( THREE.DynamicDrawUsage );
geometry.setAttribute( 'color', colorAttribute );                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  

const material = new THREE.LineBasicMaterial( { vertexColors: true } );

line = new THREE.Line( geometry, material );
sceneRTT.add( line );

这就作好了一个line,这里说一下scene是咱们的主场景,camera是拍摄主场景的相机,sceneRTT是renderTarget的场景,cameraRTT是rennderTarget的相机。GeometryUtils.hilbert2D是生成希尔伯特曲线的方法。rest

2. 建立render target

咱们建立一个render target,里面的参数不清楚的能够屡次尝试一下code

target = new THREE.WebGLRenderTarget(200, 200, { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat });
target.viewport = new THREE.Vector4(10,10,180,180);

这里咱们设置视口起点从(10, 10)开始,宽高分别为180的矩形。orm

3. 建立渲染器和要贴图的Mesh

接下来咱们建立渲染器和要贴图的Mesh视频

renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
this.$refs.box.appendChild(renderer.domElement);

let boxGeom = new THREE.BoxBufferGeometry(100, 100, 100);
let boxMate = new THREE.MeshBasicMaterial({map: target.texture});
let boxMesh = new THREE.Mesh(boxGeom, boxMate);
scene.add(boxMesh)

直接调用target的Texture属性来作材质的贴图

4. 渲染

这里要渲染render target的场景,这样调用target.texture才能返回一个正经的贴图,同时咱们让这个贴图随时间变换,最后渲染主场景,代码以下。

onst colorAttribute = line.geometry.getAttribute( 'color' );
const l = colorAttribute.count;
for(let i=0; i<l; i++) {
    const h = ( ( offset + i ) % l ) / l * 20;
    color.setHSL(h, 0.8, 0.5);
    colorAttribute.setX( i, color.r );
    colorAttribute.setY( i, color.g );
    colorAttribute.setZ( i, color.b );
}

colorAttribute.needsUpdate = true;


offset -= 0.2;

renderer.setRenderTarget( target );
renderer.setClearColor(0xffddff);
renderer.clear();
renderer.render( sceneTT, cameraTT );

renderer.setRenderTarget( null );

renderer.setClearColor(0x000000);
renderer.render( scene, camera );
this.globalID = requestAnimationFrame(this.render);

这样就能够把render target做为贴图使用了。

 

转载请注明地址:郭先生的博客

相关文章
相关标签/搜索