Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGPURenderer: Build - three.webgpu.js #28650

Merged
merged 36 commits into from
Jun 30, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
1863206
webgpu build
sunag Jun 13, 2024
b867881
update
sunag Jun 13, 2024
a36d8bf
revision
sunag Jun 13, 2024
9989e63
cleanup
sunag Jun 13, 2024
5310ee6
Restore USDZLoader
sunag Jun 13, 2024
c503f49
update
sunag Jun 13, 2024
2a3e8c3
puppeteer: added `three.webgpu` build support
sunag Jun 14, 2024
2d91329
Merge branch 'dev-webgpu-module' of https://github.com/sunag/three.js…
sunag Jun 14, 2024
9a0a199
update IESSpotLight
sunag Jun 14, 2024
b78d9cf
move to src and revision
sunag Jun 14, 2024
43fea17
Merge branch 'dev' into dev-webgpu-module
sunag Jun 14, 2024
1a648f9
cleanup
sunag Jun 14, 2024
2a60023
fix test-circular-deps test
sunag Jun 14, 2024
168e582
fix lint
sunag Jun 14, 2024
03d7776
revision
sunag Jun 14, 2024
d4ebc74
cleanup lint
sunag Jun 14, 2024
2bcf93e
update build
sunag Jun 14, 2024
adb3732
update package
sunag Jun 14, 2024
08bd1cf
Merge branch 'dev' into dev-webgpu-module
sunag Jun 17, 2024
2a80c86
Merge branch 'dev' into dev-webgpu-module
sunag Jun 17, 2024
19c34cb
Merge branch 'dev' into dev-webgpu-module
sunag Jun 20, 2024
32c6caa
Merge branch 'dev' into dev-webgpu-module
sunag Jun 21, 2024
29959c4
update builds
sunag Jun 21, 2024
03b7715
update
sunag Jun 29, 2024
ec6c34f
update - fixing conflicts
sunag Jun 29, 2024
b65e9ab
cleanup
sunag Jun 29, 2024
e2f5080
WebGPUBackend: add srcRegion to copyTextureToTexture()
sunag Jun 29, 2024
f1416c3
fix examples
sunag Jun 30, 2024
bf73edb
Merge branch 'dev' into dev-webgpu-module
sunag Jun 30, 2024
0866230
fix warnOnce
sunag Jun 30, 2024
e838a10
update path
sunag Jun 30, 2024
3970adb
update build
sunag Jun 30, 2024
84e46ea
Update package.json
sunag Jun 30, 2024
fe8458d
importmap: added alias
sunag Jun 30, 2024
b48f814
move materials to THREE
sunag Jun 30, 2024
286bebf
update import to three/tsl
sunag Jun 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
72,609 changes: 72,609 additions & 0 deletions build/three.webgpu.js

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions build/three.webgpu.min.js

Large diffs are not rendered by default.

91 changes: 91 additions & 0 deletions examples/jsm/lights/RectAreaLightTexturesLib.js

Large diffs are not rendered by default.

71 changes: 8 additions & 63 deletions examples/jsm/lights/RectAreaLightUniformsLib.js

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions examples/jsm/lines/webgpu/Line2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { LineSegments2 } from './LineSegments2.js';
import { LineGeometry } from '../LineGeometry.js';

import { Line2NodeMaterial } from 'three';

class Line2 extends LineSegments2 {

constructor( geometry = new LineGeometry(), material = new Line2NodeMaterial( { color: Math.random() * 0xffffff } ) ) {

super( geometry, material );

this.isLine2 = true;

this.type = 'Line2';

}

}

export { Line2 };
376 changes: 376 additions & 0 deletions examples/jsm/lines/webgpu/LineSegments2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,376 @@
import {
Box3,
InstancedInterleavedBuffer,
InterleavedBufferAttribute,
Line3,
MathUtils,
Matrix4,
Mesh,
Sphere,
Vector3,
Vector4,
Line2NodeMaterial
} from 'three';
import { LineSegmentsGeometry } from '../../lines/LineSegmentsGeometry.js';

const _viewport = new Vector4();

const _start = new Vector3();
const _end = new Vector3();

const _start4 = new Vector4();
const _end4 = new Vector4();

const _ssOrigin = new Vector4();
const _ssOrigin3 = new Vector3();
const _mvMatrix = new Matrix4();
const _line = new Line3();
const _closestPoint = new Vector3();

const _box = new Box3();
const _sphere = new Sphere();
const _clipToWorldVector = new Vector4();

let _ray, _lineWidth;

