Prechádzať zdrojové kódy

Examples: Add Pixel Frustum Alignment (#25140)

* Add Pixel Frustum Alignment

* Properly align the Y-Axis as well

* Adjust Tab Alignment
Johnathon Selstad 2 rokov pred
rodič
commit
1c8f5959f7
1 zmenil súbory, kde vykonal 53 pridanie a 1 odobranie
  1. 53 1
      examples/webgl_postprocessing_pixel.html

+ 53 - 1
examples/webgl_postprocessing_pixel.html

@@ -75,7 +75,7 @@
 			// gui
 
 			gui = new GUI();
-			params = { pixelSize: 6, normalEdgeStrength: .3, depthEdgeStrength: .4 };
+			params = { pixelSize: 6, normalEdgeStrength: .3, depthEdgeStrength: .4, pixelAlignedPanning: true };
 			gui.add( params, 'pixelSize' ).min( 1 ).max( 16 ).step( 1 )
 				.onChange( () => {
 
@@ -84,6 +84,7 @@
 				} );
 			gui.add( renderPixelatedPass, 'normalEdgeStrength' ).min( 0 ).max( 2 ).step( .05 );
 			gui.add( renderPixelatedPass, 'depthEdgeStrength' ).min( 0 ).max( 1 ).step( .05 );
+			gui.add( params, 'pixelAlignedPanning' );
 
 			// textures
 
@@ -179,6 +180,24 @@
 			crystalMesh.position.y = .7 + Math.sin( t * 2 ) * .05;
 			crystalMesh.rotation.y = stopGoEased( t, 2, 4 ) * 2 * Math.PI;
 
+			const rendererSize = renderer.getSize( new THREE.Vector2() );
+			const aspectRatio = rendererSize.x / rendererSize.y;
+			if ( params["pixelAlignedPanning"] ) {
+
+				pixelAlignFrustum( camera, aspectRatio, Math.floor( rendererSize.x / params[ "pixelSize" ] ), 
+									Math.floor( rendererSize.y / params[ "pixelSize" ] ) );
+
+			} else if ( camera.left != - aspectRatio || camera.top != 1.0 ) {
+
+				// Reset the Camera Frustum if it has been modified
+				camera.left   = - aspectRatio;
+				camera.right  =   aspectRatio;
+				camera.top    =   1.0        ;
+				camera.bottom = - 1.0        ;
+				camera.updateProjectionMatrix();
+
+			}
+
 			composer.render();
 
 		}
@@ -219,6 +238,39 @@
 			return cycle + linStep;
 
 		}
+
+		function pixelAlignFrustum( camera, aspectRatio, pixelsPerScreenWidth, pixelsPerScreenHeight ) {
+
+				// 0. Get Pixel Grid Units
+				let worldScreenWidth  = ( ( camera.right - camera.left ) / camera.zoom );
+				let worldScreenHeight = ( ( camera.top - camera.bottom ) / camera.zoom );
+				let pixelWidth  = worldScreenWidth  / pixelsPerScreenWidth;
+				let pixelHeight = worldScreenHeight / pixelsPerScreenHeight;
+
+				// 1. Project the current camera position along its local rotation bases
+				let camPos      = new THREE.Vector3   ();   camera.getWorldPosition  ( camPos );
+				let camRot      = new THREE.Quaternion();   camera.getWorldQuaternion( camRot );
+				let camRight    = new THREE.Vector3( 1.0, 0.0, 0.0 ) .applyQuaternion( camRot );
+				let camUp       = new THREE.Vector3( 0.0, 1.0, 0.0 ) .applyQuaternion( camRot );
+				let camPosRight = camPos.dot( camRight );
+				let camPosUp    = camPos.dot( camUp );
+
+				// 2. Find how far along its position is along these bases in pixel units
+				let camPosRightPx = camPosRight / pixelWidth;
+				let camPosUpPx    = camPosUp    / pixelHeight;
+
+				// 3. Find the fractional pixel units and convert to world units
+				let fractX = camPosRightPx - Math.round( camPosRightPx );
+				let fractY = camPosUpPx    - Math.round(    camPosUpPx );
+
+				// 4. Add fractional world units to the left/right top/bottom to align with the pixel grid
+				camera.left   = - aspectRatio - ( fractX * pixelWidth  );
+				camera.right  =   aspectRatio - ( fractX * pixelWidth  );
+				camera.top    =   1.0         - ( fractY * pixelHeight );
+				camera.bottom = - 1.0         - ( fractY * pixelHeight );
+				camera.updateProjectionMatrix();
+
+		}
 		
 	</script>
 </body>