|
@@ -767,13 +767,13 @@ var BABYLON;
|
|
else {
|
|
else {
|
|
BABYLON.Tools.Warn("Material type " + bufferMesh.material.getClassName() + " for material " + bufferMesh.material.name + " is not yet implemented in glTF serializer.");
|
|
BABYLON.Tools.Warn("Material type " + bufferMesh.material.getClassName() + " for material " + bufferMesh.material.name + " is not yet implemented in glTF serializer.");
|
|
}
|
|
}
|
|
- if (materialIndex != null) {
|
|
|
|
- if (uvCoordsPresent || !GLTF2._GLTFMaterial.HasTexturesPresent(this.materials[materialIndex])) {
|
|
|
|
|
|
+ if (materialIndex != null && Object.keys(meshPrimitive.attributes).length > 0) {
|
|
|
|
+ if (uvCoordsPresent || !GLTF2._GLTFMaterial._HasTexturesPresent(this.materials[materialIndex])) {
|
|
meshPrimitive.material = materialIndex;
|
|
meshPrimitive.material = materialIndex;
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
// If no texture coordinate information is present, make a copy of the material without the textures to be glTF compliant.
|
|
// If no texture coordinate information is present, make a copy of the material without the textures to be glTF compliant.
|
|
- var newMat = GLTF2._GLTFMaterial.StripTexturesFromMaterial(this.materials[materialIndex]);
|
|
|
|
|
|
+ var newMat = GLTF2._GLTFMaterial._StripTexturesFromMaterial(this.materials[materialIndex]);
|
|
this.materials.push(newMat);
|
|
this.materials.push(newMat);
|
|
meshPrimitive.material = this.materials.length - 1;
|
|
meshPrimitive.material = this.materials.length - 1;
|
|
}
|
|
}
|
|
@@ -796,7 +796,7 @@ var BABYLON;
|
|
if (babylonScene.meshes.length) {
|
|
if (babylonScene.meshes.length) {
|
|
var babylonMeshes = babylonScene.meshes;
|
|
var babylonMeshes = babylonScene.meshes;
|
|
var scene = { nodes: new Array() };
|
|
var scene = { nodes: new Array() };
|
|
- GLTF2._GLTFMaterial.ConvertMaterialsToGLTF(babylonScene.materials, "image/jpeg" /* JPEG */, this.images, this.textures, this.materials, this.imageData, true);
|
|
|
|
|
|
+ GLTF2._GLTFMaterial._ConvertMaterialsToGLTF(babylonScene.materials, "image/png" /* PNG */, this.images, this.textures, this.materials, this.imageData, true);
|
|
var result = this.createNodeMap(babylonScene, byteOffset);
|
|
var result = this.createNodeMap(babylonScene, byteOffset);
|
|
this.nodeMap = result.nodeMap;
|
|
this.nodeMap = result.nodeMap;
|
|
this.totalByteLength = result.byteOffset;
|
|
this.totalByteLength = result.byteOffset;
|
|
@@ -953,29 +953,40 @@ var BABYLON;
|
|
function _GLTFMaterial() {
|
|
function _GLTFMaterial() {
|
|
}
|
|
}
|
|
/**
|
|
/**
|
|
|
|
+ * Specifies if two colors are approximately equal in value.
|
|
|
|
+ * @param color1 - first color to compare to.
|
|
|
|
+ * @param color2 - second color to compare to.
|
|
|
|
+ * @param epsilon - threshold value
|
|
|
|
+ */
|
|
|
|
+ _GLTFMaterial.FuzzyEquals = function (color1, color2, epsilon) {
|
|
|
|
+ return BABYLON.Scalar.WithinEpsilon(color1.r, color2.r, epsilon) &&
|
|
|
|
+ BABYLON.Scalar.WithinEpsilon(color1.g, color2.g, epsilon) &&
|
|
|
|
+ BABYLON.Scalar.WithinEpsilon(color1.b, color2.b, epsilon);
|
|
|
|
+ };
|
|
|
|
+ /**
|
|
* Gets the materials from a Babylon scene and converts them to glTF materials.
|
|
* Gets the materials from a Babylon scene and converts them to glTF materials.
|
|
- * @param scene
|
|
|
|
- * @param mimeType
|
|
|
|
- * @param images
|
|
|
|
- * @param textures
|
|
|
|
- * @param materials
|
|
|
|
- * @param imageData
|
|
|
|
- * @param hasTextureCoords
|
|
|
|
|
|
+ * @param scene - babylonjs scene.
|
|
|
|
+ * @param mimeType - texture mime type.
|
|
|
|
+ * @param images - array of images.
|
|
|
|
+ * @param textures - array of textures.
|
|
|
|
+ * @param materials - array of materials.
|
|
|
|
+ * @param imageData - mapping of texture names to base64 textures
|
|
|
|
+ * @param hasTextureCoords - specifies if texture coordinates are present on the material.
|
|
*/
|
|
*/
|
|
- _GLTFMaterial.ConvertMaterialsToGLTF = function (babylonMaterials, mimeType, images, textures, materials, imageData, hasTextureCoords) {
|
|
|
|
|
|
+ _GLTFMaterial._ConvertMaterialsToGLTF = function (babylonMaterials, mimeType, images, textures, materials, imageData, hasTextureCoords) {
|
|
for (var i = 0; i < babylonMaterials.length; ++i) {
|
|
for (var i = 0; i < babylonMaterials.length; ++i) {
|
|
var babylonMaterial = babylonMaterials[i];
|
|
var babylonMaterial = babylonMaterials[i];
|
|
if (babylonMaterial instanceof BABYLON.StandardMaterial) {
|
|
if (babylonMaterial instanceof BABYLON.StandardMaterial) {
|
|
- _GLTFMaterial.ConvertStandardMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
|
|
|
|
|
|
+ _GLTFMaterial._ConvertStandardMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
|
|
}
|
|
}
|
|
else if (babylonMaterial instanceof BABYLON.PBRMetallicRoughnessMaterial) {
|
|
else if (babylonMaterial instanceof BABYLON.PBRMetallicRoughnessMaterial) {
|
|
- _GLTFMaterial.ConvertPBRMetallicRoughnessMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
|
|
|
|
|
|
+ _GLTFMaterial._ConvertPBRMetallicRoughnessMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
|
|
}
|
|
}
|
|
else if (babylonMaterial instanceof BABYLON.PBRMaterial) {
|
|
else if (babylonMaterial instanceof BABYLON.PBRMaterial) {
|
|
- _GLTFMaterial.ConvertPBRMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
|
|
|
|
|
|
+ _GLTFMaterial._ConvertPBRMaterial(babylonMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords);
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
- BABYLON.Tools.Error("Unsupported material type: " + babylonMaterial.name);
|
|
|
|
|
|
+ throw new Error("Unsupported material type: " + babylonMaterial.name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
@@ -984,7 +995,7 @@ var BABYLON;
|
|
* @param originalMaterial - original glTF material.
|
|
* @param originalMaterial - original glTF material.
|
|
* @returns glTF material without texture parameters
|
|
* @returns glTF material without texture parameters
|
|
*/
|
|
*/
|
|
- _GLTFMaterial.StripTexturesFromMaterial = function (originalMaterial) {
|
|
|
|
|
|
+ _GLTFMaterial._StripTexturesFromMaterial = function (originalMaterial) {
|
|
var newMaterial = {};
|
|
var newMaterial = {};
|
|
if (originalMaterial) {
|
|
if (originalMaterial) {
|
|
newMaterial.name = originalMaterial.name;
|
|
newMaterial.name = originalMaterial.name;
|
|
@@ -1007,7 +1018,7 @@ var BABYLON;
|
|
* @param material - glTF Material.
|
|
* @param material - glTF Material.
|
|
* @returns boolean specifying if texture parameters are present
|
|
* @returns boolean specifying if texture parameters are present
|
|
*/
|
|
*/
|
|
- _GLTFMaterial.HasTexturesPresent = function (material) {
|
|
|
|
|
|
+ _GLTFMaterial._HasTexturesPresent = function (material) {
|
|
if (material.emissiveTexture || material.normalTexture || material.occlusionTexture) {
|
|
if (material.emissiveTexture || material.normalTexture || material.occlusionTexture) {
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
@@ -1024,7 +1035,7 @@ var BABYLON;
|
|
* @param babylonStandardMaterial
|
|
* @param babylonStandardMaterial
|
|
* @returns - glTF Metallic Roughness Material representation
|
|
* @returns - glTF Metallic Roughness Material representation
|
|
*/
|
|
*/
|
|
- _GLTFMaterial.ConvertToGLTFPBRMetallicRoughness = function (babylonStandardMaterial) {
|
|
|
|
|
|
+ _GLTFMaterial._ConvertToGLTFPBRMetallicRoughness = function (babylonStandardMaterial) {
|
|
var P0 = new BABYLON.Vector2(0, 1);
|
|
var P0 = new BABYLON.Vector2(0, 1);
|
|
var P1 = new BABYLON.Vector2(0, 0.1);
|
|
var P1 = new BABYLON.Vector2(0, 0.1);
|
|
var P2 = new BABYLON.Vector2(0, 0.1);
|
|
var P2 = new BABYLON.Vector2(0, 0.1);
|
|
@@ -1038,7 +1049,7 @@ var BABYLON;
|
|
* @param p3 - fourth control point.
|
|
* @param p3 - fourth control point.
|
|
* @returns - number result of cubic bezier curve at the specified t.
|
|
* @returns - number result of cubic bezier curve at the specified t.
|
|
*/
|
|
*/
|
|
- function cubicBezierCurve(t, p0, p1, p2, p3) {
|
|
|
|
|
|
+ function _cubicBezierCurve(t, p0, p1, p2, p3) {
|
|
return ((1 - t) * (1 - t) * (1 - t) * p0 +
|
|
return ((1 - t) * (1 - t) * (1 - t) * p0 +
|
|
3 * (1 - t) * (1 - t) * t * p1 +
|
|
3 * (1 - t) * (1 - t) * t * p1 +
|
|
3 * (1 - t) * t * t * p2 +
|
|
3 * (1 - t) * t * t * p2 +
|
|
@@ -1051,14 +1062,14 @@ var BABYLON;
|
|
* @param specularPower - specular power of standard material.
|
|
* @param specularPower - specular power of standard material.
|
|
* @returns - Number representing the roughness value.
|
|
* @returns - Number representing the roughness value.
|
|
*/
|
|
*/
|
|
- function solveForRoughness(specularPower) {
|
|
|
|
|
|
+ function _solveForRoughness(specularPower) {
|
|
var t = Math.pow(specularPower / P3.x, 0.333333);
|
|
var t = Math.pow(specularPower / P3.x, 0.333333);
|
|
- return cubicBezierCurve(t, P0.y, P1.y, P2.y, P3.y);
|
|
|
|
|
|
+ return _cubicBezierCurve(t, P0.y, P1.y, P2.y, P3.y);
|
|
}
|
|
}
|
|
var diffuse = babylonStandardMaterial.diffuseColor.toLinearSpace().scale(0.5);
|
|
var diffuse = babylonStandardMaterial.diffuseColor.toLinearSpace().scale(0.5);
|
|
var opacity = babylonStandardMaterial.alpha;
|
|
var opacity = babylonStandardMaterial.alpha;
|
|
- var specularPower = BABYLON.Scalar.Clamp(babylonStandardMaterial.specularPower, 0, this.maxSpecularPower);
|
|
|
|
- var roughness = solveForRoughness(specularPower);
|
|
|
|
|
|
+ var specularPower = BABYLON.Scalar.Clamp(babylonStandardMaterial.specularPower, 0, this._maxSpecularPower);
|
|
|
|
+ var roughness = _solveForRoughness(specularPower);
|
|
var glTFPbrMetallicRoughness = {
|
|
var glTFPbrMetallicRoughness = {
|
|
baseColorFactor: [
|
|
baseColorFactor: [
|
|
diffuse.r,
|
|
diffuse.r,
|
|
@@ -1078,14 +1089,14 @@ var BABYLON;
|
|
* @param oneMinusSpecularStrength - one minus the specular strength
|
|
* @param oneMinusSpecularStrength - one minus the specular strength
|
|
* @returns - metallic value
|
|
* @returns - metallic value
|
|
*/
|
|
*/
|
|
- _GLTFMaterial.SolveMetallic = function (diffuse, specular, oneMinusSpecularStrength) {
|
|
|
|
- if (specular < _GLTFMaterial.dielectricSpecular.r) {
|
|
|
|
- _GLTFMaterial.dielectricSpecular;
|
|
|
|
|
|
+ _GLTFMaterial._SolveMetallic = function (diffuse, specular, oneMinusSpecularStrength) {
|
|
|
|
+ if (specular < _GLTFMaterial._dielectricSpecular.r) {
|
|
|
|
+ _GLTFMaterial._dielectricSpecular;
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
- var a = _GLTFMaterial.dielectricSpecular.r;
|
|
|
|
- var b = diffuse * oneMinusSpecularStrength / (1.0 - _GLTFMaterial.dielectricSpecular.r) + specular - 2.0 * _GLTFMaterial.dielectricSpecular.r;
|
|
|
|
- var c = _GLTFMaterial.dielectricSpecular.r - specular;
|
|
|
|
|
|
+ var a = _GLTFMaterial._dielectricSpecular.r;
|
|
|
|
+ var b = diffuse * oneMinusSpecularStrength / (1.0 - _GLTFMaterial._dielectricSpecular.r) + specular - 2.0 * _GLTFMaterial._dielectricSpecular.r;
|
|
|
|
+ var c = _GLTFMaterial._dielectricSpecular.r - specular;
|
|
var D = b * b - 4.0 * a * c;
|
|
var D = b * b - 4.0 * a * c;
|
|
return BABYLON.Scalar.Clamp((-b + Math.sqrt(D)) / (2.0 * a), 0, 1);
|
|
return BABYLON.Scalar.Clamp((-b + Math.sqrt(D)) / (2.0 * a), 0, 1);
|
|
};
|
|
};
|
|
@@ -1094,7 +1105,7 @@ var BABYLON;
|
|
* @param babylonMaterial - Babylon Material
|
|
* @param babylonMaterial - Babylon Material
|
|
* @returns - The Babylon alpha mode value
|
|
* @returns - The Babylon alpha mode value
|
|
*/
|
|
*/
|
|
- _GLTFMaterial.GetAlphaMode = function (babylonMaterial) {
|
|
|
|
|
|
+ _GLTFMaterial._GetAlphaMode = function (babylonMaterial) {
|
|
if (babylonMaterial instanceof BABYLON.StandardMaterial) {
|
|
if (babylonMaterial instanceof BABYLON.StandardMaterial) {
|
|
var babylonStandardMaterial = babylonMaterial;
|
|
var babylonStandardMaterial = babylonMaterial;
|
|
if ((babylonStandardMaterial.alpha != 1.0) ||
|
|
if ((babylonStandardMaterial.alpha != 1.0) ||
|
|
@@ -1162,11 +1173,11 @@ var BABYLON;
|
|
* @param imageData - map of image file name to data.
|
|
* @param imageData - map of image file name to data.
|
|
* @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
|
|
* @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
|
|
*/
|
|
*/
|
|
- _GLTFMaterial.ConvertStandardMaterial = function (babylonStandardMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
|
|
|
|
|
|
+ _GLTFMaterial._ConvertStandardMaterial = function (babylonStandardMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
|
|
BABYLON.Tools.Warn(babylonStandardMaterial.name + ": Standard Material is currently not fully supported/implemented in glTF serializer");
|
|
BABYLON.Tools.Warn(babylonStandardMaterial.name + ": Standard Material is currently not fully supported/implemented in glTF serializer");
|
|
- var glTFPbrMetallicRoughness = _GLTFMaterial.ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);
|
|
|
|
|
|
+ var glTFPbrMetallicRoughness = _GLTFMaterial._ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);
|
|
var glTFMaterial = { name: babylonStandardMaterial.name };
|
|
var glTFMaterial = { name: babylonStandardMaterial.name };
|
|
- if (babylonStandardMaterial.backFaceCulling) {
|
|
|
|
|
|
+ if (babylonStandardMaterial.backFaceCulling != null && !babylonStandardMaterial.backFaceCulling) {
|
|
if (!babylonStandardMaterial.twoSidedLighting) {
|
|
if (!babylonStandardMaterial.twoSidedLighting) {
|
|
BABYLON.Tools.Warn(babylonStandardMaterial.name + ": Back-face culling enabled and two-sided lighting disabled is not supported in glTF.");
|
|
BABYLON.Tools.Warn(babylonStandardMaterial.name + ": Back-face culling enabled and two-sided lighting disabled is not supported in glTF.");
|
|
}
|
|
}
|
|
@@ -1174,26 +1185,26 @@ var BABYLON;
|
|
}
|
|
}
|
|
if (hasTextureCoords) {
|
|
if (hasTextureCoords) {
|
|
if (babylonStandardMaterial.diffuseTexture) {
|
|
if (babylonStandardMaterial.diffuseTexture) {
|
|
- var glTFTexture = _GLTFMaterial.ExportTexture(babylonStandardMaterial.diffuseTexture, mimeType, images, textures, imageData);
|
|
|
|
|
|
+ var glTFTexture = _GLTFMaterial._ExportTexture(babylonStandardMaterial.diffuseTexture, mimeType, images, textures, imageData);
|
|
if (glTFTexture != null) {
|
|
if (glTFTexture != null) {
|
|
glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
|
|
glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (babylonStandardMaterial.bumpTexture) {
|
|
if (babylonStandardMaterial.bumpTexture) {
|
|
- var glTFTexture = _GLTFMaterial.ExportTexture(babylonStandardMaterial.bumpTexture, mimeType, images, textures, imageData);
|
|
|
|
|
|
+ var glTFTexture = _GLTFMaterial._ExportTexture(babylonStandardMaterial.bumpTexture, mimeType, images, textures, imageData);
|
|
if (glTFTexture) {
|
|
if (glTFTexture) {
|
|
glTFMaterial.normalTexture = glTFTexture;
|
|
glTFMaterial.normalTexture = glTFTexture;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (babylonStandardMaterial.emissiveTexture) {
|
|
if (babylonStandardMaterial.emissiveTexture) {
|
|
- var glTFEmissiveTexture = _GLTFMaterial.ExportTexture(babylonStandardMaterial.emissiveTexture, mimeType, images, textures, imageData);
|
|
|
|
|
|
+ var glTFEmissiveTexture = _GLTFMaterial._ExportTexture(babylonStandardMaterial.emissiveTexture, mimeType, images, textures, imageData);
|
|
if (glTFEmissiveTexture) {
|
|
if (glTFEmissiveTexture) {
|
|
glTFMaterial.emissiveTexture = glTFEmissiveTexture;
|
|
glTFMaterial.emissiveTexture = glTFEmissiveTexture;
|
|
}
|
|
}
|
|
glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];
|
|
glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];
|
|
}
|
|
}
|
|
if (babylonStandardMaterial.ambientTexture) {
|
|
if (babylonStandardMaterial.ambientTexture) {
|
|
- var glTFTexture = _GLTFMaterial.ExportTexture(babylonStandardMaterial.ambientTexture, mimeType, images, textures, imageData);
|
|
|
|
|
|
+ var glTFTexture = _GLTFMaterial._ExportTexture(babylonStandardMaterial.ambientTexture, mimeType, images, textures, imageData);
|
|
if (glTFTexture) {
|
|
if (glTFTexture) {
|
|
var occlusionTexture = {
|
|
var occlusionTexture = {
|
|
index: glTFTexture.index
|
|
index: glTFTexture.index
|
|
@@ -1211,7 +1222,7 @@ var BABYLON;
|
|
BABYLON.Tools.Warn(babylonStandardMaterial.name + ": glTF 2.0 does not support alpha mode: " + babylonStandardMaterial.alphaMode.toString());
|
|
BABYLON.Tools.Warn(babylonStandardMaterial.name + ": glTF 2.0 does not support alpha mode: " + babylonStandardMaterial.alphaMode.toString());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if (babylonStandardMaterial.emissiveColor) {
|
|
|
|
|
|
+ if (babylonStandardMaterial.emissiveColor && !this.FuzzyEquals(babylonStandardMaterial.emissiveColor, BABYLON.Color3.Black(), this._epsilon)) {
|
|
glTFMaterial.emissiveFactor = babylonStandardMaterial.emissiveColor.asArray();
|
|
glTFMaterial.emissiveFactor = babylonStandardMaterial.emissiveColor.asArray();
|
|
}
|
|
}
|
|
glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
|
|
glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
|
|
@@ -1227,7 +1238,7 @@ var BABYLON;
|
|
* @param imageData - map of image file name to data.
|
|
* @param imageData - map of image file name to data.
|
|
* @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
|
|
* @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
|
|
*/
|
|
*/
|
|
- _GLTFMaterial.ConvertPBRMetallicRoughnessMaterial = function (babylonPBRMetalRoughMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
|
|
|
|
|
|
+ _GLTFMaterial._ConvertPBRMetallicRoughnessMaterial = function (babylonPBRMetalRoughMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
|
|
var glTFPbrMetallicRoughness = {};
|
|
var glTFPbrMetallicRoughness = {};
|
|
if (babylonPBRMetalRoughMaterial.baseColor) {
|
|
if (babylonPBRMetalRoughMaterial.baseColor) {
|
|
glTFPbrMetallicRoughness.baseColorFactor = [
|
|
glTFPbrMetallicRoughness.baseColorFactor = [
|
|
@@ -1237,10 +1248,10 @@ var BABYLON;
|
|
babylonPBRMetalRoughMaterial.alpha
|
|
babylonPBRMetalRoughMaterial.alpha
|
|
];
|
|
];
|
|
}
|
|
}
|
|
- if (babylonPBRMetalRoughMaterial.metallic != null) {
|
|
|
|
|
|
+ if (babylonPBRMetalRoughMaterial.metallic != null && babylonPBRMetalRoughMaterial.metallic !== 1) {
|
|
glTFPbrMetallicRoughness.metallicFactor = babylonPBRMetalRoughMaterial.metallic;
|
|
glTFPbrMetallicRoughness.metallicFactor = babylonPBRMetalRoughMaterial.metallic;
|
|
}
|
|
}
|
|
- if (babylonPBRMetalRoughMaterial.roughness != null) {
|
|
|
|
|
|
+ if (babylonPBRMetalRoughMaterial.roughness != null && babylonPBRMetalRoughMaterial.roughness !== 1) {
|
|
glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMetalRoughMaterial.roughness;
|
|
glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMetalRoughMaterial.roughness;
|
|
}
|
|
}
|
|
var glTFMaterial = {
|
|
var glTFMaterial = {
|
|
@@ -1251,19 +1262,19 @@ var BABYLON;
|
|
}
|
|
}
|
|
if (hasTextureCoords) {
|
|
if (hasTextureCoords) {
|
|
if (babylonPBRMetalRoughMaterial.baseTexture != null) {
|
|
if (babylonPBRMetalRoughMaterial.baseTexture != null) {
|
|
- var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMetalRoughMaterial.baseTexture, mimeType, images, textures, imageData);
|
|
|
|
|
|
+ var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMetalRoughMaterial.baseTexture, mimeType, images, textures, imageData);
|
|
if (glTFTexture != null) {
|
|
if (glTFTexture != null) {
|
|
glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
|
|
glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (babylonPBRMetalRoughMaterial.normalTexture) {
|
|
if (babylonPBRMetalRoughMaterial.normalTexture) {
|
|
- var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMetalRoughMaterial.normalTexture, mimeType, images, textures, imageData);
|
|
|
|
|
|
+ var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMetalRoughMaterial.normalTexture, mimeType, images, textures, imageData);
|
|
if (glTFTexture) {
|
|
if (glTFTexture) {
|
|
glTFMaterial.normalTexture = glTFTexture;
|
|
glTFMaterial.normalTexture = glTFTexture;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (babylonPBRMetalRoughMaterial.occlusionTexture) {
|
|
if (babylonPBRMetalRoughMaterial.occlusionTexture) {
|
|
- var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMetalRoughMaterial.occlusionTexture, mimeType, images, textures, imageData);
|
|
|
|
|
|
+ var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMetalRoughMaterial.occlusionTexture, mimeType, images, textures, imageData);
|
|
if (glTFTexture) {
|
|
if (glTFTexture) {
|
|
glTFMaterial.occlusionTexture = glTFTexture;
|
|
glTFMaterial.occlusionTexture = glTFTexture;
|
|
if (babylonPBRMetalRoughMaterial.occlusionStrength != null) {
|
|
if (babylonPBRMetalRoughMaterial.occlusionStrength != null) {
|
|
@@ -1272,17 +1283,17 @@ var BABYLON;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (babylonPBRMetalRoughMaterial.emissiveTexture) {
|
|
if (babylonPBRMetalRoughMaterial.emissiveTexture) {
|
|
- var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMetalRoughMaterial.emissiveTexture, mimeType, images, textures, imageData);
|
|
|
|
|
|
+ var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMetalRoughMaterial.emissiveTexture, mimeType, images, textures, imageData);
|
|
if (glTFTexture != null) {
|
|
if (glTFTexture != null) {
|
|
glTFMaterial.emissiveTexture = glTFTexture;
|
|
glTFMaterial.emissiveTexture = glTFTexture;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if (babylonPBRMetalRoughMaterial.emissiveColor.equalsFloats(0.0, 0.0, 0.0)) {
|
|
|
|
|
|
+ if (this.FuzzyEquals(babylonPBRMetalRoughMaterial.emissiveColor, BABYLON.Color3.Black(), this._epsilon)) {
|
|
glTFMaterial.emissiveFactor = babylonPBRMetalRoughMaterial.emissiveColor.asArray();
|
|
glTFMaterial.emissiveFactor = babylonPBRMetalRoughMaterial.emissiveColor.asArray();
|
|
}
|
|
}
|
|
if (babylonPBRMetalRoughMaterial.transparencyMode != null) {
|
|
if (babylonPBRMetalRoughMaterial.transparencyMode != null) {
|
|
- var alphaMode = _GLTFMaterial.GetAlphaMode(babylonPBRMetalRoughMaterial);
|
|
|
|
|
|
+ var alphaMode = _GLTFMaterial._GetAlphaMode(babylonPBRMetalRoughMaterial);
|
|
if (alphaMode !== "OPAQUE" /* OPAQUE */) {
|
|
if (alphaMode !== "OPAQUE" /* OPAQUE */) {
|
|
glTFMaterial.alphaMode = alphaMode;
|
|
glTFMaterial.alphaMode = alphaMode;
|
|
if (alphaMode === "BLEND" /* BLEND */) {
|
|
if (alphaMode === "BLEND" /* BLEND */) {
|
|
@@ -1294,12 +1305,213 @@ var BABYLON;
|
|
materials.push(glTFMaterial);
|
|
materials.push(glTFMaterial);
|
|
};
|
|
};
|
|
/**
|
|
/**
|
|
|
|
+ * Converts an image typed array buffer to a base64 image.
|
|
|
|
+ * @param buffer - typed array buffer.
|
|
|
|
+ * @param width - width of the image.
|
|
|
|
+ * @param height - height of the image.
|
|
|
|
+ * @param mimeType - mimetype of the image.
|
|
|
|
+ * @returns - base64 image string.
|
|
|
|
+ */
|
|
|
|
+ _GLTFMaterial._CreateBase64FromCanvas = function (buffer, width, height, mimeType) {
|
|
|
|
+ var imageCanvas = document.createElement('canvas');
|
|
|
|
+ imageCanvas.id = "WriteCanvas";
|
|
|
|
+ var ctx = imageCanvas.getContext('2d');
|
|
|
|
+ imageCanvas.width = width;
|
|
|
|
+ imageCanvas.height = height;
|
|
|
|
+ var imgData = ctx.createImageData(width, height);
|
|
|
|
+ imgData.data.set(buffer);
|
|
|
|
+ ctx.putImageData(imgData, 0, 0);
|
|
|
|
+ return imageCanvas.toDataURL(mimeType);
|
|
|
|
+ };
|
|
|
|
+ /**
|
|
|
|
+ * Generates a white texture based on the specified width and height.
|
|
|
|
+ * @param width - width of the texture in pixels.
|
|
|
|
+ * @param height - height of the texture in pixels.
|
|
|
|
+ * @param scene - babylonjs scene.
|
|
|
|
+ * @returns - white texture.
|
|
|
|
+ */
|
|
|
|
+ _GLTFMaterial._CreateWhiteTexture = function (width, height, scene) {
|
|
|
|
+ var data = new Uint8Array(width * height * 4);
|
|
|
|
+ for (var i = 0; i < data.length; ++i) {
|
|
|
|
+ data[i] = 255;
|
|
|
|
+ }
|
|
|
|
+ var rawTexture = BABYLON.RawTexture.CreateRGBATexture(data, width, height, scene);
|
|
|
|
+ return rawTexture;
|
|
|
|
+ };
|
|
|
|
+ /**
|
|
|
|
+ * Resizes the two source textures to the same dimensions. If a texture is null, a default white texture is generated. If both textures are null, returns null.
|
|
|
|
+ * @param texture1 - first texture to resize.
|
|
|
|
+ * @param texture2 - second texture to resize.
|
|
|
|
+ * @param scene - babylonjs scene.
|
|
|
|
+ * @returns resized textures or null.
|
|
|
|
+ */
|
|
|
|
+ _GLTFMaterial._ResizeTexturesToSameDimensions = function (texture1, texture2, scene) {
|
|
|
|
+ var texture1Size = texture1 ? texture1.getSize() : { width: 0, height: 0 };
|
|
|
|
+ var texture2Size = texture2 ? texture2.getSize() : { width: 0, height: 0 };
|
|
|
|
+ var resizedTexture1;
|
|
|
|
+ var resizedTexture2;
|
|
|
|
+ if (texture1Size.width < texture2Size.width) {
|
|
|
|
+ if (texture1) {
|
|
|
|
+ resizedTexture1 = BABYLON.TextureTools.CreateResizedCopy(texture1, texture2Size.width, texture2Size.height, true);
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ resizedTexture1 = this._CreateWhiteTexture(texture2Size.width, texture2Size.height, scene);
|
|
|
|
+ }
|
|
|
|
+ resizedTexture2 = texture2;
|
|
|
|
+ }
|
|
|
|
+ else if (texture1Size.width > texture2Size.width) {
|
|
|
|
+ if (texture2) {
|
|
|
|
+ resizedTexture2 = BABYLON.TextureTools.CreateResizedCopy(texture2, texture1Size.width, texture1Size.height, true);
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ resizedTexture2 = this._CreateWhiteTexture(texture1Size.width, texture1Size.height, scene);
|
|
|
|
+ }
|
|
|
|
+ resizedTexture1 = texture1;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ resizedTexture1 = texture1;
|
|
|
|
+ resizedTexture2 = texture2;
|
|
|
|
+ }
|
|
|
|
+ return {
|
|
|
|
+ "texture1": resizedTexture1,
|
|
|
|
+ "texture2": resizedTexture2
|
|
|
|
+ };
|
|
|
|
+ };
|
|
|
|
+ /**
|
|
|
|
+ * Convert Specular Glossiness Textures to Metallic Roughness.
|
|
* See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
|
|
* See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
|
|
* @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
|
|
* @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
|
|
|
|
+ * @param diffuseTexture - texture used to store diffuse information.
|
|
|
|
+ * @param specularGlossinessTexture - texture used to store specular and glossiness information.
|
|
|
|
+ * @param factors - specular glossiness material factors.
|
|
|
|
+ * @param mimeType - the mime type to use for the texture.
|
|
|
|
+ * @returns pbr metallic roughness interface or null.
|
|
|
|
+ */
|
|
|
|
+ _GLTFMaterial._ConvertSpecularGlossinessTexturesToMetallicRoughness = function (diffuseTexture, specularGlossinessTexture, factors, mimeType) {
|
|
|
|
+ if (!(diffuseTexture || specularGlossinessTexture)) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ var scene = diffuseTexture ? diffuseTexture.getScene() : specularGlossinessTexture.getScene();
|
|
|
|
+ if (!scene) {
|
|
|
|
+ throw new Error("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Scene from textures is missing!");
|
|
|
|
+ }
|
|
|
|
+ var resizedTextures = this._ResizeTexturesToSameDimensions(diffuseTexture, specularGlossinessTexture, scene);
|
|
|
|
+ var diffuseSize = resizedTextures.texture1.getSize();
|
|
|
|
+ var diffuseBuffer;
|
|
|
|
+ var specularGlossinessBuffer;
|
|
|
|
+ var width = diffuseSize.width;
|
|
|
|
+ var height = diffuseSize.height;
|
|
|
|
+ var pixels = (resizedTextures.texture1.readPixels());
|
|
|
|
+ if (pixels instanceof Uint8Array) {
|
|
|
|
+ diffuseBuffer = (resizedTextures.texture1.readPixels());
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ throw new Error("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Pixel array buffer type not supported for texture: " + resizedTextures.texture1.name);
|
|
|
|
+ }
|
|
|
|
+ pixels = resizedTextures.texture2.readPixels();
|
|
|
|
+ if (pixels instanceof Uint8Array) {
|
|
|
|
+ specularGlossinessBuffer = (resizedTextures.texture2.readPixels());
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ throw new Error("_ConvertSpecularGlossinessTexturesToMetallicRoughness: Pixel array buffer type not supported for texture: " + resizedTextures.texture2.name);
|
|
|
|
+ }
|
|
|
|
+ var byteLength = specularGlossinessBuffer.byteLength;
|
|
|
|
+ var metallicRoughnessBuffer = new Uint8Array(byteLength);
|
|
|
|
+ var baseColorBuffer = new Uint8Array(byteLength);
|
|
|
|
+ var strideSize = 4;
|
|
|
|
+ var maxBaseColor = BABYLON.Color3.Black();
|
|
|
|
+ var maxMetallic = 0;
|
|
|
|
+ var maxRoughness = 0;
|
|
|
|
+ for (var h = 0; h < height; ++h) {
|
|
|
|
+ for (var w = 0; w < width; ++w) {
|
|
|
|
+ var offset = (width * h + w) * strideSize;
|
|
|
|
+ var diffuseColor = BABYLON.Color3.FromInts(diffuseBuffer[offset], diffuseBuffer[offset + 1], diffuseBuffer[offset + 2]).multiply(factors.diffuseColor);
|
|
|
|
+ var specularColor = BABYLON.Color3.FromInts(specularGlossinessBuffer[offset], specularGlossinessBuffer[offset + 1], specularGlossinessBuffer[offset + 2]).multiply(factors.specularColor);
|
|
|
|
+ var glossiness = (specularGlossinessBuffer[offset + 3] / 255) * factors.glossiness;
|
|
|
|
+ var specularGlossiness = {
|
|
|
|
+ diffuseColor: diffuseColor,
|
|
|
|
+ specularColor: specularColor,
|
|
|
|
+ glossiness: glossiness
|
|
|
|
+ };
|
|
|
|
+ var metallicRoughness = this._ConvertSpecularGlossinessToMetallicRoughness(specularGlossiness);
|
|
|
|
+ maxBaseColor.r = Math.max(maxBaseColor.r, metallicRoughness.baseColor.r);
|
|
|
|
+ maxBaseColor.g = Math.max(maxBaseColor.g, metallicRoughness.baseColor.g);
|
|
|
|
+ maxBaseColor.b = Math.max(maxBaseColor.b, metallicRoughness.baseColor.b);
|
|
|
|
+ maxMetallic = Math.max(maxMetallic, metallicRoughness.metallic);
|
|
|
|
+ maxRoughness = Math.max(maxRoughness, metallicRoughness.roughness);
|
|
|
|
+ baseColorBuffer[offset] = metallicRoughness.baseColor.r * 255;
|
|
|
|
+ baseColorBuffer[offset + 1] = metallicRoughness.baseColor.g * 255;
|
|
|
|
+ baseColorBuffer[offset + 2] = metallicRoughness.baseColor.b * 255;
|
|
|
|
+ baseColorBuffer[offset + 3] = resizedTextures.texture1.hasAlpha ? diffuseBuffer[offset + 3] : 255;
|
|
|
|
+ metallicRoughnessBuffer[offset] = 255;
|
|
|
|
+ metallicRoughnessBuffer[offset + 1] = metallicRoughness.roughness * 255;
|
|
|
|
+ metallicRoughnessBuffer[offset + 2] = metallicRoughness.metallic * 255;
|
|
|
|
+ metallicRoughnessBuffer[offset + 3] = 255;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // Retrieves the metallic roughness factors from the maximum texture values.
|
|
|
|
+ var metallicRoughnessFactors = {
|
|
|
|
+ baseColor: maxBaseColor,
|
|
|
|
+ metallic: maxMetallic,
|
|
|
|
+ roughness: maxRoughness
|
|
|
|
+ };
|
|
|
|
+ var writeOutMetallicRoughnessTexture = false;
|
|
|
|
+ var writeOutBaseColorTexture = false;
|
|
|
|
+ for (var h = 0; h < height; ++h) {
|
|
|
|
+ for (var w = 0; w < width; ++w) {
|
|
|
|
+ var destinationOffset = (width * h + w) * strideSize;
|
|
|
|
+ baseColorBuffer[destinationOffset] /= metallicRoughnessFactors.baseColor.r > this._epsilon ? metallicRoughnessFactors.baseColor.r : 1;
|
|
|
|
+ baseColorBuffer[destinationOffset + 1] /= metallicRoughnessFactors.baseColor.g > this._epsilon ? metallicRoughnessFactors.baseColor.g : 1;
|
|
|
|
+ baseColorBuffer[destinationOffset + 2] /= metallicRoughnessFactors.baseColor.b > this._epsilon ? metallicRoughnessFactors.baseColor.b : 1;
|
|
|
|
+ var baseColorPixel = new BABYLON.Color3(baseColorBuffer[destinationOffset], baseColorBuffer[destinationOffset + 1], baseColorBuffer[destinationOffset + 2]);
|
|
|
|
+ if (!this.FuzzyEquals(baseColorPixel, BABYLON.Color3.White(), this._epsilon)) {
|
|
|
|
+ writeOutBaseColorTexture = true;
|
|
|
|
+ }
|
|
|
|
+ metallicRoughnessBuffer[destinationOffset + 1] /= metallicRoughnessFactors.roughness > this._epsilon ? metallicRoughnessFactors.roughness : 1;
|
|
|
|
+ metallicRoughnessBuffer[destinationOffset + 2] /= metallicRoughnessFactors.metallic > this._epsilon ? metallicRoughnessFactors.metallic : 1;
|
|
|
|
+ var metallicRoughnessPixel = new BABYLON.Color3(metallicRoughnessBuffer[destinationOffset], metallicRoughnessBuffer[destinationOffset + 1], metallicRoughnessBuffer[destinationOffset + 2]);
|
|
|
|
+ if (!this.FuzzyEquals(metallicRoughnessPixel, BABYLON.Color3.White(), this._epsilon)) {
|
|
|
|
+ writeOutMetallicRoughnessTexture = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (writeOutMetallicRoughnessTexture) {
|
|
|
|
+ var metallicRoughnessBase64 = this._CreateBase64FromCanvas(metallicRoughnessBuffer, width, height, mimeType);
|
|
|
|
+ metallicRoughnessFactors.metallicRoughnessTextureBase64 = metallicRoughnessBase64;
|
|
|
|
+ }
|
|
|
|
+ if (writeOutBaseColorTexture) {
|
|
|
|
+ var baseColorBase64 = this._CreateBase64FromCanvas(baseColorBuffer, width, height, mimeType);
|
|
|
|
+ metallicRoughnessFactors.baseColorTextureBase64 = baseColorBase64;
|
|
|
|
+ }
|
|
|
|
+ return metallicRoughnessFactors;
|
|
|
|
+ };
|
|
|
|
+ /**
|
|
|
|
+ * Converts specular glossiness material properties to metallic roughness.
|
|
|
|
+ * @param specularGlossiness - interface with specular glossiness material properties.
|
|
|
|
+ * @returns - interface with metallic roughness material properties.
|
|
|
|
+ */
|
|
|
|
+ _GLTFMaterial._ConvertSpecularGlossinessToMetallicRoughness = function (specularGlossiness) {
|
|
|
|
+ var diffusePerceivedBrightness = _GLTFMaterial._GetPerceivedBrightness(specularGlossiness.diffuseColor);
|
|
|
|
+ var specularPerceivedBrightness = _GLTFMaterial._GetPerceivedBrightness(specularGlossiness.specularColor);
|
|
|
|
+ var oneMinusSpecularStrength = 1 - _GLTFMaterial._GetMaxComponent(specularGlossiness.specularColor);
|
|
|
|
+ var metallic = _GLTFMaterial._SolveMetallic(diffusePerceivedBrightness, specularPerceivedBrightness, oneMinusSpecularStrength);
|
|
|
|
+ var baseColorFromDiffuse = specularGlossiness.diffuseColor.scale(oneMinusSpecularStrength / (1.0 - this._dielectricSpecular.r) / Math.max(1 - metallic, this._epsilon));
|
|
|
|
+ var baseColorFromSpecular = specularGlossiness.specularColor.subtract(this._dielectricSpecular.scale(1 - metallic)).scale(1 / Math.max(metallic, this._epsilon));
|
|
|
|
+ var baseColor = BABYLON.Color3.Lerp(baseColorFromDiffuse, baseColorFromSpecular, metallic * metallic);
|
|
|
|
+ baseColor = baseColor.clampToRef(0, 1, baseColor);
|
|
|
|
+ var metallicRoughness = {
|
|
|
|
+ baseColor: baseColor,
|
|
|
|
+ metallic: metallic,
|
|
|
|
+ roughness: 1 - specularGlossiness.glossiness
|
|
|
|
+ };
|
|
|
|
+ return metallicRoughness;
|
|
|
|
+ };
|
|
|
|
+ /**
|
|
|
|
+ * Calculates the surface reflectance, independent of lighting conditions.
|
|
* @param color - Color source to calculate brightness from.
|
|
* @param color - Color source to calculate brightness from.
|
|
* @returns number representing the perceived brightness, or zero if color is undefined.
|
|
* @returns number representing the perceived brightness, or zero if color is undefined.
|
|
*/
|
|
*/
|
|
- _GLTFMaterial.GetPerceivedBrightness = function (color) {
|
|
|
|
|
|
+ _GLTFMaterial._GetPerceivedBrightness = function (color) {
|
|
if (color) {
|
|
if (color) {
|
|
return Math.sqrt(0.299 * color.r * color.r + 0.587 * color.g * color.g + 0.114 * color.b * color.b);
|
|
return Math.sqrt(0.299 * color.r * color.r + 0.587 * color.g * color.g + 0.114 * color.b * color.b);
|
|
}
|
|
}
|
|
@@ -1310,7 +1522,7 @@ var BABYLON;
|
|
* @param color
|
|
* @param color
|
|
* @returns maximum color component value, or zero if color is null or undefined.
|
|
* @returns maximum color component value, or zero if color is null or undefined.
|
|
*/
|
|
*/
|
|
- _GLTFMaterial.GetMaxComponent = function (color) {
|
|
|
|
|
|
+ _GLTFMaterial._GetMaxComponent = function (color) {
|
|
if (color) {
|
|
if (color) {
|
|
return Math.max(color.r, Math.max(color.g, color.b));
|
|
return Math.max(color.r, Math.max(color.g, color.b));
|
|
}
|
|
}
|
|
@@ -1326,110 +1538,117 @@ var BABYLON;
|
|
* @param imageData - map of image file name to data.
|
|
* @param imageData - map of image file name to data.
|
|
* @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
|
|
* @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
|
|
*/
|
|
*/
|
|
- _GLTFMaterial.ConvertPBRMaterial = function (babylonPBRMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
|
|
|
|
|
|
+ _GLTFMaterial._ConvertPBRMaterial = function (babylonPBRMaterial, mimeType, images, textures, materials, imageData, hasTextureCoords) {
|
|
var glTFPbrMetallicRoughness = {};
|
|
var glTFPbrMetallicRoughness = {};
|
|
|
|
+ var metallicRoughness;
|
|
var glTFMaterial = {
|
|
var glTFMaterial = {
|
|
name: babylonPBRMaterial.name
|
|
name: babylonPBRMaterial.name
|
|
};
|
|
};
|
|
var useMetallicRoughness = babylonPBRMaterial.isMetallicWorkflow();
|
|
var useMetallicRoughness = babylonPBRMaterial.isMetallicWorkflow();
|
|
- if (babylonPBRMaterial) {
|
|
|
|
- if (useMetallicRoughness) {
|
|
|
|
- glTFPbrMetallicRoughness.baseColorFactor = [
|
|
|
|
- babylonPBRMaterial.albedoColor.r,
|
|
|
|
- babylonPBRMaterial.albedoColor.g,
|
|
|
|
- babylonPBRMaterial.albedoColor.b,
|
|
|
|
- babylonPBRMaterial.alpha
|
|
|
|
- ];
|
|
|
|
- if (babylonPBRMaterial.metallic != null) {
|
|
|
|
- if (babylonPBRMaterial.metallic !== 1) {
|
|
|
|
- glTFPbrMetallicRoughness.metallicFactor = babylonPBRMaterial.metallic;
|
|
|
|
|
|
+ if (!useMetallicRoughness) {
|
|
|
|
+ var specGloss = {
|
|
|
|
+ diffuseColor: babylonPBRMaterial.albedoColor || BABYLON.Color3.White(),
|
|
|
|
+ specularColor: babylonPBRMaterial.reflectivityColor || BABYLON.Color3.White(),
|
|
|
|
+ glossiness: babylonPBRMaterial.microSurface || 1,
|
|
|
|
+ };
|
|
|
|
+ if (babylonPBRMaterial.reflectivityTexture && !babylonPBRMaterial.useMicroSurfaceFromReflectivityMapAlpha) {
|
|
|
|
+ throw new Error("_ConvertPBRMaterial: Glossiness values not included in the reflectivity texture currently not supported");
|
|
|
|
+ }
|
|
|
|
+ metallicRoughness = this._ConvertSpecularGlossinessTexturesToMetallicRoughness(babylonPBRMaterial.albedoTexture, babylonPBRMaterial.reflectivityTexture, specGloss, mimeType);
|
|
|
|
+ if (!metallicRoughness) {
|
|
|
|
+ metallicRoughness = this._ConvertSpecularGlossinessToMetallicRoughness(specGloss);
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ if (hasTextureCoords) {
|
|
|
|
+ if (metallicRoughness.baseColorTextureBase64) {
|
|
|
|
+ var glTFBaseColorTexture = _GLTFMaterial._GetTextureInfoFromBase64(metallicRoughness.baseColorTextureBase64, "bjsBaseColorTexture_" + (textures.length) + ".png", mimeType, images, textures, imageData);
|
|
|
|
+ if (glTFBaseColorTexture != null) {
|
|
|
|
+ glTFPbrMetallicRoughness.baseColorTexture = glTFBaseColorTexture;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- }
|
|
|
|
- if (babylonPBRMaterial.roughness != null) {
|
|
|
|
- if (babylonPBRMaterial.roughness !== 1) {
|
|
|
|
- glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMaterial.roughness;
|
|
|
|
|
|
+ if (metallicRoughness.metallicRoughnessTextureBase64) {
|
|
|
|
+ var glTFMRColorTexture = _GLTFMaterial._GetTextureInfoFromBase64(metallicRoughness.metallicRoughnessTextureBase64, "bjsMetallicRoughnessTexture_" + (textures.length) + ".png", mimeType, images, textures, imageData);
|
|
|
|
+ if (glTFMRColorTexture != null) {
|
|
|
|
+ glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFMRColorTexture;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- else {
|
|
|
|
- var diffuseColor = babylonPBRMaterial.albedoColor || BABYLON.Color3.Black();
|
|
|
|
- var specularColor = babylonPBRMaterial.reflectionColor || BABYLON.Color3.Black();
|
|
|
|
- var diffusePerceivedBrightness = _GLTFMaterial.GetPerceivedBrightness(diffuseColor);
|
|
|
|
- var specularPerceivedBrightness = _GLTFMaterial.GetPerceivedBrightness(specularColor);
|
|
|
|
- var oneMinusSpecularStrength = 1 - _GLTFMaterial.GetMaxComponent(babylonPBRMaterial.reflectionColor);
|
|
|
|
- var metallic = _GLTFMaterial.SolveMetallic(diffusePerceivedBrightness, specularPerceivedBrightness, oneMinusSpecularStrength);
|
|
|
|
- var glossiness = babylonPBRMaterial.microSurface || 0;
|
|
|
|
- var baseColorFromDiffuse = diffuseColor.scale(oneMinusSpecularStrength / (1.0 - this.dielectricSpecular.r) / Math.max(1 - metallic, this.epsilon));
|
|
|
|
- var baseColorFromSpecular = specularColor.subtract(this.dielectricSpecular.scale(1 - metallic)).scale(1 / Math.max(metallic, this.epsilon));
|
|
|
|
- var baseColor = BABYLON.Color3.Lerp(baseColorFromDiffuse, baseColorFromSpecular, metallic * metallic);
|
|
|
|
- baseColor = baseColor.clampToRef(0, 1, baseColor);
|
|
|
|
- glTFPbrMetallicRoughness.baseColorFactor = [
|
|
|
|
- baseColor.r,
|
|
|
|
- baseColor.g,
|
|
|
|
- baseColor.b,
|
|
|
|
- babylonPBRMaterial.alpha
|
|
|
|
- ];
|
|
|
|
- if (metallic !== 1) {
|
|
|
|
- glTFPbrMetallicRoughness.metallicFactor = metallic;
|
|
|
|
- }
|
|
|
|
- if (glossiness) {
|
|
|
|
- glTFPbrMetallicRoughness.roughnessFactor = 1 - glossiness;
|
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ metallicRoughness = {
|
|
|
|
+ baseColor: babylonPBRMaterial.albedoColor,
|
|
|
|
+ metallic: babylonPBRMaterial.metallic,
|
|
|
|
+ roughness: babylonPBRMaterial.roughness
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+ if (!(this.FuzzyEquals(metallicRoughness.baseColor, BABYLON.Color3.White(), this._epsilon) && babylonPBRMaterial.alpha >= this._epsilon)) {
|
|
|
|
+ glTFPbrMetallicRoughness.baseColorFactor = [
|
|
|
|
+ metallicRoughness.baseColor.r,
|
|
|
|
+ metallicRoughness.baseColor.g,
|
|
|
|
+ metallicRoughness.baseColor.b,
|
|
|
|
+ babylonPBRMaterial.alpha
|
|
|
|
+ ];
|
|
|
|
+ }
|
|
|
|
+ if (metallicRoughness.metallic != null && metallicRoughness.metallic !== 1) {
|
|
|
|
+ glTFPbrMetallicRoughness.metallicFactor = metallicRoughness.metallic;
|
|
|
|
+ }
|
|
|
|
+ if (metallicRoughness.roughness != null && metallicRoughness.roughness !== 1) {
|
|
|
|
+ glTFPbrMetallicRoughness.roughnessFactor = metallicRoughness.roughness;
|
|
|
|
+ }
|
|
|
|
+ if (babylonPBRMaterial.backFaceCulling != null && !babylonPBRMaterial.backFaceCulling) {
|
|
|
|
+ if (!babylonPBRMaterial.twoSidedLighting) {
|
|
|
|
+ BABYLON.Tools.Warn(babylonPBRMaterial.name + ": Back-face culling enabled and two-sided lighting disabled is not supported in glTF.");
|
|
}
|
|
}
|
|
- if (babylonPBRMaterial.backFaceCulling) {
|
|
|
|
- if (!babylonPBRMaterial.twoSidedLighting) {
|
|
|
|
- BABYLON.Tools.Warn(babylonPBRMaterial.name + ": Back-face culling enabled and two-sided lighting disabled is not supported in glTF.");
|
|
|
|
|
|
+ glTFMaterial.doubleSided = true;
|
|
|
|
+ }
|
|
|
|
+ if (hasTextureCoords) {
|
|
|
|
+ if (useMetallicRoughness && babylonPBRMaterial.albedoTexture) {
|
|
|
|
+ var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMaterial.albedoTexture, mimeType, images, textures, imageData);
|
|
|
|
+ if (glTFTexture) {
|
|
|
|
+ glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
|
|
}
|
|
}
|
|
- glTFMaterial.doubleSided = true;
|
|
|
|
}
|
|
}
|
|
- if (hasTextureCoords) {
|
|
|
|
- if (babylonPBRMaterial.albedoTexture) {
|
|
|
|
- var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.albedoTexture, mimeType, images, textures, imageData);
|
|
|
|
- if (glTFTexture) {
|
|
|
|
- glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (babylonPBRMaterial.bumpTexture) {
|
|
|
|
- var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.bumpTexture, mimeType, images, textures, imageData);
|
|
|
|
- if (glTFTexture) {
|
|
|
|
- glTFMaterial.normalTexture = glTFTexture;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (babylonPBRMaterial.ambientTexture) {
|
|
|
|
- var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.ambientTexture, mimeType, images, textures, imageData);
|
|
|
|
- if (glTFTexture) {
|
|
|
|
- var occlusionTexture = {
|
|
|
|
- index: glTFTexture.index
|
|
|
|
- };
|
|
|
|
- glTFMaterial.occlusionTexture = occlusionTexture;
|
|
|
|
- if (babylonPBRMaterial.ambientTextureStrength) {
|
|
|
|
- occlusionTexture.strength = babylonPBRMaterial.ambientTextureStrength;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ if (babylonPBRMaterial.bumpTexture) {
|
|
|
|
+ var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMaterial.bumpTexture, mimeType, images, textures, imageData);
|
|
|
|
+ if (glTFTexture) {
|
|
|
|
+ glTFMaterial.normalTexture = glTFTexture;
|
|
}
|
|
}
|
|
- if (babylonPBRMaterial.emissiveTexture) {
|
|
|
|
- var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.emissiveTexture, mimeType, images, textures, imageData);
|
|
|
|
- if (glTFTexture != null) {
|
|
|
|
- glTFMaterial.emissiveTexture = glTFTexture;
|
|
|
|
|
|
+ }
|
|
|
|
+ if (babylonPBRMaterial.ambientTexture) {
|
|
|
|
+ var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMaterial.ambientTexture, mimeType, images, textures, imageData);
|
|
|
|
+ if (glTFTexture) {
|
|
|
|
+ var occlusionTexture = {
|
|
|
|
+ index: glTFTexture.index
|
|
|
|
+ };
|
|
|
|
+ glTFMaterial.occlusionTexture = occlusionTexture;
|
|
|
|
+ if (babylonPBRMaterial.ambientTextureStrength) {
|
|
|
|
+ occlusionTexture.strength = babylonPBRMaterial.ambientTextureStrength;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if (babylonPBRMaterial.metallicTexture) {
|
|
|
|
- var glTFTexture = _GLTFMaterial.ExportTexture(babylonPBRMaterial.metallicTexture, mimeType, images, textures, imageData);
|
|
|
|
- if (glTFTexture != null) {
|
|
|
|
- glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;
|
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
+ if (babylonPBRMaterial.emissiveTexture) {
|
|
|
|
+ var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMaterial.emissiveTexture, mimeType, images, textures, imageData);
|
|
|
|
+ if (glTFTexture != null) {
|
|
|
|
+ glTFMaterial.emissiveTexture = glTFTexture;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if (!babylonPBRMaterial.emissiveColor.equalsFloats(0.0, 0.0, 0.0)) {
|
|
|
|
- glTFMaterial.emissiveFactor = babylonPBRMaterial.emissiveColor.asArray();
|
|
|
|
|
|
+ if (babylonPBRMaterial.metallicTexture) {
|
|
|
|
+ var glTFTexture = _GLTFMaterial._ExportTexture(babylonPBRMaterial.metallicTexture, mimeType, images, textures, imageData);
|
|
|
|
+ if (glTFTexture != null) {
|
|
|
|
+ glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- if (babylonPBRMaterial.transparencyMode != null) {
|
|
|
|
- var alphaMode = _GLTFMaterial.GetAlphaMode(babylonPBRMaterial);
|
|
|
|
- if (alphaMode !== "OPAQUE" /* OPAQUE */) {
|
|
|
|
- glTFMaterial.alphaMode = alphaMode;
|
|
|
|
- if (alphaMode === "BLEND" /* BLEND */) {
|
|
|
|
- glTFMaterial.alphaCutoff = babylonPBRMaterial.alphaCutOff;
|
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
+ if (!this.FuzzyEquals(babylonPBRMaterial.emissiveColor, BABYLON.Color3.Black(), this._epsilon)) {
|
|
|
|
+ glTFMaterial.emissiveFactor = babylonPBRMaterial.emissiveColor.asArray();
|
|
|
|
+ }
|
|
|
|
+ if (babylonPBRMaterial.transparencyMode != null) {
|
|
|
|
+ var alphaMode = _GLTFMaterial._GetAlphaMode(babylonPBRMaterial);
|
|
|
|
+ if (alphaMode !== "OPAQUE" /* OPAQUE */) {
|
|
|
|
+ glTFMaterial.alphaMode = alphaMode;
|
|
|
|
+ if (alphaMode === "BLEND" /* BLEND */) {
|
|
|
|
+ glTFMaterial.alphaCutoff = babylonPBRMaterial.alphaCutOff;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1443,17 +1662,13 @@ var BABYLON;
|
|
* @param images - Array of glTF images.
|
|
* @param images - Array of glTF images.
|
|
* @param textures - Array of glTF textures.
|
|
* @param textures - Array of glTF textures.
|
|
* @param imageData - map of image file name and data.
|
|
* @param imageData - map of image file name and data.
|
|
- * @return - glTF texture, or null if the texture format is not supported.
|
|
|
|
|
|
+ * @return - glTF texture info, or null if the texture format is not supported.
|
|
*/
|
|
*/
|
|
- _GLTFMaterial.ExportTexture = function (babylonTexture, mimeType, images, textures, imageData) {
|
|
|
|
- var textureInfo = null;
|
|
|
|
- var glTFTexture = {
|
|
|
|
- source: images.length
|
|
|
|
- };
|
|
|
|
|
|
+ _GLTFMaterial._ExportTexture = function (babylonTexture, mimeType, images, textures, imageData) {
|
|
var textureName = "texture_" + (textures.length - 1).toString();
|
|
var textureName = "texture_" + (textures.length - 1).toString();
|
|
var textureData = babylonTexture.getInternalTexture();
|
|
var textureData = babylonTexture.getInternalTexture();
|
|
if (textureData != null) {
|
|
if (textureData != null) {
|
|
- textureName = textureData.url;
|
|
|
|
|
|
+ textureName = textureData.url || textureName;
|
|
}
|
|
}
|
|
textureName = BABYLON.Tools.GetFilename(textureName);
|
|
textureName = BABYLON.Tools.GetFilename(textureName);
|
|
var baseFile = textureName.split('.')[0];
|
|
var baseFile = textureName.split('.')[0];
|
|
@@ -1465,28 +1680,37 @@ var BABYLON;
|
|
extension = ".png";
|
|
extension = ".png";
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
- BABYLON.Tools.Error("Unsupported mime type " + mimeType);
|
|
|
|
|
|
+ throw new Error("Unsupported mime type " + mimeType);
|
|
}
|
|
}
|
|
textureName = baseFile + extension;
|
|
textureName = baseFile + extension;
|
|
var pixels = babylonTexture.readPixels();
|
|
var pixels = babylonTexture.readPixels();
|
|
- var imageCanvas = document.createElement('canvas');
|
|
|
|
- imageCanvas.id = "ImageCanvas";
|
|
|
|
- var ctx = imageCanvas.getContext('2d');
|
|
|
|
var size = babylonTexture.getSize();
|
|
var size = babylonTexture.getSize();
|
|
- imageCanvas.width = size.width;
|
|
|
|
- imageCanvas.height = size.height;
|
|
|
|
- var imgData = ctx.createImageData(size.width, size.height);
|
|
|
|
- imgData.data.set(pixels);
|
|
|
|
- ctx.putImageData(imgData, 0, 0);
|
|
|
|
- var base64Data = imageCanvas.toDataURL(mimeType);
|
|
|
|
- var binStr = atob(base64Data.split(',')[1]);
|
|
|
|
|
|
+ var base64Data = this._CreateBase64FromCanvas(pixels, size.width, size.height, mimeType);
|
|
|
|
+ return this._GetTextureInfoFromBase64(base64Data, textureName, mimeType, images, textures, imageData);
|
|
|
|
+ };
|
|
|
|
+ /**
|
|
|
|
+ * Builds a texture from base64 string.
|
|
|
|
+ * @param base64Texture - base64 texture string.
|
|
|
|
+ * @param textureName - Name to use for the texture.
|
|
|
|
+ * @param mimeType - image mime type for the texture.
|
|
|
|
+ * @param images - array of images.
|
|
|
|
+ * @param textures - array of textures.
|
|
|
|
+ * @param imageData - map of image data.
|
|
|
|
+ * @returns - glTF texture info, or null if the texture format is not supported.
|
|
|
|
+ */
|
|
|
|
+ _GLTFMaterial._GetTextureInfoFromBase64 = function (base64Texture, textureName, mimeType, images, textures, imageData) {
|
|
|
|
+ var textureInfo = null;
|
|
|
|
+ var glTFTexture = {
|
|
|
|
+ source: images.length
|
|
|
|
+ };
|
|
|
|
+ var binStr = atob(base64Texture.split(',')[1]);
|
|
var arr = new Uint8Array(binStr.length);
|
|
var arr = new Uint8Array(binStr.length);
|
|
for (var i = 0; i < binStr.length; ++i) {
|
|
for (var i = 0; i < binStr.length; ++i) {
|
|
arr[i] = binStr.charCodeAt(i);
|
|
arr[i] = binStr.charCodeAt(i);
|
|
}
|
|
}
|
|
var imageValues = { data: arr, mimeType: mimeType };
|
|
var imageValues = { data: arr, mimeType: mimeType };
|
|
imageData[textureName] = imageValues;
|
|
imageData[textureName] = imageValues;
|
|
- if (mimeType === "image/jpeg" /* JPEG */) {
|
|
|
|
|
|
+ if (mimeType === "image/jpeg" /* JPEG */ || mimeType === "image/png" /* PNG */) {
|
|
var glTFImage = {
|
|
var glTFImage = {
|
|
uri: textureName
|
|
uri: textureName
|
|
};
|
|
};
|
|
@@ -1519,12 +1743,15 @@ var BABYLON;
|
|
/**
|
|
/**
|
|
* Represents the dielectric specular values for R, G and B.
|
|
* Represents the dielectric specular values for R, G and B.
|
|
*/
|
|
*/
|
|
- _GLTFMaterial.dielectricSpecular = new BABYLON.Color3(0.04, 0.04, 0.04);
|
|
|
|
|
|
+ _GLTFMaterial._dielectricSpecular = new BABYLON.Color3(0.04, 0.04, 0.04);
|
|
/**
|
|
/**
|
|
* Allows the maximum specular power to be defined for material calculations.
|
|
* Allows the maximum specular power to be defined for material calculations.
|
|
*/
|
|
*/
|
|
- _GLTFMaterial.maxSpecularPower = 1024;
|
|
|
|
- _GLTFMaterial.epsilon = 1e-6;
|
|
|
|
|
|
+ _GLTFMaterial._maxSpecularPower = 1024;
|
|
|
|
+ /**
|
|
|
|
+ * Numeric tolerance value
|
|
|
|
+ */
|
|
|
|
+ _GLTFMaterial._epsilon = 1e-6;
|
|
return _GLTFMaterial;
|
|
return _GLTFMaterial;
|
|
}());
|
|
}());
|
|
GLTF2._GLTFMaterial = _GLTFMaterial;
|
|
GLTF2._GLTFMaterial = _GLTFMaterial;
|