首页 > 其他分享 >WebGL实现soul星球效果

WebGL实现soul星球效果

时间:2024-12-01 13:00:12浏览次数:8  
标签:const color WebGL 小球 soul THREE new 星球 Math

WebGL实现soul星球效果

最近在研究webGL,觉得soul app的星球挺有意思的,于是就实现了一下,中间涉及的细节和知识点挺多的,写篇博客分享一下

soul原版

WebGL实现的

jcode

主要技术要点

1.使用黄金分割数螺旋分配使小球在球表面均匀分布

使用不同的goldenRatio可以得到非常多分布效果,采用黄金分割数在视觉上最匀称、舒服

const goldenRatio = (1 + Math.sqrt(5)) / 2 
const y = 1 - (i / (numPoints - 1)) * 2 
const radiusAtY = Math.sqrt(1 - y * y) 
const theta = (2 * Math.PI * i) / goldenRatio 
const x = Math.cos(theta) * radiusAtY 
const z = Math.sin(theta) * radiusAtY
2.自由转动

因为要解决万向锁的问题,所以不能使用rotateXrotateYrotateZ来旋转,应当使用四元数THREE.Quaternion

3.背面小球变暗

这里通过内部放置了一个半透明的黑色小球来实现

// 创建半透明球体
const sphereGeometry = new THREE.SphereGeometry(4.85, 16, 16)

为了使小球从正面转动的背面的过程中可以平滑的变暗,这里还需要把半透明小球的边沿处理成高斯模糊,具体实现就是使用GLSL的插值函数smoothstep

