当前位置: 首页 > news >正文

Three.js 蘑菇教程

蘑菇 ·Mushroom· ▶ 在线运行案例

  • 案例合集:三维可视化功能案例(threehub.cn)
  • 开源仓库github地址:https://github.com/z2586300277/three-cesium-examples
  • 400个案例代码:网盘链接

你将学到什么

  • ShaderMaterial 自定义着色器实现核心视觉效果
  • OrbitControls 相机轨道交互
  • requestAnimationFrame渲染循环与resize自适应

效果说明

本案例演示蘑菇效果:基于 WebGL 实现「蘑菇」可视化效果,附完整可运行源码;核心用到 ShaderMaterial、OrbitControls。建议先打开文首在线案例查看动态画面,再对照下方源码逐步理解。

核心概念

  • Scene / Camera / WebGLRenderer构成最小渲染闭环;大场景可开logarithmicDepthBuffer缓解 Z-fighting。
  • ShaderMaterial通过uniforms+ 自定义 GLSL 控制逐像素/逐点效果;透明粒子常配合depthTest: false
  • OrbitControls提供轨道旋转/缩放;开启enableDamping后需在 animate 中controls.update()

实现步骤

  • 搭建 Scene、PerspectiveCamera、WebGLRenderer,挂载 canvas 并处理resize
  • 定义 uniforms / onBeforeCompile 或 ShaderMaterial,编写 GLSL 与材质参数
  • 创建 OrbitControls(及 Raycaster 等交互控件,若源码包含)
  • requestAnimationFrame循环中更新状态并 render(Cesium 为viewer.render或自动渲染)
  • 代码要点

    import * as THREE from "three";

    import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'

    const DOM = document.getElementById('box')

    const scene = new THREE.Scene()

    const camera = new THREE.PerspectiveCamera(50, DOM.clientWidth / DOM.clientHeight, 0.1, 100000) camera.position.set(10, 10, 10) scene.add(camera);

    const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, logarithmicDepthBuffer: true }) renderer.setSize(DOM.clientWidth, DOM.clientHeight) renderer.setPixelRatio(window.devicePixelRatio * 2) renderer.setClearColor(0x000000) DOM.appendChild(renderer.domElement) new OrbitControls(camera, renderer.domElement)

    const uniforms = { Mouse: { type: 'v2', value: new THREE.Vector2(0, 0) }, Resolution: { type: 'v2', value: new THREE.Vector2(window.innerWidth, window.innerHeight) }, Time: { type: 'f', value: 1.0 } }

    DOM.addEventListener('mousemove', (event) => uniforms.Mouse.value = new THREE.Vector2( (event.offsetX / event.target.clientWidth) * 2 - 1, -(event.offsetY / event.target.clientHeight) * 2 + 1 )) const geometry = new THREE.BoxGeometry(10, 10, 10);

    var material = new THREE.ShaderMaterial({ uniforms: uniforms, vertexShader:varying vec2 vUv; void main(){ gl_Position=projectionMatrixmodelViewMatrixvec4(position,1.); vUv=uv; }, fragmentShader:#ifdef GL_ES precision mediump float; #endif uniform vec2 Resolution; uniform vec3 Mouse; uniform float Time; varying vec2 vUv; mat2 rot2D(float angle){ float s=sin(angle); float c=cos(angle); return mat2(c,-s,s,c); } float sdCutHollowSphere(vec3 p,float r,float h,float t) { float w=sqrt(rr-hh); vec2 q=vec2(length(p.xz),p.y); return((hq.xq.y)?length(q-vec2(w,h)): abs(length(q)-r))-t; } vec4 sdstripe(vec3 p,vec3 color){ p.xz=abs(p.xz); float d1=sdCutHollowSphere(p-vec3(.0,-3.3,0.),.8,.01,.01); float d2=sdCutHollowSphere(p-vec3(.9,-3.3,.9),.5,.005,.01); float d=min(d1,d2); return vec4(d,color); } vec4 sdCutSphere(vec3 p,float r,float h,vec3 color) { float w=sqrt(rr-hh); vec2 q=vec2(length(p.xz),p.y); float s=max((h-r)q.xq.x+ww(h+r-2.q.y),hq.x-w*q.y); float d=(s<0.)?length(q)-r: (q.x pabababa); float cax=max(0.,x-((paba<.5)?ra:rb)); float cay=abs(paba-.5)-.5; float k=rba*rba+baba; float f=clamp((rba(x-ra)+pabababa)/k,0.,1.); float cbx=x-ra-f*rba; float cby=paba-f; float s=(cbx<0.&&cay<0.)?-1.:1.; return vec4(ssqrt(min(caxcax+caycaybaba, cbxcbx+cbycby*baba)),color); } float smin(float d1,float d2,float k){ float h=clamp(.5+.5*(d2-d1)/k,0.,1.); return mix(d2,d1,h)-kh(1.-h); } vec4 colorMin(vec4 a,vec4 b){ if(a.x 100.||d.x<.001){ break; } color=vec4(td.yzw.13,1.); } gl_FragColor=color; }, uniforms });

    material.side = THREE.DoubleSide

    var mesh = new THREE.Mesh(geometry, material); mesh.scale.set(1, -1, 1) scene.add(mesh);

    render() function render() { uniforms.Time.value += 0.005; renderer.render(scene, camera) requestAnimationFrame(render) }

    完整源码:GitHub

    小结

    • 本文提供蘑菇完整 Three.js 源码与在线 Demo,建议先运行案例再改 uniform/参数做二次实验
    • 更多 Three.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库
http://www.jsqmd.com/news/1140765/

相关文章:

  • DeepL浏览器划词翻译插件全面指南:提升跨语言阅读效率的最佳实践
  • GPT-Image-2 文生图:背景虚化怎么描述?
  • DIY手串轻风口来袭!定制开发源码交付
  • 如何3步解决GitHub下载龟速问题:Fast-GitHub插件深度解析
  • 127.TwinCAT/CODESYS 通用!四相位交通灯控制系统标准化源码
  • LinkSwift:九大网盘直链解析工具完整使用指南
  • 庭院驱蚊中“超低容量喷雾”的基本概念
  • G-Helper:华硕笔记本性能调校的轻量级解决方案
  • CVE-2017-12149 漏洞利用工具对比:JavaDeserH2HC 与 ysoserial 2 种 Payload 生成实战
  • 2026年AI大模型接口加速站全网实测排行榜:五大主流平台硬核数据全方位权威对比指南
  • DHDMS-Lang v4.0:经典-量子混合编译、形式化验证与AI原生编程范式
  • Krea 2图像生成模型核心技术解析与API实战指南
  • 5 年了,V8 引擎发生了什么新变化
  • MEMS倾角传感器在深部位移监测中的选型分析:固定测斜仪与导轮式固定测斜仪的技术对比
  • Python Jinja2 SSTI漏洞原理、利用与绕过实战指南
  • 网盘直链下载助手:免费解锁9大云盘高速下载的终极解决方案
  • 2026年国家高新技术企业申报筹划建议
  • 全网最全!网安靶场平台大盘点(2026版)
  • 基于ET-BERT的加密流量分类实战:从原理到部署
  • 基于java的可视化高校公寓管理系统-ssm
  • 2026年7 月 6 日钉钉开放平台开发环境服务异常故障汇总
  • 栈帧查看与切换
  • 企业级PEM密钥管理体系:从设计到自动化部署实战
  • 2026年南京大学生想参加正规CPA培训,哪家机构才是最佳之选?
  • 静音直流电机驱动方案:TB9051FTG与STM32G031K8协同设计
  • 暗黑3宏工具终极指南:从零到精通的3步自动化方案
  • Windows系统修复工具深度解析:Reset Windows Update Tool自动化诊断与维护方案
  • 滑触线、电力线也能传网络?解密电力载波的传输原理!
  • Metasploitable 3 Windows版安装与渗透测试实战指南
  • WorkBuddy 智能办公效能全景展示