Add back KHR_materials_common

This commit is contained in:
Sean Lilley 2017-05-04 15:39:01 -04:00
parent dc4ba7fc6a
commit 44e9d5fa3b
4 changed files with 123 additions and 33 deletions

View File

@ -48,8 +48,9 @@ Using obj2gltf as a command-line tool:
|`--inputUpAxis`|Up axis of the obj. Choices are 'X', 'Y', and 'Z'.|No, default `Y`|
|`--outputUpAxis`|Up axis of the converted glTF. Choices are 'X', 'Y', and 'Z'.|No, default `Y`|
|`--packOcclusion`|Pack the occlusion texture in the red channel of metallic-roughness texture.|No, default `false`|
|`--inputMetallicRoughness`|The values in the mtl file are already metallic-roughness PBR values and no conversion step should be applied. Metallic is stored in the Ks and map_Ks slots and roughness is stored in the Ns and map_Ns slots.|No, default `false`|
|`--inputSpecularGlossiness`|The values in the mtl file are already specular-glossiness PBR values and no conversion step should be applied. Specular is stored in the Ks and map_Ks slots and glossiness is stored in the Ns and map_Ns slots. The glTF will be saved with the `KHR_materials_pbrSpecularGlossiness` extension.|No, default `false`|
|`--metallicRoughness`|The values in the mtl file are already metallic-roughness PBR values and no conversion step should be applied. Metallic is stored in the Ks and map_Ks slots and roughness is stored in the Ns and map_Ns slots.|No, default `false`|
|`--specularGlossiness`|The values in the mtl file are already specular-glossiness PBR values and no conversion step should be applied. Specular is stored in the Ks and map_Ks slots and glossiness is stored in the Ns and map_Ns slots. The glTF will be saved with the `KHR_materials_pbrSpecularGlossiness` extension.|No, default `false`|
|`--materialsCommon`|The glTF will be saved with the KHR_materials_common extension.|No, default `false`|
## Build Instructions

View File

@ -108,15 +108,20 @@ var argv = yargs
type: 'boolean',
default: defaults.packOcclusion
},
inputMetallicRoughness : {
metallicRoughness : {
describe: 'The values in the mtl file are already metallic-roughness PBR values and no conversion step should be applied. Metallic is stored in the Ks and map_Ks slots and roughness is stored in the Ns and map_Ns slots.',
type: 'boolean',
default : defaults.metallicRoughness
default: defaults.metallicRoughness
},
inputSpecularGlossiness : {
specularGlossiness : {
describe: 'The values in the mtl file are already specular-glossiness PBR values and no conversion step should be applied. Specular is stored in the Ks and map_Ks slots and glossiness is stored in the Ns and map_Ns slots. The glTF will be saved with the KHR_materials_pbrSpecularGlossiness extension.',
type: 'boolean',
default : defaults.specularGlossiness
default: defaults.specularGlossiness
},
materialsCommon : {
describe: 'The glTF will be saved with the KHR_materials_common extension.',
type: 'boolean',
default: defaults.materialsCommon
}
}).parse(args);
@ -144,8 +149,8 @@ var options = {
inputUpAxis : argv.inputUpAxis,
outputUpAxis : argv.outputUpAxis,
packOcclusion : argv.packOcclusion,
inputMetallicRoughness : argv.inputMetallicRoughness,
inputSpecularGlossiness : argv.inputSpecularGlossiness
metallicRoughness : argv.metallicRoughness,
specularGlossiness : argv.specularGlossiness
};
console.time('Total');

View File

