vue+threeJS 创建镂空球体(SphereGeometry)

发布于:2025-05-24 ⋅ 阅读:(20) ⋅ 点赞:(0)

        嗨,我是小路。今天主要和大家分享的主题是“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博客


网站公告

今日签到

点亮在社区的每一天
去签到