代码拉取完成,页面将自动刷新
<!DOCTYPE html>
<html lang="en">
<head>
<title>Verge3D webgl - postprocessing - unreal bloom selective</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link type="text/css" rel="stylesheet" href="main.css">
</head>
<body>
<div id="info">
<a href="https://www.soft8soft.com/verge3d" target="_blank" rel="noopener">Verge3D</a> Click on a sphere to toggle bloom<br>By <a href="http://github.com/Temdog007" target="_blank" rel="noopener">Temdog007</a>
</div>
<script type="x-shader/x-vertex" id="vertexshader">
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>
<script type="x-shader/x-fragment" id="fragmentshader">
uniform sampler2D baseTexture;
uniform sampler2D bloomTexture;
varying vec2 vUv;
void main() {
gl_FragColor = (texture2D(baseTexture, vUv) + vec4(1.0) * texture2D(bloomTexture, vUv));
}
</script>
<script type="module">
import * as v3d from '../build/v3d.module.js';
import { GUI } from './jsm/libs/dat.gui.module.js';
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { EffectComposer } from './jsm/postprocessing/EffectComposer.js';
import { RenderPass } from './jsm/postprocessing/RenderPass.js';
import { ShaderPass } from './jsm/postprocessing/ShaderPass.js';
import { UnrealBloomPass } from './jsm/postprocessing/UnrealBloomPass.js';
const ENTIRE_SCENE = 0, BLOOM_SCENE = 1;
const bloomLayer = new v3d.Layers();
bloomLayer.set(BLOOM_SCENE);
const params = {
exposure: 1,
bloomStrength: 5,
bloomThreshold: 0,
bloomRadius: 0,
scene: "Scene with Glow"
};
const darkMaterial = new v3d.MeshBasicMaterial({ color: "black" });
const materials = {};
const renderer = new v3d.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.toneMapping = v3d.ReinhardToneMapping;
document.body.appendChild(renderer.domElement);
const scene = new v3d.Scene();
const camera = new v3d.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 200);
camera.position.set(0, 0, 20);
camera.lookAt(0, 0, 0);
const controls = new OrbitControls(camera, renderer.domElement);
controls.maxPolarAngle = Math.PI * 0.5;
controls.minDistance = 1;
controls.maxDistance = 100;
controls.addEventListener('change', render);
scene.add(new v3d.AmbientLight(0x404040));
const renderScene = new RenderPass(scene, camera);
const bloomPass = new UnrealBloomPass(new v3d.Vector2(window.innerWidth, window.innerHeight), 1.5, 0.4, 0.85);
bloomPass.threshold = params.bloomThreshold;
bloomPass.strength = params.bloomStrength;
bloomPass.radius = params.bloomRadius;
const bloomComposer = new EffectComposer(renderer);
bloomComposer.renderToScreen = false;
bloomComposer.addPass(renderScene);
bloomComposer.addPass(bloomPass);
const finalPass = new ShaderPass(
new v3d.ShaderMaterial({
uniforms: {
baseTexture: { value: null },
bloomTexture: { value: bloomComposer.renderTarget2.texture }
},
vertexShader: document.getElementById('vertexshader').textContent,
fragmentShader: document.getElementById('fragmentshader').textContent,
defines: {}
}), "baseTexture"
);
finalPass.needsSwap = true;
const finalComposer = new EffectComposer(renderer);
finalComposer.addPass(renderScene);
finalComposer.addPass(finalPass);
const raycaster = new v3d.Raycaster();
const mouse = new v3d.Vector2();
window.addEventListener('pointerdown', onPointerDown, false);
const gui = new GUI();
gui.add(params, 'scene', ['Scene with Glow', 'Glow only', 'Scene only']).onChange(function(value) {
switch (value) {
case 'Scene with Glow':
bloomComposer.renderToScreen = false;
break;
case 'Glow only':
bloomComposer.renderToScreen = true;
break;
case 'Scene only':
// nothing to do
break;
}
render();
});
const folder = gui.addFolder('Bloom Parameters');
folder.add(params, 'exposure', 0.1, 2).onChange(function(value) {
renderer.toneMappingExposure = Math.pow(value, 4.0);
render();
});
folder.add(params, 'bloomThreshold', 0.0, 1.0).onChange(function(value) {
bloomPass.threshold = Number(value);
render();
});
folder.add(params, 'bloomStrength', 0.0, 10.0).onChange(function(value) {
bloomPass.strength = Number(value);
render();
});
folder.add(params, 'bloomRadius', 0.0, 1.0).step(0.01).onChange(function(value) {
bloomPass.radius = Number(value);
render();
});
setupScene();
function onPointerDown(event) {
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
const object = intersects[0].object;
object.layers.toggle(BLOOM_SCENE);
render();
}
}
window.onresize = function() {
const width = window.innerWidth;
const height = window.innerHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
bloomComposer.setSize(width, height);
finalComposer.setSize(width, height);
render();
};
function setupScene() {
scene.traverse(disposeMaterial);
scene.children.length = 0;
const geometry = new v3d.IcosahedronBufferGeometry(1, 15);
for (let i = 0; i < 50; i++) {
const color = new v3d.Color();
color.setHSL(Math.random(), 0.7, Math.random() * 0.2 + 0.05);
const material = new v3d.MeshBasicMaterial({ color: color });
const sphere = new v3d.Mesh(geometry, material);
sphere.position.x = Math.random() * 10 - 5;
sphere.position.y = Math.random() * 10 - 5;
sphere.position.z = Math.random() * 10 - 5;
sphere.position.normalize().multiplyScalar(Math.random() * 4.0 + 2.0);
sphere.scale.setScalar(Math.random() * Math.random() + 0.5);
scene.add(sphere);
if (Math.random() < 0.25) sphere.layers.enable(BLOOM_SCENE);
}
render();
}
function disposeMaterial(obj) {
if (obj.material) {
obj.material.dispose();
}
}
function render() {
switch (params.scene) {
case 'Scene only':
renderer.render(scene, camera);
break;
case 'Glow only':
renderBloom(false);
break;
case 'Scene with Glow':
default:
// render scene with bloom
renderBloom(true);
// render the entire scene, then render bloom scene on top
finalComposer.render();
break;
}
}
function renderBloom(mask) {
if (mask === true) {
scene.traverse(darkenNonBloomed);
bloomComposer.render();
scene.traverse(restoreMaterial);
} else {
camera.layers.set(BLOOM_SCENE);
bloomComposer.render();
camera.layers.set(ENTIRE_SCENE);
}
}
function darkenNonBloomed(obj) {
if (obj.isMesh && bloomLayer.test(obj.layers) === false) {
materials[obj.uuid] = obj.material;
obj.material = darkMaterial;
}
}
function restoreMaterial(obj) {
if (materials[obj.uuid]) {
obj.material = materials[obj.uuid];
delete materials[obj.uuid];
}
}
</script>
</body>
</html>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。