Ver código fonte

Add support for the int types in the ubo

Popov72 4 anos atrás
pai
commit
568dac8e5a

+ 28 - 1
src/Engines/IPipelineContext.ts

@@ -34,13 +34,40 @@ export interface IPipelineContext {
     dispose(): void;
 
     /**
-     * Sets an interger value on a uniform variable.
+     * Sets an integer value on a uniform variable.
      * @param uniformName Name of the variable.
      * @param value Value to be set.
      */
     setInt(uniformName: string, value: number): void;
 
     /**
+     * Sets an int2 value on a uniform variable.
+     * @param uniformName Name of the variable.
+     * @param x First int in int2.
+     * @param y Second int in int2.
+     */
+    setInt2(uniformName: string, x: number, y: number): void;
+
+    /**
+     * Sets an int3 value on a uniform variable.
+     * @param uniformName Name of the variable.
+     * @param x First int in int3.
+     * @param y Second int in int3.
+     * @param z Third int in int3.
+     */
+    setInt3(uniformName: string, x: number, y: number, z: number): void;
+
+    /**
+     * Sets an int4 value on a uniform variable.
+     * @param uniformName Name of the variable.
+     * @param x First int in int4.
+     * @param y Second int in int4.
+     * @param z Third int in int4.
+     * @param w Fourth int in int4.
+     */
+    setInt4(uniformName: string, x: number, y: number, z: number, w: number): void;
+
+    /**
      * Sets an int array on a uniform variable.
      * @param uniformName Name of the variable.
      * @param array array to be set.

+ 45 - 0
src/Engines/WebGL/webGLPipelineContext.ts

@@ -191,6 +191,51 @@ export class WebGLPipelineContext implements IPipelineContext {
     }
 
     /**
+     * Sets a int2 on a uniform variable.
+     * @param uniformName Name of the variable.
+     * @param x First int in int2.
+     * @param y Second int in int2.
+     */
+    public setInt2(uniformName: string, x: number, y: number): void {
+        if (this._cacheFloat2(uniformName, x, y)) {
+            if (!this.engine.setInt2(this._uniforms[uniformName], x, y)) {
+                this._valueCache[uniformName] = null;
+            }
+        }
+    }
+
+    /**
+     * Sets a int3 on a uniform variable.
+     * @param uniformName Name of the variable.
+     * @param x First int in int3.
+     * @param y Second int in int3.
+     * @param y Third int in int3.
+     */
+    public setInt3(uniformName: string, x: number, y: number, z: number): void {
+        if (this._cacheFloat3(uniformName, x, y, z)) {
+            if (!this.engine.setInt3(this._uniforms[uniformName], x, y, z)) {
+                this._valueCache[uniformName] = null;
+            }
+        }
+    }
+
+    /**
+     * Sets a int4 on a uniform variable.
+     * @param uniformName Name of the variable.
+     * @param x First int in int4.
+     * @param y Second int in int4.
+     * @param y Third int in int4.
+     * @param w Fourth int in int4.
+     */
+    public setInt4(uniformName: string, x: number, y: number, z: number, w: number): void {
+        if (this._cacheFloat4(uniformName, x, y, z, w)) {
+            if (!this.engine.setInt4(this._uniforms[uniformName], x, y, z, w)) {
+                this._valueCache[uniformName] = null;
+            }
+        }
+    }
+
+    /**
      * Sets an int array on a uniform variable.
      * @param uniformName Name of the variable.
      * @param array array to be set.

+ 59 - 6
src/Engines/WebGPU/webgpuPipelineContext.ts

@@ -8,10 +8,15 @@ import { UniformBuffer } from "../../Materials/uniformBuffer";
 import { IMatrixLike, IVector2Like, IVector3Like, IVector4Like, IColor3Like, IColor4Like } from '../../Maths/math.like';
 
 const _uniformSizes: { [type: string]: number } = {
+    "bool": 1,
+    "int": 1,
     "float": 1,
     "vec2": 2,
+    "ivec2": 2,
     "vec3": 3,
+    "ivec3": 3,
     "vec4": 4,
+    "ivec4": 4,
     "mat2": 4,
     "mat3": 9,
     "mat4": 16
@@ -185,12 +190,57 @@ export class WebGPUPipelineContext implements IPipelineContext {
     }
 
     /**
-     * Sets an interger value on a uniform variable.
+     * Sets an integer value on a uniform variable.
      * @param uniformName Name of the variable.
      * @param value Value to be set.
      */
     public setInt(uniformName: string, value: number): void {
-        throw "setInt not Supported in LeftOver UBO.";
+        if (!this.uniformBuffer || !this.leftOverUniformsByName[uniformName]) {
+            return;
+        }
+        this.uniformBuffer.updateInt(uniformName, value);
+    }
+
+    /**
+     * Sets an int2 value on a uniform variable.
+     * @param uniformName Name of the variable.
+     * @param x First int in int2.
+     * @param y Second int in int2.
+     */
+    public setInt2(uniformName: string, x: number, y: number): void {
+        if (!this.uniformBuffer || !this.leftOverUniformsByName[uniformName]) {
+            return;
+        }
+        this.uniformBuffer.updateInt2(uniformName, x, y);
+    }
+
+    /**
+     * Sets an int3 value on a uniform variable.
+     * @param uniformName Name of the variable.
+     * @param x First int in int3.
+     * @param y Second int in int3.
+     * @param z Third int in int3.
+     */
+    public setInt3(uniformName: string, x: number, y: number, z: number): void {
+        if (!this.uniformBuffer || !this.leftOverUniformsByName[uniformName]) {
+            return;
+        }
+        this.uniformBuffer.updateInt3(uniformName, x, y, z);
+    }
+
+    /**
+     * Sets an int4 value on a uniform variable.
+     * @param uniformName Name of the variable.
+     * @param x First int in int4.
+     * @param y Second int in int4.
+     * @param z Third int in int4.
+     * @param w Fourth int in int4.
+     */
+    public setInt4(uniformName: string, x: number, y: number, z: number, w: number): void {
+        if (!this.uniformBuffer || !this.leftOverUniformsByName[uniformName]) {
+            return;
+        }
+        this.uniformBuffer.updateInt4(uniformName, x, y, z, w);
     }
 
     /**
@@ -199,7 +249,10 @@ export class WebGPUPipelineContext implements IPipelineContext {
      * @param array array to be set.
      */
     public setIntArray(uniformName: string, array: Int32Array): void {
-        throw "setIntArray not Supported in LeftOver UBO.";
+        if (!this.uniformBuffer || !this.leftOverUniformsByName[uniformName]) {
+            return;
+        }
+        this.uniformBuffer.updateIntArray(uniformName, array);
     }
 
     /**
@@ -208,7 +261,7 @@ export class WebGPUPipelineContext implements IPipelineContext {
      * @param array array to be set.
      */
     public setIntArray2(uniformName: string, array: Int32Array): void {
-        throw "setIntArray2 not Supported in LeftOver UBO.";
+        this.setIntArray(uniformName, array);
     }
 
     /**
@@ -217,7 +270,7 @@ export class WebGPUPipelineContext implements IPipelineContext {
      * @param array array to be set.
      */
     public setIntArray3(uniformName: string, array: Int32Array): void {
-        throw "setIntArray3 not Supported in LeftOver UBO.";
+        this.setIntArray(uniformName, array);
     }
 
     /**
@@ -226,7 +279,7 @@ export class WebGPUPipelineContext implements IPipelineContext {
      * @param array array to be set.
      */
     public setIntArray4(uniformName: string, array: Int32Array): void {
-        throw "setIntArray4 not Supported in LeftOver UBO.";
+        this.setIntArray(uniformName, array);
     }
 
     /**

+ 48 - 2
src/Engines/nativeEngine.ts

@@ -59,6 +59,9 @@ interface INativeEngine {
 
     setMatrix(uniform: WebGLUniformLocation, matrix: Float32Array): void;
     setInt(uniform: WebGLUniformLocation, int: number): void;
+    setInt2(uniform: WebGLUniformLocation, int1: number, int2: number): void;
+    setInt3(uniform: WebGLUniformLocation, int1: number, int2: number, int3: number): void;
+    setInt4(uniform: WebGLUniformLocation, int1: number, int2: number, int3: number, int4: number): void;
     setIntArray(uniform: WebGLUniformLocation, array: Int32Array): void;
     setIntArray2(uniform: WebGLUniformLocation, array: Int32Array): void;
     setIntArray3(uniform: WebGLUniformLocation, array: Int32Array): void;
@@ -282,6 +285,51 @@ class NativePipelineContext implements IPipelineContext {
     }
 
     /**
+     * Sets a int2 on a uniform variable.
+     * @param uniformName Name of the variable.
+     * @param x First int in int2.
+     * @param y Second int in int2.
+     */
+    public setInt2(uniformName: string, x: number, y: number): void {
+        if (this._cacheFloat2(uniformName, x, y)) {
+            if (!this.engine.setInt2(this._uniforms[uniformName], x, y)) {
+                this._valueCache[uniformName] = null;
+            }
+        }
+    }
+
+    /**
+     * Sets a int3 on a uniform variable.
+     * @param uniformName Name of the variable.
+     * @param x First int in int3.
+     * @param y Second int in int3.
+     * @param y Third int in int3.
+     */
+    public setInt3(uniformName: string, x: number, y: number, z: number): void {
+        if (this._cacheFloat3(uniformName, x, y, z)) {
+            if (!this.engine.setInt3(this._uniforms[uniformName], x, y, z)) {
+                this._valueCache[uniformName] = null;
+            }
+        }
+    }
+
+    /**
+     * Sets a int4 on a uniform variable.
+     * @param uniformName Name of the variable.
+     * @param x First int in int4.
+     * @param y Second int in int4.
+     * @param y Third int in int4.
+     * @param w Fourth int in int4.
+     */
+    public setInt4(uniformName: string, x: number, y: number, z: number, w: number): void {
+        if (this._cacheFloat4(uniformName, x, y, z, w)) {
+            if (!this.engine.setInt4(this._uniforms[uniformName], x, y, z, w)) {
+                this._valueCache[uniformName] = null;
+            }
+        }
+    }
+
+    /**
      * Sets an int array on a uniform variable.
      * @param uniformName Name of the variable.
      * @param array array to be set.
@@ -477,8 +525,6 @@ class NativePipelineContext implements IPipelineContext {
             return;
         }
 
-        this._valueCache[uniformName] = bool;
-
         if (this.engine.setInt(this._uniforms[uniformName]!, bool ? 1 : 0)) {
             this._valueCache[uniformName] = bool ? 1 : 0;
         }

+ 54 - 0
src/Engines/thinEngine.ts

@@ -2478,6 +2478,60 @@ export class ThinEngine {
     }
 
     /**
+     * Set the value of an uniform to a int2
+     * @param uniform defines the webGL uniform location where to store the value
+     * @param x defines the 1st component of the value
+     * @param y defines the 2nd component of the value
+     * @returns true if the value was set
+     */
+    public setInt2(uniform: Nullable<WebGLUniformLocation>, x: number, y: number): boolean {
+        if (!uniform) {
+            return false;
+        }
+
+        this._gl.uniform2i(uniform, x, y);
+
+        return true;
+    }
+
+    /**
+     * Set the value of an uniform to a int3
+     * @param uniform defines the webGL uniform location where to store the value
+     * @param x defines the 1st component of the value
+     * @param y defines the 2nd component of the value
+     * @param z defines the 3rd component of the value
+     * @returns true if the value was set
+     */
+    public setInt3(uniform: Nullable<WebGLUniformLocation>, x: number, y: number, z: number): boolean {
+        if (!uniform) {
+            return false;
+        }
+
+        this._gl.uniform3i(uniform, x, y, z);
+
+        return true;
+    }
+
+    /**
+     * Set the value of an uniform to a int4
+     * @param uniform defines the webGL uniform location where to store the value
+     * @param x defines the 1st component of the value
+     * @param y defines the 2nd component of the value
+     * @param z defines the 3rd component of the value
+     * @param w defines the 4th component of the value
+     * @returns true if the value was set
+     */
+    public setInt4(uniform: Nullable<WebGLUniformLocation>, x: number, y: number, z: number, w: number): boolean {
+        if (!uniform) {
+            return false;
+        }
+
+        this._gl.uniform4i(uniform, x, y, z, w);
+
+        return true;
+    }
+
+    /**
      * Set the value of an uniform to an array of int32
      * @param uniform defines the webGL uniform location where to store the value
      * @param array defines the array of int32 to store

+ 39 - 0
src/Materials/effect.ts

@@ -928,6 +928,45 @@ export class Effect implements IDisposable {
     }
 
     /**
+     * Sets an int2 value on a uniform variable.
+     * @param uniformName Name of the variable.
+     * @param x First int in int2.
+     * @param y Second int in int2.
+     * @returns this effect.
+     */
+    public setInt2(uniformName: string, x: number, y: number): Effect {
+        this._pipelineContext!.setInt2(uniformName, x, y);
+        return this;
+    }
+
+    /**
+     * Sets an int3 value on a uniform variable.
+     * @param uniformName Name of the variable.
+     * @param x First int in int3.
+     * @param y Second int in int3.
+     * @param z Third int in int3.
+     * @returns this effect.
+     */
+    public setInt3(uniformName: string, x: number, y: number, z: number): Effect {
+        this._pipelineContext!.setInt3(uniformName, x, y, z);
+        return this;
+    }
+
+    /**
+     * Sets an int4 value on a uniform variable.
+     * @param uniformName Name of the variable.
+     * @param x First int in int4.
+     * @param y Second int in int4.
+     * @param z Third int in int4.
+     * @param w Fourth int in int4.
+     * @returns this effect.
+     */
+    public setInt4(uniformName: string, x: number, y: number, z: number, w: number): Effect {
+        this._pipelineContext!.setInt4(uniformName, x, y, z, w);
+        return this;
+    }
+
+    /**
      * Sets an int array on a uniform variable.
      * @param uniformName Name of the variable.
      * @param array array to be set.

+ 97 - 0
src/Materials/uniformBuffer.ts

@@ -51,6 +51,7 @@ export class UniformBuffer {
     // Pool for avoiding memory leaks
     private static _MAX_UNIFORM_SIZE = 256;
     private static _tempBuffer = new Float32Array(UniformBuffer._MAX_UNIFORM_SIZE);
+    private static _tempBufferInt32View = new Uint32Array(UniformBuffer._tempBuffer.buffer);
 
     /**
      * Lambda to Update a 3x3 Matrix in a uniform buffer.
@@ -109,6 +110,13 @@ export class UniformBuffer {
     public updateArray: (name: string, array: number[]) => void;
 
     /**
+     * Lambda to Update an array of number in a uniform buffer.
+     * This is dynamic to allow compat with webgl 1 and 2.
+     * You will need to pass the name of the uniform as well as the value.
+     */
+    public updateIntArray: (name: string, array: Int32Array) => void;
+
+    /**
      * Lambda to Update a 4x4 Matrix in a uniform buffer.
      * This is dynamic to allow compat with webgl 1 and 2.
      * You will need to pass the name of the uniform as well as the value.
@@ -151,6 +159,34 @@ export class UniformBuffer {
     public updateColor4: (name: string, color: Color3, alpha: number, suffix?: string) => void;
 
     /**
+     * Lambda to Update a int a uniform buffer.
+     * This is dynamic to allow compat with webgl 1 and 2.
+     * You will need to pass the name of the uniform as well as the value.
+     */
+    public updateInt: (name: string, x: number, suffix?: string) => void;
+
+    /**
+     * Lambda to Update a vec2 of int in a uniform buffer.
+     * This is dynamic to allow compat with webgl 1 and 2.
+     * You will need to pass the name of the uniform as well as the value.
+     */
+    public updateInt2: (name: string, x: number, y: number, suffix?: string) => void;
+
+    /**
+     * Lambda to Update a vec3 of int in a uniform buffer.
+     * This is dynamic to allow compat with webgl 1 and 2.
+     * You will need to pass the name of the uniform as well as the value.
+     */
+    public updateInt3: (name: string, x: number, y: number, z: number, suffix?: string) => void;
+
+    /**
+     * Lambda to Update a vec4 of int in a uniform buffer.
+     * This is dynamic to allow compat with webgl 1 and 2.
+     * You will need to pass the name of the uniform as well as the value.
+     */
+    public updateInt4: (name: string, x: number, y: number, z: number, w: number, suffix?: string) => void;
+
+    /**
      * Instantiates a new Uniform buffer objects.
      *
      * Handles blocks of uniform on the GPU.
@@ -194,12 +230,17 @@ export class UniformBuffer {
             this.updateFloat4 = this._updateFloat4ForEffect;
             this.updateFloatArray = this._updateFloatArrayForEffect;
             this.updateArray = this._updateArrayForEffect;
+            this.updateIntArray = this._updateIntArrayForEffect;
             this.updateMatrix = this._updateMatrixForEffect;
             this.updateMatrices = this._updateMatricesForEffect;
             this.updateVector3 = this._updateVector3ForEffect;
             this.updateVector4 = this._updateVector4ForEffect;
             this.updateColor3 = this._updateColor3ForEffect;
             this.updateColor4 = this._updateColor4ForEffect;
+            this.updateInt = this._updateIntForEffect;
+            this.updateInt2 = this._updateInt2ForEffect;
+            this.updateInt3 = this._updateInt3ForEffect;
+            this.updateInt4 = this._updateInt4ForEffect;
         } else {
             this._engine._uniformBuffers.push(this);
 
@@ -211,12 +252,17 @@ export class UniformBuffer {
             this.updateFloat4 = this._updateFloat4ForUniform;
             this.updateFloatArray = this._updateFloatArrayForUniform;
             this.updateArray = this._updateArrayForUniform;
+            this.updateIntArray = this._updateIntArrayForUniform;
             this.updateMatrix = this._updateMatrixForUniform;
             this.updateMatrices = this._updateMatricesForUniform;
             this.updateVector3 = this._updateVector3ForUniform;
             this.updateVector4 = this._updateVector4ForUniform;
             this.updateColor3 = this._updateColor3ForUniform;
             this.updateColor4 = this._updateColor4ForUniform;
+            this.updateInt = this._updateIntForUniform;
+            this.updateInt2 = this._updateInt2ForUniform;
+            this.updateInt3 = this._updateInt3ForUniform;
+            this.updateInt4 = this._updateInt4ForUniform;
         }
 
     }
@@ -821,6 +867,15 @@ export class UniformBuffer {
         this.updateUniformArray(name, array, array.length);
     }
 
+    private _updateIntArrayForEffect(name: string, array: Int32Array) {
+        this._currentEffect.setIntArray(name, array);
+    }
+
+    private _updateIntArrayForUniform(name: string, array: Int32Array) {
+        UniformBuffer._tempBufferInt32View.set(array);
+        this.updateUniformArray(name, UniformBuffer._tempBuffer, array.length);
+    }
+
     private _updateMatrixForEffect(name: string, mat: IMatrixLike) {
         this._currentEffect.setMatrix(name, mat);
     }
@@ -876,6 +931,48 @@ export class UniformBuffer {
         this.updateUniform(name, UniformBuffer._tempBuffer, 4);
     }
 
+    private _updateIntForEffect(name: string, x: number, suffix = "") {
+        this._currentEffect.setInt(name + suffix, x);
+    }
+
+    private _updateIntForUniform(name: string, x: number) {
+        UniformBuffer._tempBufferInt32View[0] = x;
+        this.updateUniform(name, UniformBuffer._tempBuffer, 1);
+    }
+
+    private _updateInt2ForEffect(name: string, x: number, y: number, suffix = "") {
+        this._currentEffect.setInt2(name + suffix, x, y);
+    }
+
+    private _updateInt2ForUniform(name: string, x: number, y: number) {
+        UniformBuffer._tempBufferInt32View[0] = x;
+        UniformBuffer._tempBufferInt32View[1] = y;
+        this.updateUniform(name, UniformBuffer._tempBuffer, 2);
+    }
+
+    private _updateInt3ForEffect(name: string, x: number, y: number, z: number, suffix = "") {
+        this._currentEffect.setInt3(name + suffix, x, y, z);
+    }
+
+    private _updateInt3ForUniform(name: string, x: number, y: number, z: number) {
+        UniformBuffer._tempBufferInt32View[0] = x;
+        UniformBuffer._tempBufferInt32View[1] = y;
+        UniformBuffer._tempBufferInt32View[2] = z;
+        this.updateUniform(name, UniformBuffer._tempBuffer, 3);
+    }
+
+    private _updateInt4ForEffect(name: string, x: number, y: number, z: number, w: number, suffix = "") {
+        this._currentEffect.setInt4(name + suffix, x, y, z, w);
+    }
+
+    private _updateInt4ForUniform(name: string, x: number, y: number, z: number, w: number) {
+        UniformBuffer._tempBufferInt32View[0] = x;
+        UniformBuffer._tempBufferInt32View[1] = y;
+        UniformBuffer._tempBufferInt32View[2] = z;
+        UniformBuffer._tempBufferInt32View[3] = w;
+        this.updateUniform(name, UniformBuffer._tempBuffer, 4);
+    }
+
     /**
      * Sets a sampler uniform on the effect.
      * @param name Define the name of the sampler.