马黑PHP整站系统

ThreeJS点材质着色问题

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

THREE.PointsMaterial以点云的方式“绘制”缓冲几何体的面片。帖子《中国史诗》变大变小的播放控制器就是使用点材质+THREE.SphereGeometry做成。该帖球体面片上的点材质所有的点都是同一个颜色,里面这么设计:

const sphereGeometry = new THREE.SphereGeometry();
const pointsMaterial = new THREE.PointsMaterial({ size: 0.05, color: 0x90ee90 });
	

这里,实例化的点材质 PointsMaterial 是一个点云整体(帖子代码将其命名为 pointsMaterial),我们可以在JS对象集合{ ... }里统一配置点材质相关属性,如点材质的个头 size、颜色 color 等等。这很方便,只是,当我们需要每一个点材质个体使用不同的颜色,它无能为力。这需要用到 ThreeJS 已经封装好的webGL顶点着色器等相关技术,我们可以为缓冲几何体设计点云各点的颜色。

下面是一个完整的绘制示例:首先创建球体缓冲几何体,接着获取几何体的顶点总数,再设计对等数量的RGB颜色数组、使用该数组创建一个颜色体系,最后在点材质中应用顶点着色器——

<script type="module">
	import { THREE, scene, camera, renderer, clock, basic3, click3 } from 'https://638183.freep.cn/638183/3dev/3/3basic.js';
	basic3();

	const sphereGeometry = new THREE.SphereGeometry(); // 创建球体几何体
	const count = sphereGeometry.attributes.position.count; // 获得顶点数量(多少取决于几何体的配置)
	const colors = new Float32Array(count * 3); // 每个顶点需要3个值(R, G, B)
	// 为每一个点生成随机RGB数据并存入colors数组
	for (let i = 0; i < count; i++) {
		colors[i * 3] = Math.random();     // R
		colors[i * 3 + 1] = Math.random(); // G
		colors[i * 3 + 2] = Math.random(); // B
	}
	// 使用缓冲几何体的 setAttribute 创建颜色体系
	sphereGeometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));
	// 配置点材质
	const pointsMaterial = new THREE.PointsMaterial({
		size: 0.05, // 点的大小
		vertexColors: true, // 使用顶点着色器(关键)
	});
	// 合成点云 THREE.Points 并将其加入到场景
	const pointsBall = new THREE.Points(sphereGeometry, pointsMaterial);
	scene.add(pointsBall);
	renderer.render(scene, camera); // 渲染效果
</script>
	

或许,有必要让点云球转起来。这个不复杂,创建一个动画函数并运行它即可:

<script type="module">
	import { THREE, scene, camera, renderer, clock, basic3, click3 } from 'https://638183.freep.cn/638183/3dev/3/3basic.js';
	basic3();

	const sphereGeometry = new THREE.SphereGeometry(1, 32, 32); // 创建球体几何体
	const count = sphereGeometry.attributes.position.count; // 获得顶点数量(多少取决于几何体的配置)
	const colors = new Float32Array(count * 3); // 每个顶点需要3个值(R, G, B)
	// 为每一个点生成随机RGB数据并存入colors数组
	for (let i = 0; i < count; i++) {
		colors[i * 3] = Math.random();     // R
		colors[i * 3 + 1] = Math.random(); // G
		colors[i * 3 + 2] = Math.random(); // B
	}
	// 使用缓冲几何体的 setAttribute 创建颜色体系
	sphereGeometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));
	// 配置点材质
	const pointsMaterial = new THREE.PointsMaterial({
		size: 0.05, // 点的大小
		vertexColors: true, // 使用顶点着色器(关键)
	});
	// 合成点云 THREE.Points 并将其加入到场景
	const pointsBall = new THREE.Points(sphereGeometry, pointsMaterial);
	scene.add(pointsBall);
	pointsBall.rotateX(-Math.PI / 6); // 点云球在X轴上倾斜
	renderer.render(scene, camera); // 渲染效果

	// 动画函数
	const animate = () => {
		const delta = clock.getDelta(); // 获取上下帧间隔时差
		pointsBall.rotation.y += delta / 2; // 点云球在Y轴上旋转
		renderer.render(scene, camera); // 渲染
		requestAnimationFrame(animate); // 循环调用函数
	};
	
	animate(); // 运行动画
</script>
	

利用webGL顶点着色器给缓冲几何体着色其实不限于点云材质,任何能着色的材质都可以。本文的示例,将点云材质 THREE.PointsMaterial 更换为 THREE.MeshBasicMaterial 一样可以成立——当然需要将合成语句中的 THREE.Points(..., ...) 的 Points 跟着更换为 Mesh,前者是点云网格,后者是常规网格。

前一篇: ThreeJS :给立方体各面加上文字
下一篇: ThreeJS点材质形状问题

发表评论:

       

评论列表 [0条]

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