Skip to content

Commit

Permalink
CreateSquareTexture refactor (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
agargaro authored Nov 22, 2024
1 parent e57fff3 commit e377df7
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 49 deletions.
10 changes: 5 additions & 5 deletions src/core/InstancedMesh2.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Box3, BufferAttribute, BufferGeometry, Camera, Color, ColorManagement, ColorRepresentation, DataTexture, FloatType, Group, InstancedBufferAttribute, Material, Matrix4, Mesh, MeshDepthMaterial, MeshDistanceMaterial, Object3D, Object3DEventMap, RGBADepthPacking, RGFormat, RedFormat, Scene, ShaderMaterial, Sphere, WebGLRenderer } from 'three';
import { createTexture_mat4, createTexture_vec4 } from '../utils/CreateTexture.js';
import { GLInstancedBufferAttribute } from './utils/GLInstancedBufferAttribute.js';
import { createSquareTexture_mat4, createSquareTexture_vec4 } from '../utils/CreateTexture.js';
import { LODInfo } from './feature/LOD.js';
import { InstancedEntity, UniformValue, UniformValueNoNumber } from './InstancedEntity.js';
import { InstancedMeshBVH } from './InstancedMeshBVH.js';
import { GLInstancedBufferAttribute } from './utils/GLInstancedBufferAttribute.js';
import { InstancedRenderItem } from './utils/InstancedRenderList.js';
import { LODInfo } from './feature/LOD.js';

// TODO: Add expand and count/maxCount when create?
// TODO: partial texture update
Expand Down Expand Up @@ -165,7 +165,7 @@ export class InstancedMesh2<
}

protected initMatricesTexture(): void {
this.matricesTexture = this._parentLOD ? this._parentLOD.matricesTexture : createTexture_mat4(this._maxCount);
this.matricesTexture = this._parentLOD ? this._parentLOD.matricesTexture : createSquareTexture_mat4(this._maxCount);
this._matrixArray = this.matricesTexture.image.data as unknown as Float32Array;
}

Expand Down Expand Up @@ -310,7 +310,7 @@ export class InstancedMesh2<

public setColorAt(id: number, color: ColorRepresentation): void {
if (this.colorsTexture === null) {
this.colorsTexture = createTexture_vec4(this._maxCount);
this.colorsTexture = createSquareTexture_vec4(this._maxCount);
this.colorsTexture.colorSpace = ColorManagement.workingColorSpace;
this._colorArray = this.colorsTexture.image.data as unknown as Float32Array;
this._colorArray.fill(1);
Expand Down
96 changes: 52 additions & 44 deletions src/utils/CreateTexture.ts
Original file line number Diff line number Diff line change
@@ -1,58 +1,66 @@
import { DataTexture, FloatType, RedFormat, RedIntegerFormat, RGBAFormat, RGFormat, UnsignedIntType } from 'three';
import { DataTexture, FloatType, IntType, PixelFormat, RedFormat, RedIntegerFormat, RGBAFormat, RGBAIntegerFormat, RGFormat, RGIntegerFormat, TextureDataType, UnsignedIntType } from 'three';

export function createTexture_float(count: number): DataTexture {
const size = Math.ceil(Math.sqrt(count));
const array = new Float32Array(size * size);
const texture = new DataTexture(array, size, size, RedFormat, FloatType);
texture.needsUpdate = true;
return texture;
export type ChannelSize = 1 | 2 | 3 | 4;

export type TypedArrayConstructor =
Int8ArrayConstructor | Int16ArrayConstructor | Int32ArrayConstructor |
Uint8ArrayConstructor | Uint8ClampedArrayConstructor | Uint16ArrayConstructor | Uint32ArrayConstructor |
Float32ArrayConstructor | Float64ArrayConstructor;

export function getTextureSquareSize(count: number, stride: number): number {
return Math.max(stride, Math.ceil(Math.sqrt(count / stride)) * stride);
}

export function createTexture_uint(count: number): DataTexture {
const size = Math.ceil(Math.sqrt(count));
const array = new Uint32Array(size * size);
const texture = new DataTexture(array, size, size, RedIntegerFormat, UnsignedIntType);
texture.needsUpdate = true;
return texture;
export function createSquareTexture_float(count: number): DataTexture {
return createSquareTexture(Float32Array, 1, 1, count);
}

export function createTexture_vec2(count: number): DataTexture {
const size = Math.ceil(Math.sqrt(count));
const array = new Float32Array(size * size * 2);
const texture = new DataTexture(array, size, size, RGFormat, FloatType);
texture.needsUpdate = true;
return texture;
export function createSquareTexture_uint(count: number): DataTexture {
return createSquareTexture(Uint32Array, 1, 1, count);
}

export function createTexture_vec4(count: number): DataTexture {
const size = Math.ceil(Math.sqrt(count));
const array = new Float32Array(size * size * 4);
const texture = new DataTexture(array, size, size, RGBAFormat, FloatType);
texture.needsUpdate = true;
return texture;
export function createSquareTexture_vec2(count: number): DataTexture {
return createSquareTexture(Float32Array, 2, 1, count);
}

export function createTexture_mat3(count: number): DataTexture {
let size = Math.sqrt(count * 3); // 3 pixels needed for 1 matrix
size = Math.ceil(size / 3) * 3;
size = Math.max(size, 3);
const array = new Float32Array(size * size * 4);
const texture = new DataTexture(array, size, size, RGBAFormat, FloatType);
texture.needsUpdate = true;
return texture;
export function createSquareTexture_vec4(count: number): DataTexture {
return createSquareTexture(Float32Array, 4, 1, count);
}

export function createSquareTexture_mat3(count: number): DataTexture {
return createSquareTexture(Float32Array, 4, 3, count);
}

export function createSquareTexture_mat4(count: number): DataTexture {
return createSquareTexture(Float32Array, 4, 4, count);
}

export function createTexture_mat4(count: number): DataTexture {
let size = Math.sqrt(count * 4); // 4 pixels needed for 1 matrix
size = Math.ceil(size / 4) * 4;
size = Math.max(size, 4);
const array = new Float32Array(size * size * 4);
const texture = new DataTexture(array, size, size, RGBAFormat, FloatType);
export function createSquareTexture(arrayType: TypedArrayConstructor, channels: ChannelSize, stride: number, count: number): DataTexture {
if (channels === 3) {
console.warn('"channels" cannot be 3. Set to 4. More info: https://github.com/mrdoob/three.js/pull/23228');
channels = 4;
}

const size = getTextureSquareSize(count, stride);
const array = new arrayType(size * size * channels);
const isFloat = arrayType.name.includes('Float');
const isUnsignedInt = arrayType.name.includes('Uint');
const type: TextureDataType = isFloat ? FloatType : (isUnsignedInt ? UnsignedIntType : IntType);
let format: PixelFormat;

switch (channels) {
case 1:
format = isFloat ? RedFormat : RedIntegerFormat;
break;
case 2:
format = isFloat ? RGFormat : RGIntegerFormat;
break;
case 4:
format = isFloat ? RGBAFormat : RGBAIntegerFormat;
break;
}

const texture = new DataTexture(array, size, size, format, type);
texture.needsUpdate = true;
return texture;
}

/**
* 'createTexture_vec3' doesn't exist because of
* https://github.com/mrdoob/three.js/pull/23228
*/

0 comments on commit e377df7

Please sign in to comment.