codepens/31-taint/dist/script.js

134 lines
4.8 KiB
JavaScript
Raw Normal View History

2023-10-06 23:12:53 +02:00
import * as $ from '//cdn.skypack.dev/three@0.125.0/build/three.module.js?min'
import { OrbitControls } from '//cdn.skypack.dev/three@0.125.0/examples/jsm/controls/OrbitControls.js?min'
import { EffectComposer } from '//cdn.skypack.dev/three@0.125.0/examples/jsm/postprocessing/EffectComposer.js?min'
import { RenderPass } from '//cdn.skypack.dev/three@0.125.0/examples/jsm/postprocessing/RenderPass.js?min'
import { UnrealBloomPass } from '//cdn.skypack.dev/three@0.125.0/examples/jsm/postprocessing/UnrealBloomPass.js?min'
//// Boot
const renderer = new $.WebGLRenderer({});
const scene = new $.Scene();
const camera = new $.PerspectiveCamera(75, 2, 20, 12000);
const controls = new OrbitControls(camera, renderer.domElement);
window.addEventListener('resize', () => {
const { clientWidth, clientHeight } = renderer.domElement;
renderer.setSize(clientWidth, clientHeight, false);
renderer.setPixelRatio(window.devicePixelRatio);
camera.aspect = clientWidth / clientHeight;
camera.updateProjectionMatrix();
});
document.body.prepend(renderer.domElement);
window.dispatchEvent(new Event('resize'));
//// Inputs
const size = 5000;
const segs = 500;
const disp = 500;
//// Setup
camera.position.set(1000, 1200, 1200);
controls.autoRotate = true;
controls.enableDamping = true;
controls.maxPolarAngle = Math.PI / 2.9;
const light0 = new $.DirectionalLight('white', 1);
light0.position.set(0, 1, 0);
scene.add(light0);
const tex0 = new $.TextureLoader().load('https://images.unsplash.com/photo-1613799122437-c48c0e4cd5c0?ixid=MXwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHw3OXx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=600&q=60');
const mesh0 = new $.Mesh(
new $.PlaneBufferGeometry(size, size, segs, segs).rotateX(-0.5 * Math.PI),
f()
);
scene.add(mesh0);
const mesh1 = new $.Mesh(
new $.PlaneBufferGeometry(size, size, segs >> 1, segs >> 1).rotateX(-0.5 * Math.PI),
f({ wireframe: true, color: new $.Color('#333') })
);
scene.add(mesh1);
//// Make Material
function f({ wireframe, color } = {}) {
const mat = new $.ShaderMaterial({
extensions: {
derivatives: true, // wgl 1
},
lights: true,
wireframe: Boolean(wireframe),
uniforms: $.UniformsUtils.merge([
$.ShaderLib.standard.uniforms, {
time: { value: 0 },
displacementScale: { value: disp },
wireframe: { value: wireframe || false },
color: { value: color || new $.Color() },
roughness: { value: 1 },
metalness: { value: 0 }
}
]),
vertexShader: `
varying vec3 vWorldPos;
` + $.ShaderLib.standard.vertexShader.replace("#include <worldpos_vertex>", `
// #if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )
vec4 worldPosition = vec4( transformed, 1.0 );
#ifdef USE_INSTANCING
worldPosition = instanceMatrix * worldPosition;
#endif
worldPosition = modelMatrix * worldPosition;
vWorldPos = worldPosition.xyz;
// #endif
`).replace("#include <displacementmap_vertex>", `
#ifdef USE_DISPLACEMENTMAP
transformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );
// form a bowl
float yOffset = length( position.xz ) / ${size.toFixed(1)};
yOffset = pow(sin(yOffset * 2.0), 2.0);
transformed.y += yOffset * ${size.toFixed(1)} / 3.0;
#endif
`),
fragmentShader: `
varying vec3 vWorldPos;
uniform float time;
uniform bool wireframe;
uniform vec3 color;
` + $.ShaderLib.standard.fragmentShader.replace(
"gl_FragColor = vec4( outgoingLight, diffuseColor.a );", `
gl_FragColor = vec4( outgoingLight, diffuseColor.a );
float ths = ${size.toFixed(1)} * pow(sin(time * 0.00015), 2.0);
if ( !wireframe ) {
if ( length( vWorldPos ) > ths ) {
discard;
}
} else {
gl_FragColor = vec4( color, 1.0 );
if ( length( vWorldPos ) < ths ) {
discard;
}
}
`)
});
mat.map = mat.uniforms.map.value = tex0;
mat.displacementMap = mat.uniforms.displacementMap.value = tex0;
return mat;
}
//// Render
const res = new $.Vector2();
window.addEventListener('resize', () => {
renderer.getDrawingBufferSize(res);
fx.setSize(res.width, res.height);
});
const fx = new EffectComposer(renderer);
fx.addPass(new RenderPass(scene, camera));
fx.addPass(new UnrealBloomPass(res, 0.5, 0.5, 0.3));
renderer.setAnimationLoop((t) => {
fx.render();
mesh0.material.uniforms.time.value = t;
mesh1.material.uniforms.time.value = t;
controls.update();
});