Skip to content

Commit c348bba

Browse files
committed
Adds unit tests for async material constructor
1 parent aa8d7c2 commit c348bba

File tree

2 files changed

+98
-8
lines changed

2 files changed

+98
-8
lines changed

packages/engine/Source/Scene/Material.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -675,23 +675,26 @@ function initializeMaterial(options, result) {
675675
// If the cache contains this material type, build the material template off of the stored template.
676676
const cachedMaterial = Material._materialCache.getMaterial(result.type);
677677
if (defined(cachedMaterial)) {
678-
const template = clone(cachedMaterial.fabric, true);
678+
const template = clone(
679+
cachedMaterial.fabric ?? cachedMaterial._template,
680+
true,
681+
);
679682
result._template = combine(result._template, template, true);
680683
translucent = cachedMaterial.translucent;
681684
}
682685

683686
// Make sure the template has no obvious errors. More error checking happens later.
684687
checkForTemplateErrors(result);
685688

689+
createMethodDefinition(result);
690+
createUniforms(result);
691+
createSubMaterials(result);
692+
686693
// If the material has a new type, add it to the cache.
687694
if (!defined(cachedMaterial)) {
688695
Material._materialCache.addMaterial(result.type, result);
689696
}
690697

691-
createMethodDefinition(result);
692-
createUniforms(result);
693-
createSubMaterials(result);
694-
695698
const defaultTranslucent =
696699
result._translucentFunctions.length === 0 ? true : undefined;
697700
translucent = translucent ?? defaultTranslucent;
@@ -970,7 +973,7 @@ function createTexture2DUpdateFunction(uniformId) {
970973
*
971974
* @param {Material} material The material to load the texture for.
972975
* @param {string} uniformId The ID of the uniform of the image.
973-
* @returns {Promise} A promise that resolves when the image is loaded, or a resolved promise if image loading is not necessary.
976+
* @returns A promise that resolves when the image is loaded, or a resolved promise if image loading is not necessary.
974977
*
975978
* @private
976979
*/
@@ -1053,9 +1056,9 @@ function createCubeMapUpdateFunction(uniformId) {
10531056
*
10541057
* @param {Material} material The material to load the cubemap images for.
10551058
* @param {string} uniformId The ID of the uniform that corresponds to the cubemap images.
1056-
* @returns {Promise} A promise that resolves when the images are loaded, or a resolved promise if image loading is not necessary.
1059+
* @returns A promise that resolves when the images are loaded, or a resolved promise if image loading is not necessary.
10571060
*/
1058-
async function loadCubeMapImagesForUniform(material, uniformId) {
1061+
function loadCubeMapImagesForUniform(material, uniformId) {
10591062
const uniforms = material.uniforms;
10601063
const uniformValue = uniforms[uniformId];
10611064
if (uniformValue === Material.DefaultCubeMapId) {

packages/engine/Specs/Scene/MaterialSpec.js

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,93 @@ describe(
630630
});
631631
});
632632

633+
it("creates a material using fromTypeAsync", async function () {
634+
const material = await Material.fromTypeAsync("Color");
635+
renderMaterial(material);
636+
});
637+
638+
it("loads a 2D texture image synchronously when awaiting fromTypeAsync", async function () {
639+
const imageMaterial = await Material.fromTypeAsync("Image", {
640+
image: "./Data/Images/Blue.png",
641+
});
642+
renderMaterial(imageMaterial);
643+
});
644+
645+
it("loads cubemap images synchronously when awaiting fromTypeAsync", async function () {
646+
// First make a material with a cubemap, then use its type to make a second cubemap material asynchronously.
647+
const material = new Material({
648+
strict: true,
649+
fabric: {
650+
uniforms: {
651+
cubeMap: {
652+
positiveX: "./Data/Images/Blue.png",
653+
negativeX: "./Data/Images/Blue.png",
654+
positiveY: "./Data/Images/Blue.png",
655+
negativeY: "./Data/Images/Blue.png",
656+
positiveZ: "./Data/Images/Blue.png",
657+
negativeZ: "./Data/Images/Blue.png",
658+
},
659+
},
660+
source:
661+
"uniform samplerCube cubeMap;\n" +
662+
"czm_material czm_getMaterial(czm_materialInput materialInput)\n" +
663+
"{\n" +
664+
" czm_material material = czm_getDefaultMaterial(materialInput);\n" +
665+
" material.diffuse = czm_textureCube(cubeMap, vec3(1.0)).xyz;\n" +
666+
" return material;\n" +
667+
"}\n",
668+
},
669+
});
670+
671+
const materialFromTypeAsync = await Material.fromTypeAsync(
672+
material.type,
673+
{
674+
cubeMap: {
675+
positiveX: "./Data/Images/Green.png",
676+
negativeX: "./Data/Images/Green.png",
677+
positiveY: "./Data/Images/Green.png",
678+
negativeY: "./Data/Images/Green.png",
679+
positiveZ: "./Data/Images/Green.png",
680+
negativeZ: "./Data/Images/Green.png",
681+
},
682+
},
683+
);
684+
685+
renderMaterial(materialFromTypeAsync);
686+
});
687+
688+
it("loads sub-materials synchronously when awaiting fromTypeAsync", async function () {
689+
// First make a material with submaterials, then use its type to make a second material asynchronously.
690+
const material = new Material({
691+
strict: true,
692+
fabric: {
693+
materials: {
694+
greenMaterial: {
695+
type: "Image",
696+
uniforms: {
697+
image: "./Data/Images/Green.png", // Green image
698+
},
699+
},
700+
blueMaterial: {
701+
type: "Image",
702+
uniforms: {
703+
image: "./Data/Images/Blue.png", // Blue image
704+
},
705+
},
706+
},
707+
components: {
708+
diffuse:
709+
"clamp(greenMaterial.diffuse + blueMaterial.diffuse, 0.0, 1.0)",
710+
},
711+
},
712+
});
713+
714+
const materialFromTypeAsync = await Material.fromTypeAsync(material.type);
715+
renderMaterial(materialFromTypeAsync, false, function (rgba) {
716+
expect(rgba).toEqual([0, 255, 255, 255]); // Expect cyan from green + blue
717+
});
718+
});
719+
633720
it("creates material with custom texture filter", function () {
634721
const materialLinear = new Material({
635722
fabric: {

0 commit comments

Comments
 (0)