@ -5,6 +5,7 @@ var PNG = require('pngjs').PNG;
var Material = require('./Material');
var CesiumMath = Cesium.Math;
var defaultValue = Cesium.defaultValue;
var defined = Cesium.defined;
var WebGLConstants = Cesium.WebGLConstants;
@ -15,9 +16,10 @@ module.exports = createGltf;
*
* @param {Object} objData Output of obj.js, containing an array of nodes containing geometry information, materials, and images.
* @param {Object} options An object with the following properties:
* @param {Boolean} [options.packOcclusion=false] Pack the occlusion texture in the red channel of metallic-roughness texture.
* @param {Boolean} [options.inputMetallicRoughness=false] The values in the mtl file are already metallic-roughness PBR values and no conversion step should be applied. Metallic is stored in the Ks and map_Ks slots and roughness is stored in the Ns and map_Ns slots.
* @param {Boolean} [options.inputSpecularGlossiness=false] The values in the mtl file are already specular-glossiness PBR values and no conversion step should be applied. Specular is stored in the Ks and map_Ks slots and glossiness is stored in the Ns and map_Ns slots. The glTF will be saved with the KHR_materials_pbrSpecularGlossiness extension.
* @param {Boolean} [options.packOcclusion] Pack the occlusion texture in the red channel of metallic-roughness texture.
* @param {Boolean} [options.metallicRoughness] The values in the mtl file are already metallic-roughness PBR values and no conversion step should be applied. Metallic is stored in the Ks and map_Ks slots and roughness is stored in the Ns and map_Ns slots.
* @param {Boolean} [options.specularGlossiness] The values in the mtl file are already specular-glossiness PBR values and no conversion step should be applied. Specular is stored in the Ks and map_Ks slots and glossiness is stored in the Ns and map_Ns slots. The glTF will be saved with the KHR_materials_pbrSpecularGlossiness extension.
* @param {Boolean} [options.materialsCommon] The glTF will be saved with the KHR_materials_common extension.
* @param {Boolean} options.logger A callback function for handling logged messages. Defaults to console.log.
* @returns {Object} A glTF asset.
*
@ -33,6 +35,8 @@ function createGltf(objData, options) {
asset : {},
buffers : [],
bufferViews : [],
extensionsUsed : [],
extensionsRequired : [],
images : [],
materials : [],
meshes : [],
@ -486,7 +490,10 @@ function createSpecularGlossinessMaterial(gltf, images, material, options) {
var doubleSided = transparent;
var alphaMode = transparent ? 'BLEND' : 'OPAQUE';
var gltfMaterial = {
gltf.extensionsUsed.push('KHR_materials_pbrSpecularGlossiness');
gltf.extensionsRequired.push('KHR_materials_pbrSpecularGlossiness');
return {
name : materialName,
extensions : {
KHR_materials_pbrSpecularGlossiness: {
@ -504,8 +511,6 @@ function createSpecularGlossinessMaterial(gltf, images, material, options) {
alphaMode : alphaMode,
doubleSided : doubleSided
};
return gltfMaterial;
}
function createMetallicRoughnessMaterial(gltf, images, material, options) {
@ -558,7 +563,7 @@ function createMetallicRoughnessMaterial(gltf, images, material, options) {
var doubleSided = transparent;
var alphaMode = transparent ? 'BLEND' : 'OPAQUE';
var gltfMaterial = {
return {
name : materialName,
pbrMetallicRoughness : {
baseColorTexture : baseColorTexture,
@ -574,14 +579,13 @@ function createMetallicRoughnessMaterial(gltf, images, material, options) {
alphaMode : alphaMode,
doubleSided : doubleSided
};
return gltfMaterial;
}
function convertTraditionalToMetallicRoughness(material) {
// Translate the blinn-phong model to the pbr metallic-roughness model
// Roughness factor is a combination of specular intensity and shininess
// Metallic factor is 0.0
// This does not convert textures
var specularIntensity = material.specularColor[0];
var specularShininess = material.specularShininess;
@ -602,12 +606,83 @@ function convertTraditionalToMetallicRoughness(material) {
material.specularShiness = roughnessFactor;
}
function addMaterial(gltf, images, material, options) {
function createMaterialsCommonMaterial(gltf, images, material, hasNormals, options) {
var materialName = material.name;
var ambientImage = getImage(images, material.ambientTexture);
var diffuseImage = getImage(images, material.diffuseTexture);
var emissiveImage = getImage(images, material.emissiveTexture);
var specularImage = getImage(images, material.specularTexture);
var ambient = defaultValue(getTexture(gltf, ambientImage), material.ambientColor);
var diffuse = defaultValue(getTexture(gltf, diffuseImage), material.diffuseColor);
var emission = defaultValue(getTexture(gltf, emissiveImage), material.emissiveColor);
var specular = defaultValue(getTexture(gltf, specularImage), material.specularColor);
var alpha = material.alpha;
var shininess = material.specularShininess;
var hasSpecular = (shininess > 0.0) && (specular[0] > 0.0 || specular[1] > 0.0 || specular[2] > 0.0);
var transparent;
var transparency = 1.0;
if (defined(diffuseImage)) {
transparency = alpha;
transparent = diffuseImage.transparent || (transparency < 1.0);
} else {
diffuse[3] = alpha;
transparent = alpha < 1.0;
}
if (!defined(ambientImage)) {
// If ambient color is [1, 1, 1] assume it is a multiplier and instead change to [0, 0, 0]
if (ambient[0] === 1.0 && ambient[1] === 1.0 && ambient[2] === 1.0) {
ambient = [0.0, 0.0, 0.0, 1.0];
}
}
var doubleSided = transparent;
if (!hasNormals) {
// Constant technique only factors in ambient and emission sources - set emission to diffuse
emission = diffuse;
diffuse = [0, 0, 0, 1];
}
var technique = hasNormals ? (hasSpecular ? 'PHONG' : 'LAMBERT') : 'CONSTANT';
gltf.extensionsUsed.push('KHR_materials_common');
gltf.extensionsRequired.push('KHR_materials_common');
return {
name : materialName,
extensions : {
KHR_materials_common : {
technique : technique,
transparent : transparent,
doubleSided : doubleSided,
values : {
ambient : ambient,
diffuse : diffuse,
emission : emission,
specular : specular,
shininess : shininess,
transparency : transparency,
transparent : transparent,
doubleSided : doubleSided
}
}
}
};
}
function addMaterial(gltf, images, material, hasNormals, options) {
var gltfMaterial;
if (options.inputSpecularGlossiness) {
if (options.specularGlossiness) {
gltfMaterial = createSpecularGlossinessMaterial(gltf, images, material, options);
} else if (options.inputMetallicRoughness) {
} else if (options.metallicRoughness) {
gltfMaterial = createMetallicRoughnessMaterial(gltf, images, material, options);
} else if (options.materialsCommon) {
gltfMaterial = createMaterialsCommonMaterial(gltf, images, material, hasNormals, options);
} else {
convertTraditionalToMetallicRoughness(material);
gltfMaterial = createMetallicRoughnessMaterial(gltf, images, material, options);
@ -629,7 +704,7 @@ function getMaterialIndex(gltf, materialName) {
return undefined;
}
function getMaterial(gltf, materials, images, materialName, options) {
function getMaterial(gltf, materials, images, materialName, hasNormals, options) {
if (!defined(materialName)) {
// Create a default material if the primitive does not specify one
materialName = 'default';
@ -651,7 +726,7 @@ function getMaterial(gltf, materials, images, materialName, options) {
var materialIndex = getMaterialIndex(gltf, materialName);
if (!defined(materialIndex)) {
materialIndex = addMaterial(gltf, images, material, options);
materialIndex = addMaterial(gltf, images, material, hasNormals, options);
}
return materialIndex;
@ -750,7 +825,7 @@ function addMesh(gltf, materials, images, bufferState, uint32Indices, mesh, opti
var indexAccessorIndex = addIndexArray(gltf, bufferState, primitive.indices, uint32Indices);
primitive.indices = undefined; // Unload resources
var materialIndex = getMaterial(gltf, materials, images, primitive.material, options);
var materialIndex = getMaterial(gltf, materials, images, primitive.material, hasNormals, options);
gltfPrimitives.push({
attributes : attributes,

View File

@ -40,8 +40,9 @@ module.exports = obj2gltf;
* @param {String} [options.inputUpAxis='Y'] Up axis of the obj. Choices are 'X', 'Y', and 'Z'.
* @param {String} [options.outputUpAxis='Y'] Up axis of the converted glTF. Choices are 'X', 'Y', and 'Z'.
* @param {Boolean} [options.packOcclusion=false] Pack the occlusion texture in the red channel of metallic-roughness texture.
* @param {Boolean} [options.inputMetallicRoughness=false] The values in the mtl file are already metallic-roughness PBR values and no conversion step should be applied. Metallic is stored in the Ks and map_Ks slots and roughness is stored in the Ns and map_Ns slots.
* @param {Boolean} [options.inputSpecularGlossiness=false] The values in the mtl file are already specular-glossiness PBR values and no conversion step should be applied. Specular is stored in the Ks and map_Ks slots and glossiness is stored in the Ns and map_Ns slots. The glTF will be saved with the KHR_materials_pbrSpecularGlossiness extension.
* @param {Boolean} [options.metallicRoughness=false] The values in the mtl file are already metallic-roughness PBR values and no conversion step should be applied. Metallic is stored in the Ks and map_Ks slots and roughness is stored in the Ns and map_Ns slots.
* @param {Boolean} [options.specularGlossiness=false] The values in the mtl file are already specular-glossiness PBR values and no conversion step should be applied. Specular is stored in the Ks and map_Ks slots and glossiness is stored in the Ns and map_Ns slots. The glTF will be saved with the KHR_materials_pbrSpecularGlossiness extension.
* @param {Boolean} [options.materialsCommon=false] The glTF will be saved with the KHR_materials_common extension.
* @param {Logger} [options.logger] A callback function for handling logged messages. Defaults to console.log.
*/
function obj2gltf(objPath, gltfPath, options) {
@ -63,8 +64,9 @@ function obj2gltf(objPath, gltfPath, options) {
var inputUpAxis = defaultValue(options.inputUpAxis, defaults.inputUpAxis);
var outputUpAxis = defaultValue(options.outputUpAxis, defaults.outputUpAxis);
var packOcclusion = defaultValue(options.packOcclusion, defaults.packOcclusion);
var inputMetallicRoughness = defaultValue(options.inputMetallicRoughness, defaults.inputMetallicRoughness);
var inputSpecularGlossiness = defaultValue(options.inputSpecularGlossiness, defaults.inputSpecularGlossiness);
var metallicRoughness = defaultValue(options.metallicRoughness, defaults.metallicRoughness);
var specularGlossiness = defaultValue(options.specularGlossiness, defaults.specularGlossiness);
var materialsCommon = defaultValue(options.materialsCommon, defaults.materialsCommon);
var logger = defaultValue(options.logger, defaults.logger);
options.separate = separate;
@ -74,8 +76,9 @@ function obj2gltf(objPath, gltfPath, options) {
options.inputUpAxis = inputUpAxis;
options.outputUpAxis = outputUpAxis;
options.packOcclusion = packOcclusion;
options.inputMetallicRoughness = inputMetallicRoughness;
options.inputSpecularGlossiness = inputSpecularGlossiness;
options.metallicRoughness = metallicRoughness;
options.specularGlossiness = specularGlossiness;
options.materialsCommon = materialsCommon;
options.logger = logger;
if (!defined(objPath)) {
@ -96,8 +99,8 @@ function obj2gltf(objPath, gltfPath, options) {
return Promise.reject(new RuntimeError('--bypassPipeline does not convert to binary glTF'));
}
if (inputMetallicRoughness && inputSpecularGlossiness) {
throw new DeveloperError('--inputMetallicRoughness and --inputSpecularGlossiness cannot both be set.');
if (metallicRoughness + specularGlossiness + materialsCommon > 1) {
throw new DeveloperError('Only one material type may be set from [--metallicRoughness, --specularGlossiness, --materialsCommon].');
}
gltfPath = path.join(path.dirname(gltfPath), modelName + extension);
@ -243,13 +246,19 @@ obj2gltf.defaults = {
* @type Boolean
* @default false
*/
inputMetallicRoughness: false,
metallicRoughness: false,
/**
* The values in the mtl file are already specular-glossiness PBR values and no conversion step should be applied. Specular is stored in the Ks and map_Ks slots and glossiness is stored in the Ns and map_Ns slots. The glTF will be saved with the KHR_materials_pbrSpecularGlossiness extension.
* @type Boolean
* @default false
*/
inputSpecularGlossiness: false,
specularGlossiness: false,
/**
* The values in the mtl file are already specular-glossiness PBR values and no conversion step should be applied. Specular is stored in the Ks and map_Ks slots and glossiness is stored in the Ns and map_Ns slots. The glTF will be saved with the KHR_materials_pbrSpecularGlossiness extension.
* @type Boolean
* @default false
*/
materialsCommon: false,
/**
* @private