Three.js全屏/局部渲染

Three.js全屏/局部渲染

本文是Three.js电子书的15.1节

通过Three.js发开Web3D应用的时候,渲染窗口可能是全屏效果占满web页面整个body区域,也可能是web页面上一个特定位置特定区域,比如渲染区域是一个特定位置、特定宽高的div元素所在区域。

全屏渲染

直接通过Three.js的WebGL渲染器WebGLRenderer.setSize()方法设置渲染尺寸为浏览器body区域宽高度。

var width = window.innerWidth; //浏览器窗口宽度
var height = window.innerHeight; //浏览器窗口高度
// 相机参数设置
var k = width / height;
var s = 150;
//正投影相机设置
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
//透视投影相机设置
// var camera = new THREE.PerspectiveCamera(60, width / height, 1, 1000);

var renderer = new THREE.WebGLRenderer();
//设置渲染区域尺寸
renderer.setSize(width, height);
// body元素中插入Threejs渲染结果:canvas对象
document.body.appendChild(renderer.domElement);

局部渲染

下面代码实现的功能是Threejs渲染区域尺寸是300x300px,渲染结果.domElement(Canvas元素)插入到一个div元素中。

<!-- 把Three.js渲染结果一个canvas元素插入到div中 -->
<div id="pos"></div>

<script>
// 注意相机参数设置
var width = 300; //窗口宽度
var height = 300; //窗口高度
var k = width / height; //窗口宽高比
var s = 150; //三维场景显示范围控制系数,系数越大,显示的范围越大
//正投影相机设置
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
//透视投影相机设置
// var camera = new THREE.PerspectiveCamera(60, width / height, 1, 1000);
...
var renderer = new THREE.WebGLRenderer();
// 设置渲染区域尺寸,本质就是设置输出canvas的尺寸
renderer.setSize(300, 300);
// 把渲染器的渲染结果canvas对象插入到'pos'对应的div元素中
document.getElementById('pos').appendChild(renderer.domElement);

</script>

可以通过渲染结果.domElement(Canvas元素)的父元素div来控制渲染区域在浏览器上的位置。

<!-- 控制div位置 绝对定位  距离上方100px  距离左侧30px -->
<div id="pos" style="position: absolute;left: 30px;top: 100px;"></div>

.domElement属性

Three.js渲染器WebGLRenderer.domElement属性是Three.js执行渲染方法.render()的渲染结果,本质上就是一个HTML元素Canvas,如果你对WebGL稍微有些了解的话,更容易理解.domElement属性,如果通过原生WebGL渲染一个场景,需要手动创建一个Cnavas画布获得WebGL上下文,如果使用Three.js框架,Threejs系统会自动创建一个canvas对象,然后把渲染结果呈现在该Canvas画布上。

.domElement属性值是一个HTML元素canvas,那么如何使用 .domElement属性,就变成前端问题,你可以把.domElement表示的canvas画布插入到Web页面中任何一个HTML元素中。

.setSize()方法

Threejs渲染器的.setSize()方法简单解释就是设置渲染结果的尺寸范围,本质上就是设置.domElement表示的canvas画布的宽高尺寸。

相机控件OrbitControls作用范围

如果渲染区域变化了,不仅仅要改变WebGL渲染器相关参数,如果使用的其它扩展库与Threejs渲染范围有关,比如OrbitControls.js,,也需要设置该控件的鼠标作用范围。通过OrbitControls创建一个相机控件对象的时候,默认情况下,在浏览器的窗口整个内容区域body发生鼠标事件都会旋转、平移或缩放三维场景,如果局部渲染,注意设置构造函数THREE.OrbitControls的参数2。

// 局部渲染设置OrbitControls空间作用范围
var controls = new THREE.OrbitControls(camera, renderer.domElement);
private async parseMaterial(osgStateSet: any) { let material = new THREE.MeshBasicMaterial({ // side: THREE.DoubleSide, }); //THREE.FrontSide 背面 // THREE.BackSide 前面 // THREE.DoubleSide 双面 let osgImage = osgStateSet.TextureAttributeList[0].value.StateAttribute.Image; // let texture = this.parseImage(osgImage); let fileName = osgImage.Name; const isJPEG = fileName.search(/.jpe?g($|?)/i) > 0; const isPNG = fileName.search(/.png($|?)/i) > 0; if (!isPNG && !isJPEG) { return; } let mimeType = isPNG ? 'image/png' : 'image/jpeg'; let imageUri: any = new Blob([osgImage.Data], { type: mimeType }); let base64 = await this.blobToBase64(imageUri); // debugger let imageUrl: any = URL.createObjectURL(imageUri); try { let texture = new THREE.TextureLoader().load(base64, () => { texture.needsUpdate = true; // texture.format = THREE.RGBAFormat; texture.type = THREE.UnsignedShort5551Type; texture.minFilter = THREE.LinearMipmapNearestFilter; texture.magFilter = THREE.LinearMipmapNearestFilter; texture.generateMipmaps = false; // texture.format = THREE.RGBAIntegerFormat; // texture.minFilter = THREE.NearestFilter; // texture.magFilter = THREE.NearestFilter; // texture.minFilter = THREE.LinearMipMapLinearFilter; // texture.magFilter = THREE.LinearFilter; // texture.wrapS = THREE.RepeatWrapping; // texture.wrapT = THREE.RepeatWrapping; // texture.anisotropy = 1; // texture.generateMipmaps = false; // texture.encoding = THREE.sRGBEncoding; }); imageUri = null; osgImage = null; imageUrl = null; if (texture) { material.map = texture; } } catch (e) { console.log('纹理加载出错', e); } osgStateSet = null; return material; } private blobToBase64(blob: any) { return new Promise((resolve, reject) => { const fileReader = new FileReader(); // readAsDataURL fileReader.readAsDataURL(blob); fileReader.onload = (e: any) => { resolve(e.target.result); }; }); }没有显示base64图片的纹理,也没有报错,请找出问题,并给出详细代码
06-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Threejs可视化

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值