@threepipe/plugin-gaussian-splatting 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/assets/worker-dK7pvmNj.js +1569 -0
  2. package/dist/assets/worker-dK7pvmNj.js.map +1 -0
  3. package/dist/dependencies.txt +212 -0
  4. package/dist/gaussian-splats-3d/GaussianSplatsPlugin.d.ts +1 -0
  5. package/dist/gaussian-splats-3d/GaussianSplatsPlugin.d.ts.map +1 -0
  6. package/dist/index.d.ts +5 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +879 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/index.mjs +876 -0
  11. package/dist/index.mjs.map +1 -0
  12. package/dist/three-gaussian-splat/ThreeGaussianSplatPlugin.d.ts +45 -0
  13. package/dist/three-gaussian-splat/ThreeGaussianSplatPlugin.d.ts.map +1 -0
  14. package/dist/three-gaussian-splat/cpp-sorter/BufferPool.d.ts +9 -0
  15. package/dist/three-gaussian-splat/cpp-sorter/BufferPool.d.ts.map +1 -0
  16. package/dist/three-gaussian-splat/cpp-sorter/SortWorkerManager.d.ts +13 -0
  17. package/dist/three-gaussian-splat/cpp-sorter/SortWorkerManager.d.ts.map +1 -0
  18. package/dist/three-gaussian-splat/cpp-sorter/worker.d.ts +18 -0
  19. package/dist/three-gaussian-splat/cpp-sorter/worker.d.ts.map +1 -0
  20. package/dist/three-gaussian-splat/geometry/GaussianSplatGeometry.d.ts +25 -0
  21. package/dist/three-gaussian-splat/geometry/GaussianSplatGeometry.d.ts.map +1 -0
  22. package/dist/three-gaussian-splat/index.d.ts +22 -0
  23. package/dist/three-gaussian-splat/index.d.ts.map +1 -0
  24. package/dist/three-gaussian-splat/loaders/SplatLoader.d.ts +13 -0
  25. package/dist/three-gaussian-splat/loaders/SplatLoader.d.ts.map +1 -0
  26. package/dist/three-gaussian-splat/materials/GaussianSplatMaterialExtension.d.ts +28 -0
  27. package/dist/three-gaussian-splat/materials/GaussianSplatMaterialExtension.d.ts.map +1 -0
  28. package/dist/three-gaussian-splat/materials/GaussianSplatMaterialPhysical.d.ts +9 -0
  29. package/dist/three-gaussian-splat/materials/GaussianSplatMaterialPhysical.d.ts.map +1 -0
  30. package/dist/three-gaussian-splat/materials/GaussianSplatMaterialRaw.d.ts +12 -0
  31. package/dist/three-gaussian-splat/materials/GaussianSplatMaterialRaw.d.ts.map +1 -0
  32. package/dist/three-gaussian-splat/materials/GaussianSplatMaterialUnlit.d.ts +9 -0
  33. package/dist/three-gaussian-splat/materials/GaussianSplatMaterialUnlit.d.ts.map +1 -0
  34. package/dist/three-gaussian-splat/materials/util.d.ts +3 -0
  35. package/dist/three-gaussian-splat/materials/util.d.ts.map +1 -0
  36. package/dist/three-gaussian-splat/mesh/GaussianSplatMesh.d.ts +10 -0
  37. package/dist/three-gaussian-splat/mesh/GaussianSplatMesh.d.ts.map +1 -0
  38. package/dist/three-gaussian-splat/shaders/index.d.ts +7 -0
  39. package/dist/three-gaussian-splat/shaders/index.d.ts.map +1 -0
  40. package/package.json +34 -0
  41. package/src/gaussian-splats-3d/GaussianSplatsPlugin.ts +50 -0
  42. package/src/global.d.ts +40 -0
  43. package/src/index.ts +5 -0
  44. package/src/three-gaussian-splat/ThreeGaussianSplatPlugin.css +3 -0
  45. package/src/three-gaussian-splat/ThreeGaussianSplatPlugin.ts +74 -0
  46. package/src/three-gaussian-splat/cpp-sorter/BufferPool.ts +30 -0
  47. package/src/three-gaussian-splat/cpp-sorter/ISort.d.ts +3 -0
  48. package/src/three-gaussian-splat/cpp-sorter/SortWorkerManager.ts +53 -0
  49. package/src/three-gaussian-splat/cpp-sorter/build-in-docker.sh +4 -0
  50. package/src/three-gaussian-splat/cpp-sorter/build.sh +7 -0
  51. package/src/three-gaussian-splat/cpp-sorter/sort.cpp +107 -0
  52. package/src/three-gaussian-splat/cpp-sorter/sort.js +16 -0
  53. package/src/three-gaussian-splat/cpp-sorter/sort.wasm +0 -0
  54. package/src/three-gaussian-splat/cpp-sorter/watch.sh +9 -0
  55. package/src/three-gaussian-splat/cpp-sorter/worker.ts +59 -0
  56. package/src/three-gaussian-splat/geometry/GaussianSplatGeometry.ts +182 -0
  57. package/src/three-gaussian-splat/index.ts +22 -0
  58. package/src/three-gaussian-splat/loaders/SplatLoader.ts +51 -0
  59. package/src/three-gaussian-splat/materials/GaussianSplatMaterialExtension.ts +105 -0
  60. package/src/three-gaussian-splat/materials/GaussianSplatMaterialPhysical.ts +25 -0
  61. package/src/three-gaussian-splat/materials/GaussianSplatMaterialRaw.ts +73 -0
  62. package/src/three-gaussian-splat/materials/GaussianSplatMaterialUnlit.ts +26 -0
  63. package/src/three-gaussian-splat/materials/util.ts +9 -0
  64. package/src/three-gaussian-splat/mesh/GaussianSplatMesh.ts +96 -0
  65. package/src/three-gaussian-splat/shaders/gsplat.main.frag.glsl +18 -0
  66. package/src/three-gaussian-splat/shaders/gsplat.main.vert.glsl +15 -0
  67. package/src/three-gaussian-splat/shaders/gsplat.pars.frag.glsl +10 -0
  68. package/src/three-gaussian-splat/shaders/gsplat.pars.vert.glsl +58 -0
  69. package/src/three-gaussian-splat/shaders/index.ts +11 -0
