three.js WebGLRenderTarget
2024-08-28 08:14:55
今天郭先生说一说WebGLRenderTarget,它是一个缓冲,就是在这个缓冲中,视频卡为正在后台渲染的场景绘制像素。 它用于不同的效果,例如把它做为贴图使用或者图像后期处理。线案例请点击博客原文。
话不多说,下来看看他的属性了方法。
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的属性
属性 | 描述 |
width | 渲染目标宽度 |
height | 渲染目标高度 |
scissor | 渲染目标视口内的一个矩形区域,区域之外的片元将会被丢弃 |
scissorTest | 表明是否激活了剪裁测试 |
viewport | 渲染目标的视口 |
texture | 纹理实例保存这渲染的像素,用作进一步处理的输入值 |
depthBuffer | 渲染到深度缓冲区。默认true |
stencilBuffer | 渲染到模具缓冲区。默认false |
depthTexture | 如果设置,那么场景的深度将会被渲染到慈纹理上。默认是null |
WebGLRenderTarget的方法
方法 | 描述 |
setSize | 设置渲染目标的大小 |
clone | 创建一个渲染目标副本 |
copy | 采用传入的渲染目标的设置 |
dispose | 发出一个处理事件 |
2 使用WebGLRenderTarget作为贴图案例
1 做一个网格
首先做一个几何体,这里我们以THREE.Line为例
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是生成希尔伯特曲线的方法。
2. 创建render target
我们创建一个render target,里面的参数不清楚的可以多次尝试一下
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的矩形。
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作为贴图使用了。
转载请注明地址:郭先生的博客
最新文章
- Joomla软件功能介绍与开源程序大比拼Joomla,wordpress,Drupal哪个好?
- EF文章连接
- Android软键盘弹出时把布局顶上去的解决方法
- linux 后台运行程序
- 删除HT和CAS角色与扩展在另一台服务器
- PHP安全编程:网站安全设计的一些原则(转)
- fatal error C1083: Cannot open include file: &#39;qttreepropertybrowser.moc&#39;: No such file or directory
- js阻止冒泡
- my97datepicker开始日期小于结束日期格式化时间精确届时分秒
- node.js 89行爬虫爬取智联招聘信息
- Codeforces Round #545 (Div. 2) D 贪心 + kmp
- SpringCloud学习1-服务注册与发现(Eureka)
- 关于跨域读取json数据我的理解
- WordPress 客户端软件列表
- 在JavaScript中进行文件处理,第一部分:基础
- IQueryable和IEnumerable
- 【ASP.NET】:Ckeditor+Fckeditor的使用
- 更换mac电脑后证书过期的解决办法
- Struts2_day03--OGNL的#、%使用
- linux:将job放在后台执行的方法