Skip to content

Commit

Permalink
Merge pull request #12060 from CesiumGS/color-blend-spec
Browse files Browse the repository at this point in the history
Fix base color calculation for 3D Tile styles
  • Loading branch information
ggetz committed Jul 1, 2024
2 parents e0fb750 + 8b8ae9c commit 290f01d
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 128 deletions.
7 changes: 3 additions & 4 deletions packages/engine/Source/Shaders/Model/MaterialStageFS.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -459,12 +459,11 @@ void materialStage(inout czm_modelMaterial material, ProcessedAttributes attribu
#endif

material.baseColor = baseColorWithAlpha;
material.diffuse = baseColorWithAlpha.rgb;
material.alpha = baseColorWithAlpha.a;

#ifdef USE_CPU_STYLING
material.diffuse = blend(material.diffuse, feature.color.rgb, model_colorBlend);
material.baseColor.rgb = blend(baseColorWithAlpha.rgb, feature.color.rgb, model_colorBlend);
#endif
material.diffuse = baseColorWithAlpha.rgb;
material.alpha = baseColorWithAlpha.a;

#ifdef HAS_OCCLUSION_TEXTURE
vec2 occlusionTexCoords = TEXCOORD_OCCLUSION;
Expand Down
245 changes: 121 additions & 124 deletions packages/engine/Specs/Scene/Cesium3DTilesetSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3312,7 +3312,7 @@ describe(
);
});

