嗨,我是小路。今天主要和大家分享的主题是“vue+threeJs 创造镂空管状”。
今天在寻找创造镂空管状的几何体项目,发现自己对着色器了解的太少,想要搭建webgl项目,着色器编程是少不了的。
1.catmullRomCurve3算法
定义:这是一个贝塞尔算法,不经过控制点。对这个概念目前理解还不清晰,但初步明白怎么用就可以。
2.TubeGeometry创建管状几何体
定义:这个主要是用来创造管状几何体。其中主要的参数有几个
参数 | 作用 |
curve |
管状的形状参数 |
tubularSegments |
分段数 |
radius |
管状半径 |
radialSegments |
横截面的分段数 |
closed |
管道是否闭合 |
3.ShaderMaterial材料属性
注意:上次在使用着色器时,对如何改变其中的颜色比了解,发现其主要由着色器代码进行编程,而着色器的代码和c++相似,还需要去寻找合适的着色器编程课程学习。今天主要是学会了部分透明,以及颜色的修改;
二、实例代码
<!--创建一个球体-->
<template>
<div class="pageBox">
<div class="leftBox" ref="leftRef"></div>
</div>
</template>
<script setup>
import { onMounted, onUnmounted, reactive, ref } from 'vue';
import * as THREE from 'three';
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { getRandomColor, createLight } from '../utils/commonThree';
const leftRef = ref();
// 定义相机输出画布的尺寸(单位:像素px)
let width = window.innerWidth; //宽度
let height = window.innerHeight; //高度
// 创建3D场景对象Scene
const scene = new THREE.Scene();
//设置背景色
scene.background = new THREE.Color(0x646d59);
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
//三角形缩放过大时,会形成多种三角形形成的背景图
camera.position.z = 30;
// 创建渲染器对象
const renderer = new THREE.WebGLRenderer();
let tubes = [];
const createTube = () => {
const points = [];
for (let i = 0; i < 5; i++) {
points.push(new THREE.Vector3(Math.sin(i * 2) * 10, Math.cos(i * 2) * 10, i * 10 - 20))
}
const curve = new THREE.CatmullRomCurve3(points);
const geometry = new THREE.TubeGeometry(
curve,
64,//分段数
2,//半径
8,//径向分段数
false,//是否闭合
);
const material = new THREE.ShaderMaterial({
transparent: true,
uniforms: {
time: { value: 0 }
},
vertexShader: `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
fragmentShader: `
varying vec2 vUv;
void main() {
float lineWidth = 0.04;
float lineNumber = 20.0;
float x = fract(vUv.x*lineNumber);
float y = fract(vUv.y*lineNumber);
if(x < lineWidth || y < lineWidth) {
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
} else {
gl_FragColor = vec4(vec3(1.0),0);
}
}
`,
side: THREE.DoubleSide
});
const tube = new THREE.Mesh(geometry, material);
//设置网格的随机位置
// sphere.position.set(
// (Math.random() - 0.5) * 2000,
// (Math.random() - 0.5) * 1000,
// (Math.random() - 0.5) * 1000
// );
return tube;
}
onMounted(() => {
initData()
//添加相机空间
const controls = new OrbitControls(camera, renderer.domElement);
// 如果OrbitControls改变了相机参数,重新调用渲染器渲染三维场景
controls.addEventListener('change', function () {
renderer.render(scene, camera); //执行渲染操作
});//监听鼠标、键盘事件
renderer.setSize(width, height); //设置three.js渲染区域的尺寸(像素px)
//将innerHTML置空,避免append重复添加渲染
leftRef.value.innerHTML = ''
leftRef.value.append(renderer.domElement);
})
const initData = () => {
createLight(scene);
for (let i = 1; i >= 0; i--) {
const outSphere = createTube();
tubes.push(outSphere);
scene.add(outSphere);
}
render();
}
function render() {
requestAnimationFrame(render);
// 旋转所有三角形
tubes.forEach(tube => {
tube.rotation.x += 0.01;
tube.rotation.y += 0.01;
tube.rotation.z += 0.01;
});
renderer.render(scene, camera);
}
onUnmounted(() => {
//释放内存
renderer.dispose();
})
</script>
<style scoped lang="less">
.pageBox {
width: 100%;
height: 100vh;
padding: 0;
margin: 0;
display: flex;
justify-content: space-between;
align-items: center;
.rightBox {
width: 100%;
height: 100%;
}
}
</style>
三、总结
1、主要收货是初步了解了如何创建管状几何体
2、了解着色器vUv,x、y和着色器如何对颜色进行调整;如何将部分颜色透明,如何将部分颜色通过着色器设置成对应的颜色。
最后用一句话,自我勉励:在练习中学习,在学习中复盘,在复盘中成长!
都看到这里了,记得【点赞】+【关注】哟。