Cailean Finn
7 months ago
5 changed files with 275 additions and 4 deletions
After Width: | Height: | Size: 35 KiB |
@ -0,0 +1,148 @@ |
|||
import * as THREE from 'three' |
|||
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js' |
|||
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; |
|||
import { RenderPixelatedPass } from 'three/addons/postprocessing/RenderPixelatedPass.js'; |
|||
import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; |
|||
import { randFloat } from 'three/src/math/MathUtils.js'; |
|||
|
|||
|
|||
let scene, camera, renderer |
|||
let aspect, frustumSize |
|||
let time = 0 |
|||
let lastTime = 0 |
|||
let controls |
|||
let mesh |
|||
let composer |
|||
let cubeGroup = [] |
|||
let instancedMesh, dummy, count |
|||
|
|||
const texture = new THREE.TextureLoader().load("public/images/dither.png") |
|||
texture.minFilter = THREE.NearestFilter |
|||
texture.colorSpace = THREE.SRGBColorSpace; |
|||
texture.wrapS = THREE.RepeatWrapping; |
|||
texture.wrapT = THREE.RepeatWrapping; |
|||
|
|||
|
|||
function init(){ |
|||
SetupRenderer() |
|||
scene = new THREE.Scene() |
|||
SetupCamera() |
|||
SetupControls() |
|||
composer = new EffectComposer( renderer ); |
|||
const renderPixelatedPass = new RenderPixelatedPass( 8, scene, camera ); |
|||
renderPixelatedPass.normalEdgeStrength = 0; |
|||
renderPixelatedPass.depthEdgeStrength = 1; |
|||
renderPixelatedPass.pixelAlignedPanning = false; |
|||
composer.addPass( renderPixelatedPass ); |
|||
const outputPass = new OutputPass(); |
|||
composer.addPass( outputPass ); |
|||
SetupCubes() |
|||
AddLights() |
|||
animate() |
|||
} |
|||
|
|||
|
|||
function SetupCubes() { |
|||
const cubeGeometry = new THREE.BoxGeometry(); |
|||
const cubeMaterial = new THREE.MeshPhongMaterial({ map: texture }); |
|||
|
|||
// Create an InstancedMesh
|
|||
count = 100; |
|||
instancedMesh = new THREE.InstancedMesh(cubeGeometry, cubeMaterial, count); |
|||
scene.add(instancedMesh) |
|||
dummy = new THREE.Object3D(); |
|||
|
|||
for (let i = 0; i < count; i++) { |
|||
let size = randFloat(5, 8); |
|||
dummy.scale.set(size, size, size); |
|||
dummy.position.set(randFloat(-10, 10), randFloat(-6, 3), 0); |
|||
dummy.updateMatrix(); |
|||
instancedMesh.setMatrixAt(i, dummy.matrix); |
|||
} |
|||
|
|||
} |
|||
|
|||
function SetupRenderer(){ |
|||
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }) |
|||
renderer.setClearColor(0xffffff, 0); |
|||
renderer.setSize(window.innerWidth, window.innerHeight) |
|||
document.getElementById('container').appendChild(renderer.domElement) |
|||
} |
|||
|
|||
function SetupCamera(){ |
|||
aspect = (window.innerWidth) / (window.innerHeight) |
|||
frustumSize = 10 |
|||
camera = new THREE.OrthographicCamera( |
|||
frustumSize * aspect / -2, |
|||
frustumSize * aspect / 2, |
|||
frustumSize / 2, |
|||
frustumSize / -2, |
|||
0.01, |
|||
5000 |
|||
) |
|||
|
|||
camera.position.x = 5 |
|||
} |
|||
|
|||
function SetupControls(){ |
|||
controls = new OrbitControls(camera, renderer.domElement) |
|||
controls.enableRotate = false; |
|||
controls.enablePan = false |
|||
controls.zoomToCursor = false; |
|||
controls.mouseButtons = { |
|||
RIGHT: THREE.MOUSE.ROTATE, |
|||
MIDDLE: THREE.MOUSE.DOLLY, |
|||
LEFT: THREE.MOUSE.PAN |
|||
} |
|||
camera.position.set(0, 0, 20) |
|||
controls.update() |
|||
} |
|||
|
|||
function AddLights() { |
|||
// Add Ambient Light
|
|||
const ambientLight = new THREE.AmbientLight(0xffffff, 10); // Soft white light
|
|||
scene.add(ambientLight); |
|||
|
|||
// Add Directional Light
|
|||
const directionalLight = new THREE.DirectionalLight(0xffffff, 0); // Soft white light
|
|||
directionalLight.position.set(-5, 0, 5).normalize(); |
|||
scene.add(directionalLight); |
|||
} |
|||
|
|||
const matrix = new THREE.Matrix4() |
|||
function animate(){ |
|||
requestAnimationFrame(animate) |
|||
// Rotate instanced meshes
|
|||
const time = performance.now() * 0.001; |
|||
const rotationSpeedX = 0.02; |
|||
const rotationSpeedY = 0.01; |
|||
lastTime = time |
|||
|
|||
|
|||
for (let i = 0; i < count; i++) { |
|||
instancedMesh.getMatrixAt(i, matrix) |
|||
matrix.decompose(dummy.position, dummy.rotation, dummy.scale) |
|||
dummy.rotation.set(i/1000 * time, i/1000 * time, i/1000 * time); |
|||
dummy.updateMatrix(); |
|||
instancedMesh.setMatrixAt(i, dummy.matrix); |
|||
} |
|||
instancedMesh.instanceMatrix.needsUpdate = true |
|||
|
|||
composer.render() |
|||
//renderer.render(scene, camera)
|
|||
} |
|||
|
|||
window.addEventListener('resize', () => { |
|||
aspect = (window.innerWidth) / (window.innerHeight) |
|||
camera.left = -frustumSize * aspect / 2 |
|||
camera.right = frustumSize * aspect / 2 |
|||
camera.top = frustumSize / 2 |
|||
camera.bottom = -frustumSize / 2 |
|||
camera.updateProjectionMatrix() |
|||
renderer.setPixelRatio(window.devicePixelRatio) |
|||
renderer.setSize(window.innerWidth, window.innerHeight) |
|||
}) |
|||
|
|||
|
|||
init() |
|||
|
Loading…
Reference in new issue