Three.js 内发光教程 内发光 ·Inner Glow· ▶ 在线运行案例案例合集三维可视化功能案例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.jsconst box document.getElementById(box)const scene new THREE.Scene()const camera new THREE.PerspectiveCamera(50, box.clientWidth / box.clientHeight, 0.1, 1000)camera.position.set(5, 5, 10)const renderer new THREE.WebGLRenderer({ antialias: true, alpha: true, logarithmicDepthBuffer: true })renderer.setSize(box.clientWidth, box.clientHeight)box.appendChild(renderer.domElement)scene.add(new THREE.AxesHelper(50))const controls new OrbitControls(camera, renderer.domElement)controls.enableDamping trueanimate()function animate() {requestAnimationFrame(animate)controls.update()renderer.render(scene, camera)}const vertexShader varying vec3 vNormal; varying vec3 vPositionNormal;void main() { // 视图空间下的单位法线向量 vNormal normalize(normalMatrix * normal); // 视图空间下的单位坐标向量 vPositionNormal normalize((modelViewMatrix * vec4(position, 1.0) ).xyz); gl_Position projectionMatrixmodelViewMatrixvec4(position, 1.0); }/**需要注意法线向量值菲涅尔反射对于法线向量差别比较大的模型效果明显即不规则物体模型表面平整的话效果较差不过可以使用法线贴图更改物体法线向量*/ const fragmentShader uniform vec3 uColor; uniform float uBias; uniform float uPower; uniform float uScale;varying vec3 vNormal; varying vec3 vPositionNormal;// 菲涅尔反射 float fresnelReflex() { return pow(uBias uScale * abs(dot(vNormal, vPositionNormal)), uPower); }void main() { float opacity fresnelReflex(); gl_FragColor vec4(uColor, opacity); }const material new THREE.ShaderMaterial({ uniforms: { uColor: { value: new THREE.Color(0x00ffff) }, uBias: { value: 1.0 }, uScale: { value: -1.0 }, uPower: { value: 2.0 } }, vertexShader, fragmentShader, transparent: true })const sphere new THREE.Mesh(new THREE.SphereGeometry(1, 32, 16), material)scene.add(sphere)const vertexShader1 varying vec2 vUV;void main() { vUV uv; gl_Position projectionMatrixmodelViewMatrixvec4(position, 1.0); }const fragmentShader1 uniform vec3 uColor;varying vec2 vUV;float glow(vec2 coord, float radius, float intensity) { return pow(radius / length(coord), intensity); }void main() { float ratio glow(vUV - vec2(0.5), 0.1, 3.0); gl_FragColor vec4(uColor * ratio, ratio); }const material1 new THREE.ShaderMaterial({ uniforms: { uColor: { value: new THREE.Color(0x00ffff) } }, vertexShader: vertexShader1, fragmentShader: fragmentShader1, depthWrite: false, transparent: true })const plane new THREE.Mesh(new THREE.PlaneGeometry(2, 2), material1)plane.position.set(1, 0, 1)scene.add(plane)完整源码GitHub小结本文提供内发光完整 Three.js 源码与在线 Demo建议先运行案例再改 uniform/参数做二次实验更多 Three.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库