类似于舞台聚光灯的效果
引入的js
<script src="../../plugins/threeLibrary/three.min.js"></script> <script src="../../plugins/threeLibrary/js/controls/OrbitControls.js"></script> <script src="../../plugins/CopyShader.js"></script> <script src="../../plugins/EffectComposer.js"></script> <script src="../../plugins/RenderPass.js"></script> <script src="../../plugins/ShaderPass.js"></script> <script src="../../plugins/LuminosityHighPassShader.js"></script> <script src="../../plugins/FocusShader.js"></script> <script src="../../plugins/UnrealBloomPass.js"></script>
<script>
function initThree(elid,options) {
let scene,camera ,renderer,viewer
viewer={}
el = document.getElementById(elid)
const width = el.offsetWidth, height = el.offsetHeight,asp = width / height
renderer = new THREE.WebGLRenderer({antialias : true});
renderer.setSize(width, height);
el.append(renderer.domElement);
renderer.setClearColor('#000')
scene = new THREE.Scene()
camera = new THREE.PerspectiveCamera(45, asp, 1, 10000)
camera.position.set(10,10,10)
camera.lookAt(0,0,0)
scene.add(camera)
viewer.scene=scene
viewer.camera=camera
viewer.renderer=renderer
const controls = new THREE.OrbitControls( camera, renderer.domElement );
// 如果使用animate方法时,将此函数删除
controls.addEventListener( 'change', ()=>{
renderer.render( scene, camera );
});
viewer.controls=controls
renderer.render( scene, camera );
return viewer
}
let app=new initThree('box')
let scene=app.scene
let renderer=app.renderer
let camera=app.camera
let controls=app.controls
const clock = new THREE.Clock()
//add light
const directionalLight = new THREE.DirectionalLight( '#fff' )
directionalLight.position.set( 30, 30, 30 ).normalize()
scene.add( directionalLight )
const ambientLight = new THREE.AmbientLight('#fff',0.3) // obj 唯一 id
scene.add(ambientLight)
/* **** **** **** ****/
// renderer.toneMapping = THREE.ReinhardToneMapping;
const box = new THREE.Mesh(new THREE.BoxGeometry(1,1,1),new THREE.MeshBasicMaterial({color:'red'}))
scene.add(box)
const geometry = new THREE.IcosahedronBufferGeometry( 1, 4 );
for ( let i = 0; i < 100; i ++ ) {
const color = new THREE.Color();
color.setHSL( Math.random(), 0.7, Math.random() * 0.2 + 0.05 );
const material = new THREE.MeshBasicMaterial( { color: color } );
const sphere = new THREE.Mesh( geometry, material );
sphere.position.x = Math.random() * 100 - 50;
sphere.position.y = Math.random() * 100 - 50;
sphere.position.z = Math.random() * 100 - 50
sphere.scale.setScalar( Math.random() * Math.random() + 0.5 );
scene.add( sphere );
}
//创建 RenderPass
const renderScene = new THREE.RenderPass( scene, camera )
//创建 bloomPass
const bloomPass = new THREE.UnrealBloomPass( new THREE.Vector2( el.offsetWidth, el.offsetHeight ), 1.5, 0.4, 0.85 );
bloomPass.renderToScreen = true;
bloomPass.threshold = 0;
bloomPass.strength = 5;
bloomPass.radius = 0;
// 创建focusShader
const focusPass = new THREE.ShaderPass(THREE.FocusShader);
focusPass.uniforms["screenWidth"].value = el.offsetWidth;
focusPass.uniforms["screenHeight"].value = el.offsetHeight;
focusPass.uniforms["sampleDistance"].value = 5; //通过调控此只来控制聚焦范围。
const copyPass = new THREE.ShaderPass(THREE.CopyShader);
// 让effectCopy渲染到屏幕上 没这句不会再屏幕上渲染
copyPass.renderToScreen = true;
//创建 EffectComposer
const bloomComposer = new THREE.EffectComposer( renderer )
bloomComposer.renderTarget1.stencilBuffer = true;
bloomComposer.renderTarget2.stencilBuffer = true;
bloomComposer.setSize( el.offsetWidth, el.offsetHeight );
bloomComposer.addPass( renderScene );
// 眩光通道bloomPass插入到composer
bloomComposer.addPass( bloomPass )
bloomComposer.addPass( focusPass )
bloomComposer.addPass( copyPass )
bloomComposer.render()
//set controls
controls.addEventListener( 'change', function () {
bloomComposer.render()
} )
controls.autoRotate = false
function render() {
controls.update(clock.getDelta())
bloomComposer.render()
requestAnimationFrame(render)
}
render()
</script>