我正在尝试使用 Threejs 中的 UnrealBloomPass 进行选择性绽放。
我尝试使用我的代码,但出现错误,因此我决定使用在 THREEJS 网站中作为演示的另一个代码进行尝试。一样。
这是完整的错误:
three.module.js:19897 THREE.WebGLProgram: Shader Error 0 - VALIDATE_STATUS false
Program Info Log: Fragment shader is not compiled.
FRAGMENT
ERROR: 0:79: 'toneMappingExposure' : redefinition
ERROR: 0:80: 'LinearToneMapping' : function already has a body
ERROR: 0:83: 'ReinhardToneMapping' : function already has a body
ERROR: 0:87: 'OptimizedCineonToneMapping' : function already has a body
ERROR: 0:92: 'RRTAndODTFit' : function already has a body
ERROR: 0:97: 'ACESFilmicToneMapping' : function already has a body
ERROR: 0:112: 'CustomToneMapping' : function already has a body
74: uniform sampler2D tDiffuse;
75:
76: #ifndef saturate
77: #define saturate( a ) clamp( a, 0.0, 1.0 )
78: #endif
> 79: uniform float toneMappingExposure;
80: vec3 LinearToneMapping( vec3 color ) {
81: return saturate( toneMappingExposure * color );
82: }
83: vec3 ReinhardToneMapping( vec3 color ) {
84: color *= toneMappingExposure;
85: return saturate( color / ( vec3( 1.0 ) + color ) );
这是我的代码(带有演示代码):
JS:
import * as THREE from 'three';
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js';
import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';
import { OutputPass } from 'three/addons/postprocessing/OutputPass.js';
const BLOOM_SCENE = 1;
const bloomLayer = new THREE.Layers();
bloomLayer.set(BLOOM_SCENE);
const params = {
threshold: 0,
strength: 1,
radius: 0.5,
exposure: 1
};
const darkMaterial = new THREE.MeshBasicMaterial({ color: 'black' });
const materials = {};
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.toneMapping = THREE.ReinhardToneMapping;
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
const camera = new THREE.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);
const renderScene = new RenderPass(scene, camera);
const bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, 0.4, 0.85);
bloomPass.threshold = params.threshold;
bloomPass.strength = params.strength;
bloomPass.radius = params.radius;
const bloomComposer = new EffectComposer(renderer);
bloomComposer.renderToScreen = false;
bloomComposer.addPass(renderScene);
bloomComposer.addPass(bloomPass);
const mixPass = new ShaderPass(
new THREE.ShaderMaterial({
uniforms: {
baseTexture: { value: null },
bloomTexture: { value: bloomComposer.renderTarget2.texture }
},
vertexShader: document.getElementById('vertexshader').textContent,
fragmentShader: document.getElementById('fragmentshader').textContent,
defines: {}
}), 'baseTexture'
);
mixPass.needsSwap = true;
const outputPass = new OutputPass();
const finalComposer = new EffectComposer(renderer);
finalComposer.addPass(renderScene);
finalComposer.addPass(mixPass);
finalComposer.addPass(outputPass);
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
window.addEventListener('pointerdown', onPointerDown);
const gui = new GUI();
const bloomFolder = gui.addFolder('bloom');
bloomFolder.add(params, 'threshold', 0.0, 1.0).onChange(function (value) {
bloomPass.threshold = Number(value);
render();
});
bloomFolder.add(params, 'strength', 0.0, 3).onChange(function (value) {
bloomPass.strength = Number(value);
render();
});
bloomFolder.add(params, 'radius', 0.0, 1.0).step(0.01).onChange(function (value) {
bloomPass.radius = Number(value);
render();
});
const toneMappingFolder = gui.addFolder('tone mapping');
toneMappingFolder.add(params, 'exposure', 0.1, 2).onChange(function (value) {
renderer.toneMappingExposure = Math.pow(value, 4.0);
render();
});
setupScene();
function onPointerDown(event) {
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, false);
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 THREE.IcosahedronGeometry(1, 15);
for (let i = 0; i < 50; 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() * 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() {
scene.traverse(darkenNonBloomed);
bloomComposer.render();
scene.traverse(restoreMaterial);
// render the entire scene, then render bloom scene on top
finalComposer.render();
}
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];
}
}
HTML:
<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>
小提琴:https://jsfiddle.net/b2vnquy9/
感谢您的帮助,喜欢你。
跟你一样的问题,你解决了吗