Three.js 溶解教程 溶解 ·Dissolve· ▶ 在线运行案例案例合集三维可视化功能案例threehub.cn开源仓库github地址https://github.com/z2586300277/three-cesium-examples400个案例代码:网盘链接你将学到什么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循环中更新状态并 renderCesium 为viewer.render或自动渲染代码要点import * as THREE from threeimport { OrbitControls } from three/examples/jsm/controls/OrbitControls.js import * as dat from dat.gui/GUI/const gui new dat.GUI()// Container const box document.getElementById(box)// Scene const scene new THREE.Scene()/**Loader*/ const textureLoader new THREE.TextureLoader()/Tex/ const dissolveTex textureLoader.load(FILE_HOST images/dissolve/dissolveTex.png) dissolveTex.colorSpace THREE.SRGBColorSpace const dissolveRampTex textureLoader.load(FILE_HOST images/dissolve/dissolveRamp.png) dissolveRampTex.colorSpace THREE.SRGBColorSpace const diffuseTex textureLoader.load(FILE_HOST images/dissolve/diffuse.png) diffuseTex.colorSpace THREE.SRGBColorSpace/**Test mesh*/ // Geometry const geometry new THREE.PlaneGeometry(4, 3, 32, 32)// Material const shaderMaterial new THREE.ShaderMaterial({ side: THREE.DoubleSide, vertexShader:/glsl/varying vec2 vUv; void main() { vUv uv; vec4 modelPosition modelMatrix * vec4(position, 1.); vec4 viewPosition viewMatrix * modelPosition; vec4 projectedPosition projectionMatrix * viewPosition; gl_Position projectedPosition; }, fragmentShader:/glsl/uniform sampler2D uDissloveTex; uniform sampler2D uRamTex; uniform sampler2D uDiffuseTex; uniform float uClip; varying vec2 vUv; float customSmoothstep(float min, float max, float x) { return (x - min) / (max - min); }vec4 map(in vec4 value, in vec4 inMin, in vec4 inMax, in vec4 outMin, in vec4 outMax) { return outMin (outMax - outMin) * (value - inMin) / (inMax - inMin); } void main() { vec4 DissloveTex texture2D(uDissloveTex, vUv); DissloveTex map(DissloveTex, vec4(0.), vec4(1.), vec4(0.1), vec4(1.));if((DissloveTex.r - uClip) 0.) { discard; } float dissloveValue clamp(customSmoothstep(uClip, uClip.1, DissloveTex.r), 0., 1.); vec4 RamTex texture2D(uRamTex, vec2(dissloveValue)); vec4 diffuse texture2D(uDiffuseTex, vUv);vec3 color vec3(clamp( diffuse.rgb RamTex.rgb, 0., 1.));gl_FragColor vec4(color, 1.0);#include #include }, uniforms: { uDissloveTex: new THREE.Uniform(dissolveTex), uRamTex: new THREE.Uniform(dissolveRampTex), uDiffuseTex: new THREE.Uniform(diffuseTex), uClip: new THREE.Uniform(0) } })gui.add(shaderMaterial.uniforms.uClip, value).min(0).max(1).step(0.01).name(Clip)// Mesh const mesh new THREE.Mesh(geometry, shaderMaterial) scene.add(mesh)/**Sizes*/ const sizes { width: window.innerWidth, height: window.innerHeight }window.addEventListener(resize, () { // Update sizes sizes.width window.innerWidth sizes.height window.innerHeight// Update camera camera.aspect sizes.width / sizes.height camera.updateProjectionMatrix()// Update renderer renderer.setSize(sizes.width, sizes.height) renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)) })/**Camera*/ // Base camera const camera new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100) camera.position.set(0.25, - 0.25, 3.5) scene.add(camera)/**Renderer*/ const renderer new THREE.WebGLRenderer() renderer.antialias true renderer.setSize(sizes.width, sizes.height) renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)) renderer.outputColorSpace THREE.SRGBColorSpace box.appendChild(renderer.domElement)// Controls const controls new OrbitControls(camera, renderer.domElement) controls.enableDamping true/**Animate*/ const clock new THREE.Clock()const tick () { const elapsedTime clock.getElapsedTime()// Update controls controls.update()// Render renderer.render(scene, camera)// Call tick again on the next frame window.requestAnimationFrame(tick) }tick()完整源码GitHub小结本文提供溶解完整 Three.js 源码与在线 Demo建议先运行案例再改 uniform/参数做二次实验更多 Three.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库