Cailean Finn
6 months ago
9 changed files with 201 additions and 13 deletions
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 5.6 KiB |
@ -0,0 +1,143 @@ |
|||
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'; |
|||
|
|||
let scene, camera, renderer |
|||
let aspect, frustumSize |
|||
let time = 0 |
|||
let lastTime = 0 |
|||
let controls |
|||
let mesh |
|||
let composer |
|||
|
|||
let container_element = document.getElementById('container-article') |
|||
|
|||
let containerW = container_element.offsetWidth |
|||
let containerH = container_element.offsetHeight |
|||
|
|||
let imgW, imgH, imgRatio |
|||
|
|||
console.log(containerH, containerW) |
|||
|
|||
|
|||
var clock = new THREE.Clock(); |
|||
|
|||
|
|||
function init(){ |
|||
SetupRenderer() |
|||
scene = new THREE.Scene() |
|||
SetupCamera() |
|||
SetupControls() |
|||
|
|||
composer = new EffectComposer( renderer ); |
|||
const renderPixelatedPass = new RenderPixelatedPass( 1.2, scene, camera ); |
|||
renderPixelatedPass.normalEdgeStrength = 1; |
|||
renderPixelatedPass.depthEdgeStrength = 1; |
|||
renderPixelatedPass.pixelAlignedPanning = false; |
|||
composer.addPass( renderPixelatedPass ); |
|||
|
|||
const outputPass = new OutputPass(); |
|||
composer.addPass( outputPass ); |
|||
|
|||
AddLights() |
|||
|
|||
const textureLoader = new THREE.TextureLoader() |
|||
textureLoader.crossOrigin = "Anonymous" |
|||
const texture = textureLoader.load(imageUrl, function ( tex ) { |
|||
// tex and texture are the same in this example, but that might not always be the case
|
|||
console.log( tex.image.width, tex.image.height ); |
|||
imgW = tex.image.width |
|||
imgH = tex.image.height |
|||
imgRatio = imgW / imgH |
|||
|
|||
tex.minFilter = THREE.NearestFilter |
|||
tex.colorSpace = THREE.SRGBColorSpace; |
|||
tex.wrapS = THREE.RepeatWrapping; |
|||
tex.wrapT = THREE.RepeatWrapping; |
|||
const geom = new THREE.PlaneGeometry(imgRatio, 1) |
|||
const mat = new THREE.MeshPhongMaterial({map: texture}) |
|||
mesh = new THREE.Mesh(geom, mat) |
|||
scene.add(mesh) |
|||
animate() |
|||
} ); |
|||
} |
|||
|
|||
function SetupRenderer(){ |
|||
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }) |
|||
renderer.setClearColor(0xffffff, 0); |
|||
renderer.setSize(containerW, containerH) |
|||
document.getElementById('container-article').appendChild(renderer.domElement) |
|||
} |
|||
|
|||
function SetupCamera(){ |
|||
aspect = (containerW) / (containerH) |
|||
frustumSize = 1.5 |
|||
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, 3); // 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); |
|||
} |
|||
|
|||
function animate(){ |
|||
requestAnimationFrame(animate) |
|||
const deltaTime = (time - lastTime) / 1000 |
|||
controls.update() |
|||
let sin = Math.sin(clock.getElapsedTime() * 0.5) |
|||
mesh.rotation.z = sin * 0.1 |
|||
mesh.rotation.x = sin * 0.15 |
|||
composer.render() |
|||
} |
|||
|
|||
function getContainerDimensions(){ |
|||
containerW = container_element.offsetWidth |
|||
containerH = container_element.offsetHeight |
|||
} |
|||
|
|||
window.addEventListener('resize', () => { |
|||
getContainerDimensions() |
|||
aspect = (containerW) / (containerH) |
|||
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(containerW, containerH) |
|||
}) |
|||
|
|||
|
|||
init() |
|||
|
Loading…
Reference in new issue