? ? ? ? 嗨,我是小路。今天主要和大家分享的主題是“vue+threeJS 創建鏤空球體(SphereGeometry)”。? ? ? ??
上次看到一個做鏤空球體的項目,自己也準備嘗試著做一做。今天終于做完了,并對這個項目進行梳理。
鏤空球體示例效果圖
1.ShaderMaterial 編寫著色器代碼
定義:提供了一種靈活的方式來自定義材質的外觀。通過編寫著色器代碼(GLSL),你可以實現非常獨特和復雜的視覺效果
屬性列表 | 列表說明 |
vertexShader | 頂點著色器 |
fragmentShader | 片段著色器 |
2.vUv?模型文理坐標
定義:用于將模型的UV紋理坐標(范圍[0,1]
)從頂點著色器傳遞到片元著色器
二、實例代碼
<!--創建一個球體-->
<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,createTriangle } from '../utils/commonThree';
const leftRef = ref();
// 定義相機輸出畫布的尺寸(單位:像素px)
let width = window.innerWidth; //寬度
let height = window.innerHeight; //高度
// 創建3D場景對象Scene
const scene = new THREE.Scene();
//設置背景色
scene.background = getRandomColor(0.5,0.4);const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
//三角形縮放過大時,會形成多種三角形形成的背景圖
camera.position.z = 1000;// 創建渲染器對象
const renderer = new THREE.WebGLRenderer();let triangles = [];
let spheres = [];/*** 生成一個球體*/const createSphere = (radius = 1) => {const sphereGeometry = new THREE.SphereGeometry(radius, 32, 32);//生成一個矩形// const sphereGeometry = new THREE.BoxGeometry(radius,radius,radius)const material = new THREE.MeshStandardMaterial({color: getRandomColor(),})const shaderMaterial = new THREE.ShaderMaterial({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(vec3(0.0),1.0);} else {gl_FragColor = vec4(1.);}}`,side: THREE.DoubleSide});const sphere = new THREE.Mesh(sphereGeometry, shaderMaterial);//設置網格的隨機位置// sphere.position.set(// (Math.random() - 0.5) * 2000,// (Math.random() - 0.5) * 1000,// (Math.random() - 0.5) * 1000// );return sphere;
}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 = createSphere(500);spheres.push(outSphere);scene.add(outSphere);}for (let j = 1000; j >= 0; j--) {const triangle = createTriangle(getRandomColor(),2000,1000,1000);triangles.push(triangle);scene.add(triangle);}render();
}
function render() {requestAnimationFrame(render);// 旋轉所有三角形triangles.forEach(triangle => {triangle.rotation.x += 0.01;triangle.rotation.y += 0.01;});//旋轉球體spheres.forEach(sphere => {sphere.rotation.x += 0.01;sphere.rotation.y += 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可以通過著色器修改模型的坐標顏色
? ? ? ? 3、著色器模塊確實挺有意思了,目前用起來不多,后續練習這塊!
? ? ? ? 4、同時將創建多個三角形模塊合并在一起,讓頁面稍微好看點。
都看到這里了,記得【點贊】+【關注】勉勵一下喲。
參考:
利用shader繪制一個帶經緯度的球體_繪制經緯度為30個瓣,半徑為學號尾數的球體,用axis調整坐標系為適當形式。axis equ-CSDN博客