From ae40eb98101e61618a2b8b5f8b0340a778dbb839 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 10 Sep 2018 17:59:17 -0400 Subject: [PATCH 01/10] Add options to enable/disbale ibl lighting and sun light intensity. --- Source/Scene/Model.js | 60 ++++++++++++++++++- .../processPbrMetallicRoughness.js | 18 +++++- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 22b36ad03ab4..44494d4e3c82 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -660,6 +660,10 @@ define([ this._rtcCenterEye = undefined; // in eye coordinates this._rtcCenter3D = undefined; // in world coordinates this._rtcCenter2D = undefined; // in projected world coordinates + + this._iblFactor = 1.0; + this._lightColor = undefined; + this._regenerateShaders = false; } defineProperties(Model.prototype, { @@ -1074,6 +1078,26 @@ define([ get : function() { return this._pickIds; } + }, + + iblFactor : { + get : function() { + return this._iblFactor; + }, + set : function(value) { + this._regenerateShaders = this._regenerateShaders || (this._iblFactor > 0.0 && value === 0.0) || (this._iblFactor === 0.0 && value > 0.0); + this._iblFactor = value; + } + }, + + lightColor : { + get : function() { + return this._lightColor; + }, + set : function(value) { + this._regenerateShaders = this._regenerateShaders || (defined(this._lightColor) && !defined(value)) || (defined(value) && !defined(this._lightColor)); + this._lightColor = Color.clone(value, this._lightColor); + } } }); @@ -2044,6 +2068,14 @@ define([ drawFS = 'uniform vec4 czm_pickColor;\n' + drawFS; } + if (model._iblFactor > 0.0) { + drawFS = '#define USE_IBL_LIGHTING \n\n' + drawFS; + } + + if (defined(model._lightColor)) { + drawFS = '#define USE_CUSTOM_LIGHT_COLOR \n\n' + drawFS; + } + createAttributesAndProgram(id, drawFS, drawVS, model, context); } @@ -2083,6 +2115,14 @@ define([ drawFS = 'uniform vec4 czm_pickColor;\n' + drawFS; } + if (model._iblFactor > 0.0) { + drawFS = '#define USE_IBL_LIGHTING \n\n' + drawFS; + } + + if (defined(model._lightColor)) { + drawFS = '#define USE_CUSTOM_LIGHT_COLOR \n\n' + drawFS; + } + createAttributesAndProgram(id, drawFS, drawVS, model, context); } @@ -3039,6 +3079,18 @@ define([ }; } + function createIBLFactorFunction(model) { + return function() { + return model._iblFactor; + }; + } + + function createLightColorFunction(model) { + return function() { + return model._lightColor; + }; + } + function triangleCountFromPrimitiveIndices(primitive, indicesCount) { switch (primitive.mode) { case PrimitiveType.TRIANGLES: @@ -3136,7 +3188,9 @@ define([ gltf_colorBlend : createColorBlendFunction(model), gltf_clippingPlanes: createClippingPlanesFunction(model), gltf_clippingPlanesEdgeStyle: createClippingPlanesEdgeStyleFunction(model), - gltf_clippingPlanesMatrix: createClippingPlanesMatrixFunction(model) + gltf_clippingPlanesMatrix: createClippingPlanesMatrixFunction(model), + gltf_iblFactor : createIBLFactorFunction(model), + gltf_lightColor : createLightColorFunction(model) }); // Allow callback to modify the uniformMap @@ -4430,7 +4484,7 @@ define([ currentClippingPlanesState = clippingPlanes.clippingPlanesState; } - var shouldRegenerateShaders = this._clippingPlanesState !== currentClippingPlanesState; + var shouldRegenerateShaders = this._clippingPlanesState !== currentClippingPlanesState || this._regenerateShaders; this._clippingPlanesState = currentClippingPlanesState; // Regenerate shaders if color shading changed from last update @@ -4446,6 +4500,8 @@ define([ updateColor(this, frameState, false); updateSilhouette(this, frameState, false); } + + this._regenerateShaders = false; } if (justLoaded) { diff --git a/Source/ThirdParty/GltfPipeline/processPbrMetallicRoughness.js b/Source/ThirdParty/GltfPipeline/processPbrMetallicRoughness.js index 0b1ebe12f525..be1197a90467 100644 --- a/Source/ThirdParty/GltfPipeline/processPbrMetallicRoughness.js +++ b/Source/ThirdParty/GltfPipeline/processPbrMetallicRoughness.js @@ -465,6 +465,16 @@ define([ ' return pow(linearIn, vec3(1.0/2.2));\n' + '}\n\n'; + if (optimizeForCesium) { + fragmentShader += '#ifdef USE_IBL_LIGHTING \n'; + fragmentShader += 'uniform float gltf_iblFactor; \n'; + fragmentShader += '#endif \n'; + + fragmentShader += '#ifdef USE_CUSTOM_LIGHT_COLOR \n'; + fragmentShader += 'uniform vec3 gltf_lightColor; \n'; + fragmentShader += '#endif \n'; + } + fragmentShader += 'void main(void) \n{\n'; // Add normal mapping to fragment shader @@ -560,7 +570,11 @@ define([ // Generate fragment shader's lighting block if (optimizeForCesium) { // The Sun is brighter than your average light source, and has a yellowish tint balanced by the Earth's ambient blue. + fragmentShader += '#ifdef USE_CUSTOM_LIGHT_COLOR \n'; + fragmentShader += ' vec3 lightColor = gltf_lightColor;\n'; + fragmentShader += '#else \n'; fragmentShader += ' vec3 lightColor = vec3(1.5, 1.4, 1.2);\n'; + fragmentShader += '#endif \n'; fragmentShader += ' vec3 l = normalize(czm_sunDirectionEC);\n'; } else { fragmentShader += ' vec3 lightColor = vec3(1.0, 1.0, 1.0);\n'; @@ -604,6 +618,7 @@ define([ fragmentShader += ' vec3 color = NdotL * lightColor * (diffuseContribution + specularContribution);\n'; if (optimizeForCesium) { + fragmentShader += '#ifdef USE_IBL_LIGHTING \n'; fragmentShader += ' float inverseRoughness = 1.04 - roughness;\n'; fragmentShader += ' inverseRoughness *= inverseRoughness;\n'; fragmentShader += ' vec3 sceneSkyBox = textureCube(czm_environmentMap, r).rgb * inverseRoughness;\n'; @@ -634,7 +649,8 @@ define([ fragmentShader += ' vec2 brdfLut = texture2D(czm_brdfLut, vec2(NdotV, 1.0 - roughness)).rg;\n'; fragmentShader += ' vec3 IBLColor = (diffuseIrradiance * diffuseColor) + (specularIrradiance * SRGBtoLINEAR3(specularColor * brdfLut.x + brdfLut.y));\n'; - fragmentShader += ' color += IBLColor;\n'; + fragmentShader += ' color += IBLColor * gltf_iblFactor;\n'; + fragmentShader += '#endif \n'; } } else { fragmentShader += ' vec3 color = baseColor;\n'; From d741cb2ca3bb4966ede063bf4ac22f7f21440b9a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 10 Sep 2018 19:37:07 -0400 Subject: [PATCH 02/10] Add ibl option and sun light color options to 3D Tiles. --- Source/Scene/Batched3DModel3DTileContent.js | 6 +++- Source/Scene/Cesium3DTileset.js | 23 ++++++++++++ Source/Scene/Instanced3DModel3DTileContent.js | 8 +++-- Source/Scene/Model.js | 35 ++++++++++++++++--- Source/Scene/ModelInstanceCollection.js | 10 +++++- 5 files changed, 74 insertions(+), 8 deletions(-) diff --git a/Source/Scene/Batched3DModel3DTileContent.js b/Source/Scene/Batched3DModel3DTileContent.js index f3e291eaaa40..5d952dae475c 100644 --- a/Source/Scene/Batched3DModel3DTileContent.js +++ b/Source/Scene/Batched3DModel3DTileContent.js @@ -384,7 +384,9 @@ define([ uniformMapLoaded : batchTable.getUniformMapCallback(), pickIdLoaded : getPickIdCallback(content), addBatchIdToGeneratedShaders : (batchLength > 0), // If the batch table has values in it, generated shaders will need a batchId attribute - pickObject : pickObject + pickObject : pickObject, + iblFactor : tileset.iblFactor, + lightColor : tileset.lightColor }); } else { // This transcodes glTF to an internal representation for geometry so we can take advantage of the re-batching of vector data. @@ -460,6 +462,8 @@ define([ this._model.modelMatrix = this._contentModelMatrix; this._model.shadows = this._tileset.shadows; + this._model.iblFactor = this._tileset.iblFactor; + this._model.lightColor = this._tileset.lightColor; this._model.debugWireframe = this._tileset.debugWireframe; // Update clipping planes diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index 604742192531..55b587ce2a58 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -113,6 +113,8 @@ define([ * @param {ClassificationType} [options.classificationType] Determines whether terrain, 3D Tiles or both will be classified by this tileset. See {@link Cesium3DTileset#classificationType} for details about restrictions and limitations. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid determining the size and shape of the globe. * @param {Object} [options.pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation based on geometric error and lighting. + * @param {Number} [options.iblFactor=1.0] Scales the IBL lighting from the earth, sky, atmosphere and star skybox. + * @param {Color} [options.lightColor] The color and intensity of the sunlight used to shade models. * @param {Boolean} [options.debugFreezeFrame=false] For debugging only. Determines if only the tiles from last frame should be used for rendering. * @param {Boolean} [options.debugColorizeTiles=false] For debugging only. When true, assigns a random color to each tile. * @param {Boolean} [options.debugWireframe=false] For debugging only. When true, render's each tile's content as a wireframe. @@ -544,6 +546,27 @@ define([ this._clippingPlanes = undefined; this.clippingPlanes = options.clippingPlanes; + /** + * Cesium adds lighting from the earth, sky, atmosphere, and star skybox. This number is used to scale the final + * lighting contribution from those sources to the final color. A value of 0.0 will disable those light sources. + * + * @type {Number} + * @default 1.0 + */ + this.iblFactor = defaultValue(options.iblFactor, 1.0); + + /** + * The color and intensity of the sunlight used to shade a model. + *

+ * For example, disabling additional light sources by setting model.iblFactor = 0.0 will make the + * model much darker. Here, increasing the intensity of the light source will make the model brighter. + *

+ * + * @type {Color} + * @default undefined + */ + this.lightColor = options.lightColor; + /** * This property is for debugging only; it is not optimized for production use. *

diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index 96a8711e1559..ba14d15ca9cc 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -272,6 +272,8 @@ define([ gltfView = new Uint8Array(uint8Array.subarray(byteOffset, byteOffset + gltfByteLength)); } + var tileset = content._tileset; + // Create model instance collection var collectionOptions = { instances : new Array(instancesLength), @@ -282,10 +284,12 @@ define([ gltf : undefined, basePath : undefined, incrementallyLoadTextures : false, - upAxis : content._tileset._gltfUpAxis, + upAxis : tileset._gltfUpAxis, forwardAxis : Axis.X, opaquePass : Pass.CESIUM_3D_TILE, // Draw opaque portions during the 3D Tiles pass - pickIdLoaded : getPickIdCallback(content) + pickIdLoaded : getPickIdCallback(content), + iblFactor : tileset.iblFactor, + lightColor : tileset.lightColor }; if (gltfFormat === 0) { diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 44494d4e3c82..e35935447dea 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -289,6 +289,8 @@ define([ * @param {Number} [options.silhouetteSize=0.0] The size of the silhouette in pixels. * @param {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the model. * @param {Boolean} [options.dequantizeInShader=true] Determines if a {@link https://github.com/google/draco|Draco} encoded model is dequantized on the GPU. This decreases total memory usage for encoded models. + * @param {Number} [options.iblFactor=1.0] Scales the IBL lighting from the earth, sky, atmosphere and star skybox. + * @param {Color} [options.lightColor] The color and intensity of the sunlight used to shade the model. * * @exception {DeveloperError} bgltf is not a valid Binary glTF file. * @exception {DeveloperError} Only glTF Binary version 1 is supported. @@ -661,8 +663,8 @@ define([ this._rtcCenter3D = undefined; // in world coordinates this._rtcCenter2D = undefined; // in projected world coordinates - this._iblFactor = 1.0; - this._lightColor = undefined; + this._iblFactor = defaultValue(options.iblFactor, 1.0); + this._lightColor = Color.clone(options.lightColor); this._regenerateShaders = false; } @@ -1080,6 +1082,15 @@ define([ } }, + /** + * Cesium adds lighting from the earth, sky, atmosphere, and star skybox. This number is used to scale the final + * lighting contribution from those sources to the final color. A value of 0.0 will disable those light sources. + * + * @memberof Model.prototype + * + * @type {Number} + * @default 1.0 + */ iblFactor : { get : function() { return this._iblFactor; @@ -1090,13 +1101,29 @@ define([ } }, + /** + * The color and intensity of the sunlight used to shade the model. + *

+ * For example, disabling additional light sources by setting model.iblFactor = 0.0 will make the + * model much darker. Here, increasing the intensity of the light source will make the model brighter. + *

+ * + * @memberof Model.prototype + * + * @type {Color} + * @default undefined + */ lightColor : { get : function() { return this._lightColor; }, set : function(value) { - this._regenerateShaders = this._regenerateShaders || (defined(this._lightColor) && !defined(value)) || (defined(value) && !defined(this._lightColor)); - this._lightColor = Color.clone(value, this._lightColor); + var lightColor = this._lightColor; + if (value === lightColor || Color.equals(value, lightColor)) { + return; + } + this._regenerateShaders = this._regenerateShaders || (defined(lightColor) && !defined(value)) || (defined(value) && !defined(lightColor)); + this._lightColor = Color.clone(value, lightColor); } } }); diff --git a/Source/Scene/ModelInstanceCollection.js b/Source/Scene/ModelInstanceCollection.js index d79691f689bb..db4f3c5825d6 100644 --- a/Source/Scene/ModelInstanceCollection.js +++ b/Source/Scene/ModelInstanceCollection.js @@ -164,6 +164,9 @@ define([ this.debugWireframe = defaultValue(options.debugWireframe, false); this._debugWireframe = false; + + this.iblFactor = defaultValue(options.iblFactor, 1.0); + this.lightColor = options.lightColor; } defineProperties(ModelInstanceCollection.prototype, { @@ -577,7 +580,9 @@ define([ uniformMapLoaded : undefined, pickIdLoaded : collection._pickIdLoaded, ignoreCommands : true, - opaquePass : collection._opaquePass + opaquePass : collection._opaquePass, + iblFactor : collection.iblFactor, + lightColor : collection.lightColor }; if (!usesBatchTable) { @@ -871,6 +876,9 @@ define([ var instancingSupported = this._instancingSupported; var model = this._model; + model.iblFactor = this.iblFactor; + model.lightColor = this.lightColor; + model.update(frameState); if (model.ready && (this._state === LoadState.LOADING)) { From 0b2029c520fc1e34ec163a9cb43924c8b3bd4ce2 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 9 Oct 2018 06:03:44 -0400 Subject: [PATCH 03/10] Fix after merge. --- Source/Scene/processPbrMaterials.js | 63 ++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/Source/Scene/processPbrMaterials.js b/Source/Scene/processPbrMaterials.js index 931a944c3cb9..b0331b21fa0b 100644 --- a/Source/Scene/processPbrMaterials.js +++ b/Source/Scene/processPbrMaterials.js @@ -425,33 +425,39 @@ define([ if (hasNormals) { fragmentShader += 'const float M_PI = 3.141592653589793;\n'; - fragmentShader += 'vec3 lambertianDiffuse(vec3 diffuseColor) \n' + + fragmentShader += + 'vec3 lambertianDiffuse(vec3 diffuseColor) \n' + '{\n' + ' return diffuseColor / M_PI;\n' + '}\n\n'; - fragmentShader += 'vec3 fresnelSchlick2(vec3 f0, vec3 f90, float VdotH) \n' + + fragmentShader += + 'vec3 fresnelSchlick2(vec3 f0, vec3 f90, float VdotH) \n' + '{\n' + ' return f0 + (f90 - f0) * pow(clamp(1.0 - VdotH, 0.0, 1.0), 5.0);\n' + '}\n\n'; - fragmentShader += 'vec3 fresnelSchlick(float metalness, float VdotH) \n' + + fragmentShader += + 'vec3 fresnelSchlick(float metalness, float VdotH) \n' + '{\n' + ' return metalness + (vec3(1.0) - metalness) * pow(1.0 - VdotH, 5.0);\n' + '}\n\n'; - fragmentShader += 'float smithVisibilityG1(float NdotV, float roughness) \n' + + fragmentShader += + 'float smithVisibilityG1(float NdotV, float roughness) \n' + '{\n' + ' float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;\n' + ' return NdotV / (NdotV * (1.0 - k) + k);\n' + '}\n\n'; - fragmentShader += 'float smithVisibilityGGX(float roughness, float NdotL, float NdotV) \n' + + fragmentShader += + 'float smithVisibilityGGX(float roughness, float NdotL, float NdotV) \n' + '{\n' + ' return smithVisibilityG1(NdotL, roughness) * smithVisibilityG1(NdotV, roughness);\n' + '}\n\n'; - fragmentShader += 'float GGX(float roughness, float NdotH) \n' + + fragmentShader += + 'float GGX(float roughness, float NdotH) \n' + '{\n' + ' float roughnessSquared = roughness * roughness;\n' + ' float f = (NdotH * roughnessSquared - NdotH) * NdotH + 1.0;\n' + @@ -459,22 +465,32 @@ define([ '}\n\n'; } - fragmentShader += 'vec3 SRGBtoLINEAR3(vec3 srgbIn) \n' + + fragmentShader += + 'vec3 SRGBtoLINEAR3(vec3 srgbIn) \n' + '{\n' + ' return pow(srgbIn, vec3(2.2));\n' + '}\n\n'; - fragmentShader += 'vec4 SRGBtoLINEAR4(vec4 srgbIn) \n' + + fragmentShader += + 'vec4 SRGBtoLINEAR4(vec4 srgbIn) \n' + '{\n' + ' vec3 linearOut = pow(srgbIn.rgb, vec3(2.2));\n' + ' return vec4(linearOut, srgbIn.a);\n' + '}\n\n'; - fragmentShader += 'vec3 LINEARtoSRGB(vec3 linearIn) \n' + + fragmentShader += + 'vec3 LINEARtoSRGB(vec3 linearIn) \n' + '{\n' + ' return pow(linearIn, vec3(1.0/2.2));\n' + '}\n\n'; + fragmentShader += '#ifdef USE_IBL_LIGHTING \n'; + fragmentShader += 'uniform float gltf_iblFactor; \n'; + fragmentShader += '#endif \n'; + fragmentShader += '#ifdef USE_CUSTOM_LIGHT_COLOR \n'; + fragmentShader += 'uniform vec3 gltf_lightColor; \n'; + fragmentShader += '#endif \n'; + fragmentShader += 'void main(void) \n{\n'; // Add normal mapping to fragment shader @@ -600,19 +616,13 @@ define([ // Generate fragment shader's lighting block // The Sun is brighter than your average light source, and has a yellowish tint balanced by the Earth's ambient blue. + fragmentShader += '#ifndef USE_CUSTOM_LIGHT_COLOR \n'; fragmentShader += ' vec3 lightColor = vec3(1.5, 1.4, 1.2);\n'; + fragmentShader += '#else \n'; + fragmentShader += ' vec3 lightColor = gltf_lightColor;\n'; + fragmentShader += '#endif \n'; fragmentShader += ' vec3 l = normalize(czm_sunDirectionEC);\n'; fragmentShader += ' vec3 h = normalize(v + l);\n'; - fragmentShader += ' vec3 r = normalize(czm_inverseViewRotation * normalize(reflect(v, n)));\n'; - // Figure out if the reflection vector hits the ellipsoid - fragmentShader += ' czm_ellipsoid ellipsoid = czm_getWgs84EllipsoidEC();\n'; - fragmentShader += ' float vertexRadius = length(v_positionWC);\n'; - fragmentShader += ' float horizonDotNadir = 1.0 - min(1.0, ellipsoid.radii.x / vertexRadius);\n'; - fragmentShader += ' float reflectionDotNadir = dot(r, normalize(v_positionWC));\n'; - // Flipping the X vector is a cheap way to get the inverse of czm_temeToPseudoFixed, since that's a rotation about Z. - fragmentShader += ' r.x = -r.x;\n'; - fragmentShader += ' r = -normalize(czm_temeToPseudoFixed * r);\n'; - fragmentShader += ' r.x = -r.x;\n'; fragmentShader += ' float NdotL = clamp(dot(n, l), 0.001, 1.0);\n'; fragmentShader += ' float NdotV = abs(dot(n, v)) + 0.001;\n'; fragmentShader += ' float NdotH = clamp(dot(n, h), 0.0, 1.0);\n'; @@ -643,6 +653,18 @@ define([ fragmentShader += ' vec3 specularContribution = F * G * D / (4.0 * NdotL * NdotV);\n'; fragmentShader += ' vec3 color = NdotL * lightColor * (diffuseContribution + specularContribution);\n'; + fragmentShader += '#ifdef USE_IBL_LIGHTING \n'; + // Figure out if the reflection vector hits the ellipsoid + fragmentShader += ' vec3 r = normalize(czm_inverseViewRotation * normalize(reflect(v, n)));\n'; + fragmentShader += ' czm_ellipsoid ellipsoid = czm_getWgs84EllipsoidEC();\n'; + fragmentShader += ' float vertexRadius = length(v_positionWC);\n'; + fragmentShader += ' float horizonDotNadir = 1.0 - min(1.0, ellipsoid.radii.x / vertexRadius);\n'; + fragmentShader += ' float reflectionDotNadir = dot(r, normalize(v_positionWC));\n'; + // Flipping the X vector is a cheap way to get the inverse of czm_temeToPseudoFixed, since that's a rotation about Z. + fragmentShader += ' r.x = -r.x;\n'; + fragmentShader += ' r = -normalize(czm_temeToPseudoFixed * r);\n'; + fragmentShader += ' r.x = -r.x;\n'; + fragmentShader += ' float inverseRoughness = 1.04 - roughness;\n'; fragmentShader += ' inverseRoughness *= inverseRoughness;\n'; fragmentShader += ' vec3 sceneSkyBox = textureCube(czm_environmentMap, r).rgb * inverseRoughness;\n'; @@ -673,7 +695,8 @@ define([ fragmentShader += ' vec2 brdfLut = texture2D(czm_brdfLut, vec2(NdotV, 1.0 - roughness)).rg;\n'; fragmentShader += ' vec3 IBLColor = (diffuseIrradiance * diffuseColor) + (specularIrradiance * SRGBtoLINEAR3(specularColor * brdfLut.x + brdfLut.y));\n'; - fragmentShader += ' color += IBLColor;\n'; + fragmentShader += ' color += IBLColor * gltf_iblFactor;\n'; + fragmentShader += '#endif \n'; } else { fragmentShader += ' vec3 color = baseColor;\n'; } From c73dbc8805d6cc6425d9517d521fbb3b3c71eb39 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 9 Oct 2018 15:52:58 -0400 Subject: [PATCH 04/10] Rename to imageBasedLightingFactor and it is now a vec2 which scales the diffuse and specular separately. --- Source/Scene/Batched3DModel3DTileContent.js | 4 +- Source/Scene/Cesium3DTileset.js | 37 ++++++++++++----- Source/Scene/Instanced3DModel3DTileContent.js | 2 +- Source/Scene/Model.js | 41 ++++++++++++------- Source/Scene/ModelInstanceCollection.js | 26 ++++++++++-- Source/Scene/processPbrMaterials.js | 6 +-- 6 files changed, 83 insertions(+), 33 deletions(-) diff --git a/Source/Scene/Batched3DModel3DTileContent.js b/Source/Scene/Batched3DModel3DTileContent.js index 382cd2f03251..e06408b62857 100644 --- a/Source/Scene/Batched3DModel3DTileContent.js +++ b/Source/Scene/Batched3DModel3DTileContent.js @@ -385,7 +385,7 @@ define([ pickIdLoaded : getPickIdCallback(content), addBatchIdToGeneratedShaders : (batchLength > 0), // If the batch table has values in it, generated shaders will need a batchId attribute pickObject : pickObject, - iblFactor : tileset.iblFactor, + imageBasedLightingFactor : tileset.imageBasedLightingFactor, lightColor : tileset.lightColor }); } else { @@ -462,7 +462,7 @@ define([ this._model.modelMatrix = this._contentModelMatrix; this._model.shadows = this._tileset.shadows; - this._model.iblFactor = this._tileset.iblFactor; + this._model.imageBasedLightingFactor = this._tileset.imageBasedLightingFactor; this._model.lightColor = this._tileset.lightColor; this._model.debugWireframe = this._tileset.debugWireframe; diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index 1f3e7f715070..83681687e324 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -115,7 +115,7 @@ define([ * @param {ClassificationType} [options.classificationType] Determines whether terrain, 3D Tiles or both will be classified by this tileset. See {@link Cesium3DTileset#classificationType} for details about restrictions and limitations. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid determining the size and shape of the globe. * @param {Object} [options.pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation based on geometric error and lighting. - * @param {Number} [options.iblFactor=1.0] Scales the IBL lighting from the earth, sky, atmosphere and star skybox. + * @param {Cartesian2} [options.imageBasedLightingFactor=new Cartesian2(1.0, 1.0)] Scales the diffuse and specular image-based lighting from the earth, sky, atmosphere and star skybox. * @param {Color} [options.lightColor] The color and intensity of the sunlight used to shade models. * @param {Boolean} [options.debugFreezeFrame=false] For debugging only. Determines if only the tiles from last frame should be used for rendering. * @param {Boolean} [options.debugColorizeTiles=false] For debugging only. When true, assigns a random color to each tile. @@ -571,19 +571,13 @@ define([ this._clippingPlanes = undefined; this.clippingPlanes = options.clippingPlanes; - /** - * Cesium adds lighting from the earth, sky, atmosphere, and star skybox. This number is used to scale the final - * lighting contribution from those sources to the final color. A value of 0.0 will disable those light sources. - * - * @type {Number} - * @default 1.0 - */ - this.iblFactor = defaultValue(options.iblFactor, 1.0); + this._imageBasedLightingFactor = new Cartesian2(1.0, 1.0); + Cartesian2.clone(options.imageBasedLightingFactor, this._imageBasedLightingFactor); /** * The color and intensity of the sunlight used to shade a model. *

- * For example, disabling additional light sources by setting model.iblFactor = 0.0 will make the + * For example, disabling additional light sources by setting model.imageBasedLightingFactor = new Cartesian2(0.0, 0.0) will make the * model much darker. Here, increasing the intensity of the light source will make the model brighter. *

* @@ -1259,6 +1253,29 @@ define([ return this._extras; } + }, + + /** + * Cesium adds lighting from the earth, sky, atmosphere, and star skybox. This cartesian is used to scale the final + * diffuse and specular lighting contribution from those sources to the final color. A value of 0.0 will disable those light sources. + * + * @type {Cartesian2} + * @default Cartesian2(1.0, 1.0) + */ + imageBasedLightingFactor : { + get : function() { + return this._imageBasedLightingFactor; + }, + set : function(value) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object('imageBasedLightingFactor', value); + Check.typeOf.number.greaterThanOrEquals('imageBasedLightingFactor.x', value.x, 0.0); + Check.typeOf.number.lessThanOrEquals('imageBasedLightingFactor.x', value.x, 1.0); + Check.typeOf.number.greaterThanOrEquals('imageBasedLightingFactor.y', value.y, 0.0); + Check.typeOf.number.lessThanOrEquals('imageBasedLightingFactor.y', value.y, 1.0); + //>>includeEnd('debug'); + Cartesian2.clone(value, this._imageBasedLightingFactor); + } } }); diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index 075d9bf8d99d..c3d1a3d9aaee 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -288,7 +288,7 @@ define([ forwardAxis : Axis.X, opaquePass : Pass.CESIUM_3D_TILE, // Draw opaque portions during the 3D Tiles pass pickIdLoaded : getPickIdCallback(content), - iblFactor : tileset.iblFactor, + imageBasedLightingFactor : tileset.imageBasedLightingFactor, lightColor : tileset.lightColor }; diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index f3d531d1f117..b5417413a5a1 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -1,8 +1,10 @@ define([ '../Core/BoundingSphere', + '../Core/Cartesian2', '../Core/Cartesian3', '../Core/Cartesian4', '../Core/Cartographic', + '../Core/Check', '../Core/clone', '../Core/Color', '../Core/combine', @@ -74,9 +76,11 @@ define([ './ShadowMode' ], function( BoundingSphere, + Cartesian2, Cartesian3, Cartesian4, Cartographic, + Check, clone, Color, combine, @@ -282,7 +286,7 @@ define([ * @param {Number} [options.silhouetteSize=0.0] The size of the silhouette in pixels. * @param {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the model. * @param {Boolean} [options.dequantizeInShader=true] Determines if a {@link https://github.com/google/draco|Draco} encoded model is dequantized on the GPU. This decreases total memory usage for encoded models. - * @param {Number} [options.iblFactor=1.0] Scales the IBL lighting from the earth, sky, atmosphere and star skybox. + * @param {Number} [options.imageBasedLightingFactor=1.0] Scales the IBL lighting from the earth, sky, atmosphere and star skybox. * @param {Color} [options.lightColor] The color and intensity of the sunlight used to shade the model. * * @see Model.fromGltf @@ -659,7 +663,8 @@ define([ this._keepPipelineExtras = options.keepPipelineExtras; // keep the buffers in memory for use in other applications - this._iblFactor = defaultValue(options.iblFactor, 1.0); + this._imageBasedLightingFactor = new Cartesian2(1.0, 1.0); + Cartesian2.clone(options.imageBasedLightingFactor, this._imageBasedLightingFactor); this._lightColor = Color.clone(options.lightColor); this._regenerateShaders = false; } @@ -1082,28 +1087,36 @@ define([ }, /** - * Cesium adds lighting from the earth, sky, atmosphere, and star skybox. This number is used to scale the final - * lighting contribution from those sources to the final color. A value of 0.0 will disable those light sources. + * Cesium adds lighting from the earth, sky, atmosphere, and star skybox. This cartesian is used to scale the final + * diffuse and specular lighting contribution from those sources to the final color. A value of 0.0 will disable those light sources. * * @memberof Model.prototype * - * @type {Number} - * @default 1.0 + * @type {Cartesian2} + * @default Cartesian2(1.0, 1.0) */ - iblFactor : { + imageBasedLightingFactor : { get : function() { - return this._iblFactor; + return this._imageBasedLightingFactor; }, set : function(value) { - this._regenerateShaders = this._regenerateShaders || (this._iblFactor > 0.0 && value === 0.0) || (this._iblFactor === 0.0 && value > 0.0); - this._iblFactor = value; + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object('imageBasedLightingFactor', value); + Check.typeOf.number.greaterThanOrEquals('imageBasedLightingFactor.x', value.x, 0.0); + Check.typeOf.number.lessThanOrEquals('imageBasedLightingFactor.x', value.x, 1.0); + Check.typeOf.number.greaterThanOrEquals('imageBasedLightingFactor.y', value.y, 0.0); + Check.typeOf.number.lessThanOrEquals('imageBasedLightingFactor.y', value.y, 1.0); + //>>includeEnd('debug'); + this._regenerateShaders = this._regenerateShaders || (this._imageBasedLightingFactor.x > 0.0 && value.x === 0.0) || (this._imageBasedLightingFactor.x === 0.0 && value.x > 0.0); + this._regenerateShaders = this._regenerateShaders || (this._imageBasedLightingFactor.y > 0.0 && value.y === 0.0) || (this._imageBasedLightingFactor.y === 0.0 && value.y > 0.0); + Cartesian2.clone(value, this._imageBasedLightingFactor); } }, /** * The color and intensity of the sunlight used to shade the model. *

- * For example, disabling additional light sources by setting model.iblFactor = 0.0 will make the + * For example, disabling additional light sources by setting model.imageBasedLightingFactor = 0.0 will make the * model much darker. Here, increasing the intensity of the light source will make the model brighter. *

* @@ -1987,7 +2000,7 @@ define([ drawFS = 'uniform vec4 czm_pickColor;\n' + drawFS; } - if (model._iblFactor > 0.0) { + if (model._imageBasedLightingFactor.x > 0.0 || model._imageBasedLightingFactor.y > 0.0) { drawFS = '#define USE_IBL_LIGHTING \n\n' + drawFS; } @@ -2037,7 +2050,7 @@ define([ drawFS = 'uniform vec4 czm_pickColor;\n' + drawFS; } - if (model._iblFactor > 0.0) { + if (model._imageBasedLightingFactor.x > 0.0 || model._imageBasedLightingFactor.y > 0.0) { drawFS = '#define USE_IBL_LIGHTING \n\n' + drawFS; } @@ -2915,7 +2928,7 @@ define([ function createIBLFactorFunction(model) { return function() { - return model._iblFactor; + return model._imageBasedLightingFactor; }; } diff --git a/Source/Scene/ModelInstanceCollection.js b/Source/Scene/ModelInstanceCollection.js index bfc4603c85ab..93e895274cb0 100644 --- a/Source/Scene/ModelInstanceCollection.js +++ b/Source/Scene/ModelInstanceCollection.js @@ -1,6 +1,8 @@ define([ '../Core/BoundingSphere', + '../Core/Cartesian2', '../Core/Cartesian3', + '../Core/Check', '../Core/clone', '../Core/Color', '../Core/ComponentDatatype', @@ -28,7 +30,9 @@ define([ './ShadowMode' ], function( BoundingSphere, + Cartesian2, Cartesian3, + Check, clone, Color, ComponentDatatype, @@ -167,7 +171,8 @@ define([ this.debugWireframe = defaultValue(options.debugWireframe, false); this._debugWireframe = false; - this.iblFactor = defaultValue(options.iblFactor, 1.0); + this._imageBasedLightingFactor = new Cartesian2(1.0, 1.0); + Cartesian2.clone(options.imageBasedLightingFactor, this._imageBasedLightingFactor); this.lightColor = options.lightColor; } @@ -196,6 +201,21 @@ define([ get : function() { return this._readyPromise.promise; } + }, + imageBasedLightingFactor : { + get : function() { + return this._imageBasedLightingFactor; + }, + set : function(value) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object('imageBasedLightingFactor', value); + Check.typeOf.number.greaterThanOrEquals('imageBasedLightingFactor.x', value.x, 0.0); + Check.typeOf.number.lessThanOrEquals('imageBasedLightingFactor.x', value.x, 1.0); + Check.typeOf.number.greaterThanOrEquals('imageBasedLightingFactor.y', value.y, 0.0); + Check.typeOf.number.lessThanOrEquals('imageBasedLightingFactor.y', value.y, 1.0); + //>>includeEnd('debug'); + Cartesian2.clone(value, this._imageBasedLightingFactor); + } } }); @@ -580,7 +600,7 @@ define([ pickIdLoaded : collection._pickIdLoaded, ignoreCommands : true, opaquePass : collection._opaquePass, - iblFactor : collection.iblFactor, + imageBasedLightingFactor : collection.imageBasedLightingFactor, lightColor : collection.lightColor }; @@ -875,7 +895,7 @@ define([ var instancingSupported = this._instancingSupported; var model = this._model; - model.iblFactor = this.iblFactor; + model.imageBasedLightingFactor = this.imageBasedLightingFactor; model.lightColor = this.lightColor; model.update(frameState); diff --git a/Source/Scene/processPbrMaterials.js b/Source/Scene/processPbrMaterials.js index b0331b21fa0b..920b22b7d617 100644 --- a/Source/Scene/processPbrMaterials.js +++ b/Source/Scene/processPbrMaterials.js @@ -485,7 +485,7 @@ define([ '}\n\n'; fragmentShader += '#ifdef USE_IBL_LIGHTING \n'; - fragmentShader += 'uniform float gltf_iblFactor; \n'; + fragmentShader += 'uniform vec2 gltf_iblFactor; \n'; fragmentShader += '#endif \n'; fragmentShader += '#ifdef USE_CUSTOM_LIGHT_COLOR \n'; fragmentShader += 'uniform vec3 gltf_lightColor; \n'; @@ -694,8 +694,8 @@ define([ fragmentShader += ' specularIrradiance = mix(specularIrradiance, nadirColor, smoothstep(farBelowHorizon, 1.0, reflectionDotNadir) * inverseRoughness);\n'; fragmentShader += ' vec2 brdfLut = texture2D(czm_brdfLut, vec2(NdotV, 1.0 - roughness)).rg;\n'; - fragmentShader += ' vec3 IBLColor = (diffuseIrradiance * diffuseColor) + (specularIrradiance * SRGBtoLINEAR3(specularColor * brdfLut.x + brdfLut.y));\n'; - fragmentShader += ' color += IBLColor * gltf_iblFactor;\n'; + fragmentShader += ' vec3 IBLColor = (diffuseIrradiance * diffuseColor * gltf_iblFactor.x) + (specularIrradiance * SRGBtoLINEAR3(specularColor * brdfLut.x + brdfLut.y) * gltf_iblFactor.y);\n'; + fragmentShader += ' color += IBLColor;\n'; fragmentShader += '#endif \n'; } else { fragmentShader += ' vec3 color = baseColor;\n'; From 7c0f5bcbcc74f6f295e7d2df95c4bdd0da5534c8 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 9 Oct 2018 16:16:57 -0400 Subject: [PATCH 05/10] Add ibl factor to model entities. --- Source/DataSources/ModelGraphics.js | 14 +++++++++++++- Source/DataSources/ModelVisualizer.js | 4 ++++ Source/Scene/Model.js | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Source/DataSources/ModelGraphics.js b/Source/DataSources/ModelGraphics.js index 1b6c77f82b32..c42a061e4a2e 100644 --- a/Source/DataSources/ModelGraphics.js +++ b/Source/DataSources/ModelGraphics.js @@ -56,6 +56,7 @@ define([ * @param {Property} [options.colorBlendMode=ColorBlendMode.HIGHLIGHT] An enum Property specifying how the color blends with the model. * @param {Property} [options.colorBlendAmount=0.5] A numeric Property specifying the color strength when the colorBlendMode is MIX. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two. * @param {Property} [options.clippingPlanes] A property specifying the {@link ClippingPlaneCollection} used to selectively disable rendering the model. + * @param {Property} [options.imageBasedLightingFactor=new Cartesian2(1.0, 1.0)] A property specifying the contribution from diffuse and specular image-based lighting. * * @see {@link https://cesiumjs.org/tutorials/3D-Models-Tutorial/|3D Models Tutorial} * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=3D%20Models.html|Cesium Sandcastle 3D Models Demo} @@ -96,6 +97,8 @@ define([ this._colorBlendAmountSubscription = undefined; this._clippingPlanes = undefined; this._clippingPlanesSubscription = undefined; + this._imageBasedLightingFactor = undefined; + this._imageBasedLightingFactorSubscription = undefined; this._definitionChanged = new Event(); this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); @@ -262,7 +265,14 @@ define([ * @memberof ModelGraphics.prototype * @type {Property} */ - clippingPlanes : createPropertyDescriptor('clippingPlanes') + clippingPlanes : createPropertyDescriptor('clippingPlanes'), + + /** + * A property specifying the {@link Cartesian2} used to scale the diffuse and specular image-based lighting contribution to the final color. + * @memberof ModelGraphics.prototype + * @type {Property} + */ + imageBasedLightingFactor : createPropertyDescriptor('imageBasedLightingFactor') }); /** @@ -293,6 +303,7 @@ define([ result.colorBlendMode = this.colorBlendMode; result.colorBlendAmount = this.colorBlendAmount; result.clippingPlanes = this.clippingPlanes; + result.imageBasedLightingFactor = this.imageBasedLightingFactor; return result; }; @@ -327,6 +338,7 @@ define([ this.colorBlendMode = defaultValue(this.colorBlendMode, source.colorBlendMode); this.colorBlendAmount = defaultValue(this.colorBlendAmount, source.colorBlendAmount); this.clippingPlanes = defaultValue(this.clippingPlanes, source.clippingPlanes); + this.imageBasedLightingFactor = defaultValue(this.imageBasedLightingFactor, source.imageBasedLightingFactor); var sourceNodeTransformations = source.nodeTransformations; if (defined(sourceNodeTransformations)) { diff --git a/Source/DataSources/ModelVisualizer.js b/Source/DataSources/ModelVisualizer.js index 37954219c7a2..7079889591b4 100644 --- a/Source/DataSources/ModelVisualizer.js +++ b/Source/DataSources/ModelVisualizer.js @@ -1,6 +1,7 @@ define([ '../Core/AssociativeArray', '../Core/BoundingSphere', + '../Core/Cartesian2', '../Core/Color', '../Core/defined', '../Core/destroyObject', @@ -17,6 +18,7 @@ define([ ], function( AssociativeArray, BoundingSphere, + Cartesian2, Color, defined, destroyObject, @@ -43,6 +45,7 @@ define([ var defaultColor = Color.WHITE; var defaultColorBlendMode = ColorBlendMode.HIGHLIGHT; var defaultColorBlendAmount = 0.5; + var defaultImageBasedLightingFactor = new Cartesian2(1.0, 1.0); var modelMatrixScratch = new Matrix4(); var nodeMatrixScratch = new Matrix4(); @@ -157,6 +160,7 @@ define([ model.colorBlendAmount = Property.getValueOrDefault(modelGraphics._colorBlendAmount, time, defaultColorBlendAmount); model.clippingPlanes = Property.getValueOrUndefined(modelGraphics._clippingPlanes, time); model.clampAnimations = Property.getValueOrDefault(modelGraphics._clampAnimations, time, defaultClampAnimations); + model.imageBasedLightingFactor = Property.getValueOrDefault(modelGraphics._imageBasedLightingFactor, time, defaultImageBasedLightingFactor); if (model.ready) { var runAnimations = Property.getValueOrDefault(modelGraphics._runAnimations, time, true); diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index b5417413a5a1..d186d2c45992 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -4461,7 +4461,7 @@ define([ destroyIfNotCached(rendererResources, cachedRendererResources); var programId; - if (isClippingEnabled(model) || isColorShadingEnabled(model)) { + if (isClippingEnabled(model) || isColorShadingEnabled(model) || model._regenerateShaders) { rendererResources.programs = {}; rendererResources.silhouettePrograms = {}; From 9e17dc6e10c39810fceea93c77b9699f40ff2265 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 9 Oct 2018 16:30:57 -0400 Subject: [PATCH 06/10] Update tests. --- Specs/DataSources/ModelGraphicsSpec.js | 13 +++++++++++++ Specs/DataSources/ModelVisualizerSpec.js | 5 +++++ 2 files changed, 18 insertions(+) diff --git a/Specs/DataSources/ModelGraphicsSpec.js b/Specs/DataSources/ModelGraphicsSpec.js index f7d49e004a70..37ec8f787ff1 100644 --- a/Specs/DataSources/ModelGraphicsSpec.js +++ b/Specs/DataSources/ModelGraphicsSpec.js @@ -1,5 +1,6 @@ defineSuite([ 'DataSources/ModelGraphics', + 'Core/Cartesian2', 'Core/Cartesian3', 'Core/Color', 'Core/DistanceDisplayCondition', @@ -14,6 +15,7 @@ defineSuite([ 'Scene/ShadowMode' ], function( ModelGraphics, + Cartesian2, Cartesian3, Color, DistanceDisplayCondition, @@ -47,6 +49,7 @@ defineSuite([ colorBlendMode : ColorBlendMode.HIGHLIGHT, colorBlendAmount : 0.5, clippingPlanes : new ClippingPlaneCollection(), + imageBasedLightingFactor : new Cartesian2(0.5, 0.5), nodeTransformations : { node1 : { translation : Cartesian3.UNIT_Y, @@ -72,6 +75,7 @@ defineSuite([ expect(model.colorBlendMode).toBeInstanceOf(ConstantProperty); expect(model.colorBlendAmount).toBeInstanceOf(ConstantProperty); expect(model.clippingPlanes).toBeInstanceOf(ConstantProperty); + expect(model.imageBasedLightingFactor).toBeInstanceOf(ConstantProperty); expect(model.runAnimations).toBeInstanceOf(ConstantProperty); expect(model.clampAnimations).toBeInstanceOf(ConstantProperty); @@ -92,6 +96,7 @@ defineSuite([ expect(model.colorBlendMode.getValue()).toEqual(options.colorBlendMode); expect(model.colorBlendAmount.getValue()).toEqual(options.colorBlendAmount); expect(model.clippingPlanes.getValue().planes).toEqual(options.clippingPlanes.planes); + expect(model.imageBasedLightingFactor.getValue()).toEqual(options.imageBasedLightingFactor); expect(model.runAnimations.getValue()).toEqual(options.runAnimations); expect(model.clampAnimations.getValue()).toEqual(options.clampAnimations); @@ -121,6 +126,7 @@ defineSuite([ source.colorBlendMode = new ConstantProperty(ColorBlendMode.HIGHLIGHT); source.colorBlendAmount = new ConstantProperty(0.5); source.clippingPlanes = new ConstantProperty(new ClippingPlaneCollection()); + source.imageBasedLightingFactor = new ConstantProperty(new Cartesian2(0.5, 0.5)); source.runAnimations = new ConstantProperty(true); source.clampAnimations = new ConstantProperty(true); source.nodeTransformations = { @@ -152,6 +158,7 @@ defineSuite([ expect(target.colorBlendMode).toBe(source.colorBlendMode); expect(target.colorBlendAmount).toBe(source.colorBlendAmount); expect(target.clippingPlanes).toBe(source.clippingPlanes); + expect(target.imageBasedLightingFactor).toBe(source.imageBasedLightingFactor); expect(target.runAnimations).toBe(source.runAnimations); expect(target.clampAnimations).toBe(source.clampAnimations); expect(target.nodeTransformations).toEqual(source.nodeTransformations); @@ -174,6 +181,7 @@ defineSuite([ source.colorBlendMode = new ConstantProperty(ColorBlendMode.HIGHLIGHT); source.colorBlendAmount = new ConstantProperty(0.5); source.clippingPlanes = new ConstantProperty(new ClippingPlaneCollection()); + source.imageBasedLightingFactor = new ConstantProperty(new Cartesian2(0.5, 0.5)); source.runAnimations = new ConstantProperty(true); source.clampAnimations = new ConstantProperty(true); source.nodeTransformations = { @@ -195,6 +203,7 @@ defineSuite([ var colorBlendMode = new ConstantProperty(ColorBlendMode.HIGHLIGHT); var colorBlendAmount = new ConstantProperty(0.5); var clippingPlanes = new ConstantProperty(new ClippingPlaneCollection()); + var imageBasedLightingFactor = new ConstantProperty(new Cartesian2(0.5, 0.5)); var runAnimations = new ConstantProperty(true); var clampAnimations = new ConstantProperty(true); var nodeTransformations = new PropertyBag({ @@ -217,6 +226,7 @@ defineSuite([ target.colorBlendMode = colorBlendMode; target.colorBlendAmount = colorBlendAmount; target.clippingPlanes = clippingPlanes; + target.imageBasedLightingFactor = imageBasedLightingFactor; target.runAnimations = runAnimations; target.clampAnimations = clampAnimations; target.nodeTransformations = nodeTransformations; @@ -238,6 +248,7 @@ defineSuite([ expect(target.colorBlendMode).toBe(colorBlendMode); expect(target.colorBlendAmount).toBe(colorBlendAmount); expect(target.clippingPlanes).toBe(clippingPlanes); + expect(target.imageBasedLightingFactor).toBe(imageBasedLightingFactor); expect(target.runAnimations).toBe(runAnimations); expect(target.clampAnimations).toBe(clampAnimations); expect(target.nodeTransformations).toBe(nodeTransformations); @@ -260,6 +271,7 @@ defineSuite([ source.colorBlendMode = new ConstantProperty(ColorBlendMode.HIGHLIGHT); source.colorBlendAmount = new ConstantProperty(0.5); source.clippingPlanes = new ConstantProperty(new ClippingPlaneCollection()); + source.imageBasedLightingFactor = new ConstantProperty(new Cartesian2(0.5, 0.5)); source.runAnimations = new ConstantProperty(true); source.clampAnimations = new ConstantProperty(true); source.nodeTransformations = { @@ -283,6 +295,7 @@ defineSuite([ expect(result.colorBlendMode).toBe(source.colorBlendMode); expect(result.colorBlendAmount).toBe(source.colorBlendAmount); expect(result.clippingPlanes).toBe(source.clippingPlanes); + expect(result.imageBasedLightingFactor).toBe(source.imageBasedLightingFactor); expect(result.runAnimations).toBe(source.runAnimations); expect(result.clampAnimations).toBe(source.clampAnimations); expect(result.nodeTransformations).toEqual(source.nodeTransformations); diff --git a/Specs/DataSources/ModelVisualizerSpec.js b/Specs/DataSources/ModelVisualizerSpec.js index 97b049c998dc..2962135d4f7d 100644 --- a/Specs/DataSources/ModelVisualizerSpec.js +++ b/Specs/DataSources/ModelVisualizerSpec.js @@ -1,6 +1,7 @@ defineSuite([ 'DataSources/ModelVisualizer', 'Core/BoundingSphere', + 'Core/Cartesian2', 'Core/Cartesian3', 'Core/defined', 'Core/DistanceDisplayCondition', @@ -23,6 +24,7 @@ defineSuite([ ], function( ModelVisualizer, BoundingSphere, + Cartesian2, Cartesian3, defined, DistanceDisplayCondition, @@ -149,6 +151,8 @@ defineSuite([ }); model.clippingPlanes = new ConstantProperty(clippingPlanes); + model.imageBasedLightingFactor = new ConstantProperty(new Cartesian2(0.5, 0.5)); + var testObject = entityCollection.getOrCreateEntity('test'); testObject.position = new ConstantPositionProperty(Cartesian3.fromDegrees(1, 2, 3)); testObject.model = model; @@ -167,6 +171,7 @@ defineSuite([ expect(primitive.clippingPlanes._planes.length).toEqual(clippingPlanes._planes.length); expect(Cartesian3.equals(primitive.clippingPlanes._planes[0].normal, clippingPlanes._planes[0].normal)).toBe(true); expect(primitive.clippingPlanes._planes[0].distance).toEqual(clippingPlanes._planes[0].distance); + expect(primitive.imageBasedLightingFactor).toEqual(new Cartesian2(0.5, 0.5)); // wait till the model is loaded before we can check node transformations return pollToPromise(function() { From f90dc62275d70243ff4c6c3341648bc5db67cbbb Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 9 Oct 2018 17:47:53 -0400 Subject: [PATCH 07/10] Add light color to model entities and update CHANGES.md. --- CHANGES.md | 2 ++ Source/DataSources/ModelGraphics.js | 14 +++++++++++++- Source/DataSources/ModelVisualizer.js | 1 + Specs/DataSources/ModelGraphicsSpec.js | 11 +++++++++++ Specs/DataSources/ModelVisualizerSpec.js | 4 ++++ 5 files changed, 31 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 5390d63f48a4..08257b049f0a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,8 @@ Change Log ##### Additions :tada: * Added WMS-T (time) support in WebMapServiceImageryProvider [#2581](https://github.com/AnalyticalGraphicsInc/cesium/issues/2581) +* Added `imageBasedLightingFactor` property to `Cesium3DTileset`, `Model`, and `ModelGraphics` to scale the diffuse and specular image-based lighting contributions to the final color. [#7025](https://github.com/AnalyticalGraphicsInc/cesium/pull/7025) +* Added `lightColor` property to `Cesium3DTileset`, `Model`, and `ModelGraphics` to change the intensity of the light used when shading model. [#7025](https://github.com/AnalyticalGraphicsInc/cesium/pull/7025) ### 1.50 - 2018-10-01 diff --git a/Source/DataSources/ModelGraphics.js b/Source/DataSources/ModelGraphics.js index c42a061e4a2e..5953b7ecbe75 100644 --- a/Source/DataSources/ModelGraphics.js +++ b/Source/DataSources/ModelGraphics.js @@ -57,6 +57,7 @@ define([ * @param {Property} [options.colorBlendAmount=0.5] A numeric Property specifying the color strength when the colorBlendMode is MIX. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two. * @param {Property} [options.clippingPlanes] A property specifying the {@link ClippingPlaneCollection} used to selectively disable rendering the model. * @param {Property} [options.imageBasedLightingFactor=new Cartesian2(1.0, 1.0)] A property specifying the contribution from diffuse and specular image-based lighting. + * @param {Property} [options.lightColor] A property specifying the light color to use when shading the model. The default sun light color will be used when undefined. * * @see {@link https://cesiumjs.org/tutorials/3D-Models-Tutorial/|3D Models Tutorial} * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=3D%20Models.html|Cesium Sandcastle 3D Models Demo} @@ -99,6 +100,8 @@ define([ this._clippingPlanesSubscription = undefined; this._imageBasedLightingFactor = undefined; this._imageBasedLightingFactorSubscription = undefined; + this._lightColor = undefined; + this._lightColorSubscription = undefined; this._definitionChanged = new Event(); this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); @@ -272,7 +275,14 @@ define([ * @memberof ModelGraphics.prototype * @type {Property} */ - imageBasedLightingFactor : createPropertyDescriptor('imageBasedLightingFactor') + imageBasedLightingFactor : createPropertyDescriptor('imageBasedLightingFactor'), + + /** + * A property specifying the {@link Color} of the light source when shading the model. + * @memberOf ModelGraphics.prototype + * @type {Property} + */ + lightColor : createPropertyDescriptor('lightColor') }); /** @@ -304,6 +314,7 @@ define([ result.colorBlendAmount = this.colorBlendAmount; result.clippingPlanes = this.clippingPlanes; result.imageBasedLightingFactor = this.imageBasedLightingFactor; + result.lightColor = this.lightColor; return result; }; @@ -339,6 +350,7 @@ define([ this.colorBlendAmount = defaultValue(this.colorBlendAmount, source.colorBlendAmount); this.clippingPlanes = defaultValue(this.clippingPlanes, source.clippingPlanes); this.imageBasedLightingFactor = defaultValue(this.imageBasedLightingFactor, source.imageBasedLightingFactor); + this.lightColor = defaultValue(this.lightColor, source.lightColor); var sourceNodeTransformations = source.nodeTransformations; if (defined(sourceNodeTransformations)) { diff --git a/Source/DataSources/ModelVisualizer.js b/Source/DataSources/ModelVisualizer.js index 7079889591b4..3ce724f63523 100644 --- a/Source/DataSources/ModelVisualizer.js +++ b/Source/DataSources/ModelVisualizer.js @@ -161,6 +161,7 @@ define([ model.clippingPlanes = Property.getValueOrUndefined(modelGraphics._clippingPlanes, time); model.clampAnimations = Property.getValueOrDefault(modelGraphics._clampAnimations, time, defaultClampAnimations); model.imageBasedLightingFactor = Property.getValueOrDefault(modelGraphics._imageBasedLightingFactor, time, defaultImageBasedLightingFactor); + model.lightColor = Property.getValueOrUndefined(modelGraphics._lightColor, time); if (model.ready) { var runAnimations = Property.getValueOrDefault(modelGraphics._runAnimations, time, true); diff --git a/Specs/DataSources/ModelGraphicsSpec.js b/Specs/DataSources/ModelGraphicsSpec.js index 37ec8f787ff1..9d521fc14600 100644 --- a/Specs/DataSources/ModelGraphicsSpec.js +++ b/Specs/DataSources/ModelGraphicsSpec.js @@ -50,6 +50,7 @@ defineSuite([ colorBlendAmount : 0.5, clippingPlanes : new ClippingPlaneCollection(), imageBasedLightingFactor : new Cartesian2(0.5, 0.5), + lightColor : new Color(1.0, 1.0, 0.0, 1.0), nodeTransformations : { node1 : { translation : Cartesian3.UNIT_Y, @@ -76,6 +77,7 @@ defineSuite([ expect(model.colorBlendAmount).toBeInstanceOf(ConstantProperty); expect(model.clippingPlanes).toBeInstanceOf(ConstantProperty); expect(model.imageBasedLightingFactor).toBeInstanceOf(ConstantProperty); + expect(model.lightColor).toBeInstanceOf(ConstantProperty); expect(model.runAnimations).toBeInstanceOf(ConstantProperty); expect(model.clampAnimations).toBeInstanceOf(ConstantProperty); @@ -97,6 +99,7 @@ defineSuite([ expect(model.colorBlendAmount.getValue()).toEqual(options.colorBlendAmount); expect(model.clippingPlanes.getValue().planes).toEqual(options.clippingPlanes.planes); expect(model.imageBasedLightingFactor.getValue()).toEqual(options.imageBasedLightingFactor); + expect(model.lightColor.getValue()).toEqual(options.lightColor); expect(model.runAnimations.getValue()).toEqual(options.runAnimations); expect(model.clampAnimations.getValue()).toEqual(options.clampAnimations); @@ -127,6 +130,7 @@ defineSuite([ source.colorBlendAmount = new ConstantProperty(0.5); source.clippingPlanes = new ConstantProperty(new ClippingPlaneCollection()); source.imageBasedLightingFactor = new ConstantProperty(new Cartesian2(0.5, 0.5)); + source.lightColor = new ConstantProperty(new Color(1.0, 1.0, 0.0, 1.0)); source.runAnimations = new ConstantProperty(true); source.clampAnimations = new ConstantProperty(true); source.nodeTransformations = { @@ -159,6 +163,7 @@ defineSuite([ expect(target.colorBlendAmount).toBe(source.colorBlendAmount); expect(target.clippingPlanes).toBe(source.clippingPlanes); expect(target.imageBasedLightingFactor).toBe(source.imageBasedLightingFactor); + expect(target.lightColor).toBe(source.lightColor); expect(target.runAnimations).toBe(source.runAnimations); expect(target.clampAnimations).toBe(source.clampAnimations); expect(target.nodeTransformations).toEqual(source.nodeTransformations); @@ -182,6 +187,7 @@ defineSuite([ source.colorBlendAmount = new ConstantProperty(0.5); source.clippingPlanes = new ConstantProperty(new ClippingPlaneCollection()); source.imageBasedLightingFactor = new ConstantProperty(new Cartesian2(0.5, 0.5)); + source.lightColor = new ConstantProperty(new Color(1.0, 1.0, 0.0, 1.0)); source.runAnimations = new ConstantProperty(true); source.clampAnimations = new ConstantProperty(true); source.nodeTransformations = { @@ -204,6 +210,7 @@ defineSuite([ var colorBlendAmount = new ConstantProperty(0.5); var clippingPlanes = new ConstantProperty(new ClippingPlaneCollection()); var imageBasedLightingFactor = new ConstantProperty(new Cartesian2(0.5, 0.5)); + var lightColor = new ConstantProperty(new Color(1.0, 1.0, 0.0, 1.0)); var runAnimations = new ConstantProperty(true); var clampAnimations = new ConstantProperty(true); var nodeTransformations = new PropertyBag({ @@ -227,6 +234,7 @@ defineSuite([ target.colorBlendAmount = colorBlendAmount; target.clippingPlanes = clippingPlanes; target.imageBasedLightingFactor = imageBasedLightingFactor; + target.lightColor = lightColor; target.runAnimations = runAnimations; target.clampAnimations = clampAnimations; target.nodeTransformations = nodeTransformations; @@ -249,6 +257,7 @@ defineSuite([ expect(target.colorBlendAmount).toBe(colorBlendAmount); expect(target.clippingPlanes).toBe(clippingPlanes); expect(target.imageBasedLightingFactor).toBe(imageBasedLightingFactor); + expect(target.lightColor).toBe(lightColor); expect(target.runAnimations).toBe(runAnimations); expect(target.clampAnimations).toBe(clampAnimations); expect(target.nodeTransformations).toBe(nodeTransformations); @@ -272,6 +281,7 @@ defineSuite([ source.colorBlendAmount = new ConstantProperty(0.5); source.clippingPlanes = new ConstantProperty(new ClippingPlaneCollection()); source.imageBasedLightingFactor = new ConstantProperty(new Cartesian2(0.5, 0.5)); + source.lightColor = new ConstantProperty(new Color(1.0, 1.0, 0.0, 1.0)); source.runAnimations = new ConstantProperty(true); source.clampAnimations = new ConstantProperty(true); source.nodeTransformations = { @@ -296,6 +306,7 @@ defineSuite([ expect(result.colorBlendAmount).toBe(source.colorBlendAmount); expect(result.clippingPlanes).toBe(source.clippingPlanes); expect(result.imageBasedLightingFactor).toBe(source.imageBasedLightingFactor); + expect(result.lightColor).toBe(source.lightColor); expect(result.runAnimations).toBe(source.runAnimations); expect(result.clampAnimations).toBe(source.clampAnimations); expect(result.nodeTransformations).toEqual(source.nodeTransformations); diff --git a/Specs/DataSources/ModelVisualizerSpec.js b/Specs/DataSources/ModelVisualizerSpec.js index 2962135d4f7d..34034c24f0d6 100644 --- a/Specs/DataSources/ModelVisualizerSpec.js +++ b/Specs/DataSources/ModelVisualizerSpec.js @@ -3,6 +3,7 @@ defineSuite([ 'Core/BoundingSphere', 'Core/Cartesian2', 'Core/Cartesian3', + 'Core/Color', 'Core/defined', 'Core/DistanceDisplayCondition', 'Core/JulianDate', @@ -26,6 +27,7 @@ defineSuite([ BoundingSphere, Cartesian2, Cartesian3, + Color, defined, DistanceDisplayCondition, JulianDate, @@ -152,6 +154,7 @@ defineSuite([ model.clippingPlanes = new ConstantProperty(clippingPlanes); model.imageBasedLightingFactor = new ConstantProperty(new Cartesian2(0.5, 0.5)); + model.lightColor = new ConstantProperty(new Color(1.0, 1.0, 0.0, 1.0)); var testObject = entityCollection.getOrCreateEntity('test'); testObject.position = new ConstantPositionProperty(Cartesian3.fromDegrees(1, 2, 3)); @@ -172,6 +175,7 @@ defineSuite([ expect(Cartesian3.equals(primitive.clippingPlanes._planes[0].normal, clippingPlanes._planes[0].normal)).toBe(true); expect(primitive.clippingPlanes._planes[0].distance).toEqual(clippingPlanes._planes[0].distance); expect(primitive.imageBasedLightingFactor).toEqual(new Cartesian2(0.5, 0.5)); + expect(primitive.lightColor).toEqual(new Color(1.0, 1.0, 0.0, 1.0)); // wait till the model is loaded before we can check node transformations return pollToPromise(function() { From d18d192e3cfcb043fca9861452dec92ad490f5bb Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 15 Oct 2018 17:43:59 -0400 Subject: [PATCH 08/10] Fix doc. --- Source/Scene/Model.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index d186d2c45992..1aeb0e90f1c9 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -286,7 +286,7 @@ define([ * @param {Number} [options.silhouetteSize=0.0] The size of the silhouette in pixels. * @param {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the model. * @param {Boolean} [options.dequantizeInShader=true] Determines if a {@link https://github.com/google/draco|Draco} encoded model is dequantized on the GPU. This decreases total memory usage for encoded models. - * @param {Number} [options.imageBasedLightingFactor=1.0] Scales the IBL lighting from the earth, sky, atmosphere and star skybox. + * @param {Cartesian2} [options.imageBasedLightingFactor=Cartesian2(1.0, 1.0)] Scales diffuse and specular image-based lighting from the earth, sky, atmosphere and star skybox. * @param {Color} [options.lightColor] The color and intensity of the sunlight used to shade the model. * * @see Model.fromGltf @@ -1116,7 +1116,7 @@ define([ /** * The color and intensity of the sunlight used to shade the model. *

- * For example, disabling additional light sources by setting model.imageBasedLightingFactor = 0.0 will make the + * For example, disabling additional light sources by setting model.imageBasedLightingFactor = new Cesium.Cartesian2(0.0, 0.0) will make the * model much darker. Here, increasing the intensity of the light source will make the model brighter. *

* From ca42a1be5c48eb79b8cf1aaa0bdbcd3feaaebd96 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 16 Oct 2018 15:40:17 -0400 Subject: [PATCH 09/10] Change lightColor to Cartesian3. --- Source/DataSources/ModelGraphics.js | 2 +- Source/Scene/Cesium3DTileset.js | 4 ++-- Source/Scene/Model.js | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Source/DataSources/ModelGraphics.js b/Source/DataSources/ModelGraphics.js index 5953b7ecbe75..6ee82b453bb8 100644 --- a/Source/DataSources/ModelGraphics.js +++ b/Source/DataSources/ModelGraphics.js @@ -278,7 +278,7 @@ define([ imageBasedLightingFactor : createPropertyDescriptor('imageBasedLightingFactor'), /** - * A property specifying the {@link Color} of the light source when shading the model. + * A property specifying the {@link Cartesian3} color of the light source when shading the model. * @memberOf ModelGraphics.prototype * @type {Property} */ diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index 83681687e324..154d24a78c45 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -116,7 +116,7 @@ define([ * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid determining the size and shape of the globe. * @param {Object} [options.pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation based on geometric error and lighting. * @param {Cartesian2} [options.imageBasedLightingFactor=new Cartesian2(1.0, 1.0)] Scales the diffuse and specular image-based lighting from the earth, sky, atmosphere and star skybox. - * @param {Color} [options.lightColor] The color and intensity of the sunlight used to shade models. + * @param {Cartesian3} [options.lightColor] The color and intensity of the sunlight used to shade models. * @param {Boolean} [options.debugFreezeFrame=false] For debugging only. Determines if only the tiles from last frame should be used for rendering. * @param {Boolean} [options.debugColorizeTiles=false] For debugging only. When true, assigns a random color to each tile. * @param {Boolean} [options.debugWireframe=false] For debugging only. When true, render's each tile's content as a wireframe. @@ -581,7 +581,7 @@ define([ * model much darker. Here, increasing the intensity of the light source will make the model brighter. *

* - * @type {Color} + * @type {Cartesian3} * @default undefined */ this.lightColor = options.lightColor; diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 1aeb0e90f1c9..ffa122a1b0ed 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -287,7 +287,7 @@ define([ * @param {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the model. * @param {Boolean} [options.dequantizeInShader=true] Determines if a {@link https://github.com/google/draco|Draco} encoded model is dequantized on the GPU. This decreases total memory usage for encoded models. * @param {Cartesian2} [options.imageBasedLightingFactor=Cartesian2(1.0, 1.0)] Scales diffuse and specular image-based lighting from the earth, sky, atmosphere and star skybox. - * @param {Color} [options.lightColor] The color and intensity of the sunlight used to shade the model. + * @param {Cartesian3} [options.lightColor] The color and intensity of the sunlight used to shade the model. * * @see Model.fromGltf * @@ -665,7 +665,7 @@ define([ this._imageBasedLightingFactor = new Cartesian2(1.0, 1.0); Cartesian2.clone(options.imageBasedLightingFactor, this._imageBasedLightingFactor); - this._lightColor = Color.clone(options.lightColor); + this._lightColor = Cartesian3.clone(options.lightColor); this._regenerateShaders = false; } @@ -1122,7 +1122,7 @@ define([ * * @memberof Model.prototype * - * @type {Color} + * @type {Cartesian3} * @default undefined */ lightColor : { @@ -1131,11 +1131,11 @@ define([ }, set : function(value) { var lightColor = this._lightColor; - if (value === lightColor || Color.equals(value, lightColor)) { + if (value === lightColor || Cartesian3.equals(value, lightColor)) { return; } this._regenerateShaders = this._regenerateShaders || (defined(lightColor) && !defined(value)) || (defined(value) && !defined(lightColor)); - this._lightColor = Color.clone(value, lightColor); + this._lightColor = Cartesian3.clone(value, lightColor); } } }); From 7dba70b359581b9bad5876c54fedc4cef5d3dffb Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 16 Oct 2018 15:59:20 -0400 Subject: [PATCH 10/10] Add tests. --- Specs/Scene/Cesium3DTilesetSpec.js | 26 +++++++++++++++++++++++ Specs/Scene/ModelSpec.js | 34 ++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/Specs/Scene/Cesium3DTilesetSpec.js b/Specs/Scene/Cesium3DTilesetSpec.js index 38313c4b79cb..e68374ff6c5e 100644 --- a/Specs/Scene/Cesium3DTilesetSpec.js +++ b/Specs/Scene/Cesium3DTilesetSpec.js @@ -1,5 +1,6 @@ defineSuite([ 'Scene/Cesium3DTileset', + 'Core/Cartesian2', 'Core/Cartesian3', 'Core/Color', 'Core/defined', @@ -32,6 +33,7 @@ defineSuite([ 'ThirdParty/when' ], function( Cesium3DTileset, + Cartesian2, Cartesian3, Color, defined, @@ -1920,6 +1922,30 @@ defineSuite([ }); }); + it('renders with imageBaseLightingFactor', function() { + return Cesium3DTilesTester.loadTileset(scene, withoutBatchTableUrl).then(function(tileset) { + expect(scene).toRenderAndCall(function(rgba) { + expect(rgba).not.toEqual([0, 0, 0, 255]); + tileset.imageBasedLightingFactor = new Cartesian2(0.0, 0.0); + expect(scene).notToRender(rgba); + }); + }); + }); + + it('renders with lightColor', function() { + return Cesium3DTilesTester.loadTileset(scene, withoutBatchTableUrl).then(function(tileset) { + expect(scene).toRenderAndCall(function(rgba) { + expect(rgba).not.toEqual([0, 0, 0, 255]); + tileset.imageBasedLightingFactor = new Cartesian2(0.0, 0.0); + expect(scene).toRenderAndCall(function(rgba2) { + expect(rgba2).not.toEqual(rgba); + tileset.lightColor = new Cartesian3(5.0, 5.0, 5.0); + expect(scene).notToRender(rgba2); + }); + }); + }); + }); + /////////////////////////////////////////////////////////////////////////// // Styling tests diff --git a/Specs/Scene/ModelSpec.js b/Specs/Scene/ModelSpec.js index c4d67c41b25a..394c93fa3567 100644 --- a/Specs/Scene/ModelSpec.js +++ b/Specs/Scene/ModelSpec.js @@ -1,5 +1,6 @@ defineSuite([ 'Scene/Model', + 'Core/Cartesian2', 'Core/Cartesian3', 'Core/Cartesian4', 'Core/CesiumTerrainProvider', @@ -37,6 +38,7 @@ defineSuite([ 'ThirdParty/when' ], function( Model, + Cartesian2, Cartesian3, Cartesian4, CesiumTerrainProvider, @@ -2926,6 +2928,38 @@ defineSuite([ }); }); + it('renders with imageBaseLightingFactor', function() { + return loadModel(boxPbrUrl).then(function(model) { + model.show = true; + model.zoomTo(); + expect(scene).toRenderAndCall(function(rgba) { + expect(rgba).not.toEqual([0, 0, 0, 255]); + model.imageBasedLightingFactor = new Cartesian2(0.0, 0.0); + expect(scene).notToRender(rgba); + + primitives.remove(model); + }); + }); + }); + + it('renders with lightColor', function() { + return loadModel(boxPbrUrl).then(function(model) { + model.show = true; + model.zoomTo(); + expect(scene).toRenderAndCall(function(rgba) { + expect(rgba).not.toEqual([0, 0, 0, 255]); + model.imageBasedLightingFactor = new Cartesian2(0.0, 0.0); + expect(scene).toRenderAndCall(function(rgba2) { + expect(rgba2).not.toEqual(rgba); + model.lightColor = new Cartesian3(5.0, 5.0, 5.0); + expect(scene).notToRender(rgba2); + + primitives.remove(model); + }); + }); + }); + }); + it('Updates clipping planes when clipping planes are enabled', function () { return loadModel(boxUrl).then(function(model) { model.show = true;