Specular and texture fixes

This commit is contained in:
Sean Lilley 2015-10-19 13:35:28 -04:00
parent 1a0901b842
commit 3708651148
5 changed files with 90 additions and 94 deletions

View File

@ -20,14 +20,16 @@ if (process.argv.length < 3 || defined(argv.h) || defined(argv.help)) {
console.log(' -o, --output Directory or filename for the exported glTF file'); console.log(' -o, --output Directory or filename for the exported glTF file');
console.log(' -b, --binary Output binary glTF'); console.log(' -b, --binary Output binary glTF');
console.log(' -c --combine Combine glTF resources into a single file'); console.log(' -c --combine Combine glTF resources into a single file');
console.log(' -t --technique Shading technique. Possible values are lambert, phong, blinn, constant');
console.log(' -h, --help Display this help'); console.log(' -h, --help Display this help');
process.exit(0); process.exit(0);
} }
var objFile = defaultValue(argv._[0], defaultValue(argv.i, argv.input)); var objFile = defaultValue(argv._[0], defaultValue(argv.i, argv.input));
var outputPath = defaultValue(defaultValue(argv.o, argv.output)); var outputPath = defaultValue(argv._[1], defaultValue(argv.o, argv.output));
var binary = defaultValue(defaultValue(argv.b, argv.binary), false); var binary = defaultValue(defaultValue(argv.b, argv.binary), false);
var combine = defaultValue(defaultValue(argv.c, argv.combine), false); var combine = defaultValue(defaultValue(argv.c, argv.combine), false);
var technique = defaultValue(argv.t, argv.technique);
if (!defined(objFile)) { if (!defined(objFile)) {
console.error('-i or --input argument is required. See --help for details.'); console.error('-i or --input argument is required. See --help for details.');
@ -38,6 +40,13 @@ if (!defined(outputPath)) {
outputPath = path.dirname(objFile); outputPath = path.dirname(objFile);
} }
if (defined(technique)) {
technique = technique.toUpperCase();
if ((technique !== 'LAMBERT') && (technique !== 'PHONG') && (technique !== 'BLINN') && (technique !== 'CONSTANT')) {
console.log('Unrecognized technique \'' + technique + '\'. Using default instead.');
}
}
var inputPath = path.dirname(objFile); var inputPath = path.dirname(objFile);
var modelName = path.basename(objFile, '.obj'); var modelName = path.basename(objFile, '.obj');
@ -53,7 +62,7 @@ fs.mkdir(outputPath, function(){
parseObj(objFile, inputPath, function(data) { parseObj(objFile, inputPath, function(data) {
console.timeEnd('Parse Obj'); console.timeEnd('Parse Obj');
console.time('Create glTF'); console.time('Create glTF');
createGltf(data, modelName, inputPath, outputPath, binary, combine, function() { createGltf(data, modelName, inputPath, outputPath, binary, combine, technique, function() {
console.timeEnd('Create glTF'); console.timeEnd('Create glTF');
console.timeEnd('Total'); console.timeEnd('Total');
}); });

View File

@ -15,16 +15,21 @@ module.exports = createGltf;
function getImages(inputPath, outputPath, combine, materials, done) { function getImages(inputPath, outputPath, combine, materials, done) {
var images = []; var images = [];
for (var name in materials) { for (var name in materials) {
if (materials.hasOwnProperty(name)) { if (materials.hasOwnProperty(name)) {
var material = materials[name]; var material = materials[name];
for (var property in material) { if (defined(material.ambientColorMap) && (images.indexOf(material.ambientColorMap) === -1)) {
if (material.hasOwnProperty(property)) { images.push(material.ambientColorMap);
var image = material[property];
if (typeof image === 'string') {
images.push(image);
} }
if (defined(material.diffuseColorMap) && (images.indexOf(material.diffuseColorMap) === -1)) {
images.push(material.diffuseColorMap);
} }
if (defined(material.emissionColorMap) && (images.indexOf(material.emissionColorMap) === -1)) {
images.push(material.emissionColorMap);
}
if (defined(material.specularColorMap) && (images.indexOf(material.specularColorMap) === -1)) {
images.push(material.specularColorMap);
} }
} }
} }
@ -47,12 +52,16 @@ function getImages(inputPath, outputPath, combine, materials, done) {
uri : uri uri : uri
}; };
fsExtra.copy(imagePath, copyPath, function (err) { if (combine) {
callback();
} else {
fsExtra.copy(imagePath, copyPath, {clobber : true}, function (err) {
if (err) { if (err) {
throw err; throw err;
} }
callback(); callback();
}); });
}
}); });
}, function (err) { }, function (err) {
if (err) { if (err) {
@ -62,7 +71,7 @@ function getImages(inputPath, outputPath, combine, materials, done) {
}); });
} }
function createGltf(data, modelName, inputPath, outputPath, binary, combine, done) { function createGltf(data, modelName, inputPath, outputPath, binary, combine, technique, done) {
var vertexCount = data.vertexCount; var vertexCount = data.vertexCount;
var vertexArray = data.vertexArray; var vertexArray = data.vertexArray;
var positionMin = data.positionMin; var positionMin = data.positionMin;
@ -305,16 +314,11 @@ function createGltf(data, modelName, inputPath, outputPath, binary, combine, don
}); });
} }
function addTexture(name) { for (name in images) {
if (images.hasOwnProperty(name)) {
var image = images[name];
var imageId = getImageId(name); var imageId = getImageId(name);
var textureId = getTextureId(name); var textureId = getTextureId(name);
// Don't add the texture twice
if (defined(gltf.images[imageId])) {
return;
}
var image = images[name];
var format; var format;
var channels = image.channels; var channels = image.channels;
switch (channels) { switch (channels) {
@ -344,58 +348,48 @@ function createGltf(data, modelName, inputPath, outputPath, binary, combine, don
type : WebGLConstants.UNSIGNED_BYTE type : WebGLConstants.UNSIGNED_BYTE
}; };
} }
}
for (i = 0; i < primitivesLength; ++i) { for (i = 0; i < primitivesLength; ++i) {
var materialName = primitives[i].material; var materialName = primitives[i].material;
var material = materials[materialName]; var material = materials[materialName];
var materialId = getMaterialId(materialName); var materialId = getMaterialId(materialName);
// Get specular color as combination of specular color and intensity // Get shading technique
var specularColor = material.specularColor; var shadingTechnique = technique;
var specularIntensity = material.specularIntensity; var specularColor = defaultValue(material.specularColor, [0, 0, 0, 1]);
if (defined(specularColor)) { var specularShininess = material.specularShininess;
specularIntensity = defaultValue(specularIntensity, 1.0); var hasSpecularColor = (specularColor[0] > 0) || (specularColor[1] > 0) || (specularColor[2] > 0);
specularColor[0] *= specularIntensity; var hasSpecularColorMap = defined(material.specularColorMap);
specularColor[1] *= specularIntensity; if (defined(shadingTechnique)) {
specularColor[2] *= specularIntensity; if ((shadingTechnique === 'PHONG') || (shadingTechnique === 'BLINN')) {
} else if(defined(specularIntensity)){ if (!defined(specularShininess)) {
specularColor = [specularIntensity, specularIntensity, specularIntensity, 1]; specularShininess = 10.0;
} else {
specularColor = [0, 0, 0, 1];
} }
if (!hasSpecularColor) {
var specularMap = defaultValue(material.specularColorMap, material.specularIntensityMap); specularColor[0] = specularColor[1] = specularColor[2] = 0.5;
var shadingTechnique = 'PHONG'; // or 'BLINN' }
if (!defined(specularMap) && (specularColor[0] === 0) && (specularColor[1] === 0) && (specularColor[2] === 0)) { }
} else {
shadingTechnique = 'BLINN';
if (!hasSpecularColorMap && !hasSpecularColor) {
shadingTechnique = 'LAMBERT'; shadingTechnique = 'LAMBERT';
} }
if (defined(material.ambientColorMap)) {
addTexture(material.ambientColorMap);
}
if (defined(material.diffuseColorMap)) {
addTexture(material.diffuseColorMap);
}
if (defined(material.emissionColorMap)) {
addTexture(material.emissionColorMap);
}
if (defined(specularMap)) {
addTexture(specularMap);
} }
var values = { var values = {
ambient : defaultValue(defaultValue(getTextureId(material.ambientColorMap), material.ambientColor), [0, 0, 0, 1]), ambient : defaultValue(defaultValue(getTextureId(material.ambientColorMap), material.ambientColor), [0, 0, 0, 1]),
diffuse : defaultValue(defaultValue(getTextureId(material.diffuseColorMap), material.diffuseColor), [0, 0, 0, 1]), diffuse : defaultValue(defaultValue(getTextureId(material.diffuseColorMap), material.diffuseColor), [0, 0, 0, 1]),
emission : defaultValue(defaultValue(getTextureId(material.emissionColorMap), material.emissionColor), [0, 0, 0, 1]), emission : defaultValue(defaultValue(getTextureId(material.emissionColorMap), material.emissionColor), [0, 0, 0, 1]),
specular : defaultValue(getTextureId(specularMap), specularColor), specular : defaultValue(getTextureId(material.specularColorMap), specularColor),
shininess : defaultValue(material.specularShininess, 0.0), shininess : defaultValue(specularShininess, 0.0),
transparency : defaultValue(material.alpha, 1.0) transparency : defaultValue(material.alpha, 1.0)
}; };
// If an image is transparent, set transparency to 0.99 to force alpha path // If an image is transparent, set transparency to 0.99 to force alpha path
var diffuseColorMap = material.diffuseColorMap; var diffuseColorMap = material.diffuseColorMap;
if (defined(diffuseColorMap) && images[diffuseColorMap].transparent) { if (defined(diffuseColorMap) && images[diffuseColorMap].transparent) {
values.transparency = 0.99 * values.transparency; values.transparency = 0.99 * (values.transparency || 1.0);
} }
gltf.materials[materialId] = { gltf.materials[materialId] = {

View File

@ -479,7 +479,7 @@ function generateTechnique(gltf, khrMaterialsCommon, attributes, lightParameters
if (hasSpecular) { if (hasSpecular) {
if (techniqueParameters.specular.type === WebGLConstants.SAMPLER_2D) { if (techniqueParameters.specular.type === WebGLConstants.SAMPLER_2D) {
fragmentShader += ' vec3 specular = texture2D(u_specular, ' + v_texcoord + ');\n'; fragmentShader += ' vec3 specular = texture2D(u_specular, ' + v_texcoord + ').rgb;\n';
} }
else { else {
fragmentShader += ' vec3 specular = u_specular.rgb;\n'; fragmentShader += ' vec3 specular = u_specular.rgb;\n';
@ -747,4 +747,4 @@ function modelMaterialsCommon(gltf) {
} }
return gltf; return gltf;
}; }

View File

@ -13,14 +13,12 @@ function createMaterial() {
diffuseColor : undefined, // Kd diffuseColor : undefined, // Kd
specularColor : undefined, // Ks specularColor : undefined, // Ks
specularShininess : undefined, // Ns specularShininess : undefined, // Ns
specularIntensity : undefined, // Ni
alpha : undefined, // d alpha : undefined, // d
ambientColorMap : undefined, // map_Ka ambientColorMap : undefined, // map_Ka
emissionColorMap : undefined, // map_Ke emissionColorMap : undefined, // map_Ke
diffuseColorMap : undefined, // map_Kd diffuseColorMap : undefined, // map_Kd
specularColorMap : undefined, // map_Ks specularColorMap : undefined, // map_Ks
specularShininessMap : undefined, // map_Ns specularShininessMap : undefined, // map_Ns
specularIntensityMap : undefined, // map_Ni
normalMap : undefined, // map_Bump normalMap : undefined, // map_Bump
alphaMap : undefined // map_d alphaMap : undefined // map_d
}; };
@ -88,9 +86,6 @@ function parse(mtlPath, done) {
} else if (/^Ns /i.test(line)) { } else if (/^Ns /i.test(line)) {
value = line.substring(3).trim(); value = line.substring(3).trim();
material.specularShininess = parseFloat(value); material.specularShininess = parseFloat(value);
} else if (/^Ni /i.test(line)) {
value = line.substring(3).trim();
material.specularIntensity = parseFloat(value);
} else if (/^d /i.test(line)) { } else if (/^d /i.test(line)) {
value = line.substring(2).trim(); value = line.substring(2).trim();
material.alpha = parseFloat(value); material.alpha = parseFloat(value);
@ -104,8 +99,6 @@ function parse(mtlPath, done) {
material.specularColorMap = line.substring(7).trim(); material.specularColorMap = line.substring(7).trim();
} else if (/^map_Ns /i.test(line)) { } else if (/^map_Ns /i.test(line)) {
material.specularShininessMap = line.substring(7).trim(); material.specularShininessMap = line.substring(7).trim();
} else if (/^map_Ni /i.test(line)) {
material.specularIntensityMap = line.substring(7).trim();
} else if (/^map_Bump /i.test(line)) { } else if (/^map_Bump /i.test(line)) {
material.normalMap = line.substring(9).trim(); material.normalMap = line.substring(9).trim();
} else if (/^map_d /i.test(line)) { } else if (/^map_d /i.test(line)) {

View File

@ -55,7 +55,7 @@ function parseObj(objFile, inputPath, done) {
var hasUVs = /^vt/gm.test(contents); var hasUVs = /^vt/gm.test(contents);
if (!hasPositions) { if (!hasPositions) {
console.log('Could not process obj file, no positions.') console.log('Could not process obj file, no positions.');
} }
// Map material to index array // Map material to index array