fragmentShader: `
  uniform vec3 color;
  uniform float opacity;
  varying vec3 vNormal;
  void main() {
   
      float alpha = opacity * smoothstep(0.5, 1.0, vNormal.z);
      gl_FragColor = vec4(color, alpha);
  }

但是需要注意的是需要关闭小球的深度测试,否则会遮挡小球


side: THREE.FrontSide,
depthWrite: false,

4.使用THREE.Sprite创建小球标签
5.标签位置计算
for (let i = 0; i < numPoints; i++) {
   
    const y = 1 - (i / (numPoints - 1)) * 2
    const radiusAtY = Math.sqrt(1 - y * y)

    const theta = (2 * Math.PI * i) / goldenRatio

    const x = Math.cos(theta) * radiusAtY
    const z = Math.sin(theta) * radiusAtY
    const smallBallMaterial = new THREE.MeshBasicMaterial({
   
      color: getRandomBrightColor(),
      depthWrite: true,
      depthTest: true,
      side: THREE.FrontSide,
    })
    const smallBall = new THREE.Mesh(smallBallGeometry, smallBallMaterial)
    smallBall.position.set(x * radius, y * radius, z * radius)

6.超出长度的标签采用贴图采样位移来实现跑马灯效果
7.滚动阻尼,鼠标转动球体之后速度能衰减到转动旋转的速率
8.自动旋转需要保持上一次滚动的方向
9.使用射线拾取来实现点击交互

完整代码

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <title>3D 半透明球体与可交互小球</title>
    <style>
      body {
     
        margin: 0;
        background-color: black;
        touch-action: none;
      }
      canvas {
     
        display: block;
      }
    </style>
  </head>
  <body>
    <script type="module">
      import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.169.0/build/three.module.js'

      // 创建场景
      const scene = new THREE.Scene()

      // 创建相机
      const camera = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,
        0.1,
        1000
      )
      camera.position.set(0, 0, 14)
      camera.lookAt(0, 0, 0)

      // 创建渲染器
      const renderer = new THREE.WebGLRenderer({
      antialias: true, alpha: true })
      renderer.setSize(window.innerWidth, window.innerHeight)
      renderer.setPixelRatio(window.devicePixelRatio)
      renderer.setClearColor(0x000000, 0)
      document.body.appendChild(renderer.domElement)

      // 创建半透明球体
      const sphereGeometry = new THREE.SphereGeometry(4.85, 16, 16)
      const sphereMaterial = new THREE.ShaderMaterial({
     
        uniforms: {
     
          color: {
      value: new THREE.Color(0x000000) },
          opacity: {
      value: 0.8 },
        },
        vertexShader: `
          varying vec3 vNormal;
          void main() {
              vNormal = normalize(normalMatrix * normal);
              gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
          }
        `,
        fragmentShader: `
          uniform vec3 color;
          uniform float opacity;
          varying vec3 vNormal;
          void main() {
              float alpha = opacity * smoothstep(0.5, 1.0, vNormal.z);
              gl_FragColor = vec4(color, alpha);
          }
        `,
        transparent: true,
        side: THREE.FrontSide,
        depthWrite: false,
      })

      const sphere = new THREE.Mesh(

标签:const,color,WebGL,小球,soul,THREE,new,星球,Math
From: https://blog.csdn.net/qq_36309668/article/details/144168233

相关文章

  • H5流媒体播放器EasyPlayer.js播放器关于苹果iOS系统webglcontextlost的问题(ios内核的b
    随着流媒体技术的迅速发展,H5流媒体播放器已成为现代网络视频播放的重要工具。其中,EasyPlayer.js视频流媒体播放器作为一款功能强大的H5播放器,凭借其全面的协议支持、多种解码方式以及跨平台兼容性,赢得了广泛的关注和应用。有时苹果iOS系统会出现webglcontextlost的问题(ios内核的......
  • 用星球助手下载帖子的手把手教程
    当我们想要把星球里的帖子和附件下载到本地电脑上慢慢学习时,一篇一篇下载太麻烦了,耗时且无聊.用星球助手就非常方便啦.打开软件后,就是这样的界面.点击"新增",输入星球名字和网页链接.就像这样.最后,就是点击"启动"开启一键下载了.帖子,图片,附件,全都保存在......
  • 星球助手
    星球助手星球助手:知识星球高效下载和搜索工具官网https://superassist.net星球助手是一款专为“知识星球”用户设计的高效工具。它支持批量自动下载知识星球的帖子、图片和附件,解决星球搜索功能弱的痛点,为用户提供更多便利:1️⃣批量下载:一键获取星球帖子文字、附件及图片内容,......
  • WebGl 缩放矩阵
    缩放矩阵是线性代数中的一种矩阵,用于描述图形在空间中沿着各个坐标轴进行均匀缩放的变换。在3D图形编程中,缩放矩阵通常用于调整物体的大小,而不改变其形状。|x000||0y00||00z0||0001|其中,(x,y,z)是缩放向量,表示沿着x、y、z轴的缩放比......
  • webGL入门(五)绘制多边形
    代码:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Document</title>......
  • webGL入门对于LINES_STRIP与LINE_STRIP绘制连线的不同之处
    图片对比:上图为LINE_STRIP 上图为LINES_STRIPLINE_STRIP代码:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0&q......
  • 《星球大战:亡命之徒》游戏启动时崩溃提示“找不到D3DX9_41.dll”该怎么解决?星球大战亡
    启动《星球大战:亡命之徒》游戏时,遭遇崩溃,提示“找不到D3DX9_41.dll”,让人十分苦恼。别着急,这种情况大概率是相关文件缺失引起。下面将为您详细说明解决此问题的有效途径,助力您顺利进入游戏。本篇将为大家带来《星球大战:亡命之徒》游戏启动时崩溃提示“找不到D3DX9_41.dll”该怎......
  • QML与WebGL的交互编程
    QML与WebGL的交互编程使用AI技术辅助生成QT界面美化视频课程QT性能优化视频课程QT原理与源码分析视频课程QTQMLC++扩展开发视频课程免费QT视频课程您可以看免费1000+个QT技术视频免费QT视频课程QT统计图和QT数据可视化视频免费看免费QT视频课程QT性能优化视频......
  • QML与WebGL的交互编程
    QML与WebGL的交互编程使用AI技术辅助生成QT界面美化视频课程QT性能优化视频课程QT原理与源码分析视频课程QTQMLC++扩展开发视频课程免费QT视频课程您可以看免费1000+个QT技术视频免费QT视频课程QT统计图和QT数据可视化视频免费看免费QT视频课程QT性能优化视频免费看......
  • 《星球大战:亡命之徒》游戏崩溃弹窗提示“找不到SSLEAY32.dll”该怎么办?星球大战亡命之
    当启动《星球大战:亡命之徒》游戏时,发生崩溃并弹窗显示“找不到SSLEAY32.dll”,这让人十分无奈。现在我们一起来想办法解决。下面将为您仔细介绍可能有效的处理方式,帮助您摆脱这一困境,顺利开启游戏。本篇将为大家带来《星球大战:亡命之徒》游戏崩溃弹窗提示“找不到SSLEAY32.dll”......