import addExtensionsUsed from "./addExtensionsUsed.js"; import ForEach from "./ForEach.js"; import defaultValue from "../../Core/defaultValue.js"; import defined from "../../Core/defined.js"; import WebGLConstants from "../../Core/WebGLConstants.js"; const defaultBlendEquation = [WebGLConstants.FUNC_ADD, WebGLConstants.FUNC_ADD]; const defaultBlendFactors = [ WebGLConstants.ONE, WebGLConstants.ZERO, WebGLConstants.ONE, WebGLConstants.ZERO, ]; function isStateEnabled(renderStates, state) { const enabled = renderStates.enable; if (!defined(enabled)) { return false; } return enabled.indexOf(state) > -1; } const supportedBlendFactors = [ WebGLConstants.ZERO, WebGLConstants.ONE, WebGLConstants.SRC_COLOR, WebGLConstants.ONE_MINUS_SRC_COLOR, WebGLConstants.SRC_ALPHA, WebGLConstants.ONE_MINUS_SRC_ALPHA, WebGLConstants.DST_ALPHA, WebGLConstants.ONE_MINUS_DST_ALPHA, WebGLConstants.DST_COLOR, WebGLConstants.ONE_MINUS_DST_COLOR, ]; // If any of the blend factors are not supported, return the default function getSupportedBlendFactors(value, defaultValue) { if (!defined(value)) { return defaultValue; } for (let i = 0; i < 4; i++) { if (supportedBlendFactors.indexOf(value[i]) === -1) { return defaultValue; } } return value; } /** * Move glTF 1.0 technique render states to glTF 2.0 materials properties and KHR_blend extension. * * @param {Object} gltf A javascript object containing a glTF asset. * @returns {Object} The updated glTF asset. * * @private */ function moveTechniqueRenderStates(gltf) { const blendingForTechnique = {}; const materialPropertiesForTechnique = {}; const techniquesLegacy = gltf.techniques; if (!defined(techniquesLegacy)) { return gltf; } ForEach.technique(gltf, function (techniqueLegacy, techniqueIndex) { const renderStates = techniqueLegacy.states; if (defined(renderStates)) { const materialProperties = (materialPropertiesForTechnique[ techniqueIndex ] = {}); // If BLEND is enabled, the material should have alpha mode BLEND if (isStateEnabled(renderStates, WebGLConstants.BLEND)) { materialProperties.alphaMode = "BLEND"; const blendFunctions = renderStates.functions; if ( defined(blendFunctions) && (defined(blendFunctions.blendEquationSeparate) || defined(blendFunctions.blendFuncSeparate)) ) { blendingForTechnique[techniqueIndex] = { blendEquation: defaultValue( blendFunctions.blendEquationSeparate, defaultBlendEquation ), blendFactors: getSupportedBlendFactors( blendFunctions.blendFuncSeparate, defaultBlendFactors ), }; } } // If CULL_FACE is not enabled, the material should be doubleSided if (!isStateEnabled(renderStates, WebGLConstants.CULL_FACE)) { materialProperties.doubleSided = true; } delete techniqueLegacy.states; } }); if (Object.keys(blendingForTechnique).length > 0) { if (!defined(gltf.extensions)) { gltf.extensions = {}; } addExtensionsUsed(gltf, "KHR_blend"); } ForEach.material(gltf, function (material) { if (defined(material.technique)) { const materialProperties = materialPropertiesForTechnique[material.technique]; ForEach.objectLegacy(materialProperties, function (value, property) { material[property] = value; }); const blending = blendingForTechnique[material.technique]; if (defined(blending)) { if (!defined(material.extensions)) { material.extensions = {}; } material.extensions.KHR_blend = blending; } } }); return gltf; } export default moveTechniqueRenderStates;