// Returns the margin required to expand by in world space given the distance from the camera,
// line width, resolution, and camera projection
function getWorldSpaceHalfWidth( camera, distance, resolution ) {

// transform into clip space, adjust the x and y values by the pixel width offset, then
// transform back into world space to get world offset. Note clip space is [-1, 1] so full
// width does not need to be halved.
_clipToWorldVector.set( 0, 0, - distance, 1.0 ).applyMatrix4( camera.projectionMatrix );
_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );
_clipToWorldVector.x = _lineWidth / resolution.width;
_clipToWorldVector.y = _lineWidth / resolution.height;
_clipToWorldVector.applyMatrix4( camera.projectionMatrixInverse );
_clipToWorldVector.multiplyScalar( 1.0 / _clipToWorldVector.w );

return Math.abs( Math.max( _clipToWorldVector.x, _clipToWorldVector.y ) );

}

function raycastWorldUnits( lineSegments, intersects ) {

const matrixWorld = lineSegments.matrixWorld;
const geometry = lineSegments.geometry;
const instanceStart = geometry.attributes.instanceStart;
const instanceEnd = geometry.attributes.instanceEnd;
const segmentCount = Math.min( geometry.instanceCount, instanceStart.count );

for ( let i = 0, l = segmentCount; i < l; i ++ ) {

_line.start.fromBufferAttribute( instanceStart, i );
_line.end.fromBufferAttribute( instanceEnd, i );

_line.applyMatrix4( matrixWorld );

const pointOnLine = new Vector3();
const point = new Vector3();

_ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine );
const isInside = point.distanceTo( pointOnLine ) < _lineWidth * 0.5;

if ( isInside ) {

intersects.push( {
point,
pointOnLine,
distance: _ray.origin.distanceTo( point ),
object: lineSegments,
face: null,
faceIndex: i,
uv: null,
uv1: null,
} );

}

}

}

function raycastScreenSpace( lineSegments, camera, intersects ) {

const projectionMatrix = camera.projectionMatrix;
const material = lineSegments.material;
const resolution = material.resolution;
const matrixWorld = lineSegments.matrixWorld;

const geometry = lineSegments.geometry;
const instanceStart = geometry.attributes.instanceStart;
const instanceEnd = geometry.attributes.instanceEnd;
const segmentCount = Math.min( geometry.instanceCount, instanceStart.count );

const near = - camera.near;

//

// pick a point 1 unit out along the ray to avoid the ray origin
// sitting at the camera origin which will cause "w" to be 0 when
// applying the projection matrix.
_ray.at( 1, _ssOrigin );

// ndc space [ - 1.0, 1.0 ]
_ssOrigin.w = 1;
_ssOrigin.applyMatrix4( camera.matrixWorldInverse );
_ssOrigin.applyMatrix4( projectionMatrix );
_ssOrigin.multiplyScalar( 1 / _ssOrigin.w );

// screen space
_ssOrigin.x *= resolution.x / 2;
_ssOrigin.y *= resolution.y / 2;
_ssOrigin.z = 0;

_ssOrigin3.copy( _ssOrigin );

_mvMatrix.multiplyMatrices( camera.matrixWorldInverse, matrixWorld );

for ( let i = 0, l = segmentCount; i < l; i ++ ) {

_start4.fromBufferAttribute( instanceStart, i );
_end4.fromBufferAttribute( instanceEnd, i );

_start4.w = 1;
_end4.w = 1;

// camera space
_start4.applyMatrix4( _mvMatrix );
_end4.applyMatrix4( _mvMatrix );

// skip the segment if it's entirely behind the camera
const isBehindCameraNear = _start4.z > near && _end4.z > near;
if ( isBehindCameraNear ) {

continue;

}

// trim the segment if it extends behind camera near
if ( _start4.z > near ) {

const deltaDist = _start4.z - _end4.z;
const t = ( _start4.z - near ) / deltaDist;
_start4.lerp( _end4, t );

} else if ( _end4.z > near ) {

const deltaDist = _end4.z - _start4.z;
const t = ( _end4.z - near ) / deltaDist;
_end4.lerp( _start4, t );

}

// clip space
_start4.applyMatrix4( projectionMatrix );
_end4.applyMatrix4( projectionMatrix );

// ndc space [ - 1.0, 1.0 ]
_start4.multiplyScalar( 1 / _start4.w );
_end4.multiplyScalar( 1 / _end4.w );

// screen space
_start4.x *= resolution.x / 2;
_start4.y *= resolution.y / 2;

_end4.x *= resolution.x / 2;
_end4.y *= resolution.y / 2;

// create 2d segment
_line.start.copy( _start4 );
_line.start.z = 0;

_line.end.copy( _end4 );
_line.end.z = 0;

// get closest point on ray to segment
const param = _line.closestPointToPointParameter( _ssOrigin3, true );
_line.at( param, _closestPoint );

// check if the intersection point is within clip space
const zPos = MathUtils.lerp( _start4.z, _end4.z, param );
const isInClipSpace = zPos >= - 1 && zPos <= 1;

const isInside = _ssOrigin3.distanceTo( _closestPoint ) < _lineWidth * 0.5;

if ( isInClipSpace && isInside ) {

_line.start.fromBufferAttribute( instanceStart, i );
_line.end.fromBufferAttribute( instanceEnd, i );

_line.start.applyMatrix4( matrixWorld );
_line.end.applyMatrix4( matrixWorld );

const pointOnLine = new Vector3();
const point = new Vector3();

_ray.distanceSqToSegment( _line.start, _line.end, point, pointOnLine );

intersects.push( {
point: point,
pointOnLine: pointOnLine,
distance: _ray.origin.distanceTo( point ),
object: lineSegments,
face: null,
faceIndex: i,
uv: null,
uv1: null,
} );

}

}

}

