Thank you for your time @Mugen87 !
OK, here’s what I tried in svelte, using source to limit size (but imported twice for the moment).
There’s no error but no DoF and a vertically compressed camera view with poor fps at scene 1.
import {
MeshBasicMaterial,
PlaneBufferGeometry,
BoxGeometry,
DoubleSide,
VideoTexture,
RGBAFormat,
Mesh,
DirectionalLight,
PerspectiveCamera,
WebGLRenderer,
Scene,
Color,
CubeTextureLoader,
Vector2,
WebGLRenderTarget,
MeshPhongMaterial,
BoxBufferGeometry,
SphereBufferGeometry,
MeshLambertMaterial,
ShaderMaterial,
UniformsUtils,
OrthographicCamera,
PlaneGeometry
} from 'three/src/Three.js';
import { TrackballControls } from './trackball.js';
import { BokehShader, BokehDepthShader } from 'three/examples/jsm/shaders/BokehShader2.js';
// vars
let materialDepth;
const postprocessing = { enabled: true };
const shaderSettings = {
rings: 3,
samples: 4
};
function main() {
const canvas = document.querySelector('#c');
const renderer = new WebGLRenderer({ canvas, alpha: true, antialias: true });
const sceneElements = [];
function addScene(elem, fn) {
sceneElements.push({ elem, fn });
}
//DoFv2
const depthShader = BokehDepthShader;
effectController = {
enabled: true,
jsDepthCalculation: true,
shaderFocus: false,
fstop: 2.2,
maxblur: 1.0,
showFocus: false,
focalDepth: 2.8,
manualdof: false,
vignetting: false,
depthblur: false,
threshold: 0.5,
gain: 2.0,
bias: 0.5,
fringe: 0.7,
focalLength: 35,
noise: true,
pentagon: false,
dithering: 0.0001
};
const postprocessing = { enabled: true };
const shaderSettings = {
rings: 3,
samples: 4
};
materialDepth = new ShaderMaterial({
uniforms: depthShader.uniforms,
vertexShader: depthShader.vertexShader,
fragmentShader: depthShader.fragmentShader
});
function makeScene(elem) {
const scene = new Scene();
const fov = 45;
const aspect = 2; // the canvas default
const near = 0.1;
const far = 5;
const camera = new PerspectiveCamera(60, 16 / 9, 0.1, 3000);
camera.position.set(0, 1, 2);
camera.lookAt(0, 0, 0);
scene.add(camera);
//DoFv2
materialDepth.uniforms['mNear'].value = camera.near;
materialDepth.uniforms['mFar'].value = camera.far;
const controls = new TrackballControls(camera, elem);
// controls.noZoom = true;
controls.noPan = true;
{
const color = 0xffffff;
const intensity = 1;
const light = new DirectionalLight(color, intensity);
light.position.set(-1, 2, 4);
scene.add(light);
}
return { scene, camera, controls };
}
const sceneInitFunctionsByName = {
box: (elem) => {
const { scene, camera, controls } = makeScene(elem);
const geometry = new BoxBufferGeometry(10, 10, 10);
const material = new MeshPhongMaterial({ color: 'red' });
const mesh = new Mesh(geometry, material);
for (let i = 0; i < 1500; i++) {
const object = new Mesh(
geometry,
new MeshLambertMaterial({ color: Math.random() * 0xffffff })
);
object.position.x = Math.random() * 800 - 400;
object.position.y = Math.random() * 800 - 400;
object.position.z = Math.random() * 800 - 400;
scene.add(object);
}
scene.add(mesh);
return (time, rect) => {
mesh.rotation.y = time * 0.1;
// mesh.position.z = Math.sin(time * 0.5) * 50;
camera.aspect = rect.width / rect.height;
// camera.updateMatrixWorld();
camera.updateProjectionMatrix();
controls.handleResize();
controls.update();
//DoFv2
initPostprocessing();
// not working
// postprocessing.rtTextureDepth.setSize(window.innerWidth, window.innerHeight);
// postprocessing.rtTextureColor.setSize(window.innerWidth, window.innerHeight);
// postprocessing.bokeh_uniforms['textureWidth'].value = window.innerWidth;
// postprocessing.bokeh_uniforms['textureHeight'].value = window.innerHeight;
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);
};
},
pyramid: (elem) => {
const { scene, camera, controls } = makeScene(elem);
const radius = 0.8;
const widthSegments = 4;
const heightSegments = 2;
const geometry = new SphereBufferGeometry(radius, widthSegments, heightSegments);
const material = new MeshPhongMaterial({
color: 'blue',
flatShading: true
});
const mesh = new Mesh(geometry, material);
scene.add(mesh);
return (time, rect) => {
mesh.rotation.y = time * 0.1;
camera.aspect = rect.width / rect.height;
camera.updateProjectionMatrix();
controls.handleResize();
controls.update();
renderer.render(scene, camera);
};
}
};
document.querySelectorAll('[data-diagram]').forEach((elem) => {
// @ts-ignore
const sceneName = elem.dataset.diagram;
const sceneInitFunction = sceneInitFunctionsByName[sceneName];
const sceneRenderFunction = sceneInitFunction(elem);
addScene(elem, sceneRenderFunction);
});
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
const clearColor = new Color('#000');
function render(time) {
time *= 0.001;
resizeRendererToDisplaySize(renderer);
renderer.setScissorTest(false);
renderer.setClearColor(clearColor, 0);
renderer.clear(true, true);
renderer.setScissorTest(true);
const transform = `translateY(${window.scrollY}px)`;
renderer.domElement.style.transform = transform;
for (const { elem, fn } of sceneElements) {
// get the viewport relative position of this element
const rect = elem.getBoundingClientRect();
const { left, right, top, bottom, width, height } = rect;
const isOffscreen =
bottom < 0 ||
top > renderer.domElement.clientHeight ||
right < 0 ||
left > renderer.domElement.clientWidth;
if (isOffscreen) {
}
if (!isOffscreen) {
const positiveYUpBottom = renderer.domElement.clientHeight - bottom;
renderer.setScissor(left, positiveYUpBottom, width, height);
renderer.setViewport(left, positiveYUpBottom, width, height);
fn(time, rect);
}
}
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
//DoFv2
function animate(renderer, scene, camera) {
requestAnimationFrame(animate);
render(renderer, scene, camera);
}
function render(renderer, scene, camera) {
const time = Date.now() * 0.00015;
camera.position.x = Math.cos(time) * 400;
camera.position.z = Math.sin(time) * 500;
camera.position.y = Math.sin(time / 1.4) * 100;
// camera.lookAt(target);
camera.updateMatrixWorld();
if (postprocessing.enabled) {
renderer.clear();
// render scene into texture
renderer.setRenderTarget(postprocessing.rtTextureColor);
renderer.clear();
renderer.render(scene, camera);
// render depth into texture
scene.overrideMaterial = materialDepth;
renderer.setRenderTarget(postprocessing.rtTextureDepth);
renderer.clear();
renderer.render(scene, camera);
scene.overrideMaterial = null;
// render bokeh composite
renderer.setRenderTarget(null);
renderer.render(postprocessing.scene, postprocessing.camera);
} else {
scene.overrideMaterial = null;
renderer.setRenderTarget(null);
renderer.clear();
renderer.render(scene, camera);
}
}
function initPostprocessing() {
postprocessing.scene = new Scene();
postprocessing.camera = new OrthographicCamera(
window.innerWidth / -2,
window.innerWidth / 2,
window.innerHeight / 2,
window.innerHeight / -2,
-10000,
10000
);
postprocessing.camera.position.z = 100;
postprocessing.scene.add(postprocessing.camera);
postprocessing.rtTextureDepth = new WebGLRenderTarget(window.innerWidth, window.innerHeight);
postprocessing.rtTextureColor = new WebGLRenderTarget(window.innerWidth, window.innerHeight);
const bokeh_shader = BokehShader;
postprocessing.bokeh_uniforms = UniformsUtils.clone(bokeh_shader.uniforms);
postprocessing.bokeh_uniforms['tColor'].value = postprocessing.rtTextureColor.texture;
postprocessing.bokeh_uniforms['tDepth'].value = postprocessing.rtTextureDepth.texture;
postprocessing.bokeh_uniforms['textureWidth'].value = window.innerWidth;
postprocessing.bokeh_uniforms['textureHeight'].value = window.innerHeight;
postprocessing.materialBokeh = new ShaderMaterial({
uniforms: postprocessing.bokeh_uniforms,
vertexShader: bokeh_shader.vertexShader,
fragmentShader: bokeh_shader.fragmentShader,
defines: {
RINGS: shaderSettings.rings,
SAMPLES: shaderSettings.samples
}
});
postprocessing.quad = new Mesh(
new PlaneGeometry(window.innerWidth, window.innerHeight),
postprocessing.materialBokeh
);
postprocessing.quad.position.z = -500;
postprocessing.scene.add(postprocessing.quad);
}
onMount(() => {
main();
});
</script>
and html + style
<svelte:head>
<title>Svelte</title></svelte:head
>
<div class="forcanvas">
<canvas id="c" />
<p>
<span data-diagram="box" class="left" />
I love boxes. Presents come in boxes. When I find a new box I'm always excited to find out what's
inside.
</p>
<p>
<span data-diagram="pyramid" class="right" />
When I was a kid I dreamed of going on an expedition inside a pyramid and finding a undiscovered
tomb full of mummies and treasure.
</p>
</div>
<style>
#c {
position: absolute;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
display: block;
z-index: -1;
}
*[data-diagram] {
display: inline-block;
width: 10em;
height: 6em;
}
.left {
float: left;
margin-right: 0.25em;
}
.right {
float: right;
margin-left: 0.25em;
}
p {
margin: 1em auto;
max-width: 500px;
font-size: xx-large;
}
</style>
There’s no DoF in the scene 1 (box).