Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix quantized vec3 colors in ModelExperimental #9957

Merged
merged 3 commits into from
Dec 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# Change Log

### 1.88 - 2021-12-1
### 1.89 - 2022-01-03

##### Fixes :wrench:

- Fixed handling of vec3 vertex colors in `ModelExperimental`. [#9955](https://github.com/CesiumGS/cesium/pull/9955)
- Fixed handling of Draco quantized vec3 vertex colors in `ModelExperimental`. [#9957](https://github.com/CesiumGS/cesium/pull/9957)

### 1.88 - 2021-12-01

##### Fixes :wrench:

Expand Down
25 changes: 23 additions & 2 deletions Source/Scene/ModelExperimental/DequantizationPipelineStage.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import defined from "../../Core/defined.js";
import Cartesian4 from "../../Core/Cartesian4.js";
import ShaderDestination from "../../Renderer/ShaderDestination.js";
import ModelExperimentalUtility from "./ModelExperimentalUtility.js";

Expand Down Expand Up @@ -82,16 +83,36 @@ function addDequantizationUniforms(renderResources, attributeInfo) {
shaderBuilder.addUniform(glslType, offset, ShaderDestination.VERTEX);
shaderBuilder.addUniform(glslType, stepSize, ShaderDestination.VERTEX);

var quantizedVolumeOffset = quantization.quantizedVolumeOffset;
var quantizedVolumeStepSize = quantization.quantizedVolumeStepSize;

// COLOR_n is promoted to a vec4 in the shader, so the alpha value
// defaults to 1. For correctness, the quantization uniforms must be
// promoted to vec4s. The alpha values are chosen so the alpha
// dequantization is the identity, i.e. 0.0 + 1.0 * color.a
if (/^color_\d+$/.test(variableName)) {
quantizedVolumeOffset = promoteToVec4(quantizedVolumeOffset, 0);
quantizedVolumeStepSize = promoteToVec4(quantizedVolumeStepSize, 1);
}

uniformMap[offset] = function () {
return quantization.quantizedVolumeOffset;
return quantizedVolumeOffset;
};

uniformMap[stepSize] = function () {
return quantization.quantizedVolumeStepSize;
return quantizedVolumeStepSize;
};
}
}

function promoteToVec4(value, defaultAlpha) {
if (value instanceof Cartesian4) {
return value;
}

return new Cartesian4(value.x, value.y, value.z, defaultAlpha);
}

function updateDequantizationFunction(shaderBuilder, attributeInfo) {
var variableName = attributeInfo.variableName;
var quantization = attributeInfo.attribute.quantization;
Expand Down
10 changes: 7 additions & 3 deletions Source/Scene/ModelExperimental/ModelExperimentalUtility.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,20 +119,24 @@ ModelExperimentalUtility.getAttributeInfo = function (attribute) {
variableName = variableName.toLowerCase();
}

var isVertexColor = /^color_\d+$/.test(variableName);
var attributeType = attribute.type;
var glslType = AttributeType.getGlslType(attributeType);

// color_n can be either a vec3 or a vec4. But in GLSL we can always use
// attribute vec4 since GLSL promotes vec3 attribute data to vec4 with
// the .a channel set to 1.0
if (/^color_\d+$/.test(variableName)) {
// the .a channel set to 1.0.
if (isVertexColor) {
glslType = "vec4";
}

var isQuantized = defined(attribute.quantization);
var quantizedGlslType;
if (isQuantized) {
quantizedGlslType = AttributeType.getGlslType(attribute.quantization.type);
// The quantized color_n attribute also is promoted to a vec4 in the shader
quantizedGlslType = isVertexColor
? "vec4"
: AttributeType.getGlslType(attribute.quantization.type);
}

return {
Expand Down
68 changes: 68 additions & 0 deletions Specs/Scene/ModelExperimental/DequantizationPipelineStageSpec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
Cartesian2,
Cartesian3,
Cartesian4,
combine,
DequantizationPipelineStage,
GltfLoader,
Expand All @@ -20,6 +21,8 @@ describe("Scene/ModelExperimental/DequantizationPipelineStage", function () {
"./Data/Models/DracoCompression/BoxWithLines/BoxWithLines.gltf";
var milkTruck =
"./Data/Models/DracoCompression/CesiumMilkTruck/CesiumMilkTruck.gltf";
var boxDracoRGBColors =
"./Data/Models/DracoCompression/BoxVertexColorsDracoRGB.gltf";

var scene;
var gltfLoaders = [];
Expand Down Expand Up @@ -148,6 +151,71 @@ describe("Scene/ModelExperimental/DequantizationPipelineStage", function () {
});
});

it("promotes vertex color dequantization uniforms to vec4", function () {
var uniformMap = {};
var shaderBuilder = new ShaderBuilder();
var renderResources = {
uniformMap: uniformMap,
shaderBuilder: shaderBuilder,
};

return loadGltf(boxDracoRGBColors).then(function (gltfLoader) {
var components = gltfLoader.components;
var primitive = components.nodes[2].primitives[0];
DequantizationPipelineStage.process(renderResources, primitive);

ShaderBuilderTester.expectHasVertexUniforms(shaderBuilder, [
"uniform float model_normalizationRange_normalMC;",
"uniform vec2 model_quantizedVolumeOffset_texCoord_0;",
"uniform vec2 model_quantizedVolumeStepSize_texCoord_0;",
"uniform vec3 model_quantizedVolumeOffset_positionMC;",
"uniform vec3 model_quantizedVolumeStepSize_positionMC;",
"uniform vec4 model_quantizedVolumeOffset_color_0;",
"uniform vec4 model_quantizedVolumeStepSize_color_0;",
]);
ShaderBuilderTester.expectHasFragmentUniforms(shaderBuilder, []);

var uniformValues = {
normalRange: uniformMap.model_normalizationRange_normalMC(),
texCoordOffset: uniformMap.model_quantizedVolumeOffset_texCoord_0(),
texCoordStepSize: uniformMap.model_quantizedVolumeStepSize_texCoord_0(),
positionOffset: uniformMap.model_quantizedVolumeOffset_positionMC(),
positionStepSize: uniformMap.model_quantizedVolumeStepSize_positionMC(),
colorOffset: uniformMap.model_quantizedVolumeOffset_color_0(),
colorStepSize: uniformMap.model_quantizedVolumeStepSize_color_0(),
};

var expected = {
normalRange: 1023,
positionOffset: new Cartesian3(-0.5, -0.5, -0.5),
positionStepSize: new Cartesian3(
0.00006103888176768602,
0.00006103888176768602,
0.00006103888176768602
),
texCoordOffset: new Cartesian2(0, 0),
texCoordStepSize: new Cartesian2(
0.0002442002442002442,
0.0002442002442002442
),
colorOffset: new Cartesian4(
4.908018991223173e-10,
0.0006933663971722126,
0.000028382812160998583,
0
),
colorStepSize: new Cartesian4(
0.00392145689795999,
0.00392145689795999,
0.00392145689795999,
1
),
};

expect(uniformValues).toEqualEpsilon(expected, CesiumMath.EPSILON15);
});
});

it("skips non-quantized attributes", function () {
var uniformMap = {};
var shaderBuilder = new ShaderBuilder();
Expand Down
20 changes: 20 additions & 0 deletions Specs/Scene/ModelExperimental/ModelExperimentalUtilitySpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,26 @@ describe("Scene/ModelExperimental/ModelExperimentalUtility", function () {
});
});

it("getAttributeInfo handles quantized vertex colors correctly", function () {
var attribute = {
semantic: "COLOR",
setIndex: 0,
type: AttributeType.VEC3,
quantization: {
type: AttributeType.VEC3,
},
};

expect(ModelExperimentalUtility.getAttributeInfo(attribute)).toEqual({
attribute: attribute,
isQuantized: true,
variableName: "color_0",
hasSemantic: true,
glslType: "vec4",
quantizedGlslType: "vec4",
});
});

it("createBoundingSphere works", function () {
var mockPrimitive = {
attributes: [
Expand Down