You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							143 lines
						
					
					
						
							3.9 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							143 lines
						
					
					
						
							3.9 KiB
						
					
					
				| 	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() | |
| 
 | |
| 
 |