123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914 |
- import defaultValue from "../Core/defaultValue.js";
- import defined from "../Core/defined.js";
- import WebGLConstants from "../Core/WebGLConstants.js";
- import webGLConstantToGlslType from "../Core/webGLConstantToGlslType.js";
- import addToArray from "../ThirdParty/GltfPipeline/addToArray.js";
- import ForEach from "../ThirdParty/GltfPipeline/ForEach.js";
- import hasExtension from "../ThirdParty/GltfPipeline/hasExtension.js";
- import ModelUtility from "./ModelUtility.js";
- /**
- * @private
- */
- function processModelMaterialsCommon(gltf, options) {
- options = defaultValue(options, defaultValue.EMPTY_OBJECT);
- if (!defined(gltf)) {
- return;
- }
- if (!hasExtension(gltf, "KHR_materials_common")) {
- return;
- }
- if (!hasExtension(gltf, "KHR_techniques_webgl")) {
- if (!defined(gltf.extensions)) {
- gltf.extensions = {};
- }
- gltf.extensions.KHR_techniques_webgl = {
- programs: [],
- shaders: [],
- techniques: [],
- };
- gltf.extensionsUsed.push("KHR_techniques_webgl");
- gltf.extensionsRequired.push("KHR_techniques_webgl");
- }
- var techniquesWebgl = gltf.extensions.KHR_techniques_webgl;
- lightDefaults(gltf);
- var lightParameters = generateLightParameters(gltf);
- var primitiveByMaterial = ModelUtility.splitIncompatibleMaterials(gltf);
- var techniques = {};
- var generatedTechniques = false;
- ForEach.material(gltf, function (material, materialIndex) {
- if (
- defined(material.extensions) &&
- defined(material.extensions.KHR_materials_common)
- ) {
- var khrMaterialsCommon = material.extensions.KHR_materials_common;
- var primitiveInfo = primitiveByMaterial[materialIndex];
- var techniqueKey = getTechniqueKey(khrMaterialsCommon, primitiveInfo);
- var technique = techniques[techniqueKey];
- if (!defined(technique)) {
- technique = generateTechnique(
- gltf,
- techniquesWebgl,
- primitiveInfo,
- khrMaterialsCommon,
- lightParameters,
- options.addBatchIdToGeneratedShaders
- );
- techniques[techniqueKey] = technique;
- generatedTechniques = true;
- }
- var materialValues = {};
- var values = khrMaterialsCommon.values;
- var uniformName;
- for (var valueName in values) {
- if (
- values.hasOwnProperty(valueName) &&
- valueName !== "transparent" &&
- valueName !== "doubleSided"
- ) {
- uniformName = "u_" + valueName.toLowerCase();
- materialValues[uniformName] = values[valueName];
- }
- }
- material.extensions.KHR_techniques_webgl = {
- technique: technique,
- values: materialValues,
- };
- material.alphaMode = "OPAQUE";
- if (khrMaterialsCommon.transparent) {
- material.alphaMode = "BLEND";
- }
- if (khrMaterialsCommon.doubleSided) {
- material.doubleSided = true;
- }
- }
- });
- if (!generatedTechniques) {
- return gltf;
- }
- // If any primitives have semantics that aren't declared in the generated
- // shaders, we want to preserve them.
- ModelUtility.ensureSemanticExistence(gltf);
- return gltf;
- }
- function generateLightParameters(gltf) {
- var result = {};
- var lights;
- if (
- defined(gltf.extensions) &&
- defined(gltf.extensions.KHR_materials_common)
- ) {
- lights = gltf.extensions.KHR_materials_common.lights;
- }
- if (defined(lights)) {
- // Figure out which node references the light
- var nodes = gltf.nodes;
- for (var nodeName in nodes) {
- if (nodes.hasOwnProperty(nodeName)) {
- var node = nodes[nodeName];
- if (
- defined(node.extensions) &&
- defined(node.extensions.KHR_materials_common)
- ) {
- var nodeLightId = node.extensions.KHR_materials_common.light;
- if (defined(nodeLightId) && defined(lights[nodeLightId])) {
- lights[nodeLightId].node = nodeName;
- }
- delete node.extensions.KHR_materials_common;
- }
- }
- }
- // Add light parameters to result
- var lightCount = 0;
- for (var lightName in lights) {
- if (lights.hasOwnProperty(lightName)) {
- var light = lights[lightName];
- var lightType = light.type;
- if (lightType !== "ambient" && !defined(light.node)) {
- delete lights[lightName];
- continue;
- }
- var lightBaseName = "light" + lightCount.toString();
- light.baseName = lightBaseName;
- switch (lightType) {
- case "ambient":
- var ambient = light.ambient;
- result[lightBaseName + "Color"] = {
- type: WebGLConstants.FLOAT_VEC3,
- value: ambient.color,
- };
- break;
- case "directional":
- var directional = light.directional;
- result[lightBaseName + "Color"] = {
- type: WebGLConstants.FLOAT_VEC3,
- value: directional.color,
- };
- if (defined(light.node)) {
- result[lightBaseName + "Transform"] = {
- node: light.node,
- semantic: "MODELVIEW",
- type: WebGLConstants.FLOAT_MAT4,
- };
- }
- break;
- case "point":
- var point = light.point;
- result[lightBaseName + "Color"] = {
- type: WebGLConstants.FLOAT_VEC3,
- value: point.color,
- };
- if (defined(light.node)) {
- result[lightBaseName + "Transform"] = {
- node: light.node,
- semantic: "MODELVIEW",
- type: WebGLConstants.FLOAT_MAT4,
- };
- }
- result[lightBaseName + "Attenuation"] = {
- type: WebGLConstants.FLOAT_VEC3,
- value: [
- point.constantAttenuation,
- point.linearAttenuation,
- point.quadraticAttenuation,
- ],
- };
- break;
- case "spot":
- var spot = light.spot;
- result[lightBaseName + "Color"] = {
- type: WebGLConstants.FLOAT_VEC3,
- value: spot.color,
- };
- if (defined(light.node)) {
- result[lightBaseName + "Transform"] = {
- node: light.node,
- semantic: "MODELVIEW",
- type: WebGLConstants.FLOAT_MAT4,
- };
- result[lightBaseName + "InverseTransform"] = {
- node: light.node,
- semantic: "MODELVIEWINVERSE",
- type: WebGLConstants.FLOAT_MAT4,
- useInFragment: true,
- };
- }
- result[lightBaseName + "Attenuation"] = {
- type: WebGLConstants.FLOAT_VEC3,
- value: [
- spot.constantAttenuation,
- spot.linearAttenuation,
- spot.quadraticAttenuation,
- ],
- };
- result[lightBaseName + "FallOff"] = {
- type: WebGLConstants.FLOAT_VEC2,
- value: [spot.fallOffAngle, spot.fallOffExponent],
- };
- break;
- }
- ++lightCount;
- }
- }
- }
- return result;
- }
- function generateTechnique(
- gltf,
- techniquesWebgl,
- primitiveInfo,
- khrMaterialsCommon,
- lightParameters,
- addBatchIdToGeneratedShaders
- ) {
- if (!defined(khrMaterialsCommon)) {
- khrMaterialsCommon = {};
- }
- addBatchIdToGeneratedShaders = defaultValue(
- addBatchIdToGeneratedShaders,
- false
- );
- var techniques = techniquesWebgl.techniques;
- var shaders = techniquesWebgl.shaders;
- var programs = techniquesWebgl.programs;
- var lightingModel = khrMaterialsCommon.technique.toUpperCase();
- var lights;
- if (
- defined(gltf.extensions) &&
- defined(gltf.extensions.KHR_materials_common)
- ) {
- lights = gltf.extensions.KHR_materials_common.lights;
- }
- var parameterValues = khrMaterialsCommon.values;
- var jointCount = defaultValue(khrMaterialsCommon.jointCount, 0);
- var skinningInfo;
- var hasSkinning = false;
- var hasVertexColors = false;
- if (defined(primitiveInfo)) {
- skinningInfo = primitiveInfo.skinning;
- hasSkinning = skinningInfo.skinned;
- hasVertexColors = primitiveInfo.hasVertexColors;
- }
- var vertexShader = "precision highp float;\n";
- var fragmentShader = "precision highp float;\n";
- var hasNormals = lightingModel !== "CONSTANT";
- // Add techniques
- var techniqueUniforms = {
- u_modelViewMatrix: {
- semantic: hasExtension(gltf, "CESIUM_RTC")
- ? "CESIUM_RTC_MODELVIEW"
- : "MODELVIEW",
- type: WebGLConstants.FLOAT_MAT4,
- },
- u_projectionMatrix: {
- semantic: "PROJECTION",
- type: WebGLConstants.FLOAT_MAT4,
- },
- };
- if (hasNormals) {
- techniqueUniforms.u_normalMatrix = {
- semantic: "MODELVIEWINVERSETRANSPOSE",
- type: WebGLConstants.FLOAT_MAT3,
- };
- }
- if (hasSkinning) {
- techniqueUniforms.u_jointMatrix = {
- count: jointCount,
- semantic: "JOINTMATRIX",
- type: WebGLConstants.FLOAT_MAT4,
- };
- }
- // Add material values
- var uniformName;
- var hasTexCoords = false;
- for (var name in parameterValues) {
- //generate shader parameters for KHR_materials_common attributes
- //(including a check, because some boolean flags should not be used as shader parameters)
- if (
- parameterValues.hasOwnProperty(name) &&
- name !== "transparent" &&
- name !== "doubleSided"
- ) {
- var uniformType = getKHRMaterialsCommonValueType(
- name,
- parameterValues[name]
- );
- uniformName = "u_" + name.toLowerCase();
- if (!hasTexCoords && uniformType === WebGLConstants.SAMPLER_2D) {
- hasTexCoords = true;
- }
- techniqueUniforms[uniformName] = {
- type: uniformType,
- };
- }
- }
- // Give the diffuse uniform a semantic to support color replacement in 3D Tiles
- if (defined(techniqueUniforms.u_diffuse)) {
- techniqueUniforms.u_diffuse.semantic = "_3DTILESDIFFUSE";
- }
- // Copy light parameters into technique parameters
- if (defined(lightParameters)) {
- for (var lightParamName in lightParameters) {
- if (lightParameters.hasOwnProperty(lightParamName)) {
- uniformName = "u_" + lightParamName;
- techniqueUniforms[uniformName] = lightParameters[lightParamName];
- }
- }
- }
- // Add uniforms to shaders
- for (uniformName in techniqueUniforms) {
- if (techniqueUniforms.hasOwnProperty(uniformName)) {
- var uniform = techniqueUniforms[uniformName];
- var arraySize = defined(uniform.count) ? "[" + uniform.count + "]" : "";
- if (
- (uniform.type !== WebGLConstants.FLOAT_MAT3 &&
- uniform.type !== WebGLConstants.FLOAT_MAT4) ||
- uniform.useInFragment
- ) {
- fragmentShader +=
- "uniform " +
- webGLConstantToGlslType(uniform.type) +
- " " +
- uniformName +
- arraySize +
- ";\n";
- delete uniform.useInFragment;
- } else {
- vertexShader +=
- "uniform " +
- webGLConstantToGlslType(uniform.type) +
- " " +
- uniformName +
- arraySize +
- ";\n";
- }
- }
- }
- // Add attributes with semantics
- var vertexShaderMain = "";
- if (hasSkinning) {
- vertexShaderMain +=
- " mat4 skinMatrix =\n" +
- " a_weight.x * u_jointMatrix[int(a_joint.x)] +\n" +
- " a_weight.y * u_jointMatrix[int(a_joint.y)] +\n" +
- " a_weight.z * u_jointMatrix[int(a_joint.z)] +\n" +
- " a_weight.w * u_jointMatrix[int(a_joint.w)];\n";
- }
- // Add position always
- var techniqueAttributes = {
- a_position: {
- semantic: "POSITION",
- },
- };
- vertexShader += "attribute vec3 a_position;\n";
- vertexShader += "varying vec3 v_positionEC;\n";
- if (hasSkinning) {
- vertexShaderMain +=
- " vec4 pos = u_modelViewMatrix * skinMatrix * vec4(a_position,1.0);\n";
- } else {
- vertexShaderMain +=
- " vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);\n";
- }
- vertexShaderMain += " v_positionEC = pos.xyz;\n";
- vertexShaderMain += " gl_Position = u_projectionMatrix * pos;\n";
- fragmentShader += "varying vec3 v_positionEC;\n";
- // Add normal if we don't have constant lighting
- if (hasNormals) {
- techniqueAttributes.a_normal = {
- semantic: "NORMAL",
- };
- vertexShader += "attribute vec3 a_normal;\n";
- vertexShader += "varying vec3 v_normal;\n";
- if (hasSkinning) {
- vertexShaderMain +=
- " v_normal = u_normalMatrix * mat3(skinMatrix) * a_normal;\n";
- } else {
- vertexShaderMain += " v_normal = u_normalMatrix * a_normal;\n";
- }
- fragmentShader += "varying vec3 v_normal;\n";
- }
- // Add texture coordinates if the material uses them
- var v_texcoord;
- if (hasTexCoords) {
- techniqueAttributes.a_texcoord_0 = {
- semantic: "TEXCOORD_0",
- };
- v_texcoord = "v_texcoord_0";
- vertexShader += "attribute vec2 a_texcoord_0;\n";
- vertexShader += "varying vec2 " + v_texcoord + ";\n";
- vertexShaderMain += " " + v_texcoord + " = a_texcoord_0;\n";
- fragmentShader += "varying vec2 " + v_texcoord + ";\n";
- }
- if (hasSkinning) {
- techniqueAttributes.a_joint = {
- semantic: "JOINTS_0",
- };
- techniqueAttributes.a_weight = {
- semantic: "WEIGHTS_0",
- };
- vertexShader += "attribute vec4 a_joint;\n";
- vertexShader += "attribute vec4 a_weight;\n";
- }
- if (hasVertexColors) {
- techniqueAttributes.a_vertexColor = {
- semantic: "COLOR_0",
- };
- vertexShader += "attribute vec4 a_vertexColor;\n";
- vertexShader += "varying vec4 v_vertexColor;\n";
- vertexShaderMain += " v_vertexColor = a_vertexColor;\n";
- fragmentShader += "varying vec4 v_vertexColor;\n";
- }
- if (addBatchIdToGeneratedShaders) {
- techniqueAttributes.a_batchId = {
- semantic: "_BATCHID",
- };
- vertexShader += "attribute float a_batchId;\n";
- }
- var hasSpecular =
- hasNormals &&
- (lightingModel === "BLINN" || lightingModel === "PHONG") &&
- defined(techniqueUniforms.u_specular) &&
- defined(techniqueUniforms.u_shininess) &&
- techniqueUniforms.u_shininess > 0.0;
- // Generate lighting code blocks
- var hasNonAmbientLights = false;
- var hasAmbientLights = false;
- var fragmentLightingBlock = "";
- for (var lightName in lights) {
- if (lights.hasOwnProperty(lightName)) {
- var light = lights[lightName];
- var lightType = light.type.toLowerCase();
- var lightBaseName = light.baseName;
- fragmentLightingBlock += " {\n";
- var lightColorName = "u_" + lightBaseName + "Color";
- var varyingDirectionName;
- var varyingPositionName;
- if (lightType === "ambient") {
- hasAmbientLights = true;
- fragmentLightingBlock +=
- " ambientLight += " + lightColorName + ";\n";
- } else if (hasNormals) {
- hasNonAmbientLights = true;
- varyingDirectionName = "v_" + lightBaseName + "Direction";
- varyingPositionName = "v_" + lightBaseName + "Position";
- if (lightType !== "point") {
- vertexShader += "varying vec3 " + varyingDirectionName + ";\n";
- fragmentShader += "varying vec3 " + varyingDirectionName + ";\n";
- vertexShaderMain +=
- " " +
- varyingDirectionName +
- " = mat3(u_" +
- lightBaseName +
- "Transform) * vec3(0.,0.,1.);\n";
- if (lightType === "directional") {
- fragmentLightingBlock +=
- " vec3 l = normalize(" + varyingDirectionName + ");\n";
- }
- }
- if (lightType !== "directional") {
- vertexShader += "varying vec3 " + varyingPositionName + ";\n";
- fragmentShader += "varying vec3 " + varyingPositionName + ";\n";
- vertexShaderMain +=
- " " +
- varyingPositionName +
- " = u_" +
- lightBaseName +
- "Transform[3].xyz;\n";
- fragmentLightingBlock +=
- " vec3 VP = " + varyingPositionName + " - v_positionEC;\n";
- fragmentLightingBlock += " vec3 l = normalize(VP);\n";
- fragmentLightingBlock += " float range = length(VP);\n";
- fragmentLightingBlock +=
- " float attenuation = 1.0 / (u_" +
- lightBaseName +
- "Attenuation.x + ";
- fragmentLightingBlock +=
- "(u_" + lightBaseName + "Attenuation.y * range) + ";
- fragmentLightingBlock +=
- "(u_" + lightBaseName + "Attenuation.z * range * range));\n";
- } else {
- fragmentLightingBlock += " float attenuation = 1.0;\n";
- }
- if (lightType === "spot") {
- fragmentLightingBlock +=
- " float spotDot = dot(l, normalize(" +
- varyingDirectionName +
- "));\n";
- fragmentLightingBlock +=
- " if (spotDot < cos(u_" + lightBaseName + "FallOff.x * 0.5))\n";
- fragmentLightingBlock += " {\n";
- fragmentLightingBlock += " attenuation = 0.0;\n";
- fragmentLightingBlock += " }\n";
- fragmentLightingBlock += " else\n";
- fragmentLightingBlock += " {\n";
- fragmentLightingBlock +=
- " attenuation *= max(0.0, pow(spotDot, u_" +
- lightBaseName +
- "FallOff.y));\n";
- fragmentLightingBlock += " }\n";
- }
- fragmentLightingBlock +=
- " diffuseLight += " +
- lightColorName +
- "* max(dot(normal,l), 0.) * attenuation;\n";
- if (hasSpecular) {
- if (lightingModel === "BLINN") {
- fragmentLightingBlock += " vec3 h = normalize(l + viewDir);\n";
- fragmentLightingBlock +=
- " float specularIntensity = max(0., pow(max(dot(normal, h), 0.), u_shininess)) * attenuation;\n";
- } else {
- // PHONG
- fragmentLightingBlock +=
- " vec3 reflectDir = reflect(-l, normal);\n";
- fragmentLightingBlock +=
- " float specularIntensity = max(0., pow(max(dot(reflectDir, viewDir), 0.), u_shininess)) * attenuation;\n";
- }
- fragmentLightingBlock +=
- " specularLight += " +
- lightColorName +
- " * specularIntensity;\n";
- }
- }
- fragmentLightingBlock += " }\n";
- }
- }
- if (!hasAmbientLights) {
- // Add an ambient light if we don't have one
- fragmentLightingBlock += " ambientLight += vec3(0.2, 0.2, 0.2);\n";
- }
- if (!hasNonAmbientLights && lightingModel !== "CONSTANT") {
- fragmentShader += "#ifdef USE_CUSTOM_LIGHT_COLOR \n";
- fragmentShader += "uniform vec3 gltf_lightColor; \n";
- fragmentShader += "#endif \n";
- fragmentLightingBlock += "#ifndef USE_CUSTOM_LIGHT_COLOR \n";
- fragmentLightingBlock += " vec3 lightColor = czm_lightColor;\n";
- fragmentLightingBlock += "#else \n";
- fragmentLightingBlock += " vec3 lightColor = gltf_lightColor;\n";
- fragmentLightingBlock += "#endif \n";
- fragmentLightingBlock += " vec3 l = normalize(czm_lightDirectionEC);\n";
- var minimumLighting = "0.2"; // Use strings instead of values as 0.0 -> 0 when stringified
- fragmentLightingBlock +=
- " diffuseLight += lightColor * max(dot(normal,l), " +
- minimumLighting +
- ");\n";
- if (hasSpecular) {
- if (lightingModel === "BLINN") {
- fragmentLightingBlock += " vec3 h = normalize(l + viewDir);\n";
- fragmentLightingBlock +=
- " float specularIntensity = max(0., pow(max(dot(normal, h), 0.), u_shininess));\n";
- } else {
- // PHONG
- fragmentLightingBlock += " vec3 reflectDir = reflect(-l, normal);\n";
- fragmentLightingBlock +=
- " float specularIntensity = max(0., pow(max(dot(reflectDir, viewDir), 0.), u_shininess));\n";
- }
- fragmentLightingBlock +=
- " specularLight += lightColor * specularIntensity;\n";
- }
- }
- vertexShader += "void main(void) {\n";
- vertexShader += vertexShaderMain;
- vertexShader += "}\n";
- fragmentShader += "void main(void) {\n";
- var colorCreationBlock = " vec3 color = vec3(0.0, 0.0, 0.0);\n";
- if (hasNormals) {
- fragmentShader += " vec3 normal = normalize(v_normal);\n";
- if (khrMaterialsCommon.doubleSided) {
- fragmentShader += " if (czm_backFacing())\n";
- fragmentShader += " {\n";
- fragmentShader += " normal = -normal;\n";
- fragmentShader += " }\n";
- }
- }
- var finalColorComputation;
- if (lightingModel !== "CONSTANT") {
- if (defined(techniqueUniforms.u_diffuse)) {
- if (techniqueUniforms.u_diffuse.type === WebGLConstants.SAMPLER_2D) {
- fragmentShader +=
- " vec4 diffuse = texture2D(u_diffuse, " + v_texcoord + ");\n";
- } else {
- fragmentShader += " vec4 diffuse = u_diffuse;\n";
- }
- fragmentShader += " vec3 diffuseLight = vec3(0.0, 0.0, 0.0);\n";
- colorCreationBlock += " color += diffuse.rgb * diffuseLight;\n";
- }
- if (hasSpecular) {
- if (techniqueUniforms.u_specular.type === WebGLConstants.SAMPLER_2D) {
- fragmentShader +=
- " vec3 specular = texture2D(u_specular, " + v_texcoord + ").rgb;\n";
- } else {
- fragmentShader += " vec3 specular = u_specular.rgb;\n";
- }
- fragmentShader += " vec3 specularLight = vec3(0.0, 0.0, 0.0);\n";
- colorCreationBlock += " color += specular * specularLight;\n";
- }
- if (defined(techniqueUniforms.u_transparency)) {
- finalColorComputation =
- " gl_FragColor = vec4(color * diffuse.a * u_transparency, diffuse.a * u_transparency);\n";
- } else {
- finalColorComputation =
- " gl_FragColor = vec4(color * diffuse.a, diffuse.a);\n";
- }
- } else if (defined(techniqueUniforms.u_transparency)) {
- finalColorComputation =
- " gl_FragColor = vec4(color * u_transparency, u_transparency);\n";
- } else {
- finalColorComputation = " gl_FragColor = vec4(color, 1.0);\n";
- }
- if (hasVertexColors) {
- colorCreationBlock += " color *= v_vertexColor.rgb;\n";
- }
- if (defined(techniqueUniforms.u_emission)) {
- if (techniqueUniforms.u_emission.type === WebGLConstants.SAMPLER_2D) {
- fragmentShader +=
- " vec3 emission = texture2D(u_emission, " + v_texcoord + ").rgb;\n";
- } else {
- fragmentShader += " vec3 emission = u_emission.rgb;\n";
- }
- colorCreationBlock += " color += emission;\n";
- }
- if (defined(techniqueUniforms.u_ambient) || lightingModel !== "CONSTANT") {
- if (defined(techniqueUniforms.u_ambient)) {
- if (techniqueUniforms.u_ambient.type === WebGLConstants.SAMPLER_2D) {
- fragmentShader +=
- " vec3 ambient = texture2D(u_ambient, " + v_texcoord + ").rgb;\n";
- } else {
- fragmentShader += " vec3 ambient = u_ambient.rgb;\n";
- }
- } else {
- fragmentShader += " vec3 ambient = diffuse.rgb;\n";
- }
- colorCreationBlock += " color += ambient * ambientLight;\n";
- }
- fragmentShader += " vec3 viewDir = -normalize(v_positionEC);\n";
- fragmentShader += " vec3 ambientLight = vec3(0.0, 0.0, 0.0);\n";
- // Add in light computations
- fragmentShader += fragmentLightingBlock;
- fragmentShader += colorCreationBlock;
- fragmentShader += finalColorComputation;
- fragmentShader += "}\n";
- // Add shaders
- var vertexShaderId = addToArray(shaders, {
- type: WebGLConstants.VERTEX_SHADER,
- extras: {
- _pipeline: {
- source: vertexShader,
- extension: ".glsl",
- },
- },
- });
- var fragmentShaderId = addToArray(shaders, {
- type: WebGLConstants.FRAGMENT_SHADER,
- extras: {
- _pipeline: {
- source: fragmentShader,
- extension: ".glsl",
- },
- },
- });
- // Add program
- var programId = addToArray(programs, {
- fragmentShader: fragmentShaderId,
- vertexShader: vertexShaderId,
- });
- var techniqueId = addToArray(techniques, {
- attributes: techniqueAttributes,
- program: programId,
- uniforms: techniqueUniforms,
- });
- return techniqueId;
- }
- function getKHRMaterialsCommonValueType(paramName, paramValue) {
- var value;
- // Backwards compatibility for COLLADA2GLTF v1.0-draft when it encoding
- // materials using KHR_materials_common with explicit type/value members
- if (defined(paramValue.value)) {
- value = paramValue.value;
- } else if (defined(paramValue.index)) {
- value = [paramValue.index];
- } else {
- value = paramValue;
- }
- switch (paramName) {
- case "ambient":
- return value.length === 1
- ? WebGLConstants.SAMPLER_2D
- : WebGLConstants.FLOAT_VEC4;
- case "diffuse":
- return value.length === 1
- ? WebGLConstants.SAMPLER_2D
- : WebGLConstants.FLOAT_VEC4;
- case "emission":
- return value.length === 1
- ? WebGLConstants.SAMPLER_2D
- : WebGLConstants.FLOAT_VEC4;
- case "specular":
- return value.length === 1
- ? WebGLConstants.SAMPLER_2D
- : WebGLConstants.FLOAT_VEC4;
- case "shininess":
- return WebGLConstants.FLOAT;
- case "transparency":
- return WebGLConstants.FLOAT;
- // these two are usually not used directly within shaders,
- // they are just added here for completeness
- case "transparent":
- return WebGLConstants.BOOL;
- case "doubleSided":
- return WebGLConstants.BOOL;
- }
- }
- function getTechniqueKey(khrMaterialsCommon, primitiveInfo) {
- var techniqueKey = "";
- techniqueKey += "technique:" + khrMaterialsCommon.technique + ";";
- var values = khrMaterialsCommon.values;
- var keys = Object.keys(values).sort();
- var keysCount = keys.length;
- for (var i = 0; i < keysCount; ++i) {
- var name = keys[i];
- if (values.hasOwnProperty(name)) {
- techniqueKey +=
- name + ":" + getKHRMaterialsCommonValueType(name, values[name]);
- techniqueKey += ";";
- }
- }
- var jointCount = defaultValue(khrMaterialsCommon.jointCount, 0);
- techniqueKey += jointCount.toString() + ";";
- if (defined(primitiveInfo)) {
- var skinningInfo = primitiveInfo.skinning;
- if (jointCount > 0) {
- techniqueKey += skinningInfo.type + ";";
- }
- techniqueKey += primitiveInfo.hasVertexColors;
- }
- return techniqueKey;
- }
- function lightDefaults(gltf) {
- var khrMaterialsCommon = gltf.extensions.KHR_materials_common;
- if (!defined(khrMaterialsCommon) || !defined(khrMaterialsCommon.lights)) {
- return;
- }
- var lights = khrMaterialsCommon.lights;
- var lightsLength = lights.length;
- for (var lightId = 0; lightId < lightsLength; lightId++) {
- var light = lights[lightId];
- if (light.type === "ambient") {
- if (!defined(light.ambient)) {
- light.ambient = {};
- }
- var ambientLight = light.ambient;
- if (!defined(ambientLight.color)) {
- ambientLight.color = [1.0, 1.0, 1.0];
- }
- } else if (light.type === "directional") {
- if (!defined(light.directional)) {
- light.directional = {};
- }
- var directionalLight = light.directional;
- if (!defined(directionalLight.color)) {
- directionalLight.color = [1.0, 1.0, 1.0];
- }
- } else if (light.type === "point") {
- if (!defined(light.point)) {
- light.point = {};
- }
- var pointLight = light.point;
- if (!defined(pointLight.color)) {
- pointLight.color = [1.0, 1.0, 1.0];
- }
- pointLight.constantAttenuation = defaultValue(
- pointLight.constantAttenuation,
- 1.0
- );
- pointLight.linearAttenuation = defaultValue(
- pointLight.linearAttenuation,
- 0.0
- );
- pointLight.quadraticAttenuation = defaultValue(
- pointLight.quadraticAttenuation,
- 0.0
- );
- } else if (light.type === "spot") {
- if (!defined(light.spot)) {
- light.spot = {};
- }
- var spotLight = light.spot;
- if (!defined(spotLight.color)) {
- spotLight.color = [1.0, 1.0, 1.0];
- }
- spotLight.constantAttenuation = defaultValue(
- spotLight.constantAttenuation,
- 1.0
- );
- spotLight.fallOffAngle = defaultValue(spotLight.fallOffAngle, 3.14159265);
- spotLight.fallOffExponent = defaultValue(spotLight.fallOffExponent, 0.0);
- spotLight.linearAttenuation = defaultValue(
- spotLight.linearAttenuation,
- 0.0
- );
- spotLight.quadraticAttenuation = defaultValue(
- spotLight.quadraticAttenuation,
- 0.0
- );
- }
- }
- }
- export default processModelMaterialsCommon;
|