Skip to content

Commit

Permalink
test: add unit test for material
Browse files Browse the repository at this point in the history
  • Loading branch information
GuoLei1990 committed Sep 13, 2022
1 parent 47fb691 commit 0e3fb28
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 26 deletions.
44 changes: 22 additions & 22 deletions packages/core/src/shader/ShaderData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class ShaderData implements IRefObject, IClone {
/** @internal */
_group: ShaderDataGroup;
/** @internal */
_properties: Record<number, ShaderPropertyValueType> = Object.create(null);
_propertyValueMap: Record<number, ShaderPropertyValueType> = Object.create(null);
/** @internal */
_macroCollection: ShaderMacroCollection = new ShaderMacroCollection();

Expand Down Expand Up @@ -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;
}
}

Expand All @@ -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;
}
}
}
Expand All @@ -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;
}

/**
Expand Down Expand Up @@ -668,7 +668,7 @@ export class ShaderData implements IRefObject, IClone {
}
}

this._properties[property._uniqueId] = value;
this._propertyValueMap[property._uniqueId] = value;
}

/**
Expand All @@ -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.
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/shader/ShaderProgram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand All @@ -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 = <Texture>properties[uniform.propertyId];
const texture = <Texture>propertyValueMap[uniform.propertyId];
if (texture && !texture.destroyed) {
uniform.applyFunc(uniform, texture);
} else {
Expand Down
92 changes: 92 additions & 0 deletions tests/src/core/material/Material.test.ts
Original file line number Diff line number Diff line change
@@ -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;
}
}
});
});

0 comments on commit 0e3fb28

Please sign in to comment.