如何在Three.js中实现光源亮度信息的可视化叠加显示?
Three.js光源亮度可视化页面叠加层实现方案
需求说明
开发了一款Three.js应用,用于展示数年前光源的亮度情况,目前仅能通过console.log输出相关亮度信息,用户体验不佳,希望实现简单的页面叠加层直观展示该亮度信息,现有代码如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>How to put GUI in three.js app?</title> <style> body { margin: 0; } </style> </head> <body> <script src="https://threejs.org/build/three.min.js"></script> <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script> <!-- MODULE option is more difficult to use in this simple setup: <script src="https://threejs.org/examples/jsm/libs/lil-gui.module.min.js"></script> --> <script src="https://cdn.jsdelivr.net/npm/lil-gui@0.17"></script> <script> const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); camera.position.set( 0, 0, 50 ); camera.lookAt( 0, 0, 0 ); const renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); const geometry2 = new THREE.SphereGeometry( 50, 32, 16 ); const texture2 = new THREE.TextureLoader().load( 'https://i.imgur.com/P4PQzYk.jpg' ); const material2 = new THREE.MeshPhongMaterial( { map: texture2 } ); const sphere2 = new THREE.Mesh( geometry2, material2 ); scene.add( sphere2 ); sphere2.position.set(100, 0, -500); let colorofsun = new THREE.Color ("rgb( 255, 255, 255)"); var light = new THREE.PointLight( colorofsun , 2, 5000, 2 ); light.position.set( 0, 0, 0 ); scene.add( light ); function blueDoge(newBlue, newBrightness) { const blue = newBlue; const bright = newBrightness; newBlue = ((-2.4722934782608703 * Math.pow(10, -11)) * blue) + 1; newBrightness = ((-6.52173913043478 * Math.pow(10, -11)) * blue) + 0.7; light.color.setRGB(1, 1, newBlue); light.intensity = 4 * newBrightness; console.log("Doge's brightness is " + ((100 * newBrightness) + 30) + " percent of the current value " + blue + " years ago."); } blueDoge(0, 0); const GUI = lil.GUI; const gui = new GUI(); const params = { green: 0 } const folderDoge = gui.addFolder( 'Years ago' ); folderDoge.add( params, 'green', 0, 4600000000, 10000000).onChange( blueDoge ); folderDoge.open(); const controls = new THREE.OrbitControls( camera, renderer.domElement ); controls.update(); function animate() { sphere2.rotation.x += 0.00; sphere2.rotation.y += 0.01; renderer.render( scene, camera ); requestAnimationFrame(animate); }; requestAnimationFrame(animate); </script> </body> </html>
实现思路与方案
方案1:静态DOM叠加层(最简实现)
直接在页面中添加固定定位的DOM元素,实时更新亮度信息,无需额外依赖:
- 在
<body>标签内添加显示容器:
<div id="brightness-info" style="position: fixed; top: 20px; left: 20px; color: #fff; font-family: Arial, sans-serif; font-size: 16px; background: rgba(0,0,0,0.7); padding: 10px 15px; border-radius: 4px; z-index: 9999;"></div>
- 修正
blueDoge函数(原函数第二个参数无效,lil-gui的onChange仅传入滑块值)并更新DOM内容:
function blueDoge(yearsAgo) { const blue = yearsAgo; const newBlue = ((-2.4722934782608703 * Math.pow(10, -11)) * blue) + 1; const newBrightness = ((-6.52173913043478 * Math.pow(10, -11)) * blue) + 0.7; light.color.setRGB(1, 1, newBlue); light.intensity = 4 * newBrightness; // 更新DOM显示 const brightnessPercent = ((100 * newBrightness) + 30).toFixed(2); document.getElementById('brightness-info').textContent = `亮度:${brightnessPercent}%(${blue}年前)`; }
方案2:整合进lil-gui面板(风格统一)
利用已引入的lil-gui,在现有控制面板中添加只读显示项,保持UI风格一致:
- 修改
params对象,新增显示字段:
const params = { green: 0, brightnessDisplay: "" }
- 在lil-gui文件夹中添加只读显示项:
const folderDoge = gui.addFolder( '时间调整' ); folderDoge.add( params, 'green', 0, 4600000000, 10000000).onChange( blueDoge ); // 添加只读显示项 folderDoge.add(params, 'brightnessDisplay').name('当前亮度').disable(); folderDoge.open();
- 更新
blueDoge函数,同步更新GUI显示:
function blueDoge(yearsAgo) { const blue = yearsAgo; const newBlue = ((-2.4722934782608703 * Math.pow(10, -11)) * blue) + 1; const newBrightness = ((-6.52173913043478 * Math.pow(10, -11)) * blue) + 0.7; light.color.setRGB(1, 1, newBlue); light.intensity = 4 * newBrightness; // 更新GUI显示 const brightnessPercent = ((100 * newBrightness) + 30).toFixed(2); params.brightnessDisplay = `${brightnessPercent}%`; gui.updateDisplay(); }
方案3:动态样式增强(直观交互)
在方案1基础上,根据亮度值调整显示样式,用进度条可视化百分比:
- 添加带进度条的DOM容器:
<div id="brightness-container" style="position: fixed; top: 20px; right: 20px; color: #fff; font-family: Arial, sans-serif; background: rgba(0,0,0,0.7); padding: 10px 15px; border-radius: 4px; z-index: 9999; min-width: 200px;"> <div>亮度:<span id="brightness-value">100%</span></div> <div style="height: 8px; background: #333; margin-top: 8px; border-radius: 4px; overflow: hidden;"> <div id="brightness-bar" style="height: 100%; width: 100%; background: #ffd700; transition: width 0.3s ease;"></div> </div> </div>
- 更新
blueDoge函数,同步调整进度条宽度:
function blueDoge(yearsAgo) { const blue = yearsAgo; const newBlue = ((-2.4722934782608703 * Math.pow(10, -11)) * blue) + 1; const newBrightness = ((-6.52173913043478 * Math.pow(10, -11)) * blue) + 0.7; light.color.setRGB(1, 1, newBlue); light.intensity = 4 * newBrightness; // 计算亮度百分比 const brightnessPercent = ((100 * newBrightness) + 30).toFixed(2); // 更新文本和进度条 document.getElementById('brightness-value').textContent = `${brightnessPercent}%`; document.getElementById('brightness-bar').style.width = `${brightnessPercent}%`; }
内容的提问来源于stack exchange,提问作者Cambria
相关产品推荐
相关产品推荐

