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(' -b, --binary Output binary glTF');
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');
process.exit(0);
}
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 combine = defaultValue(defaultValue(argv.c, argv.combine), false);
var technique = defaultValue(argv.t, argv.technique);
if (!defined(objFile)) {
console.error('-i or --input argument is required. See --help for details.');
@ -38,6 +40,13 @@ if (!defined(outputPath)) {
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 modelName = path.basename(objFile, '.obj');
@ -53,7 +62,7 @@ fs.mkdir(outputPath, function(){
parseObj(objFile, inputPath, function(data) {
console.timeEnd('Parse Obj');
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('Total');
});

View File

@ -15,16 +15,21 @@ module.exports = createGltf;
function getImages(inputPath, outputPath, combine, materials, done) {
var images = [];
for (var name in materials) {
if (materials.hasOwnProperty(name)) {
var material = materials[name];
for (var property in material) {
if (material.hasOwnProperty(property)) {
var image = material[property];
if (typeof image === 'string') {
images.push(image);
}
}
if (defined(material.ambientColorMap) && (images.indexOf(material.ambientColorMap) === -1)) {
images.push(material.ambientColorMap);
}
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
};
fsExtra.copy(imagePath, copyPath, function (err) {
if (err) {
throw err;
}
if (combine) {
callback();
});
} else {
fsExtra.copy(imagePath, copyPath, {clobber : true}, function (err) {
if (err) {
throw err;
}
callback();
});
}
});
}, function (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 vertexArray = data.vertexArray;
var positionMin = data.positionMin;
@ -305,44 +314,40 @@ function createGltf(data, modelName, inputPath, outputPath, binary, combine, don
});
}
function addTexture(name) {
var imageId = getImageId(name);
var textureId = getTextureId(name);
for (name in images) {
if (images.hasOwnProperty(name)) {
var image = images[name];
var imageId = getImageId(name);
var textureId = getTextureId(name);
var format;
var channels = image.channels;
switch (channels) {
case 1:
format = WebGLConstants.ALPHA;
break;
case 2:
format = WebGLConstants.LUMINANCE_ALPHA;
break;
case 3:
format = WebGLConstants.RGB;
break;
case 4:
format = WebGLConstants.RGBA;
break;
}
// Don't add the texture twice
if (defined(gltf.images[imageId])) {
return;
gltf.images[imageId] = {
uri : image.uri
};
gltf.textures[textureId] = {
format : format,
internalFormat : format,
sampler : samplerId,
source : imageId,
target : WebGLConstants.TEXTURE_2D,
type : WebGLConstants.UNSIGNED_BYTE
};
}
var image = images[name];
var format;
var channels = image.channels;
switch (channels) {
case 1:
format = WebGLConstants.ALPHA;
break;
case 2:
format = WebGLConstants.LUMINANCE_ALPHA;
break;
case 3:
format = WebGLConstants.RGB;
break;
case 4:
format = WebGLConstants.RGBA;
break;
}
gltf.images[imageId] = {
uri : image.uri
};
gltf.textures[textureId] = {
format : format,
internalFormat : format,
sampler : samplerId,
source : imageId,
target : WebGLConstants.TEXTURE_2D,
type : WebGLConstants.UNSIGNED_BYTE
};
}
for (i = 0; i < primitivesLength; ++i) {
@ -350,52 +355,41 @@ function createGltf(data, modelName, inputPath, outputPath, binary, combine, don
var material = materials[materialName];
var materialId = getMaterialId(materialName);
// Get specular color as combination of specular color and intensity
var specularColor = material.specularColor;
var specularIntensity = material.specularIntensity;
if (defined(specularColor)) {
specularIntensity = defaultValue(specularIntensity, 1.0);
specularColor[0] *= specularIntensity;
specularColor[1] *= specularIntensity;
specularColor[2] *= specularIntensity;
} else if(defined(specularIntensity)){
specularColor = [specularIntensity, specularIntensity, specularIntensity, 1];
// Get shading technique
var shadingTechnique = technique;
var specularColor = defaultValue(material.specularColor, [0, 0, 0, 1]);
var specularShininess = material.specularShininess;
var hasSpecularColor = (specularColor[0] > 0) || (specularColor[1] > 0) || (specularColor[2] > 0);
var hasSpecularColorMap = defined(material.specularColorMap);
if (defined(shadingTechnique)) {
if ((shadingTechnique === 'PHONG') || (shadingTechnique === 'BLINN')) {
if (!defined(specularShininess)) {
specularShininess = 10.0;
}
if (!hasSpecularColor) {
specularColor[0] = specularColor[1] = specularColor[2] = 0.5;
}
}
} else {
specularColor = [0, 0, 0, 1];
}
var specularMap = defaultValue(material.specularColorMap, material.specularIntensityMap);
var shadingTechnique = 'PHONG'; // or 'BLINN'
if (!defined(specularMap) && (specularColor[0] === 0) && (specularColor[1] === 0) && (specularColor[2] === 0)) {
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);
shadingTechnique = 'BLINN';
if (!hasSpecularColorMap && !hasSpecularColor) {
shadingTechnique = 'LAMBERT';
}
}
var values = {
ambient : defaultValue(defaultValue(getTextureId(material.ambientColorMap), material.ambientColor), [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]),
specular : defaultValue(getTextureId(specularMap), specularColor),
shininess : defaultValue(material.specularShininess, 0.0),
specular : defaultValue(getTextureId(material.specularColorMap), specularColor),
shininess : defaultValue(specularShininess, 0.0),
transparency : defaultValue(material.alpha, 1.0)
};
// If an image is transparent, set transparency to 0.99 to force alpha path
var diffuseColorMap = material.diffuseColorMap;
if (defined(diffuseColorMap) && images[diffuseColorMap].transparent) {
values.transparency = 0.99 * values.transparency;
values.transparency = 0.99 * (values.transparency || 1.0);
}
gltf.materials[materialId] = {

View File

@ -479,7 +479,7 @@ function generateTechnique(gltf, khrMaterialsCommon, attributes, lightParameters
if (hasSpecular) {
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 {
fragmentShader += ' vec3 specular = u_specular.rgb;\n';
@ -747,4 +747,4 @@ function modelMaterialsCommon(gltf) {
}
return gltf;
};
}

View File

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

View File

@ -55,7 +55,7 @@ function parseObj(objFile, inputPath, done) {
var hasUVs = /^vt/gm.test(contents);
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