From 06a09540dc71828680fb4e93f6b5a9ac3eec90ea Mon Sep 17 00:00:00 2001 From: Robert Taglang Date: Fri, 28 Apr 2017 11:17:17 -0400 Subject: [PATCH 1/6] Added pbrToMaterialsCommon --- lib/pbrToMaterialsCommon.js | 93 +++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 lib/pbrToMaterialsCommon.js diff --git a/lib/pbrToMaterialsCommon.js b/lib/pbrToMaterialsCommon.js new file mode 100644 index 00000000..438b5404 --- /dev/null +++ b/lib/pbrToMaterialsCommon.js @@ -0,0 +1,93 @@ +'use strict'; +var Cesium = require('cesium'); +var ForEach = require('./ForEach'); + +var defined = Cesium.defined; + +module.exports = pbrToMaterialsCommon; + +/** + * Convert PBR materials to use a KHR_materials_common PHONG shader. + * This is a lossy conversion, and as such is only to be used for + * compatibility reasons. Normal texture and metallic roughness information + * will be lost, and some color or texture information may be lost. + * + * The preferred solution is to properly + * implement PBR materials, and as such this function will likely + * by deprecated in the future. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @returns {Object} The glTF asset with materials converted to KHR_materials_common + */ +function pbrToMaterialsCommon(gltf) { + ForEach.material(gltf, function(material) { + var values = { + ambient : [ 0.0, 0.0, 0.0, 1.0 ], + diffuse : [ 0.0, 0.0, 0.0, 1.0 ], + emission : [ 0.0, 0.0, 0.0, 1.0 ], + specular : [ 0.0, 0.0, 0.0, 1.0], + shininess : [ 0.0 ] + }; + var pbrMetallicRoughness = material.pbrMetallicRoughness; + if (defined(pbrMetallicRoughness)) { + var baseColorFactor = pbrMetallicRoughness.baseColorFactor; + if (defined(baseColorFactor)) { + values.diffuse = baseColorFactor; + } + var baseColorTexture = pbrMetallicRoughness.baseColorTexture; + if (defined(baseColorTexture)) { + values.diffuse = [ baseColorTexture.index ]; + } + } + var extensions = material.extensions; + if (defined(extensions)) { + var pbrSpecularGlossiness = extensions.KHR_materials_pbrSpecularGlossiness; + if (defined(pbrSpecularGlossiness)) { + var diffuseFactor = pbrSpecularGlossiness.diffuseFactor; + // Use baseColorTexture if it was defined + if (defined(diffuseFactor) && values.diffuse.length > 1) { + values.diffuse = diffuseFactor; + } + // diffuseTexture should be used instead of baseColorTexture if defined + var diffuseTexture = pbrSpecularGlossiness.diffuseTexture; + if (defined(diffuseTexture)) { + values.diffuse = [ diffuseTexture.index ]; + } + var specularFactor = pbrSpecularGlossiness.specularFactor; + if (defined(specularFactor)) { + values.specular[0] = specularFactor[0]; + values.specular[1] = specularFactor[1]; + values.specular[2] = specularFactor[2]; + } + var glossinessFactor = pbrSpecularGlossiness.glossinessFactor; + if (defined(glossinessFactor)) { + values.shininess[0] = glossinessFactor; + } + var specularGlossinessTexture = pbrSpecularGlossiness.specularGlossinessTexture; + if (defined(specularGlossinessTexture)) { + values.specular = [ specularGlossinessTexture.index ]; + } + } + } + var occlusionTexture = material.occlusionTexture; + if (defined(occlusionTexture)) { + values.ambient = [ occlusionTexture.index ]; + } + var emissiveFactor = material.emissiveFactor; + if (defined(emissiveFactor)) { + values.emission[0] = emissiveFactor[0]; + values.emission[1] = emissiveFactor[1]; + values.emission[2] = emissiveFactor[2]; + } + delete material.emissiveFactor; + delete material.normalTexture; + delete material.occlusionTexture; + delete material.pbrMetallicRoughness; + material.extensions = { + technique : 'PHONG', + KHR_materials_common : { + values: values + } + }; + }); +} \ No newline at end of file From d373dc2f38c41b2d78d6291909bd90e3c3804bcb Mon Sep 17 00:00:00 2001 From: Robert Taglang Date: Fri, 28 Apr 2017 14:22:32 -0400 Subject: [PATCH 2/6] Moved out getJointCountForMaterials as a separate function and added pbr->materialsCommon generation --- gulpfile.js | 2 + lib/generateModelMaterialsCommon.js | 184 ++++++--------- lib/getJointCountForMaterials.js | 47 ++++ lib/pbrToMaterialsCommon.js | 64 ++++-- lib/processModelMaterialsCommon.js | 4 +- specs/lib/generateModelMaterialsCommonSpec.js | 128 ++++++----- specs/lib/pbrToMaterialsCommonSpec.js | 214 ++++++++++++++++++ 7 files changed, 440 insertions(+), 203 deletions(-) create mode 100644 lib/getJointCountForMaterials.js create mode 100644 specs/lib/pbrToMaterialsCommonSpec.js diff --git a/gulpfile.js b/gulpfile.js index da431bae..d10e983a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -285,9 +285,11 @@ gulp.task('build-cesium', function () { 'findAccessorMinMax.js', 'ForEach.js', 'getAccessorByteStride.js', + 'getJointCountForMaterials.js', 'getStatistics.js', 'numberOfComponentsForType.js', 'parseBinaryGltf.js', + 'pbrToMaterialsCommon.js', 'processModelMaterialsCommon.js', 'removePipelineExtras.js', 'removeExtensionsRequired.js', diff --git a/lib/generateModelMaterialsCommon.js b/lib/generateModelMaterialsCommon.js index 51cd0b39..c07516d3 100644 --- a/lib/generateModelMaterialsCommon.js +++ b/lib/generateModelMaterialsCommon.js @@ -1,6 +1,8 @@ 'use strict'; var Cesium = require('cesium'); var addExtensionsRequired = require('./addExtensionsRequired'); +var ForEach = require('./ForEach'); +var getJointCountForMaterials = require('./getJointCountForMaterials'); var defaultValue = Cesium.defaultValue; var defined = Cesium.defined; @@ -26,7 +28,6 @@ function generateModelMaterialsCommon(gltf, kmcOptions) { kmcOptions.technique = defaultValue(kmcOptions.technique, 'PHONG'); addExtensionsRequired(gltf, 'KHR_materials_common'); var materialsCommon; - var materials = gltf.materials; var nodes = gltf.nodes; var techniques = gltf.techniques; var jointCountForMaterialId = getJointCountForMaterials(gltf); @@ -41,133 +42,82 @@ function generateModelMaterialsCommon(gltf, kmcOptions) { var lights = {}; materialsCommon.lights = lights; - for (var materialId in materials) { - if (materials.hasOwnProperty(materialId)) { - var material = materials[materialId]; - var technique = techniques[material.technique]; - var techniqueParameters = technique.parameters; - if (defined(techniqueParameters.ambient) && !defined(lights.defaultAmbient)) { - lights.defaultAmbient = { - ambient: { - color: [1, 1, 1] - }, - name: 'defaultAmbient', - type: 'ambient' - }; - } - for (var parameterId in techniqueParameters) { - if (techniqueParameters.hasOwnProperty(parameterId)) { - if (parameterId.indexOf('light') === 0 && parameterId.indexOf('Transform') >= 0) { - var lightId = parameterId.substring(0, parameterId.indexOf('Transform')); - var lightTransform = techniqueParameters[parameterId]; - var lightNodeId = lightTransform.node; - var lightNode = nodes[lightNodeId]; - var nodeExtensions = lightNode.extensions; - if (!defined(nodeExtensions)) { - nodeExtensions = {}; - lightNode.extensions = nodeExtensions; - } - materialsCommon = {}; - nodeExtensions.KHR_materials_common = materialsCommon; - materialsCommon.light = lightId; - var lightColor = techniqueParameters[lightId + 'Color']; - var light = { - name: lightId, - type: 'directional', - directional: { - color: defaultValue(lightColor.value, [1, 1, 1]) - } - }; - lights[lightId] = light; + ForEach.material(gltf, function(material, materialId) { + var technique = techniques[material.technique]; + var techniqueParameters = technique.parameters; + if (defined(techniqueParameters.ambient) && !defined(lights.defaultAmbient)) { + lights.defaultAmbient = { + ambient: { + color: [1, 1, 1] + }, + name: 'defaultAmbient', + type: 'ambient' + }; + } + for (var parameterId in techniqueParameters) { + if (techniqueParameters.hasOwnProperty(parameterId)) { + if (parameterId.indexOf('light') === 0 && parameterId.indexOf('Transform') >= 0) { + var lightId = parameterId.substring(0, parameterId.indexOf('Transform')); + var lightTransform = techniqueParameters[parameterId]; + var lightNodeId = lightTransform.node; + var lightNode = nodes[lightNodeId]; + var nodeExtensions = lightNode.extensions; + if (!defined(nodeExtensions)) { + nodeExtensions = {}; + lightNode.extensions = nodeExtensions; } + materialsCommon = {}; + nodeExtensions.KHR_materials_common = materialsCommon; + materialsCommon.light = lightId; + var lightColor = techniqueParameters[lightId + 'Color']; + var light = { + name: lightId, + type: 'directional', + directional: { + color: defaultValue(lightColor.value, [1, 1, 1]) + } + }; + lights[lightId] = light; } } + } - delete material.technique; - var extensions = material.extensions; - if (!defined(extensions)) { - extensions = {}; - material.extensions = extensions; - } - materialsCommon = {}; - extensions.KHR_materials_common = materialsCommon; - for (var kmcOption in kmcOptions) { - if (kmcOptions.hasOwnProperty(kmcOption) && kmcOption !== 'enable') { - materialsCommon[kmcOption] = kmcOptions[kmcOption]; - } - } - var jointCount = jointCountForMaterialId[materialId]; - if (defined(jointCount)) { - materialsCommon.jointCount = jointCount; + delete material.technique; + var extensions = material.extensions; + if (!defined(extensions)) { + extensions = {}; + material.extensions = extensions; + } + materialsCommon = {}; + extensions.KHR_materials_common = materialsCommon; + for (var kmcOption in kmcOptions) { + if (kmcOptions.hasOwnProperty(kmcOption) && kmcOption !== 'enable') { + materialsCommon[kmcOption] = kmcOptions[kmcOption]; } + } + var jointCount = jointCountForMaterialId[materialId]; + if (defined(jointCount)) { + materialsCommon.jointCount = jointCount; + } - var materialValues = material.values; - var diffuseColor, transparency; - if (defined(materialValues)) { - diffuseColor = materialValues.diffuse; - transparency = materialValues.transparency; - materialsCommon.values = materialValues; - } + var materialValues = material.values; + var diffuseColor, transparency; + if (defined(materialValues)) { + diffuseColor = materialValues.diffuse; + transparency = materialValues.transparency; + materialsCommon.values = materialValues; + } - // Check if we have transparency and set transparent flag - if ((defined(transparency) && transparency < 1.0) || - (defined(diffuseColor) && Array.isArray(diffuseColor) && diffuseColor[3] < 1.0)) { - materialsCommon.values.transparent = true; - } - delete material.values; + // Check if we have transparency and set transparent flag + if ((defined(transparency) && transparency < 1.0) || + (defined(diffuseColor) && Array.isArray(diffuseColor) && diffuseColor[3] < 1.0)) { + materialsCommon.values.transparent = true; } - } + delete material.values; + }); delete gltf.techniques; delete gltf.programs; delete gltf.shaders; return gltf; } -function getJointCountForMaterials(gltf) { - var accessors = gltf.accessors; - var meshes = gltf.meshes; - var nodes = gltf.nodes; - var skins = gltf.skins; - var jointCountForMaterialId = {}; - - var nodesForSkinId = {}; - for (var nodeId in nodes) { - if (nodes.hasOwnProperty(nodeId)) { - var node = nodes[nodeId]; - if (defined(node.skin)) { - if (!defined(nodesForSkinId[node.skin])) { - nodesForSkinId[node.skin] = []; - } - nodesForSkinId[node.skin].push(node); - } - } - } - - for (var skinId in skins) { - if (skins.hasOwnProperty(skinId)) { - var skin = skins[skinId]; - var jointCount = 1; - if (defined(skin.inverseBindMatrices)) { - jointCount = accessors[skin.inverseBindMatrices].count; - } - var skinnedNodes = nodesForSkinId[skinId]; - var skinnedNodesLength = skinnedNodes.length; - for (var i = 0; i < skinnedNodesLength; i++) { - var skinnedNode = skinnedNodes[i]; - var nodeMeshes = skinnedNode.meshes; - var nodeMeshesLength = nodeMeshes.length; - for (var j = 0; j < nodeMeshesLength; j++) { - var meshId = nodeMeshes[j]; - var mesh = meshes[meshId]; - var primitives = mesh.primitives; - var primitivesLength = primitives.length; - for (var k = 0; k < primitivesLength; k++) { - var primitive = primitives[k]; - jointCountForMaterialId[primitive.material] = jointCount; - } - } - } - } - } - return jointCountForMaterialId; -} diff --git a/lib/getJointCountForMaterials.js b/lib/getJointCountForMaterials.js new file mode 100644 index 00000000..25b2fd95 --- /dev/null +++ b/lib/getJointCountForMaterials.js @@ -0,0 +1,47 @@ +'use strict'; +var Cesium = require('cesium'); +var ForEach = require('./ForEach'); + +var defined = Cesium.defined; + +module.exports = getJointCountForMaterials; + +function getJointCountForMaterials(gltf) { + var accessors = gltf.accessors; + var meshes = gltf.meshes; + var jointCountForMaterialId = {}; + + var nodesForSkinId = {}; + ForEach.node(gltf, function(node) { + if (defined(node.skin)) { + if (!defined(nodesForSkinId[node.skin])) { + nodesForSkinId[node.skin] = []; + } + nodesForSkinId[node.skin].push(node); + } + }); + + ForEach.skin(gltf, function(skin, skinId) { + var jointCount = 1; + if (defined(skin.inverseBindMatrices)) { + jointCount = accessors[skin.inverseBindMatrices].count; + } + var skinnedNodes = nodesForSkinId[skinId]; + var skinnedNodesLength = skinnedNodes.length; + for (var i = 0; i < skinnedNodesLength; i++) { + var skinnedNode = skinnedNodes[i]; + var meshId = skinnedNode.mesh; + if (defined(meshId)) { + var mesh = meshes[meshId]; + var primitives = mesh.primitives; + var primitivesLength = primitives.length; + for (var k = 0; k < primitivesLength; k++) { + var primitive = primitives[k]; + jointCountForMaterialId[primitive.material] = jointCount; + } + } + } + }); + + return jointCountForMaterialId; +} diff --git a/lib/pbrToMaterialsCommon.js b/lib/pbrToMaterialsCommon.js index 438b5404..c2510e3e 100644 --- a/lib/pbrToMaterialsCommon.js +++ b/lib/pbrToMaterialsCommon.js @@ -1,26 +1,26 @@ 'use strict'; var Cesium = require('cesium'); +var addExtensionsRequired = require('./addExtensionsRequired'); var ForEach = require('./ForEach'); +var getJointCountForMaterials = require('./getJointCountForMaterials'); +var removeExtensionsUsed = require('./removeExtensionsUsed'); var defined = Cesium.defined; module.exports = pbrToMaterialsCommon; /** - * Convert PBR materials to use a KHR_materials_common PHONG shader. - * This is a lossy conversion, and as such is only to be used for + * Convert PBR materials to use a KHR_materials_common BLINN shader. + * This is a lossy conversion, and as such should only be used for * compatibility reasons. Normal texture and metallic roughness information * will be lost, and some color or texture information may be lost. * - * The preferred solution is to properly - * implement PBR materials, and as such this function will likely - * by deprecated in the future. - * * @param {Object} gltf A javascript object containing a glTF asset. * @returns {Object} The glTF asset with materials converted to KHR_materials_common */ function pbrToMaterialsCommon(gltf) { - ForEach.material(gltf, function(material) { + var materialJointCount = getJointCountForMaterials(gltf); + ForEach.material(gltf, function(material, materialId) { var values = { ambient : [ 0.0, 0.0, 0.0, 1.0 ], diffuse : [ 0.0, 0.0, 0.0, 1.0 ], @@ -29,6 +29,13 @@ function pbrToMaterialsCommon(gltf) { shininess : [ 0.0 ] }; var pbrMetallicRoughness = material.pbrMetallicRoughness; + var isPBR = defined(pbrMetallicRoughness) || + (defined(material.extensions) && defined(material.extensions.KHR_materials_pbrSpecularGlossiness) || + defined(material.occlusionTexture) || + defined(material.emissiveFactor) || + defined(material.emissiveTexture) || + defined(material.doubleSided)); + if (defined(pbrMetallicRoughness)) { var baseColorFactor = pbrMetallicRoughness.baseColorFactor; if (defined(baseColorFactor)) { @@ -36,7 +43,7 @@ function pbrToMaterialsCommon(gltf) { } var baseColorTexture = pbrMetallicRoughness.baseColorTexture; if (defined(baseColorTexture)) { - values.diffuse = [ baseColorTexture.index ]; + values.diffuse = [baseColorTexture.index]; } } var extensions = material.extensions; @@ -51,7 +58,7 @@ function pbrToMaterialsCommon(gltf) { // diffuseTexture should be used instead of baseColorTexture if defined var diffuseTexture = pbrSpecularGlossiness.diffuseTexture; if (defined(diffuseTexture)) { - values.diffuse = [ diffuseTexture.index ]; + values.diffuse = [diffuseTexture.index]; } var specularFactor = pbrSpecularGlossiness.specularFactor; if (defined(specularFactor)) { @@ -65,13 +72,13 @@ function pbrToMaterialsCommon(gltf) { } var specularGlossinessTexture = pbrSpecularGlossiness.specularGlossinessTexture; if (defined(specularGlossinessTexture)) { - values.specular = [ specularGlossinessTexture.index ]; + values.specular = [specularGlossinessTexture.index]; } } } var occlusionTexture = material.occlusionTexture; if (defined(occlusionTexture)) { - values.ambient = [ occlusionTexture.index ]; + values.ambient = [occlusionTexture.index]; } var emissiveFactor = material.emissiveFactor; if (defined(emissiveFactor)) { @@ -79,15 +86,34 @@ function pbrToMaterialsCommon(gltf) { values.emission[1] = emissiveFactor[1]; values.emission[2] = emissiveFactor[2]; } - delete material.emissiveFactor; - delete material.normalTexture; - delete material.occlusionTexture; - delete material.pbrMetallicRoughness; - material.extensions = { - technique : 'PHONG', - KHR_materials_common : { + var emissiveTexture = material.emissiveTexture; + if (defined(emissiveTexture)) { + values.emission = [emissiveTexture.index]; + } + var doubleSided = material.doubleSided; + if (isPBR) { + delete material.doubleSided; + delete material.emissiveFactor; + delete material.emissiveTexture; + delete material.normalTexture; + delete material.occlusionTexture; + delete material.pbrMetallicRoughness; + var materialsCommon = { + technique: 'BLINN', values: values + }; + var jointCount = materialJointCount[materialId]; + if (defined(jointCount)) { + materialsCommon.jointCount = jointCount; } - }; + if (defined(doubleSided)) { + materialsCommon.doubleSided = doubleSided; + } + material.extensions = { + KHR_materials_common: materialsCommon + }; + addExtensionsRequired(gltf, 'KHR_materials_common'); + removeExtensionsUsed(gltf, 'KHR_materials_pbrSpecularGlossiness'); + } }); } \ No newline at end of file diff --git a/lib/processModelMaterialsCommon.js b/lib/processModelMaterialsCommon.js index 39cae316..ea562a55 100644 --- a/lib/processModelMaterialsCommon.js +++ b/lib/processModelMaterialsCommon.js @@ -486,7 +486,7 @@ function generateTechnique(gltf, khrMaterialsCommon, lightParameters, optimizeFo var colorCreationBlock = ' vec3 color = vec3(0.0, 0.0, 0.0);\n'; if (hasNormals) { fragmentShader += ' vec3 normal = normalize(v_normal);\n'; - if (parameterValues.doubleSided) { + if (khrMaterialsCommon.doubleSided) { fragmentShader += ' if (gl_FrontFacing == false)\n'; fragmentShader += ' {\n'; fragmentShader += ' normal = -normal;\n'; @@ -581,7 +581,7 @@ function generateTechnique(gltf, khrMaterialsCommon, lightParameters, optimizeFo ] } }; - } else if (parameterValues.doubleSided) { + } else if (khrMaterialsCommon.doubleSided) { techniqueStates = { enable: [ WebGLConstants.DEPTH_TEST diff --git a/specs/lib/generateModelMaterialsCommonSpec.js b/specs/lib/generateModelMaterialsCommonSpec.js index 72bf1c64..d7304e83 100644 --- a/specs/lib/generateModelMaterialsCommonSpec.js +++ b/specs/lib/generateModelMaterialsCommonSpec.js @@ -4,9 +4,9 @@ var generateModelMaterialsCommon = require('../../lib/generateModelMaterialsComm describe('generateModelMaterialsCommon', function () { it('removes techniques, programs, and shaders', function () { var gltf = { - techniques: {}, - programs: {}, - shaders: {} + techniques: [], + programs: [], + shaders: [] }; generateModelMaterialsCommon(gltf); expect(gltf.extensionsUsed).toEqual(['KHR_materials_common']); @@ -17,20 +17,20 @@ describe('generateModelMaterialsCommon', function () { it('generates a KHR_materials_common material with values', function () { var gltf = { - materials: { - material: { + materials: [ + { values: { ambient: [0, 0, 0, 1], otherAttribute: true }, - technique: 'technique' + technique: 0 } - }, - techniques: { - technique: { + ], + techniques: [ + { parameters: {} } - } + ] }; generateModelMaterialsCommon(gltf, { technique: 'PHONG', @@ -38,7 +38,7 @@ describe('generateModelMaterialsCommon', function () { someAttribute: true }); expect(gltf.extensionsUsed).toEqual(['KHR_materials_common']); - var material = gltf.materials.material; + var material = gltf.materials[0]; var materialsCommon = material.extensions.KHR_materials_common; expect(materialsCommon.doubleSided).toBe(true); expect(materialsCommon.technique).toBe('PHONG'); @@ -50,23 +50,23 @@ describe('generateModelMaterialsCommon', function () { it('generates a KHR_materials_common with correct transparent flag set if diffuse alpha is less than 1', function () { var gltf = { - materials: { - material: { + materials: [ + { values: { diffuse: [1, 0, 0, 0.5] }, - technique: 'technique' + technique: 0 } - }, - techniques: { - technique: { + ], + techniques: [ + { parameters: {} } - } + ] }; generateModelMaterialsCommon(gltf); expect(gltf.extensionsUsed).toEqual(['KHR_materials_common']); - var material = gltf.materials.material; + var material = gltf.materials[0]; var materialsCommon = material.extensions.KHR_materials_common; expect(materialsCommon.technique).toBe('PHONG'); var values = materialsCommon.values; @@ -76,24 +76,24 @@ describe('generateModelMaterialsCommon', function () { it('generates a KHR_materials_common with correct transparent flag set if transparency less than 1', function () { var gltf = { - materials: { - material: { + materials: [ + { values: { diffuse: [1, 0, 0, 1], transparency: 0.5 }, - technique: 'technique' + technique: 0 } - }, - techniques: { - technique: { + ], + techniques: [ + { parameters: {} } - } + ] }; generateModelMaterialsCommon(gltf); expect(gltf.extensionsUsed).toEqual(['KHR_materials_common']); - var material = gltf.materials.material; + var material = gltf.materials[0]; var materialsCommon = material.extensions.KHR_materials_common; expect(materialsCommon.technique).toBe('PHONG'); var values = materialsCommon.values; @@ -104,30 +104,30 @@ describe('generateModelMaterialsCommon', function () { it('generates lights from a technique', function () { var gltf = { - materials: { - material: { - technique: 'technique' + materials: [ + { + technique: 0 } - }, - nodes: { - lightNode: {} - }, - techniques: { - technique: { + ], + nodes: [ + {} + ], + techniques: [ + { parameters: { ambient: {}, light0Color: { value: [1, 1, 0.5] }, light0Transform: { - node: 'lightNode' + node: 0 } } } - } + ] }; generateModelMaterialsCommon(gltf); - expect(gltf.nodes.lightNode.extensions.KHR_materials_common.light).toBe('light0'); + expect(gltf.nodes[0].extensions.KHR_materials_common.light).toBe('light0'); var lights = gltf.extensions.KHR_materials_common.lights; expect(lights.defaultAmbient.ambient.color).toEqual([1, 1, 1]); expect(lights.light0.directional.color).toEqual([1, 1, 0.5]); @@ -136,46 +136,44 @@ describe('generateModelMaterialsCommon', function () { it('declares jointCount for skinned nodes', function () { var gltf = { - accessors: { - accessor: { + accessors: [ + { count: 4 } - }, - materials: { - material: { - technique: 'technique' + ], + materials: [ + { + technique: 0 } - }, - meshes: { - mesh: { + ], + meshes: [ + { primitives: [ { - material: 'material' + material: 0 } ] } - }, - nodes: { - skinnedNode: { - meshes: [ - 'mesh' - ], - skin: 'skin' + ], + nodes: [ + { + mesh: 0, + skin: 0 } - }, - skins: { - skin: { - inverseBindMatrices: 'accessor' + ], + skins: [ + { + inverseBindMatrices: 0 } - }, - techniques: { - technique: { + ], + techniques: [ + { parameters: {} } - } + ] }; generateModelMaterialsCommon(gltf); - var material = gltf.materials.material; + var material = gltf.materials[0]; var materialsCommon = material.extensions.KHR_materials_common; expect(materialsCommon.jointCount).toBe(4); }); diff --git a/specs/lib/pbrToMaterialsCommonSpec.js b/specs/lib/pbrToMaterialsCommonSpec.js new file mode 100644 index 00000000..779b331c --- /dev/null +++ b/specs/lib/pbrToMaterialsCommonSpec.js @@ -0,0 +1,214 @@ +'use strict'; +var pbrToMaterialsCommon = require('../../lib/pbrToMaterialsCommon'); + +describe('pbrToMaterialsCommon', function() { + it('deletes PBR properties and modifies extensionsRequired', function() { + var gltf = { + materials : [ + { + doubleSided : true, + emissiveFactor : [], + emissiveTexture : {}, + extensions : { + KHR_materials_pbrSpecularGlossiness : {} + }, + normalTexture : {}, + occlusionTexture : {}, + pbrMetallicRoughness : {} + } + ], + extensionsRequired : [ 'KHR_materials_pbrSpecularGlossiness' ], + extensionsUsed : [ 'KHR_materials_pbrSpecularGlossiness' ] + }; + pbrToMaterialsCommon(gltf); + var material = gltf.materials[0]; + expect(material.doubleSided).not.toBeDefined(); + expect(material.emissiveFactor).not.toBeDefined(); + expect(material.emissiveTexture).not.toBeDefined(); + expect(material.extensions.KHR_materials_pbrSpecularGlossiness).not.toBeDefined(); + expect(material.normalTexture).not.toBeDefined(); + expect(material.occlusionTexture).not.toBeDefined(); + expect(material.pbrMetallicRoughness).not.toBeDefined(); + expect(gltf.extensionsRequired).toEqual([ 'KHR_materials_common' ]); + expect(gltf.extensionsUsed).toEqual([ 'KHR_materials_common' ]); + }); + + it('maps baseColorFactor -> diffuse', function() { + var gltf = { + materials : [ + { + pbrMetallicRoughness : { + baseColorFactor : [ 1.0, 1.0, 1.0, 1.0 ] + } + } + ] + }; + pbrToMaterialsCommon(gltf); + expect(gltf.materials[0].extensions.KHR_materials_common.values.diffuse).toEqual([ 1.0, 1.0, 1.0, 1.0 ]); + }); + + it('maps baseColorTexture -> diffuse, overriding baseColorFactor', function() { + var gltf = { + materials : [ + { + pbrMetallicRoughness : { + baseColorFactor : [ 1.0, 1.0, 1.0, 1.0 ], + baseColorTexture : { + index : 2 + } + } + } + ] + }; + pbrToMaterialsCommon(gltf); + expect(gltf.materials[0].extensions.KHR_materials_common.values.diffuse).toEqual([ 2 ]); + }); + + it('maps pbrSpecularGlossiness.diffuseFactor -> diffuse', function() { + var gltf = { + materials : [ + { + extensions : { + KHR_materials_pbrSpecularGlossiness : { + diffuseFactor : [ 1.0, 1.0, 1.0, 1.0 ] + } + } + } + ] + }; + pbrToMaterialsCommon(gltf); + expect(gltf.materials[0].extensions.KHR_materials_common.values.diffuse).toEqual([ 1.0, 1.0, 1.0, 1.0 ]); + }); + + it('maps baseColorTexture -> diffuse even if pbrSpecularGlossiness.diffuseFactor is defined', function() { + var gltf = { + materials : [ + { + pbrMetallicRoughness : { + baseColorFactor : [ 1.0, 1.0, 1.0, 1.0 ], + baseColorTexture : { + index : 2 + } + }, + extensions : { + KHR_materials_pbrSpecularGlossiness : { + diffuseFactor : [ 1.0, 1.0, 1.0, 1.0 ] + } + } + } + ] + }; + pbrToMaterialsCommon(gltf); + expect(gltf.materials[0].extensions.KHR_materials_common.values.diffuse).toEqual([ 2 ]); + }); + + it('maps pbrSpecularGlossiness.diffuseTexture -> diffuse to overwrite baseColorTexture', function() { + var gltf = { + materials : [ + { + pbrMetallicRoughness : { + baseColorFactor : [ 1.0, 1.0, 1.0, 1.0 ], + baseColorTexture : { + index : 2 + } + }, + extensions : { + KHR_materials_pbrSpecularGlossiness : { + diffuseFactor : [ 1.0, 1.0, 1.0, 1.0 ], + diffuseTexture : { + index : 3 + } + } + } + } + ] + }; + pbrToMaterialsCommon(gltf); + expect(gltf.materials[0].extensions.KHR_materials_common.values.diffuse).toEqual([ 3 ]); + }); + + it('maps pbrSpecularGlossiness.specularFactor -> specular', function() { + var gltf = { + materials : [ + { + extensions : { + KHR_materials_pbrSpecularGlossiness : { + specularFactor : [ 1.0, 2.0, 3.0 ] + } + } + } + ] + }; + pbrToMaterialsCommon(gltf); + expect(gltf.materials[0].extensions.KHR_materials_common.values.specular).toEqual([ 1.0, 2.0, 3.0, 1.0 ]); + }); + + it('maps pbrSpecularGlossiness.glossinessFactor -> shininess', function() { + var gltf = { + materials : [ + { + extensions : { + KHR_materials_pbrSpecularGlossiness : { + glossinessFactor : 100.0 + } + } + } + ] + }; + pbrToMaterialsCommon(gltf); + expect(gltf.materials[0].extensions.KHR_materials_common.values.shininess).toEqual([ 100.0 ]); + }); + + it('maps occlusionTexture -> ambient', function() { + var gltf = { + materials : [ + { + occlusionTexture : { + index : 4 + } + } + ] + }; + pbrToMaterialsCommon(gltf); + expect(gltf.materials[0].extensions.KHR_materials_common.values.ambient).toEqual([ 4 ]); + }); + + it('maps emissiveFactor -> emission', function() { + var gltf = { + materials : [ + { + emissiveFactor : [1.0, 2.0, 3.0] + } + ] + }; + pbrToMaterialsCommon(gltf); + expect(gltf.materials[0].extensions.KHR_materials_common.values.emission).toEqual([ 1.0, 2.0, 3.0, 1.0 ]); + }); + + it('maps emissiveTexture -> emission', function() { + var gltf = { + materials : [ + { + emissiveFactor : [1.0, 2.0, 3.0], + emissiveTexture : { + index : 5 + } + } + ] + }; + pbrToMaterialsCommon(gltf); + expect(gltf.materials[0].extensions.KHR_materials_common.values.emission).toEqual([ 5 ]); + }); + + it('preserves doubleSided', function () { + var gltf = { + materials : [ + { + doubleSided : true + } + ] + }; + pbrToMaterialsCommon(gltf); + expect(gltf.materials[0].extensions.KHR_materials_common.doubleSided).toEqual(true); + }); +}); \ No newline at end of file From d9842a0d09244841f76887dd2740bfdb516411a3 Mon Sep 17 00:00:00 2001 From: Robert Taglang Date: Fri, 9 Jun 2017 10:52:03 -0400 Subject: [PATCH 3/6] Added spec for getJointCountForMaterials and some cleanup --- lib/getJointCountForMaterials.js | 12 +++------ lib/pbrToMaterialsCommon.js | 2 +- specs/lib/getJointCountForMaterialsSpec.js | 29 ++++++++++++++++++++++ 3 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 specs/lib/getJointCountForMaterialsSpec.js diff --git a/lib/getJointCountForMaterials.js b/lib/getJointCountForMaterials.js index 25b2fd95..6f985450 100644 --- a/lib/getJointCountForMaterials.js +++ b/lib/getJointCountForMaterials.js @@ -22,10 +22,7 @@ function getJointCountForMaterials(gltf) { }); ForEach.skin(gltf, function(skin, skinId) { - var jointCount = 1; - if (defined(skin.inverseBindMatrices)) { - jointCount = accessors[skin.inverseBindMatrices].count; - } + var jointCount = skin.joints.length; var skinnedNodes = nodesForSkinId[skinId]; var skinnedNodesLength = skinnedNodes.length; for (var i = 0; i < skinnedNodesLength; i++) { @@ -33,12 +30,9 @@ function getJointCountForMaterials(gltf) { var meshId = skinnedNode.mesh; if (defined(meshId)) { var mesh = meshes[meshId]; - var primitives = mesh.primitives; - var primitivesLength = primitives.length; - for (var k = 0; k < primitivesLength; k++) { - var primitive = primitives[k]; + ForEach.meshPrimitive(mesh, function(primitive) { jointCountForMaterialId[primitive.material] = jointCount; - } + }); } } }); diff --git a/lib/pbrToMaterialsCommon.js b/lib/pbrToMaterialsCommon.js index c2510e3e..13a8873e 100644 --- a/lib/pbrToMaterialsCommon.js +++ b/lib/pbrToMaterialsCommon.js @@ -26,7 +26,7 @@ function pbrToMaterialsCommon(gltf) { diffuse : [ 0.0, 0.0, 0.0, 1.0 ], emission : [ 0.0, 0.0, 0.0, 1.0 ], specular : [ 0.0, 0.0, 0.0, 1.0], - shininess : [ 0.0 ] + shininess : [ 0.0 ] }; var pbrMetallicRoughness = material.pbrMetallicRoughness; var isPBR = defined(pbrMetallicRoughness) || diff --git a/specs/lib/getJointCountForMaterialsSpec.js b/specs/lib/getJointCountForMaterialsSpec.js new file mode 100644 index 00000000..a0d740a8 --- /dev/null +++ b/specs/lib/getJointCountForMaterialsSpec.js @@ -0,0 +1,29 @@ +'use strict'; +var getJointCountForMaterials = require('../../lib/getJointCountForMaterials'); + +describe('getJointCountForMaterials', function() { + fit('gets joint counts for materials on skinned meshes', function() { + var gltf = { + materials : [{}, {}], + meshes : [{ + primitives : [{ + material : 1 + }] + }, { + primitives : [{ + material : 0 + }] + }], + nodes : [{ + mesh : 0, + skin : 0 + }], + skins : [{ + joints : [0, 1, 2, 3, 4] + }] + }; + var jointCounts = getJointCountForMaterials(gltf); + expect(jointCounts[0]).not.toBeDefined(); + expect(jointCounts[1]).toEqual(5); + }); +}); \ No newline at end of file From 5c722f96c934591213efeabab1853dadb63ea944 Mon Sep 17 00:00:00 2001 From: Robert Taglang Date: Fri, 9 Jun 2017 11:02:25 -0400 Subject: [PATCH 4/6] Clean up jsHint --- lib/getJointCountForMaterials.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/getJointCountForMaterials.js b/lib/getJointCountForMaterials.js index 6f985450..e769e292 100644 --- a/lib/getJointCountForMaterials.js +++ b/lib/getJointCountForMaterials.js @@ -7,7 +7,6 @@ var defined = Cesium.defined; module.exports = getJointCountForMaterials; function getJointCountForMaterials(gltf) { - var accessors = gltf.accessors; var meshes = gltf.meshes; var jointCountForMaterialId = {}; @@ -23,6 +22,9 @@ function getJointCountForMaterials(gltf) { ForEach.skin(gltf, function(skin, skinId) { var jointCount = skin.joints.length; + var meshPrimitiveFunction = function(primitive) { + jointCountForMaterialId[primitive.material] = jointCount; + }; var skinnedNodes = nodesForSkinId[skinId]; var skinnedNodesLength = skinnedNodes.length; for (var i = 0; i < skinnedNodesLength; i++) { @@ -30,9 +32,7 @@ function getJointCountForMaterials(gltf) { var meshId = skinnedNode.mesh; if (defined(meshId)) { var mesh = meshes[meshId]; - ForEach.meshPrimitive(mesh, function(primitive) { - jointCountForMaterialId[primitive.material] = jointCount; - }); + ForEach.meshPrimitive(mesh, meshPrimitiveFunction); } } }); From d7d939149731292cfe62362ee1f42e6fab1fe91a Mon Sep 17 00:00:00 2001 From: Robert Taglang Date: Fri, 9 Jun 2017 11:03:55 -0400 Subject: [PATCH 5/6] fit -> it --- specs/lib/getJointCountForMaterialsSpec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/lib/getJointCountForMaterialsSpec.js b/specs/lib/getJointCountForMaterialsSpec.js index a0d740a8..9b16f7db 100644 --- a/specs/lib/getJointCountForMaterialsSpec.js +++ b/specs/lib/getJointCountForMaterialsSpec.js @@ -2,7 +2,7 @@ var getJointCountForMaterials = require('../../lib/getJointCountForMaterials'); describe('getJointCountForMaterials', function() { - fit('gets joint counts for materials on skinned meshes', function() { + it('gets joint counts for materials on skinned meshes', function() { var gltf = { materials : [{}, {}], meshes : [{ From 8f83cc2a5fd66c8e18faf9252ee20c85af761fd2 Mon Sep 17 00:00:00 2001 From: Robert Taglang Date: Fri, 9 Jun 2017 11:06:36 -0400 Subject: [PATCH 6/6] Fix failing test --- specs/lib/generateModelMaterialsCommonSpec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specs/lib/generateModelMaterialsCommonSpec.js b/specs/lib/generateModelMaterialsCommonSpec.js index d7304e83..979934fe 100644 --- a/specs/lib/generateModelMaterialsCommonSpec.js +++ b/specs/lib/generateModelMaterialsCommonSpec.js @@ -163,7 +163,8 @@ describe('generateModelMaterialsCommon', function () { ], skins: [ { - inverseBindMatrices: 0 + inverseBindMatrices: 0, + joints: [1, 2, 3, 4] } ], techniques: [