class LineSegments2 extends Mesh {

constructor( geometry = new LineSegmentsGeometry(), material = new Line2NodeMaterial( { color: Math.random() * 0xffffff } ) ) {

super( geometry, material );

this.isLineSegments2 = true;

this.type = 'LineSegments2';

}

// for backwards-compatibility, but could be a method of LineSegmentsGeometry...

computeLineDistances() {

const geometry = this.geometry;

const instanceStart = geometry.attributes.instanceStart;
const instanceEnd = geometry.attributes.instanceEnd;
const lineDistances = new Float32Array( 2 * instanceStart.count );

for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {

_start.fromBufferAttribute( instanceStart, i );
_end.fromBufferAttribute( instanceEnd, i );

lineDistances[ j ] = ( j === 0 ) ? 0 : lineDistances[ j - 1 ];
lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end );

}

const instanceDistanceBuffer = new InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1

geometry.setAttribute( 'instanceDistanceStart', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
geometry.setAttribute( 'instanceDistanceEnd', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1

return this;

}

raycast( raycaster, intersects ) {

const worldUnits = this.material.worldUnits;
const camera = raycaster.camera;

if ( camera === null && ! worldUnits ) {

console.error( 'LineSegments2: "Raycaster.camera" needs to be set in order to raycast against LineSegments2 while worldUnits is set to false.' );

}

const threshold = ( raycaster.params.Line2 !== undefined ) ? raycaster.params.Line2.threshold || 0 : 0;

_ray = raycaster.ray;

const matrixWorld = this.matrixWorld;
const geometry = this.geometry;
const material = this.material;

_lineWidth = material.linewidth + threshold;

// check if we intersect the sphere bounds
if ( geometry.boundingSphere === null ) {

geometry.computeBoundingSphere();

}

_sphere.copy( geometry.boundingSphere ).applyMatrix4( matrixWorld );

// increase the sphere bounds by the worst case line screen space width
let sphereMargin;
if ( worldUnits ) {

sphereMargin = _lineWidth * 0.5;

} else {

const distanceToSphere = Math.max( camera.near, _sphere.distanceToPoint( _ray.origin ) );
sphereMargin = getWorldSpaceHalfWidth( camera, distanceToSphere, material.resolution );

}

_sphere.radius += sphereMargin;

if ( _ray.intersectsSphere( _sphere ) === false ) {

return;

}

// check if we intersect the box bounds
if ( geometry.boundingBox === null ) {

geometry.computeBoundingBox();

}

_box.copy( geometry.boundingBox ).applyMatrix4( matrixWorld );

// increase the box bounds by the worst case line width
let boxMargin;
if ( worldUnits ) {

boxMargin = _lineWidth * 0.5;

} else {

const distanceToBox = Math.max( camera.near, _box.distanceToPoint( _ray.origin ) );
boxMargin = getWorldSpaceHalfWidth( camera, distanceToBox, material.resolution );

}

_box.expandByScalar( boxMargin );

if ( _ray.intersectsBox( _box ) === false ) {

return;

}

if ( worldUnits ) {

raycastWorldUnits( this, intersects );

} else {

raycastScreenSpace( this, camera, intersects );

}

}

onBeforeRender( renderer ) {

const uniforms = this.material.uniforms;

if ( uniforms && uniforms.resolution ) {

renderer.getViewport( _viewport );
this.material.uniforms.resolution.value.set( _viewport.z, _viewport.w );

}

}

}

export { LineSegments2 };
Loading