Skip to content

Commit

Permalink
Normalize color attributes (#3365)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pessimistress committed Jul 23, 2019
1 parent 581ba9c commit 502affb
Show file tree
Hide file tree
Showing 31 changed files with 179 additions and 90 deletions.
2 changes: 1 addition & 1 deletion modules/core/package.json
Expand Up @@ -35,7 +35,7 @@
"dependencies": {
"@loaders.gl/core": "^1.1.6",
"@loaders.gl/images": "^1.1.6",
"@luma.gl/core": "^7.2.0-alpha.2",
"@luma.gl/core": "^7.2.0-alpha.4",
"gl-matrix": "^3.0.0",
"math.gl": "^2.3.0",
"mjolnir.js": "^2.1.2",
Expand Down
30 changes: 19 additions & 11 deletions modules/core/src/lib/attribute.js
Expand Up @@ -45,17 +45,25 @@ export default class Attribute extends BaseAttribute {
// Initialize the attribute descriptor, with WebGL and metadata fields
this.shaderAttributes[shaderAttributeName] = new Attribute(
this.gl,
Object.assign({}, shaderAttribute, {
id: shaderAttributeName,
// Luma fields
constant: shaderAttribute.constant || false,
isIndexed: shaderAttribute.isIndexed || shaderAttribute.elements,
size: (shaderAttribute.elements && 1) || shaderAttribute.size || this.size,
value: shaderAttribute.value || null,
divisor: shaderAttribute.instanced || shaderAttribute.divisor || this.divisor,
buffer: this.getBuffer(),
noAlloc: true
})
Object.assign(
{
offset: this.offset,
stride: this.stride,
normalized: this.normalized
},
shaderAttribute,
{
id: shaderAttributeName,
// Luma fields
constant: shaderAttribute.constant || false,
isIndexed: shaderAttribute.isIndexed || shaderAttribute.elements,
size: (shaderAttribute.elements && 1) || shaderAttribute.size || this.size,
value: shaderAttribute.value || null,
divisor: shaderAttribute.instanced || shaderAttribute.divisor || this.divisor,
buffer: this.getBuffer(),
noAlloc: true
}
)
);

this.hasShaderAttributes = true;
Expand Down
29 changes: 29 additions & 0 deletions modules/core/src/lib/base-attribute.js
Expand Up @@ -81,6 +81,10 @@ export default class BaseAttribute {
}

this._setAccessor(opts);

if (constant && this.normalized) {
this.value = this._normalizeConstant(this.value);
}
}

getBuffer() {
Expand Down Expand Up @@ -156,6 +160,31 @@ export default class BaseAttribute {
}
}

// https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer
_normalizeConstant(value) {
switch (this.type) {
case GL.BYTE:
// normalize [-128, 127] to [-1, 1]
return new Float32Array(value).map(x => ((x + 128) / 255) * 2 - 1);

case GL.SHORT:
// normalize [-32768, 32767] to [-1, 1]
return new Float32Array(value).map(x => ((x + 32768) / 65535) * 2 - 1);

case GL.UNSIGNED_BYTE:
// normalize [0, 255] to [0, 1]
return new Float32Array(value).map(x => x / 255);

case GL.UNSIGNED_SHORT:
// normalize [0, 65535] to [0, 1]
return new Float32Array(value).map(x => x / 65535);

default:
// No normalization for gl.FLOAT and gl.HALF_FLOAT
return value;
}
}

_validateAttributeDefinition() {
// Can be undefined for buffers (auto deduced from shaders)
// or larger than 4 for uniform arrays
Expand Down
5 changes: 0 additions & 5 deletions modules/core/src/lib/layer.js
Expand Up @@ -301,11 +301,6 @@ export default class Layer extends Component {
for (const extension of this.props.extensions) {
shaders = mergeShaders(shaders, extension.getShaders.call(this, extension));
}
if (this.props.colorFormat === 'RGB') {
shaders = mergeShaders(shaders, {
defines: {COLOR_FORMAT_RGB: 1}
});
}
return shaders;
}

Expand Down
14 changes: 0 additions & 14 deletions modules/core/src/shaderlib/index.js
Expand Up @@ -40,20 +40,6 @@ export function initializeShaderModules() {
createShaderHook('vs:DECKGL_FILTER_COLOR(inout vec4 color, VertexGeometry geometry)');
createShaderHook('fs:DECKGL_FILTER_COLOR(inout vec4 color, FragmentGeometry geometry)');

// https://www.khronos.org/opengl/wiki/Vertex_Specification
// If the vertex shader has more components than the array provides, the extras are given values
// from the vector (0, 0, 0, 1) for the missing XYZW components.
// In RGB mode (color attributes missing the 4th component), a is default to 1.0. We want 255.0
createModuleInjection('geometry', {
hook: 'vs:DECKGL_FILTER_COLOR',
order: 99,
injection: `
#ifdef COLOR_FORMAT_RGB
color.a *= 255.;
#endif
`
});

createModuleInjection('picking', {
hook: 'fs:DECKGL_FILTER_COLOR',
order: 99,
Expand Down
Expand Up @@ -126,7 +126,7 @@ void main(void) {
gl_Position = curr + vec4(project_pixel_size_to_clipspace(offset.xy), 0.0, 0.0);
DECKGL_FILTER_GL_POSITION(gl_Position, geometry);
vec4 color = mix(instanceSourceColors, instanceTargetColors, segmentRatio) / 255.0;
vec4 color = mix(instanceSourceColors, instanceTargetColors, segmentRatio);
vColor = vec4(color.rgb, color.a * opacity);
DECKGL_FILTER_COLOR(vColor, geometry);
Expand Down
2 changes: 1 addition & 1 deletion modules/layers/src/arc-layer/arc-layer-vertex.glsl.js
Expand Up @@ -115,7 +115,7 @@ void main(void) {
gl_Position = curr + vec4(project_pixel_size_to_clipspace(offset.xy), 0.0, 0.0);
DECKGL_FILTER_GL_POSITION(gl_Position, geometry);
vec4 color = mix(instanceSourceColors, instanceTargetColors, segmentRatio) / 255.;
vec4 color = mix(instanceSourceColors, instanceTargetColors, segmentRatio);
vColor = vec4(color.rgb, color.a * opacity);
DECKGL_FILTER_COLOR(vColor, geometry);
Expand Down
2 changes: 2 additions & 0 deletions modules/layers/src/arc-layer/arc-layer.js
Expand Up @@ -70,13 +70,15 @@ export default class ArcLayer extends Layer {
instanceSourceColors: {
size: this.props.colorFormat.length,
type: GL.UNSIGNED_BYTE,
normalized: true,
transition: true,
accessor: 'getSourceColor',
defaultValue: DEFAULT_COLOR
},
instanceTargetColors: {
size: this.props.colorFormat.length,
type: GL.UNSIGNED_BYTE,
normalized: true,
transition: true,
accessor: 'getTargetColor',
defaultValue: DEFAULT_COLOR
Expand Down
4 changes: 2 additions & 2 deletions modules/layers/src/column-layer/column-layer-vertex.glsl.js
Expand Up @@ -90,9 +90,9 @@ void main(void) {
// Light calculations
if (extruded && !isStroke) {
vec3 lightColor = lighting_getLightColor(color.rgb, project_uCameraPosition, geometry.position.xyz, geometry.normal);
vColor = vec4(lightColor, color.a * opacity) / 255.0;
vColor = vec4(lightColor, color.a * opacity);
} else {
vColor = vec4(color.rgb, color.a * opacity) / 255.0;
vColor = vec4(color.rgb, color.a * opacity);
}
DECKGL_FILTER_COLOR(vColor, geometry);
Expand Down
2 changes: 2 additions & 0 deletions modules/layers/src/column-layer/column-layer.js
Expand Up @@ -88,13 +88,15 @@ export default class ColumnLayer extends Layer {
instanceFillColors: {
size: this.props.colorFormat.length,
type: GL.UNSIGNED_BYTE,
normalized: true,
transition: true,
accessor: 'getFillColor',
defaultValue: DEFAULT_COLOR
},
instanceLineColors: {
size: this.props.colorFormat.length,
type: GL.UNSIGNED_BYTE,
normalized: true,
transition: true,
accessor: 'getLineColor',
defaultValue: DEFAULT_COLOR
Expand Down
2 changes: 1 addition & 1 deletion modules/layers/src/icon-layer/icon-layer-vertex.glsl.js
Expand Up @@ -95,7 +95,7 @@ void main(void) {
vTextureCoords.y = 1.0 - vTextureCoords.y;
vColor = instanceColors / 255.;
vColor = instanceColors;
DECKGL_FILTER_COLOR(vColor, geometry);
vColorMode = instanceColorModes;
Expand Down
1 change: 1 addition & 0 deletions modules/layers/src/icon-layer/icon-layer.js
Expand Up @@ -105,6 +105,7 @@ export default class IconLayer extends Layer {
instanceColors: {
size: this.props.colorFormat.length,
type: GL.UNSIGNED_BYTE,
normalized: true,
transition: true,
accessor: 'getColor',
defaultValue: DEFAULT_COLOR
Expand Down
2 changes: 1 addition & 1 deletion modules/layers/src/line-layer/line-layer-vertex.glsl.js
Expand Up @@ -80,7 +80,7 @@ void main(void) {
DECKGL_FILTER_GL_POSITION(gl_Position, geometry);
// Color
vColor = vec4(instanceColors.rgb, instanceColors.a * opacity) / 255.;
vColor = vec4(instanceColors.rgb, instanceColors.a * opacity);
DECKGL_FILTER_COLOR(vColor, geometry);
// Set color to be rendered to picking fbo (also used to check for selection highlight).
Expand Down
1 change: 1 addition & 0 deletions modules/layers/src/line-layer/line-layer.js
Expand Up @@ -70,6 +70,7 @@ export default class LineLayer extends Layer {
instanceColors: {
size: this.props.colorFormat.length,
type: GL.UNSIGNED_BYTE,
normalized: true,
transition: true,
accessor: 'getColor',
defaultValue: [0, 0, 0, 255]
Expand Down
2 changes: 1 addition & 1 deletion modules/layers/src/path-layer/path-layer-vertex.glsl.js
Expand Up @@ -214,7 +214,7 @@ void main() {
geometry.worldPosition = instanceStartPositions;
geometry.worldPositionAlt = instanceEndPositions;
vColor = vec4(instanceColors.rgb, instanceColors.a * opacity) / 255.;
vColor = vec4(instanceColors.rgb, instanceColors.a * opacity);
// Set color to be rendered to picking fbo (also used to check for selection highlight).
picking_setPickingColor(instancePickingColors);
Expand Down
1 change: 1 addition & 0 deletions modules/layers/src/path-layer/path-layer.js
Expand Up @@ -122,6 +122,7 @@ export default class PathLayer extends Layer {
instanceColors: {
size: this.props.colorFormat.length,
type: GL.UNSIGNED_BYTE,
normalized: true,
accessor: 'getColor',
transition: ATTRIBUTE_TRANSITION,
defaultValue: DEFAULT_COLOR
Expand Down
Expand Up @@ -54,7 +54,7 @@ void main(void) {
vec3 lightColor = lighting_getLightColor(instanceColors.rgb, project_uCameraPosition, geometry.position.xyz, geometry.normal);
// Apply opacity to instance color, or return instance picking color
vColor = vec4(lightColor, instanceColors.a * opacity) / 255.0;
vColor = vec4(lightColor, instanceColors.a * opacity);
DECKGL_FILTER_COLOR(vColor, geometry);
// Set color to be rendered to picking fbo (also used to check for selection highlight).
Expand Down
1 change: 1 addition & 0 deletions modules/layers/src/point-cloud-layer/point-cloud-layer.js
Expand Up @@ -91,6 +91,7 @@ export default class PointCloudLayer extends Layer {
instanceColors: {
size: this.props.colorFormat.length,
type: GL.UNSIGNED_BYTE,
normalized: true,
transition: true,
accessor: 'getColor',
defaultValue: DEFAULT_COLOR
Expand Down
Expand Up @@ -76,9 +76,9 @@ void main(void) {
DECKGL_FILTER_GL_POSITION(gl_Position, geometry);
// Apply opacity to instance color, or return instance picking color
vFillColor = vec4(instanceFillColors.rgb, instanceFillColors.a * opacity) / 255.;
vFillColor = vec4(instanceFillColors.rgb, instanceFillColors.a * opacity);
DECKGL_FILTER_COLOR(vFillColor, geometry);
vLineColor = vec4(instanceLineColors.rgb, instanceLineColors.a * opacity) / 255.;
vLineColor = vec4(instanceLineColors.rgb, instanceLineColors.a * opacity);
DECKGL_FILTER_COLOR(vLineColor, geometry);
// Set color to be rendered to picking fbo (also used to check for selection highlight).
Expand Down
2 changes: 2 additions & 0 deletions modules/layers/src/scatterplot-layer/scatterplot-layer.js
Expand Up @@ -78,13 +78,15 @@ export default class ScatterplotLayer extends Layer {
instanceFillColors: {
size: this.props.colorFormat.length,
transition: true,
normalized: true,
type: GL.UNSIGNED_BYTE,
accessor: 'getFillColor',
defaultValue: [0, 0, 0, 255]
},
instanceLineColors: {
size: this.props.colorFormat.length,
transition: true,
normalized: true,
type: GL.UNSIGNED_BYTE,
accessor: 'getLineColor',
defaultValue: [0, 0, 0, 255]
Expand Down
Expand Up @@ -88,9 +88,9 @@ void calculatePosition(PolygonProps props) {
if (extruded) {
vec3 lightColor = lighting_getLightColor(colors.rgb, project_uCameraPosition, geometry.position.xyz, normal);
vColor = vec4(lightColor, colors.a * opacity) / 255.0;
vColor = vec4(lightColor, colors.a * opacity);
} else {
vColor = vec4(colors.rgb, colors.a * opacity) / 255.0;
vColor = vec4(colors.rgb, colors.a * opacity);
}
DECKGL_FILTER_COLOR(vColor, geometry);
Expand Down
2 changes: 2 additions & 0 deletions modules/layers/src/solid-polygon-layer/solid-polygon-layer.js
Expand Up @@ -151,6 +151,7 @@ export default class SolidPolygonLayer extends Layer {
alias: 'colors',
size: this.props.colorFormat.length,
type: GL.UNSIGNED_BYTE,
normalized: true,
transition: ATTRIBUTE_TRANSITION,
accessor: 'getFillColor',
defaultValue: DEFAULT_COLOR,
Expand All @@ -167,6 +168,7 @@ export default class SolidPolygonLayer extends Layer {
alias: 'colors',
size: this.props.colorFormat.length,
type: GL.UNSIGNED_BYTE,
normalized: true,
transition: ATTRIBUTE_TRANSITION,
accessor: 'getLineColor',
defaultValue: DEFAULT_COLOR,
Expand Down
Expand Up @@ -101,7 +101,7 @@ void main(void) {
vTextureCoords.y = 1.0 - vTextureCoords.y;
vColor = vec4(instanceColors.rgb, instanceColors.a * opacity) / 255.;
vColor = vec4(instanceColors.rgb, instanceColors.a * opacity);
DECKGL_FILTER_COLOR(vColor, geometry);
picking_setPickingColor(instancePickingColors);
Expand Down
2 changes: 1 addition & 1 deletion modules/mesh-layers/package.json
Expand Up @@ -33,6 +33,6 @@
"@deck.gl/core": "^7.0.0"
},
"dependencies": {
"@luma.gl/addons": "^7.2.0-alpha.1"
"@luma.gl/addons": "^7.2.0-alpha.4"
}
}
Expand Up @@ -78,7 +78,7 @@ void main(void) {
pbr_vPosition = geometry.position.xyz;
#endif
vColor = instanceColors / 255.0;
vColor = instanceColors;
DECKGL_FILTER_COLOR(vColor, geometry);
picking_setPickingColor(instancePickingColors);
Expand Down
3 changes: 3 additions & 0 deletions modules/mesh-layers/src/scenegraph-layer/scenegraph-layer.js
Expand Up @@ -21,6 +21,7 @@
import {Layer, createIterable, fp64LowPart} from '@deck.gl/core';
import {ScenegraphNode, isWebGL2, pbr, log} from '@luma.gl/core';
import {createGLTFObjects} from '@luma.gl/addons';
import GL from '@luma.gl/constants';
import {waitForGLTFAssets} from './gltf-utils';

import {MATRIX_ATTRIBUTES} from '../utils/matrix';
Expand Down Expand Up @@ -76,8 +77,10 @@ export default class ScenegraphLayer extends Layer {
update: this.calculateInstancePositions64xyLow
},
instanceColors: {
type: GL.UNSIGNED_BYTE,
size: this.props.colorFormat.length,
accessor: 'getColor',
normalized: true,
defaultValue: DEFAULT_COLOR,
transition: true
},
Expand Down
Expand Up @@ -26,9 +26,9 @@ void main(void) {
normal = normals_commonspace;
}
vec4 color = hasTexture ? texture(sampler, vTexCoord) : vColor / 255.;
vec3 lightColor = lighting_getLightColor(color.rgb * 255., cameraPosition, position_commonspace.xyz, normal);
fragColor = vec4(lightColor / 255., color.a);
vec4 color = hasTexture ? texture(sampler, vTexCoord) : vColor;
vec3 lightColor = lighting_getLightColor(color.rgb, cameraPosition, position_commonspace.xyz, normal);
fragColor = vec4(lightColor, color.a);
DECKGL_FILTER_COLOR(fragColor, geometry);
}
Expand Down
Expand Up @@ -31,9 +31,9 @@ void main(void) {
normal = normals_commonspace;
}
vec4 color = hasTexture ? texture2D(sampler, vTexCoord) : vColor / 255.;
vec3 lightColor = lighting_getLightColor(color.rgb * 255., cameraPosition, position_commonspace.xyz, normal);
gl_FragColor = vec4(lightColor / 255., color.a);
vec4 color = hasTexture ? texture2D(sampler, vTexCoord) : vColor;
vec3 lightColor = lighting_getLightColor(color.rgb, cameraPosition, position_commonspace.xyz, normal);
gl_FragColor = vec4(lightColor, color.a);
DECKGL_FILTER_COLOR(gl_FragColor, geometry);
}
Expand Down
Expand Up @@ -136,8 +136,10 @@ export default class SimpleMeshLayer extends Layer {
update: this.calculateInstancePositions64xyLow
},
instanceColors: {
type: GL.UNSIGNED_BYTE,
transition: true,
size: this.props.colorFormat.length,
normalized: true,
accessor: 'getColor',
defaultValue: [0, 0, 0, 255]
},
Expand Down

0 comments on commit 502affb

Please sign in to comment.