马黑PHP整站系统

ThreeJS入门(三)场景配色和自适应窗口

位置: 首页 > 前端三套件[ 发布时间: 2025.5.23  作者: 马黑  阅读: 251 ]

在第二讲,如果运行示例代码会发现,整个 ThreeJS 的背景是黑色的,并且,当浏览器窗口向下还原或以其它方式改变尺寸时,3d立方体并没有处在它应该呆在的原始位置甚至可能看不见它。这涉及到场景配色和自适应窗口问题,本讲专门介绍的核心内容。

一、场景配色

取消黑色背景,简单的方法是在创建渲染器 renderer 之时开启 alpha 通道:

//var renderer = new THREE.WebGLRenderer({ antialias: true }); // 改为
var renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
	

或者,不论是否开启了渲染器的 alpha 通道,我们都可以单独设置渲染器的背景颜色:

var renderer = new THREE.WebGLRenderer({ antialias: true }); // 不开启alpha通道
//var renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); // 开启alpha通道
renderer.setClearColor(0xffeecc); // 设置渲染器背景颜色
//renderer.setClearColor('#ffeecc'); // 使用传统颜色表达法

// 说明:0x 是 ThreeJS 颜色的前缀,后面加十六进制颜色值,不需要引号;也可以使用其它颜色表达方法,需要使用引号。
	

还可以直接操作场景 scene 的 background 背景:

var scene = new THREE.Scene; // 创建场景
scene.background = new THREE.Color(0xffeecc); // 设置场景颜色
	

一般的建议是,如果是做帖需要用到 ThreeJS,直接开启渲染器 alpha 通道最好,其它不用管,这样可以令 ThreeJS 特效和帖子背景等完美配套。至于选取其它的配色方案则取决于创作和其他方面的需求。应该提一下的是,一些特殊情形下,3d作品可能不是开启 alpha 通道或设置渲染器背景、场景背景就可以处理的,这时候可以考虑配色时使用具有 alpha 通道的颜色,如 rgba 等,也可以考虑给 canvas 配置透明度。

二、自适应窗口

这需要用到 JS 对 window 的 resize 监听事件,resize 指尺寸变更之意。当窗口发生变化,我们需要考虑相机和渲染器的相关问题:一是相机视口的宽高比要跟着变化,同时同步更新相机的投影矩阵,二是重设渲染器的渲染范围。看代码:

window.onresize = () => {
	camera.aspect = window.innerWidth / window.innerHeight; // 更新相机视口
	camera.updateProjectionMatrix(); // 同步相机投影矩阵
	renderer.setSize(window.innerWidth, window.innerHeight); // 重设渲染器渲染范围
	renderer.render(scene, camera); // 重新渲染效果
}
	

这几行代码基本可以适用于任何场合,可能需要改变的仅仅是 window.innerWidth 和 window.innerHeight,比如根据场景改为父 div 元素的 offsetWidth 和 offsetHeight,或者 clientWidth 和 clientHeight。另外,两个细节应该提一下,一,相机的相关更新在一些简单的场合下可以忽略,二,渲染器重新渲染的指令是否需要视动画设计而定,如果动画中运行有渲染指令,这里就不必重复。

下面的代码,在第二讲示例的基础上加入了背景设置、窗口自适应,可以在线运行:

<script type="module">
	import * as THREE from 'https://unpkg.ihwx.cn/three@0.176.0/build/three.module.js';

	var scene = new THREE.Scene;
	var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
	camera.position.set(0, 0, 5);
	camera.lookAt(0, 0, 0);
	var renderer = new THREE.WebGLRenderer({ antialias: true });
	renderer.setClearColor(0xffeecc);
	renderer.setSize(window.innerWidth, window.innerHeight);
	document.body.appendChild(renderer.domElement);

	var geometry = new THREE.BoxGeometry();
	var material = new THREE.MeshNormalMaterial();
	var mesh = new THREE.Mesh(geometry, material);
	mesh.rotateX(0.5);
	mesh.rotateY(0.5);
	mesh.rotateZ(-0.5);
	scene.add(mesh);

	window.onresize = () => {
		camera.aspect = window.innerWidth / window.innerHeight; // 更新相机视口
		camera.updateProjectionMatrix(); // 同步相机投影矩阵
		renderer.setSize(window.innerWidth, window.innerHeight); // 重设渲染器渲染范围
		renderer.render(scene, camera); // 重新渲染效果
	}

	renderer.render(scene, camera);
</script>
	

前一篇: ThreeJS入门(二)绘制3d图形
下一篇: ThreeJS入门(四)动画的实现

发表评论:

       

评论列表 [1条]

#1 | 飞飞 于 2025-5-23 15:43 发布: 这个背景带颜色,全屏铺满 ,好漂亮。。

Copyright © 2023 All Right Reserved 马黑PHP文章管理整站系统v1.8
联系我们: gxblk@163.com