diff --git a/src/SparkRenderer.ts b/src/SparkRenderer.ts index f3f3fecb..1e24ef64 100644 --- a/src/SparkRenderer.ts +++ b/src/SparkRenderer.ts @@ -20,6 +20,7 @@ import { isMobile, isOculus, isVisionPro, + uploadU32DataTextureRows, } from "./utils"; export interface SparkRendererOptions { @@ -1084,34 +1085,16 @@ export class SparkRenderer extends THREE.Mesh { this.orderingTexture = orderingTexture; } else { const renderer = this.renderer; - const gl = renderer.getContext() as WebGL2RenderingContext; if (!renderer.properties.has(this.orderingTexture)) { this.orderingTexture.needsUpdate = true; } else { - const props = renderer.properties.get(this.orderingTexture) as { - __webglTexture: WebGLTexture; - }; - const glTexture = props.__webglTexture; - if (!glTexture) { - throw new Error("ordering texture not found"); - } - renderer.state.activeTexture(gl.TEXTURE0); - renderer.state.bindTexture(gl.TEXTURE_2D, glTexture); - gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, null); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); - gl.texSubImage2D( - gl.TEXTURE_2D, - 0, - 0, - 0, + uploadU32DataTextureRows( + renderer, + this.orderingTexture, 4096, rows, - gl.RGBA_INTEGER, - gl.UNSIGNED_INT, - // data, result.ordering, ); - renderer.state.bindTexture(gl.TEXTURE_2D, null); } } diff --git a/src/SplatPager.ts b/src/SplatPager.ts index 3d53d743..5876bd7e 100644 --- a/src/SplatPager.ts +++ b/src/SplatPager.ts @@ -16,7 +16,12 @@ import { SplatFileType, } from "./defines"; import { pagedSplatTexCoord } from "./dyno"; -import { decodeExtSplat, getTextureSize, unpackSplat } from "./utils"; +import { + decodeExtSplat, + getTextureSize, + unpackSplat, + uploadU32DataTextureRows, +} from "./utils"; import * as wasm from "./wasm"; export interface PagedSplatsOptions { @@ -341,26 +346,13 @@ export class PagedSplats implements SplatSource { const textureIndices = indicesTexture.image.data as Uint32Array; textureIndices.set(indices.subarray(0, numSplats)); - const gl = renderer.getContext() as WebGL2RenderingContext; - renderer.state.activeTexture(gl.TEXTURE0); - renderer.state.bindTexture( - gl.TEXTURE_2D, - getGlTexture(renderer, indicesTexture), - ); - gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, null); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); - gl.texSubImage2D( - gl.TEXTURE_2D, - 0, - 0, - 0, + uploadU32DataTextureRows( + renderer, + indicesTexture, 4096, rows, - gl.RGBA_INTEGER, - gl.UNSIGNED_INT, - indices, + textureIndices, ); - renderer.state.bindTexture(gl.TEXTURE_2D, null); } } @@ -1278,10 +1270,6 @@ export class SplatPager { // this.renderer.state.bindTexture(gl.TEXTURE_2D_ARRAY, null); } - private getGlTexture(texture: THREE.Texture): WebGLTexture { - return getGlTexture(this.renderer, texture); - } - private newUint32ArrayTexture( data: Uint32Array | null, width: number, @@ -1523,23 +1511,6 @@ export class SplatPager { static emptyExtSh3BTexture = this.emptyUint32x4; } -function getGlTexture( - renderer: THREE.WebGLRenderer, - texture: THREE.Texture, -): WebGLTexture { - if (!renderer.properties.has(texture)) { - throw new Error("texture not found"); - } - const props = renderer.properties.get(texture) as { - __webglTexture: WebGLTexture; - }; - const glTexture = props.__webglTexture; - if (!glTexture) { - throw new Error("texture not found"); - } - return glTexture; -} - async function fetchRange({ url, requestHeader, diff --git a/src/utils.ts b/src/utils.ts index 1b469f76..f83d6f00 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1676,3 +1676,44 @@ export class GunzipReader { return result; } } + +export function uploadU32DataTextureRows( + renderer: THREE.WebGLRenderer, + texture: THREE.Texture, + width: number, + rows: number, + data: Uint32Array, +) { + const gl = renderer.getContext() as WebGL2RenderingContext; + + const props = renderer.properties.get(texture) as { + __webglTexture: WebGLTexture; + }; + const glTexture = props?.__webglTexture; + if (!glTexture) { + throw new Error("texture not found"); + } + // Note: instead of saving and restoring the pixelStorei parameters + // renderer.state.pixelStorei can be used with Three.js >= r184 + const currentFlipY = gl.getParameter(gl.UNPACK_FLIP_Y_WEBGL); + const currentPremultiply = gl.getParameter(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL); + renderer.state.activeTexture(gl.TEXTURE0); + renderer.state.bindTexture(gl.TEXTURE_2D, glTexture); + gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, null); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + gl.texSubImage2D( + gl.TEXTURE_2D, + 0, + 0, + 0, + width, + rows, + gl.RGBA_INTEGER, + gl.UNSIGNED_INT, + data, + ); + renderer.state.unbindTexture(); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, currentFlipY); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, currentPremultiply); +}