@@ -0,0 +1,51 @@
1
+ import {FileLoader, ILoader, IMaterial, Loader, LoadingManager} from 'threepipe'
2
+ import {SortWorkerManager, SPLAT_ROW_LENGTH} from '../cpp-sorter/SortWorkerManager'
3
+ import {GaussianSplatGeometry} from '../geometry/GaussianSplatGeometry'
4
+ import {GaussianSplatMesh} from '../mesh/GaussianSplatMesh'
5
+ import {GaussianSplatMaterialUnlit} from '../materials/GaussianSplatMaterialUnlit'
6
+
7
+ export class SplatLoader extends Loader implements ILoader {
8
+ sortWorkerManager: SortWorkerManager
9
+
10
+ materialConstructor = (_: GaussianSplatGeometry): IMaterial|undefined => new GaussianSplatMaterialUnlit()
11
+
12
+ constructor(manager?: LoadingManager) {
13
+ super(manager)
14
+ }
15
+
16
+ onGeometryLoad = (_: GaussianSplatGeometry)=>{
17
+ return
18
+ }
19
+
20
+ public load(url: string, onLoad?: (data: GaussianSplatMesh) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void): void {
21
+ // const path = ( scope.path === '' ) ? LoaderUtils.extractUrlBase( url ) : scope.path;
22
+ const loader = new FileLoader(this.manager)
23
+ loader.setPath(this.path)
24
+ loader.setResponseType('arraybuffer')
25
+ loader.setRequestHeader(this.requestHeader)
26
+ loader.setWithCredentials(this.withCredentials)
27
+ loader.load(url, async(buffer) => {
28
+ try {
29
+ const data = new Uint8Array(buffer as ArrayBuffer)
30
+ const maxSplats = 1000000
31
+ const vertexCount = Math.floor(data.length / SPLAT_ROW_LENGTH)
32
+ const worker = await this.sortWorkerManager.createWorker(data, maxSplats)
33
+ const geometry = new GaussianSplatGeometry(worker, vertexCount, maxSplats, this.onGeometryLoad)
34
+ const mesh = new GaussianSplatMesh(geometry, this.materialConstructor(geometry) as any)
35
+ // const mesh = new GaussianSplatMesh(geometry, new UnlitMaterial() as any)
36
+ mesh.rotation.x = Math.PI
37
+ if (!url.startsWith('blob:') && !url.startsWith('data:'))
38
+ mesh.name = url.split('/').pop()!.split('?')[0]
39
+ onLoad && onLoad(mesh)
40
+ } catch (e) {
41
+ if (onError) onError(e)
42
+ else console.error(e)
43
+ this.manager.itemError(url)
44
+ }
45
+ }, onProgress, onError)
46
+ }
47
+
48
+ public async loadAsync(url: string, onProgress?: (event: ProgressEvent) => void): Promise<GaussianSplatMesh> {
49
+ return new Promise((resolve, reject) => this.load(url, resolve, onProgress, reject))
50
+ }
51
+ }
@@ -0,0 +1,105 @@
1
+ import {
2
+ Camera,
3
+ IMaterial,
4
+ MaterialExtension,
5
+ PerspectiveCamera,
6
+ Shader,
7
+ shaderReplaceString,
8
+ Vector2,
9
+ WebGLRenderer,
10
+ } from 'threepipe'
11
+ import {computeFocalLengths} from './util'
12
+ import {gaussianSplatShaders} from '../shaders'
13
+
14
+ export class GaussianSplatMaterialExtension implements MaterialExtension {
15
+ readonly isGaussianSplatMaterialExtension = true
16
+ extraUniforms = {
17
+ viewport: {value: new Vector2()},
18
+ focal: {value: new Vector2()},
19
+ minAlpha: {value: 0.02},
20
+ }
21
+ parsFragmentSnippet = gaussianSplatShaders.pars_frag
22
+ parsVertexSnippet = gaussianSplatShaders.pars_vert
23
+ shaderExtender = (shader: Shader, material: IMaterial) => {
24
+ shader.vertexShader = shaderReplaceString(shader.vertexShader,
25
+ '#include <begin_vertex>',
26
+ 'vec3 transformed = vec3( center );')
27
+ if (shader.vertexShader.includes('#include <beginnormal_vertex>')) {
28
+ // todo: get correct normal by rendering to depth and then sampling the normal
29
+ shader.vertexShader = shaderReplaceString(shader.vertexShader,
30
+ '#include <beginnormal_vertex>',
31
+ '\nobjectNormal = vec3(1,0,0);\n', {append: true})
32
+ }
33
+ shader.vertexShader = shaderReplaceString(shader.vertexShader,
34
+ '#include <project_vertex>',
35
+ gaussianSplatShaders.main_vert, {append: true})
36
+
37
+ if (!material.isGBufferMaterial && !material.userData.isGBufferMaterial) {
38
+ shader.fragmentShader = shaderReplaceString(shader.fragmentShader,
39
+ '#include <map_fragment>',
40
+ shaderReplaceString(
41
+ gaussianSplatShaders.main_frag,
42
+ /gl_FragColor\s*=/, // because of minification
43
+ 'diffuseColor*='
44
+ ), {prepend: true})
45
+ }
46
+ // eslint-disable-next-line no-constant-condition
47
+ if (0)
48
+ shader.fragmentShader = shaderReplaceString(shader.fragmentShader,
49
+ '#include <output_fragment>',
50
+ '\ngl_FragColor=diffuseColor;',
51
+ // '\ngl_FragColor=vec4(reflectedLight.directDiffuse, 1.);',
52
+ // '\ngl_FragColor=vec4(geometryNormal, 1.);',
53
+ {append: true})
54
+ return shader
55
+ }
56
+ isCompatible = (material: IMaterial) =>
57
+ !!material.isPhysicalMaterial ||
58
+ !!material.isUnlitMaterial ||
59
+ !!material.isGBufferMaterial ||
60
+ !!material.userData.isGBufferMaterial
61
+
62
+ setDirty?: () => void
63
+
64
+ private _currentCamera?: PerspectiveCamera | Camera
65
+ private _renderer?: WebGLRenderer
66
+
67
+ public set minAlpha(value: number) {
68
+ this.extraUniforms.minAlpha.value = value
69
+ this.setDirty && this.setDirty()
70
+ }
71
+
72
+
73
+ constructor() {
74
+ window.addEventListener('resize', this._refresh)
75
+ }
76
+
77
+ dispose() {
78
+ // todo: add again on added to mesh?
79
+ window.removeEventListener('resize', this._refresh)
80
+ }
81
+
82
+ update(camera: PerspectiveCamera | Camera, renderer: WebGLRenderer): void {
83
+ if (this._currentCamera === camera && this._renderer === renderer) return
84
+ this._renderer = renderer
85
+ this._currentCamera = camera
86
+ this._refresh()
87
+ }
88
+
89
+ private _refresh = (): void => {
90
+ if (!this._currentCamera) return
91
+ const size = new Vector2()
92
+ this._renderer?.getSize(size)
93
+ const dpr = this._renderer?.getPixelRatio() || 1
94
+ let fov = 75
95
+ let aspect = size.x / size.y
96
+
97
+ if (this._currentCamera instanceof PerspectiveCamera) {
98
+ fov = this._currentCamera.fov
99
+ aspect = this._currentCamera.aspect
100
+ }
101
+
102
+ this.extraUniforms.focal.value = computeFocalLengths(size.x, size.y, fov, aspect, dpr)
103
+ this.extraUniforms.viewport.value = new Vector2(size.x * dpr, size.y * dpr)
104
+ }
105
+ }
@@ -0,0 +1,25 @@
1
+ import {PhysicalMaterial} from 'threepipe'
2
+ import {GaussianSplatMaterialExtension} from './GaussianSplatMaterialExtension'
3
+
4
+ export class GaussianSplatMaterialPhysical extends PhysicalMaterial {
5
+ readonly isGaussianSplatMaterialPhysical = true
6
+
7
+ gsplatExtension = new GaussianSplatMaterialExtension()
8
+
9
+ constructor() {
10
+ super({
11
+ depthTest: true,
12
+ depthWrite: false,
13
+ transparent: true,
14
+ vertexColors: false,
15
+ })
16
+ // this.userData.renderToGBuffer = true
17
+ // this.userData.renderToDepth = true
18
+ this.registerMaterialExtensions([this.gsplatExtension])
19
+ }
20
+
21
+ dispose() {
22
+ this.gsplatExtension.dispose()
23
+ return super.dispose()
24
+ }
25
+ }
@@ -0,0 +1,73 @@
1
+ import {Camera, PerspectiveCamera, ShaderMaterial2, Vector2, WebGLRenderer} from 'threepipe'
2
+ import {computeFocalLengths} from './util'
3
+ import {gaussianSplatShaders} from '../shaders'
4
+
5
+ export class GaussianSplatMaterialRaw extends ShaderMaterial2 {
6
+ private _currentCamera?: PerspectiveCamera | Camera
7
+ private _renderer?: WebGLRenderer
8
+
9
+ readonly isGaussianSplatMaterialRaw = true
10
+
11
+ public set minAlpha(value: number) {
12
+ this.uniforms.minAlpha.value = value
13
+ this.needsUpdate = true
14
+ }
15
+
16
+ constructor() {
17
+ super({
18
+ uniforms: {
19
+ viewport: {value: new Vector2()},
20
+ focal: {value: new Vector2()},
21
+ minAlpha: {value: 0.02},
22
+ },
23
+ fragmentShader: `${gaussianSplatShaders.pars_frag}
24
+ void main () {
25
+ ${gaussianSplatShaders.main_frag}
26
+ }`,
27
+ vertexShader: `${gaussianSplatShaders.pars_vert}
28
+ void main () {
29
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(center, 1);
30
+ ${gaussianSplatShaders.main_vert}
31
+ }`,
32
+ depthTest: true,
33
+ depthWrite: false,
34
+ transparent: true,
35
+ }, true)
36
+
37
+ window.addEventListener('resize', this._refresh)
38
+ }
39
+
40
+ private _refresh = (): void => {
41
+ if (!this._currentCamera) return
42
+
43
+ const size = new Vector2()
44
+ this._renderer?.getSize(size)
45
+ const width = size.x
46
+ const height = size.y
47
+
48
+ const dpr = this._renderer?.getPixelRatio() || 1
49
+
50
+ let fov = 75
51
+ let aspect = width / height
52
+
53
+ if (this._currentCamera instanceof PerspectiveCamera) {
54
+ fov = this._currentCamera.fov
55
+ aspect = this._currentCamera.aspect
56
+ }
57
+
58
+ this.uniforms.focal.value = computeFocalLengths(width, height, fov, aspect, dpr)
59
+ this.uniforms.viewport.value = new Vector2(width * dpr, height * dpr)
60
+ }
61
+
62
+ dispose() {
63
+ // todo: add again on added to mesh?
64
+ window.removeEventListener('resize', this._refresh)
65
+ return super.dispose()
66
+ }
67
+
68
+ update(camera: PerspectiveCamera | Camera, renderer: WebGLRenderer): void {
69
+ this._renderer = renderer
70
+ this._currentCamera = camera
71
+ this._refresh()
72
+ }
73
+ }
@@ -0,0 +1,26 @@
1
+ import {UnlitMaterial} from 'threepipe'
2
+
3
+ import {GaussianSplatMaterialExtension} from './GaussianSplatMaterialExtension'
4
+
5
+ export class GaussianSplatMaterialUnlit extends UnlitMaterial {
6
+ readonly isGaussianSplatMaterialUnlit = true
7
+ gsplatExtension = new GaussianSplatMaterialExtension()
8
+
9
+ constructor() {
10
+ super({
11
+ depthTest: true,
12
+ depthWrite: false,
13
+ transparent: true,
14
+ vertexColors: false,
15
+ })
16
+ // this.userData.renderToGBuffer = true
17
+ // this.userData.renderToDepth = true
18
+ this.registerMaterialExtensions([this.gsplatExtension])
19
+ }
20
+
21
+ dispose() {
22
+ this.gsplatExtension.dispose()
23
+ return super.dispose()
24
+ }
25
+ }
26
+
@@ -0,0 +1,9 @@
1
+ import {MathUtils, Vector2} from 'threepipe'
2
+
3
+ export const computeFocalLengths = (width: number, height: number, fov: number, aspect: number, dpr: number) => {
4
+ const fovRad = MathUtils.degToRad(fov)
5
+ const fovXRad = 2 * Math.atan(Math.tan(fovRad / 2) * aspect)
6
+ const fy = dpr * height / (2 * Math.tan(fovRad / 2))
7
+ const fx = dpr * width / (2 * Math.tan(fovXRad / 2))
8
+ return new Vector2(fx, fy)
9
+ }
@@ -0,0 +1,96 @@
1
+ import {GaussianSplatGeometry} from '../geometry/GaussianSplatGeometry'
2
+ import {Camera, IMaterial, Mesh2, PerspectiveCamera, WebGLRenderer} from 'threepipe'
3
+ import type {GaussianSplatMaterialRaw} from '../materials/GaussianSplatMaterialRaw'
4
+ import {GaussianSplatMaterialUnlit} from '../materials/GaussianSplatMaterialUnlit'
5
+ import {Matrix4, Ray, Raycaster, Sphere, Vector3} from 'three'
6
+ import {GaussianSplatMaterialExtension} from '../materials/GaussianSplatMaterialExtension'
7
+
8
+ export class GaussianSplatMesh extends Mesh2<GaussianSplatGeometry, IMaterial> {
9
+ readonly isGaussianSplatMesh = true
10
+
11
+ constructor(geometry: GaussianSplatGeometry, material: IMaterial) {
12
+ super(geometry, material)
13
+ this.frustumCulled = false
14
+ }
15
+
16
+ public async update(camera: PerspectiveCamera | Camera, renderer: WebGLRenderer) {
17
+ if ((this.material as any as GaussianSplatMaterialRaw)?.isGaussianSplatMaterialRaw) {
18
+ (this.material as any as GaussianSplatMaterialRaw).update(camera, renderer)
19
+ } else if (this.material) {
20
+ const ext =
21
+ (this.material as GaussianSplatMaterialUnlit).gsplatExtension ??
22
+ this.material.materialExtensions.find(e=>
23
+ (e as GaussianSplatMaterialExtension).isGaussianSplatMaterialExtension) as GaussianSplatMaterialExtension
24
+ ext && ext.update(camera, renderer)
25
+ }
26
+ this.updateMatrixWorld(true)
27
+ return this.geometry.update(camera, this.matrixWorld)
28
+ }
29
+
30
+ raycast(raycaster: Raycaster, intersects: any[]) {
31
+
32
+ const geometry = this.geometry
33
+ const matrixWorld = this.matrixWorld
34
+ // const threshold = raycaster.params.Points?.threshold ?? .01
35
+ const threshold = .02
36
+
37
+ // Checking boundingSphere distance to ray
38
+
39
+ if (geometry.boundingSphere === null) geometry.computeBoundingSphere()
40
+
41
+ const sphere = new Sphere()
42
+ sphere.copy(geometry.boundingSphere!)
43
+ sphere.applyMatrix4(matrixWorld)
44
+ sphere.radius += threshold
45
+
46
+ if (!raycaster.ray.intersectsSphere(sphere)) return
47
+
48
+ //
49
+
50
+ const inverseMatrix = new Matrix4()
51
+ const ray = new Ray()
52
+
53
+ inverseMatrix.copy(matrixWorld).invert()
54
+ ray.copy(raycaster.ray).applyMatrix4(inverseMatrix)
55
+
56
+ const localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3)
57
+ const localThresholdSq = localThreshold * localThreshold
58
+
59
+ const attributes = geometry.attributes
60
+ const positionAttribute = attributes.center
61
+
62
+ const position = new Vector3()
63
+ for (let i = 0, l = positionAttribute.count; i < l; i++) {
64
+
65
+ position.fromBufferAttribute(positionAttribute, i)
66
+
67
+ const rayPointDistanceSq = ray.distanceSqToPoint(position)
68
+
69
+ if (rayPointDistanceSq < localThresholdSq) {
70
+
71
+ const intersectPoint = new Vector3()
72
+
73
+ ray.closestPointToPoint(position, intersectPoint)
74
+ intersectPoint.applyMatrix4(matrixWorld)
75
+
76
+ const distance = raycaster.ray.origin.distanceTo(intersectPoint)
77
+
78
+ if (distance < raycaster.near || distance > raycaster.far) return
79
+
80
+ intersects.push({
81
+
82
+ distance: distance,
83
+ distanceToRay: Math.sqrt(rayPointDistanceSq),
84
+ point: intersectPoint,
85
+ face: null,
86
+ object: this,
87
+
88
+ })
89
+
90
+
91
+ }
92
+ }
93
+
94
+ }
95
+
96
+ }
@@ -0,0 +1,18 @@
1
+ vec2 d = (vCenter - 2.0 * (gl_FragCoord.xy/viewport - vec2(0.5, 0.5))) * viewport * 0.5;
2
+
3
+ float power = -0.5 * (vConic.x * d.x * d.x + vConic.z * d.y * d.y) + vConic.y * d.x * d.y;
4
+
5
+ if (power > 0.0) discard;
6
+ float alpha = min(0.99, vColor.a * exp(power));
7
+ if(alpha < minAlpha) discard;
8
+
9
+ gl_FragColor = vec4(vColor.rgb, alpha);
10
+ //vec2 d = (vCenter - 2.0 * (gl_FragCoord.xy/viewport - vec2(0.5, 0.5))) * viewport * 0.5;
11
+ //
12
+ //float power = -0.5 * (vConic.x * d.x * d.x + vConic.z * d.y * d.y) + vConic.y * d.x * d.y;
13
+ //
14
+ //if (power > 0.0) discard;
15
+ //float alpha = min(0.99, vColor.a * exp(power));
16
+ //if(alpha < minAlpha) discard;
17
+ //
18
+ //diffuseColor *= vec4(vColor.rgb, alpha);
@@ -0,0 +1,15 @@
1
+ vec3 cov2d = compute_cov2d(center, scale, quat);
2
+ float det = cov2d.x * cov2d.z - cov2d.y * cov2d.y;
3
+ vec3 conic = vec3(cov2d.z, cov2d.y, cov2d.x) / det;
4
+ float mid = 0.5 * (cov2d.x + cov2d.z);
5
+ float lambda1 = mid + sqrt(max(0.1, mid * mid - det));
6
+ float lambda2 = mid - sqrt(max(0.1, mid * mid - det));
7
+ vec2 v1 = 7.0 * sqrt(lambda1) * normalize(vec2(cov2d.y, lambda1 - cov2d.x));
8
+ vec2 v2 = 7.0 * sqrt(lambda2) * normalize(vec2(-(lambda1 - cov2d.x),cov2d.y));
9
+
10
+ vColor = color;
11
+ vConic = conic;
12
+ vCenter = vec2(gl_Position) / gl_Position.w;
13
+
14
+ vPosition = vec2(vCenter + position.x * (position.y < 0.0 ? v1 : v2) / viewport);
15
+ gl_Position = vec4(vPosition, gl_Position.z / gl_Position.w, 1);
@@ -0,0 +1,10 @@
1
+ // https://github.com/vincent-lecrubier-skydio/react-three-fiber-gaussian-splat
2
+ precision mediump float;
3
+
4
+ varying vec4 vColor;
5
+ varying vec3 vConic;
6
+ varying vec2 vCenter;
7
+
8
+ uniform vec2 viewport;
9
+ uniform vec2 focal;
10
+ uniform float minAlpha;
@@ -0,0 +1,58 @@
1
+ // https://github.com/vincent-lecrubier-skydio/react-three-fiber-gaussian-splat
2
+ precision mediump float;
3
+
4
+ #ifndef SHADER_NAME // isRawShaderMaterial
5
+ attribute vec3 position;
6
+ uniform mat4 modelViewMatrix;
7
+ uniform mat4 projectionMatrix;
8
+ mat3 transpose(mat3 m) { return mat3(m[0][0], m[1][0], m[2][0], m[0][1], m[1][1], m[2][1], m[0][2], m[1][2], m[2][2]); }
9
+ #endif
10
+
11
+ attribute vec4 color;
12
+ attribute vec4 quat;
13
+ attribute vec3 scale;
14
+ attribute vec3 center;
15
+
16
+ uniform vec2 focal;
17
+ uniform vec2 viewport;
18
+ //uniform vec3 sphereCenter;
19
+ //uniform vec3 planeNormal;
20
+ //uniform float planeDistance;
21
+
22
+ varying vec4 vColor;
23
+ varying vec3 vConic;
24
+ varying vec2 vCenter;
25
+ varying vec2 vPosition;
26
+ //varying float vDistance;
27
+ //varying float vPlaneSide;
28
+
29
+ mat3 compute_cov3d(vec3 scale, vec4 rot) {
30
+ mat3 S = mat3(
31
+ scale.x, 0.0, 0.0,
32
+ 0.0, scale.y, 0.0,
33
+ 0.0, 0.0, scale.z
34
+ );
35
+ mat3 R = mat3(
36
+ 1.0 - 2.0 * (rot.z * rot.z + rot.w * rot.w), 2.0 * (rot.y * rot.z - rot.x * rot.w), 2.0 * (rot.y * rot.w + rot.x * rot.z),
37
+ 2.0 * (rot.y * rot.z + rot.x * rot.w), 1.0 - 2.0 * (rot.y * rot.y + rot.w * rot.w), 2.0 * (rot.z * rot.w - rot.x * rot.y),
38
+ 2.0 * (rot.y * rot.w - rot.x * rot.z), 2.0 * (rot.z * rot.w + rot.x * rot.y), 1.0 - 2.0 * (rot.y * rot.y + rot.z * rot.z)
39
+ );
40
+ mat3 M = S * R;
41
+ return transpose(M) * M;
42
+ }
43
+
44
+ vec3 compute_cov2d(vec3 center, vec3 scale, vec4 rot){
45
+ mat3 Vrk = compute_cov3d(scale, rot);
46
+ vec4 t = modelViewMatrix * vec4(center, 1.0);
47
+ vec2 lims = 1.3 * 0.5 * viewport / focal;
48
+ t.xy = min(lims, max(-lims, t.xy / t.z)) * t.z;
49
+ mat3 J = mat3(
50
+ focal.x / t.z, 0., -(focal.x * t.x) / (t.z * t.z),
51
+ 0., focal.y / t.z, -(focal.y * t.y) / (t.z * t.z),
52
+ 0., 0., 0.
53
+ );
54
+ mat3 W = transpose(mat3(modelViewMatrix));
55
+ mat3 T = W * J;
56
+ mat3 cov = transpose(T) * transpose(Vrk) * T;
57
+ return vec3(cov[0][0] + 0.3, cov[0][1], cov[1][1] + 0.3);
58
+ }
@@ -0,0 +1,11 @@
1
+ import fragmentParsShaderSource from '../shaders/gsplat.pars.frag.glsl'
2
+ import vertexParsShaderSource from '../shaders/gsplat.pars.vert.glsl'
3
+ import vertexShaderSource from '../shaders/gsplat.main.vert.glsl'
4
+ import fragmentShaderSource from '../shaders/gsplat.main.frag.glsl'
5
+
6
+ export const gaussianSplatShaders = {
7
+ main_frag: '\n' + fragmentShaderSource + '\n',
8
+ main_vert: '\n' + vertexShaderSource + '\n',
9
+ pars_frag: fragmentParsShaderSource,
10
+ pars_vert: vertexParsShaderSource,
11
+ }