Просмотр исходного кода

PointsNodeMaterial: Fix broken point rendering. (#31702)

* PointsNodeMaterial: Fix broken point rendering.

* E2E: Update screenshot.
Michael Herzog 4 месяцев назад
Родитель
Сommit
e1ea0a0cd7

BIN
examples/screenshots/webgpu_lights_custom.jpg


BIN
examples/screenshots/webgpu_sandbox.jpg


+ 30 - 7
src/materials/nodes/PointsNodeMaterial.js

@@ -1,14 +1,16 @@
 import SpriteNodeMaterial from './SpriteNodeMaterial.js';
-import { viewportSize, screenSize } from '../../nodes/display/ScreenNode.js';
+import { viewportSize, screenDPR } from '../../nodes/display/ScreenNode.js';
 import { positionGeometry, positionLocal, positionView } from '../../nodes/accessors/Position.js';
 import { modelViewMatrix } from '../../nodes/accessors/ModelNode.js';
 import { materialPointSize } from '../../nodes/accessors/MaterialNode.js';
 import { rotate } from '../../nodes/utils/RotateNode.js';
-import { float, vec2, vec3, vec4 } from '../../nodes/tsl/TSLBase.js';
+import { float, uniform, vec2, vec3, vec4 } from '../../nodes/tsl/TSLBase.js';
 
 import { PointsMaterial } from '../PointsMaterial.js';
+import { Vector2 } from '../../math/Vector2.js';
 
 const _defaultValues = /*@__PURE__*/ new PointsMaterial();
+const _size = /*@__PURE__*/ new Vector2();
 
 /**
  * Node material version of {@link PointsMaterial}.
@@ -68,7 +70,7 @@ class PointsNodeMaterial extends SpriteNodeMaterial {
 
 	}
 
-	setupVertex( builder ) {
+	setupVertexSprite( builder ) {
 
 		const { material, camera } = builder;
 
@@ -88,16 +90,13 @@ class PointsNodeMaterial extends SpriteNodeMaterial {
 
 		let pointSize = sizeNode !== null ? vec2( sizeNode ) : materialPointSize;
 
-		const dpr = builder.renderer.getPixelRatio();
-
-		pointSize = pointSize.mul( dpr );
+		pointSize = pointSize.mul( screenDPR );
 
 		// size attenuation
 
 		if ( camera.isPerspectiveCamera && sizeAttenuation === true ) {
 
 			// follow WebGLRenderer's implementation, and scale by half the canvas height in logical units
-			const scale = float( 0.5 ).mul( screenSize.y ).div( dpr );
 
 			pointSize = pointSize.mul( scale.div( positionView.z.negate() ) );
 
@@ -145,6 +144,21 @@ class PointsNodeMaterial extends SpriteNodeMaterial {
 
 	}
 
+	setupVertex( builder ) {
+
+		if ( builder.object.isPoints ) {
+
+			return super.setupVertex( builder );
+
+
+		} else {
+
+			return this.setupVertexSprite( builder );
+
+		}
+
+	}
+
 	/**
 	 * Whether alpha to coverage should be used or not.
 	 *
@@ -170,4 +184,13 @@ class PointsNodeMaterial extends SpriteNodeMaterial {
 
 }
 
+const scale = /*@__PURE__*/ uniform( 1 ).onFrameUpdate( function ( { renderer } ) {
+
+	const dpr = renderer.getPixelRatio();
+	const size = renderer.getSize( _size );
+
+	this.value = 0.5 * size.y * dpr;
+
+} );
+
 export default PointsNodeMaterial;

+ 36 - 9
src/nodes/display/ScreenNode.js

@@ -6,7 +6,7 @@ import { Fn, nodeImmutable, vec2 } from '../tsl/TSLBase.js';
 import { Vector2 } from '../../math/Vector2.js';
 import { Vector4 } from '../../math/Vector4.js';
 
-let screenSizeVec, viewportVec;
+let _screenSizeVec, _viewportVec;
 
 /**
  * This node provides a collection of screen related metrics.
@@ -44,6 +44,14 @@ class ScreenNode extends Node {
 		 */
 		this.scope = scope;
 
+		/**
+		 * This output node.
+		 *
+		 * @type {?Node}
+		 * @default null
+		 */
+		this._output = null;
+
 		/**
 		 * This flag can be used for type testing.
 		 *
@@ -102,26 +110,30 @@ class ScreenNode extends Node {
 
 			if ( renderTarget !== null ) {
 
-				viewportVec.copy( renderTarget.viewport );
+				_viewportVec.copy( renderTarget.viewport );
 
 			} else {
 
-				renderer.getViewport( viewportVec );
+				renderer.getViewport( _viewportVec );
 
-				viewportVec.multiplyScalar( renderer.getPixelRatio() );
+				_viewportVec.multiplyScalar( renderer.getPixelRatio() );
 
 			}
 
+		} else if ( this.scope === ScreenNode.DPR ) {
+
+			this._output.value = renderer.getPixelRatio();
+
 		} else {
 
 			if ( renderTarget !== null ) {
 
-				screenSizeVec.width = renderTarget.width;
-				screenSizeVec.height = renderTarget.height;
+				_screenSizeVec.width = renderTarget.width;
+				_screenSizeVec.height = renderTarget.height;
 
 			} else {
 
-				renderer.getDrawingBufferSize( screenSizeVec );
+				renderer.getDrawingBufferSize( _screenSizeVec );
 
 			}
 
@@ -137,11 +149,15 @@ class ScreenNode extends Node {
 
 		if ( scope === ScreenNode.SIZE ) {
 
-			output = uniform( screenSizeVec || ( screenSizeVec = new Vector2() ) );
+			output = uniform( _screenSizeVec || ( _screenSizeVec = new Vector2() ) );
 
 		} else if ( scope === ScreenNode.VIEWPORT ) {
 
-			output = uniform( viewportVec || ( viewportVec = new Vector4() ) );
+			output = uniform( _viewportVec || ( _viewportVec = new Vector4() ) );
+
+		} else if ( scope === ScreenNode.DPR ) {
+
+			output = uniform( 1 );
 
 		} else {
 
@@ -149,6 +165,8 @@ class ScreenNode extends Node {
 
 		}
 
+		this._output = output;
+
 		return output;
 
 	}
@@ -183,11 +201,20 @@ ScreenNode.COORDINATE = 'coordinate';
 ScreenNode.VIEWPORT = 'viewport';
 ScreenNode.SIZE = 'size';
 ScreenNode.UV = 'uv';
+ScreenNode.DPR = 'dpr';
 
 export default ScreenNode;
 
 // Screen
 
+/**
+ * TSL object that represents the current DPR.
+ *
+ * @tsl
+ * @type {ScreenNode<vec2>}
+ */
+export const screenDPR = /*@__PURE__*/ nodeImmutable( ScreenNode, ScreenNode.DPR );
+
 /**
  * TSL object that represents normalized screen coordinates, unitless in `[0, 1]`.
  *

粤ICP备19079148号