在科幻 3D 数字孪生、Web3 机甲展示或元宇宙太空战舰场景中,围绕在飞船或核心服务器机柜外围的六边形能量护盾(Hexagonal Cyber Energy Shield)是最具未来科技感的视觉焦点:
- 护盾表面是一层半透明的流动六边形蜂窝力场网格(Honeycomb Forcefield);
- 护盾边缘呈现出极其通透的菲涅尔发光边缘(Fresnel Rim Light);
- 当外部激光、子弹或用户鼠标点击撞击护盾表面时,撞击点瞬间激发出向外扩散的同心能量冲击波纹(Shield Hit Wave),并伴随局部六边形电路的超载高亮!
通过编写自定义的Three.js 力场着色器(Custom Shield GLSL ShaderMaterial),我们可以在单个球体/胶囊体网格上以满帧 60 FPS 渲染出逼真的三维能量护盾与动态力场碰撞反馈!
一、能量护盾六边形蜂窝与碰撞冲击波着色器拓扑
graph LR ShieldMesh[能量护盾半透明网格 (SphereGeometry / Capsule)] --> ShieldShader[GPU 片元着色器 (Shield GLSL Shader)] subgraph GPU 片元着色器实时能量力场计算 ShieldShader --> HexGrid[计算 UV 六边形蜂窝网格距离场 (Hexagonal Voronoi Field)] ShieldShader --> HitImpact[计算撞击点欧氏距离: dist(vWorldPos, uHitPoint)] HitImpact --> Shockwave[冲击波衰减扩散: sin(dist * 10.0 - uHitTime * 12.0) * exp(-dist * 2.0)] HexGrid & Shockwave --> FresnelCalc[计算视线与法线菲涅尔边缘光: pow(1.0 - dot(V, N), 3.0)] end FresnelCalc --> AdditiveBlend[THREE.AdditiveBlending 发光加法混合] AdditiveBlend --> Output[输出晶莹剔透、遇袭激荡发光的科幻数字能量护盾]二、能量护盾 ShaderMaterial(GLSL 实现)
// shaders/cyberEnergyShieldShader.ts import * as THREE from 'three'; export function createEnergyShieldMaterial() { return new THREE.ShaderMaterial({ uniforms: { uTime: { value: 0 }, uShieldColor: { value: new THREE.Color(0x00f3ff) }, // 赛博能量青 uHitColor: { value: new THREE.Color(0xff0055) }, // 遭袭高能粉红 uHitPoint: { value: new THREE.Vector3(0, 0, 0) }, // 当前撞击世界坐标 uHitTime: { value: 999.0 }, // 距离撞击经过的时长 uHexScale: { value: 24.0 }, // 六边形网格密集度 }, vertexShader: ` varying vec2 vUv; varying vec3 vNormal; varying vec3 vWorldPosition; void main() { vUv = uv; vNormal = normalize(normalMatrix * normal); vec4 worldPos = modelMatrix * vec4(position, 1.0); vWorldPosition = worldPos.xyz; gl_Position = projectionMatrix * viewMatrix * worldPos; } `, fragmentShader: ` uniform float uTime; uniform vec3 uShieldColor; uniform vec3 uHitColor; uniform vec3 uHitPoint; uniform float uHitTime; uniform float uHexScale; varying vec2 vUv; varying vec3 vNormal; varying vec3 vWorldPosition; // 经典二维六边形网格距离场算法 vec4 hexGrid(vec2 p) { vec2 s = vec2(1.0, 1.7320508); vec4 hC = floor(vec4(p, p - vec2(0.5, 1.0))/s.xyxy) + 0.5; vec4 h = vec4(p - hC.xy*s, p - (hC.zw + 0.5)*s); return dot(h.xy, h.xy) < dot(h.zw, h.zw) ? vec4(h.xy, hC.xy) : vec4(h.zw, hC.zw + 9.73); } void main() { // 1. 计算六边形蜂窝力场边界 (Hexagon Edges) vec4 h = hexGrid(vUv * uHexScale); float hexDist = max(abs(h.x) * 1.5 + abs(h.y) * 0.866025, abs(h.y) * 1.7320508); float hexEdge = smoothstep(0.85, 0.98, hexDist); // 2. 计算菲涅尔发光边缘 (Fresnel Rim Lighting) vec3 viewDir = normalize(cameraPosition - vWorldPosition); vec3 normal = normalize(vNormal); float fresnel = pow(1.0 - abs(dot(viewDir, normal)), 2.8); // 3. 计算力场遭袭撞击能量冲击波 (Hit Ripple Impact) float distToHit = distance(vWorldPosition, uHitPoint); float hitWave = 0.0; if (uHitTime < 2.0) { float waveFront = uHitTime * 4.5; // 扩散波前 float diff = abs(distToHit - waveFront); hitWave = smoothstep(0.6, 0.0, diff) * exp(-uHitTime * 2.0); } // 4. 颜色与能量合成 // 常态:半透明青色菲涅尔边缘 + 微微流动的六边形网格 vec3 color = uShieldColor * (fresnel * 1.8 + hexEdge * 0.4); // 遇袭:叠加高亮粉红冲击波与六边形过载高光 if (hitWave > 0.01) { vec3 activeHit = mix(uShieldColor, uHitColor, hitWave); color += activeHit * (hitWave * 3.5 + hexEdge * hitWave * 2.0); } // 整体半透明透明度计算 float alpha = clamp(fresnel * 0.7 + hexEdge * 0.3 + hitWave * 0.85, 0.0, 0.95); gl_FragColor = vec4(color, alpha); } `, transparent: true, blending: THREE.AdditiveBlending, depthWrite: false, side: THREE.DoubleSide, }); }三、场景装配与鼠标射线点击碰撞拾取交互
// scene/cyberShieldStage.ts import * as THREE from 'three'; import { createEnergyShieldMaterial } from '../shaders/cyberEnergyShieldShader'; export function setupEnergyShieldStage(container: HTMLElement) { const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 0, 7); const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); container.appendChild(renderer.domElement); // 1. 创建被保护的内部核心机甲/服务器球体 const innerGeo = new THREE.DodecahedronGeometry(1.4, 2); const innerMat = new THREE.MeshStandardMaterial({ color: 0x0f172a, roughness: 0.3, metalness: 0.8 }); const innerCore = new THREE.Mesh(innerGeo, innerMat); scene.add(innerCore); // 2. 创建外围能量护盾网格 const shieldGeo = new THREE.SphereGeometry(2.4, 64, 64); const shieldMat = createEnergyShieldMaterial(); const shieldMesh = new THREE.Mesh(shieldGeo, shieldMat); scene.add(shieldMesh); scene.add(new THREE.AmbientLight(0xffffff, 0.8)); // 3. 鼠标点击射线拾取:触发护盾撞击波纹 const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2(); window.addEventListener('pointerdown', (event) => { mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; raycaster.setFromCamera(mouse, camera); const intersects = raycaster.intersectObject(shieldMesh); if (intersects.length > 0) { const hitPoint = intersects[0].point; console.log('💥 [Shield Impact] Hit detected at world position:', hitPoint); // 注入撞击点世界坐标并重置时间 shieldMat.uniforms.uHitPoint.value.copy(hitPoint); shieldMat.uniforms.uHitTime.value = 0.0; } }); return { update: (delta: number) => { shieldMat.uniforms.uTime.value += delta; shieldMat.uniforms.uHitTime.value += delta; innerCore.rotation.y += delta * 0.3; shieldMesh.rotation.y -= delta * 0.1; renderer.render(scene, camera); }, }; }四、能量护盾三大极客优化法则
- 绝对单网格极简 Draw Call(Single Draw Call Forcefield):整个六边形蜂窝网格、菲涅尔发光与冲击波完全在单一片元着色器内计算完成,Draw Call 恒定为1;
AdditiveBlending叠加 UnrealBloomPass 泛光:遭袭瞬间冲击波中心在加法混合下激发出耀眼的纯白能量火花,带来震撼的科幻打击反馈;- 双面渲染(DoubleSide Rendering):开启
side: THREE.DoubleSide,当镜头穿入护盾内部时依然能看到内壁的六边形能量网格流动,沉浸感倍增。
用精密的数学蜂窝距离场与光影着色器雕刻科幻防御壁垒,为 Web3 三维交互空间注入无尽的硬核未来魅力。