From 0e3fb2824fd40408f5aad89287b62d160ece408c Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Tue, 13 Sep 2022 14:48:51 +0800 Subject: [PATCH] test: add unit test for material --- packages/core/src/shader/ShaderData.ts | 44 +++++------ packages/core/src/shader/ShaderProgram.ts | 8 +- tests/src/core/material/Material.test.ts | 92 +++++++++++++++++++++++ 3 files changed, 118 insertions(+), 26 deletions(-) create mode 100644 tests/src/core/material/Material.test.ts diff --git a/packages/core/src/shader/ShaderData.ts b/packages/core/src/shader/ShaderData.ts index 42acc097f9..540d98b90d 100644 --- a/packages/core/src/shader/ShaderData.ts +++ b/packages/core/src/shader/ShaderData.ts @@ -29,7 +29,7 @@ export class ShaderData implements IRefObject, IClone { /** @internal */ _group: ShaderDataGroup; /** @internal */ - _properties: Record = Object.create(null); + _propertyValueMap: Record = Object.create(null); /** @internal */ _macroCollection: ShaderMacroCollection = new ShaderMacroCollection(); @@ -574,22 +574,22 @@ export class ShaderData implements IRefObject, IClone { getShaderProperties(out: ShaderProperty[]): void; getShaderProperties(out?: ShaderProperty[]): void | ShaderProperty[] { - let shaderProperties: ShaderProperty[]; + let properties: ShaderProperty[]; if (out) { out.length = 0; - shaderProperties = out; + properties = out; } else { - shaderProperties = []; + properties = []; } - const properties = this._properties; + const propertyValueMap = this._propertyValueMap; const propertyIdMap = Shader._propertyIdMap; - for (let key in properties) { - out.push(propertyIdMap[key]); + for (let key in propertyValueMap) { + properties.push(propertyIdMap[key]); } - if (out) { - return shaderProperties; + if (!out) { + return properties; } } @@ -603,29 +603,29 @@ export class ShaderData implements IRefObject, IClone { CloneManager.deepCloneObject(this._macroCollection, target._macroCollection); Object.assign(target._macroMap, this._macroMap); - const properties = this._properties; - const targetProperties = target._properties; - const keys = Object.keys(properties); + const propertyValueMap = this._propertyValueMap; + const targetPropertyValueMap = target._propertyValueMap; + const keys = Object.keys(propertyValueMap); for (let i = 0, n = keys.length; i < n; i++) { const k = keys[i]; - const property: ShaderPropertyValueType = properties[k]; + const property: ShaderPropertyValueType = propertyValueMap[k]; if (property != null) { if (typeof property === "number") { - targetProperties[k] = property; + targetPropertyValueMap[k] = property; } else if (property instanceof Texture) { - targetProperties[k] = property; + targetPropertyValueMap[k] = property; } else if (property instanceof Array || property instanceof Float32Array || property instanceof Int32Array) { - targetProperties[k] = property.slice(); + targetPropertyValueMap[k] = property.slice(); } else { - const targetProperty = targetProperties[k]; + const targetProperty = targetPropertyValueMap[k]; if (targetProperty) { targetProperty.copyFrom(property); } else { - targetProperties[k] = property.clone(); + targetPropertyValueMap[k] = property.clone(); } } } else { - targetProperties[k] = property; + targetPropertyValueMap[k] = property; } } } @@ -637,7 +637,7 @@ export class ShaderData implements IRefObject, IClone { if (typeof property === "string") { property = Shader.getPropertyByName(property); } - return this._properties[property._uniqueId] as T; + return this._propertyValueMap[property._uniqueId] as T; } /** @@ -668,7 +668,7 @@ export class ShaderData implements IRefObject, IClone { } } - this._properties[property._uniqueId] = value; + this._propertyValueMap[property._uniqueId] = value; } /** @@ -683,7 +683,7 @@ export class ShaderData implements IRefObject, IClone { */ _addRefCount(value: number): void { this._refCount += value; - const properties = this._properties; + const properties = this._propertyValueMap; for (const k in properties) { const property = properties[k]; // @todo: Separate array to speed performance. diff --git a/packages/core/src/shader/ShaderProgram.ts b/packages/core/src/shader/ShaderProgram.ts index 513fbfe3f4..7320147f41 100644 --- a/packages/core/src/shader/ShaderProgram.ts +++ b/packages/core/src/shader/ShaderProgram.ts @@ -104,12 +104,12 @@ export class ShaderProgram { * @param shaderData - shader data */ uploadUniforms(uniformBlock: ShaderUniformBlock, shaderData: ShaderData): void { - const properties = shaderData._properties; + const propertyValueMap = shaderData._propertyValueMap; const constUniforms = uniformBlock.constUniforms; for (let i = 0, n = constUniforms.length; i < n; i++) { const uniform = constUniforms[i]; - const data = properties[uniform.propertyId]; + const data = propertyValueMap[uniform.propertyId]; data != null && uniform.applyFunc(uniform, data); } } @@ -120,13 +120,13 @@ export class ShaderProgram { * @param shaderData - shader data */ uploadTextures(uniformBlock: ShaderUniformBlock, shaderData: ShaderData): void { - const properties = shaderData._properties; + const propertyValueMap = shaderData._propertyValueMap; const textureUniforms = uniformBlock.textureUniforms; // textureUniforms property maybe null if ShaderUniformBlock not contain any texture. if (textureUniforms) { for (let i = 0, n = textureUniforms.length; i < n; i++) { const uniform = textureUniforms[i]; - const texture = properties[uniform.propertyId]; + const texture = propertyValueMap[uniform.propertyId]; if (texture && !texture.destroyed) { uniform.applyFunc(uniform, texture); } else { diff --git a/tests/src/core/material/Material.test.ts b/tests/src/core/material/Material.test.ts new file mode 100644 index 0000000000..0791a56fbf --- /dev/null +++ b/tests/src/core/material/Material.test.ts @@ -0,0 +1,92 @@ +import { Material, Shader, ShaderPropertyType, Texture2D, Texture2DArray } from "@oasis-engine/core"; +import { Color, Matrix, Vector2, Vector3, Vector4 } from "@oasis-engine/math"; +import { WebGLEngine } from "@oasis-engine/rhi-webgl"; +import { expect } from "chai"; + +describe("Material", () => { + const canvas = document.createElement("canvas"); + const engine = new WebGLEngine(canvas); + + it("property", () => { + const color = new Color(0.2, 0.1, 0.3, 1.0); + const vector2 = new Vector2(0.1, 0.2); + const vector3 = new Vector3(0.1, 0.2, 0.3); + const vector4 = new Vector4(0.1, 0.2, 0.4, 1.0); + const matrix = new Matrix(0.1, 0.2, 0.4, 1.0); + // @ts-ignore + const texture = new Texture2D(engine, 64, 64); + // @ts-ignore + const textureArray = new Texture2DArray(engine, 64, 64, 6); + const intArray = new Int32Array([5, 6, 6, 6]); + const floatArray = new Float32Array([0.4, 0.323, 2323.232, 23.232]); + + const material = new Material(engine, Shader.find("blinn-phong")); + const shaderData = material.shaderData; + + shaderData.setFloat("_float", 0.2); + shaderData.setInt("_int", 6); + shaderData.setColor("_color", color); + shaderData.setVector2("_vector2", vector2); + shaderData.setVector3("_vector3", vector3); + shaderData.setVector4("_vector4", vector4); + shaderData.setMatrix("_matrix", matrix); + // @ts-ignore + shaderData.setTexture("_texture", texture); + // @ts-ignore + shaderData.setTextureArray("_textureArray", textureArray); + shaderData.setIntArray("_intArray", intArray); + shaderData.setFloatArray("_floatArray", floatArray); + + expect(shaderData.getFloat("_float")).to.equal(0.2); + expect(shaderData.getInt("_int")).to.equal(6); + expect(shaderData.getFloat("_color")).to.equal(color); + expect(shaderData.getFloat("_vector2")).to.equal(vector2); + expect(shaderData.getFloat("_vector3")).to.equal(vector3); + expect(shaderData.getFloat("_vector4")).to.equal(vector4); + expect(shaderData.getFloat("_matrix")).to.equal(matrix); + expect(shaderData.getFloat("_texture")).to.equal(texture); + expect(shaderData.getFloat("_textureArray")).to.equal(textureArray); + expect(shaderData.getFloat("_intArray")).to.equal(intArray); + expect(shaderData.getFloat("_floatArray")).to.equal(floatArray); + + const shaderProperties = shaderData.getShaderProperties(); + for (let i = 0, n = shaderProperties.length; i < n; i++) { + const shaderProperty = shaderProperties[i]; + switch (shaderProperty.type) { + case ShaderPropertyType.Float: + expect(shaderData.getFloat(shaderProperty)).to.equal(0.2); + break; + case ShaderPropertyType.Int: + expect(shaderData.getInt(shaderProperty)).to.equal(6); + break; + case ShaderPropertyType.Color: + expect(shaderData.getColor(shaderProperty)).to.equal(color); + break; + case ShaderPropertyType.Vector2: + expect(shaderData.getVector2(shaderProperty)).to.equal(vector2); + break; + case ShaderPropertyType.Vector3: + expect(shaderData.getVector3(shaderProperty)).to.equal(vector3); + break; + case ShaderPropertyType.Vector4: + expect(shaderData.getVector4(shaderProperty)).to.equal(vector4); + break; + case ShaderPropertyType.Matrix: + expect(shaderData.getMatrix(shaderProperty)).to.equal(matrix); + break; + case ShaderPropertyType.Texture: + expect(shaderData.getTexture(shaderProperty)).to.equal(texture); + break; + case ShaderPropertyType.TextureArray: + expect(shaderData.getTextureArray(shaderProperty)).to.equal(textureArray); + break; + case ShaderPropertyType.IntArray: + expect(shaderData.getIntArray(shaderProperty)).to.equal(intArray); + break; + case ShaderPropertyType.FloatArray: + expect(shaderData.getFloatArray(shaderProperty)).to.equal(floatArray); + break; + } + } + }); +});