|
|
@@ -1,5 +1,5 @@
|
|
|
import SpriteNodeMaterial from './SpriteNodeMaterial.js';
|
|
|
-import { viewport } from '../../nodes/display/ScreenNode.js';
|
|
|
+import { viewportSize, screenSize } 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';
|
|
|
@@ -70,61 +70,76 @@ class PointsNodeMaterial extends SpriteNodeMaterial {
|
|
|
|
|
|
setupVertex( builder ) {
|
|
|
|
|
|
- const mvp = super.setupVertex( builder );
|
|
|
+ const { material, camera } = builder;
|
|
|
+
|
|
|
+ const { rotationNode, scaleNode, sizeNode, sizeAttenuation } = this;
|
|
|
+
|
|
|
+ let mvp = super.setupVertex( builder );
|
|
|
|
|
|
// skip further processing if the material is not a node material
|
|
|
|
|
|
- if ( builder.material.isNodeMaterial !== true ) {
|
|
|
+ if ( material.isNodeMaterial !== true ) {
|
|
|
|
|
|
return mvp;
|
|
|
|
|
|
}
|
|
|
|
|
|
- // ndc space
|
|
|
+ // point size
|
|
|
|
|
|
- const { rotationNode, scaleNode, sizeNode } = this;
|
|
|
+ let pointSize = sizeNode !== null ? vec2( sizeNode ) : materialPointSize;
|
|
|
|
|
|
- const alignedPosition = positionGeometry.xy.toVar();
|
|
|
- const aspect = viewport.z.div( viewport.w );
|
|
|
+ const dpr = builder.renderer.getPixelRatio();
|
|
|
|
|
|
- // rotation
|
|
|
+ pointSize = pointSize.mul( dpr );
|
|
|
|
|
|
- if ( rotationNode && rotationNode.isNode ) {
|
|
|
+ // size attenuation
|
|
|
|
|
|
- const rotation = float( rotationNode );
|
|
|
+ if ( camera.isPerspectiveCamera && sizeAttenuation === true ) {
|
|
|
|
|
|
- alignedPosition.assign( rotate( alignedPosition, rotation ) );
|
|
|
+ // 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() ) );
|
|
|
|
|
|
- // point size
|
|
|
+ }
|
|
|
|
|
|
- let pointSize = sizeNode !== null ? vec2( sizeNode ) : materialPointSize;
|
|
|
+ // scale
|
|
|
|
|
|
- if ( this.sizeAttenuation === true ) {
|
|
|
+ if ( scaleNode && scaleNode.isNode ) {
|
|
|
|
|
|
- pointSize = pointSize.mul( pointSize.div( positionView.z.negate() ) );
|
|
|
+ pointSize = pointSize.mul( vec2( scaleNode ) );
|
|
|
|
|
|
}
|
|
|
|
|
|
- // scale
|
|
|
+ // compute offset
|
|
|
|
|
|
- if ( scaleNode && scaleNode.isNode ) {
|
|
|
+ let offset = positionGeometry.xy;
|
|
|
|
|
|
- pointSize = pointSize.mul( vec2( scaleNode ) );
|
|
|
+ // apply rotation
|
|
|
+
|
|
|
+ if ( rotationNode && rotationNode.isNode ) {
|
|
|
+
|
|
|
+ const rotation = float( rotationNode );
|
|
|
+
|
|
|
+ offset = rotate( offset, rotation );
|
|
|
|
|
|
}
|
|
|
|
|
|
- alignedPosition.mulAssign( pointSize.mul( 2 ) );
|
|
|
+ // account for point size
|
|
|
+
|
|
|
+ offset = offset.mul( pointSize );
|
|
|
+
|
|
|
+ // scale by viewport size
|
|
|
+
|
|
|
+ offset = offset.div( viewportSize.div( 2 ) );
|
|
|
+
|
|
|
+ // compensate for the perspective divide
|
|
|
|
|
|
- alignedPosition.assign( alignedPosition.div( viewport.z ) );
|
|
|
- alignedPosition.y.assign( alignedPosition.y.mul( aspect ) );
|
|
|
+ offset = offset.mul( mvp.w );
|
|
|
|
|
|
- // back to clip space
|
|
|
- alignedPosition.assign( alignedPosition.mul( mvp.w ) );
|
|
|
+ // add offset
|
|
|
|
|
|
- //clipPos.xy += offset;
|
|
|
- mvp.addAssign( vec4( alignedPosition, 0, 0 ) );
|
|
|
+ mvp = mvp.add( vec4( offset, 0, 0 ) );
|
|
|
|
|
|
return mvp;
|
|
|
|