mirror of
https://github.com/CesiumGS/obj2gltf.git
synced 2024-11-27 02:24:04 -05:00
Specular and texture fixes
This commit is contained in:
parent
1a0901b842
commit
3708651148
@ -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');
|
||||
});
|
||||
|
158
lib/gltf.js
158
lib/gltf.js
@ -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] = {
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user