function testColorBlendMode(url) {
async function testColorBlendMode(url) {
// Check that the feature is red
let sourceRed;
let sourceGreen;
Expand All @@ -3322,148 +3322,145 @@ describe(
scene: scene,
time: new JulianDate(2457522.154792),
};
let tileset;
return Cesium3DTilesTester.loadTileset(scene, url).then(function (t) {
tileset = t;
tileset.luminanceAtZenith = undefined;

expect(renderOptions).toRenderAndCall(function (rgba) {
sourceRed = rgba[0];
sourceGreen = rgba[1];
});
const tileset = await Cesium3DTilesTester.loadTileset(scene, url);
tileset.luminanceAtZenith = undefined;

expect(renderOptions).toRenderAndCall(function (rgba) {
expect(rgba[0]).toBeGreaterThan(200);
expect(rgba[1]).toBeLessThan(25);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});
expect(renderOptions).toRenderAndCall(function (rgba) {
sourceRed = rgba[0];
sourceGreen = rgba[1];
});

// Use HIGHLIGHT blending
tileset.colorBlendMode = Cesium3DTileColorBlendMode.HIGHLIGHT;
expect(renderOptions).toRenderAndCall(function (rgba) {
expect(rgba[0]).toBeGreaterThan(200);
expect(rgba[1]).toBeLessThan(25);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});

// Style with dark yellow. Expect the red channel to be darker than before.
tileset.style = new Cesium3DTileStyle({
color: "rgb(128, 128, 0)",
});
// Use HIGHLIGHT blending
tileset.colorBlendMode = Cesium3DTileColorBlendMode.HIGHLIGHT;

expect(renderOptions).toRenderAndCall(function (rgba) {
expect(rgba[0]).toBeGreaterThan(100);
expect(rgba[0]).toBeLessThan(sourceRed);
expect(rgba[1]).toBeLessThan(25);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});
// Style with dark yellow. Expect the red channel to be darker than before.
tileset.style = new Cesium3DTileStyle({
color: "rgb(128, 128, 0)",
});

// Style with yellow + alpha. Expect the red channel to be darker than before.
tileset.style = new Cesium3DTileStyle({
color: "rgba(255, 255, 0, 0.5)",
});
expect(renderOptions).toRenderAndCall(function (rgba) {
expect(rgba[0]).toBeGreaterThan(100);
expect(rgba[0]).toBeLessThan(sourceRed);
expect(rgba[1]).toBeLessThan(25);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});

expect(renderOptions).toRenderAndCall(function (rgba) {
expect(rgba[0]).toBeGreaterThan(100);
expect(rgba[0]).toBeLessThan(sourceRed);
expect(rgba[1]).toBeLessThan(25);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});
// Style with yellow + alpha. Expect the red channel to be darker than before.
tileset.style = new Cesium3DTileStyle({
color: "rgba(255, 255, 0, 0.5)",
});

// Use REPLACE blending
tileset.colorBlendMode = Cesium3DTileColorBlendMode.REPLACE;
expect(renderOptions).toRenderAndCall(function (rgba) {
expect(rgba[0]).toBeGreaterThan(100);
expect(rgba[0]).toBeLessThan(sourceRed);
expect(rgba[1]).toBeLessThan(25);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});

// Style with dark yellow. Expect the red and green channels to be roughly dark yellow.
tileset.style = new Cesium3DTileStyle({
color: "rgb(128, 128, 0)",
});
// Use REPLACE blending
tileset.colorBlendMode = Cesium3DTileColorBlendMode.REPLACE;

expect(renderOptions).toRenderAndCall(function (rgba) {
replaceRed = rgba[0];
replaceGreen = rgba[1];
expect(rgba[0]).toBeGreaterThan(100);
expect(rgba[0]).toBeLessThan(255);
expect(rgba[1]).toBeGreaterThan(100);
expect(rgba[1]).toBeLessThan(255);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});
// Style with dark yellow. Expect the red and green channels to be roughly dark yellow.
tileset.style = new Cesium3DTileStyle({
color: "rgb(128, 128, 0)",
});

// Style with yellow + alpha. Expect the red and green channels to be a shade of yellow.
tileset.style = new Cesium3DTileStyle({
color: "rgba(255, 255, 0, 0.5)",
});
expect(renderOptions).toRenderAndCall(function (rgba) {
replaceRed = rgba[0];
replaceGreen = rgba[1];
expect(rgba[0]).toBeGreaterThan(100);
expect(rgba[0]).toBeLessThan(255);
expect(rgba[1]).toBeGreaterThan(100);
expect(rgba[1]).toBeLessThan(255);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});

expect(renderOptions).toRenderAndCall(function (rgba) {
expect(rgba[0]).toBeGreaterThan(100);
expect(rgba[0]).toBeLessThan(255);
expect(rgba[1]).toBeGreaterThan(100);
expect(rgba[1]).toBeLessThan(255);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});
// Style with yellow + alpha. Expect the red and green channels to be a shade of yellow.
tileset.style = new Cesium3DTileStyle({
color: "rgba(255, 255, 0, 0.5)",
});

// Use MIX blending
tileset.colorBlendMode = Cesium3DTileColorBlendMode.MIX;
tileset.colorBlendAmount = 0.5;
expect(renderOptions).toRenderAndCall(function (rgba) {
expect(rgba[0]).toBeGreaterThan(100);
expect(rgba[0]).toBeLessThan(255);
expect(rgba[1]).toBeGreaterThan(100);
expect(rgba[1]).toBeLessThan(255);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});

// Style with dark yellow. Expect color to be a mix of the source and style colors.
tileset.style = new Cesium3DTileStyle({
color: "rgb(128, 128, 0)",
});
// Use MIX blending
tileset.colorBlendMode = Cesium3DTileColorBlendMode.MIX;
tileset.colorBlendAmount = 0.5;

let mixRed;
let mixGreen;
expect(renderOptions).toRenderAndCall(function (rgba) {
mixRed = rgba[0];
mixGreen = rgba[1];
expect(rgba[0]).toBeGreaterThan(replaceRed);
expect(rgba[0]).toBeLessThan(sourceRed);
expect(rgba[1]).toBeGreaterThan(sourceGreen);
expect(rgba[1]).toBeLessThan(replaceGreen);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});
// Style with dark yellow. Expect color to be a mix of the source and style colors.
tileset.style = new Cesium3DTileStyle({
color: "rgb(128, 128, 0)",
});

let mixRed;
let mixGreen;
expect(renderOptions).toRenderAndCall(function (rgba) {
mixRed = rgba[0];
mixGreen = rgba[1];
expect(rgba[0]).toBeGreaterThan(replaceRed);
expect(rgba[0]).toBeLessThan(sourceRed);
expect(rgba[1]).toBeGreaterThan(sourceGreen);
expect(rgba[1]).toBeLessThan(replaceGreen);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});

// Set colorBlendAmount to 0.25. Expect color to be closer to the source color.
tileset.colorBlendAmount = 0.25;
expect(renderOptions).toRenderAndCall(function (rgba) {
expect(rgba[0]).toBeGreaterThan(mixRed);
expect(rgba[0]).toBeLessThan(sourceRed);
expect(rgba[1]).toBeGreaterThan(0);
expect(rgba[1]).toBeLessThan(mixGreen);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});
// Set colorBlendAmount to 0.25. Expect color to be closer to the source color.
tileset.colorBlendAmount = 0.25;
expect(renderOptions).toRenderAndCall(function (rgba) {
expect(rgba[0]).toBeGreaterThan(mixRed);
expect(rgba[0]).toBeLessThan(sourceRed);
expect(rgba[1]).toBeGreaterThan(0);
expect(rgba[1]).toBeLessThan(mixGreen);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});

// Set colorBlendAmount to 0.0. Expect color to equal the source color
tileset.colorBlendAmount = 0.0;
expect(renderOptions).toRenderAndCall(function (rgba) {
expect(rgba[0]).toEqual(sourceRed);
expect(rgba[1]).toBeLessThan(25);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});
// Set colorBlendAmount to 0.0. Expect color to equal the source color
tileset.colorBlendAmount = 0.0;
expect(renderOptions).toRenderAndCall(function (rgba) {
expect(rgba[0]).toEqual(sourceRed);
expect(rgba[1]).toBeLessThan(25);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});

// Set colorBlendAmount to 1.0. Expect color to equal the style color
tileset.colorBlendAmount = 1.0;
expect(renderOptions).toRenderAndCall(function (rgba) {
expect(rgba[0]).toEqual(replaceRed);
expect(rgba[1]).toEqual(replaceGreen);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});
// Set colorBlendAmount to 1.0. Expect color to equal the style color
tileset.colorBlendAmount = 1.0;
expect(renderOptions).toRenderAndCall(function (rgba) {
expect(rgba[0]).toEqual(replaceRed);
expect(rgba[1]).toEqual(replaceGreen);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});

// Style with yellow + alpha. Expect color to be a mix of the source and style colors.
tileset.colorBlendAmount = 0.5;
tileset.style = new Cesium3DTileStyle({
color: "rgba(255, 255, 0, 0.5)",
});
// Style with yellow + alpha. Expect color to be a mix of the source and style colors.
tileset.colorBlendAmount = 0.5;
tileset.style = new Cesium3DTileStyle({
color: "rgba(255, 255, 0, 0.5)",
});

expect(renderOptions).toRenderAndCall(function (rgba) {
expect(rgba[0]).toBeGreaterThan(0);
expect(rgba[1]).toBeGreaterThan(0);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});
expect(renderOptions).toRenderAndCall(function (rgba) {
expect(rgba[0]).toBeGreaterThan(0);
expect(rgba[1]).toBeGreaterThan(0);
expect(rgba[2]).toBeLessThan(25);
expect(rgba[3]).toEqual(255);
});
}

Expand Down

0 comments on commit 290f01d

Please sign in to comment.