Skip to content

Commit

Permalink
feat(Points): Add support for return, elevation and source id attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
Desplandis committed Sep 15, 2023
1 parent c275bcd commit f5fad38
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 5 deletions.
19 changes: 18 additions & 1 deletion src/Layer/PointCloudLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,18 @@ function changeIntensityRange(layer) {
}
}

function changeElevationRange(layer) {
if (layer.material.elevationRange) {
layer.material.elevationRange.set(
layer.minElevationRange,
layer.maxElevationRange,
);
}
}

/**
* The basis for all point clouds related layers.
* @extends GeometryLayer
*
* @property {boolean} isPointCloudLayer - Used to checkout whether this layer
* is a PointCloudLayer. Default is `true`. You should not change this, as it is
Expand Down Expand Up @@ -97,6 +107,12 @@ function changeIntensityRange(layer) {
* @property {number} [maxIntensityRange=1] - The maximal intensity of the
* layer. Changing this value will affect the material, if it has the
* corresponding uniform. The value is normalized between 0 and 1.
* @property {number} [minElevationRange=0] - The minimal elevation of the
* layer. Changing this value will affect the material, if it has the
* corresponding uniform.
* @property {number} [maxElevationRange=1] - The maximal elevation of the
* layer. Changing this value will affect the material, if it has the
* corresponding uniform.
*/
class PointCloudLayer extends GeometryLayer {
/**
Expand All @@ -105,7 +121,6 @@ class PointCloudLayer extends GeometryLayer {
* directly, but rather implemented using `extends`.
*
* @constructor
* @extends GeometryLayer
*
* @param {string} id - The id of the layer, that should be unique. It is
* not mandatory, but an error will be emitted if this layer is added a
Expand Down Expand Up @@ -136,6 +151,8 @@ class PointCloudLayer extends GeometryLayer {

this.defineLayerProperty('minIntensityRange', config.minIntensityRange || 0, changeIntensityRange);
this.defineLayerProperty('maxIntensityRange', config.maxIntensityRange || 1, changeIntensityRange);
this.defineLayerProperty('minElevationRange', config.minElevationRange || 0, changeElevationRange);
this.defineLayerProperty('maxElevationRange', config.maxElevationRange || 1, changeElevationRange);

this.material = config.material || {};
if (!this.material.isMaterial) {
Expand Down
8 changes: 8 additions & 0 deletions src/Renderer/PointsMaterial.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ export const PNTS_MODE = {
INTENSITY: 1,
CLASSIFICATION: 2,
NORMAL: 3,
RETURN_NUMBER: 4,
NUMBER_OF_RETURNS: 5,
POINT_SOURCE_ID: 6,
ELEVATION: 7,
};

export const PNTS_SHAPE = {
Expand Down Expand Up @@ -68,6 +72,7 @@ class PointsMaterial extends THREE.RawShaderMaterial {
* @param {number} [options.mode=PNTS_SHAPE.CIRCLE] rendered points shape.
* @param {THREE.Vector4} [options.overlayColor=new THREE.Vector4(0, 0, 0, 0)] overlay color.
* @param {THREE.Vector2} [options.intensityRange=new THREE.Vector2(0, 1)] intensity range.
* @param {THREE.Vector2} [options.elevationRange=new THREE.Vector2(0, 1)] - elevation range.
* @param {boolean} [options.applyOpacityClassication=false] apply opacity classification on all display mode.
* @param {Classification} [options.classification] - define points classification.
* @param {number} [options.sizeMode=PNTS_SIZE_MODE.VALUE] point cloud size mode. Only 'VALUE' or 'ATTENUATED' are possible. VALUE use constant size, ATTENUATED compute size depending on distance from point to camera.
Expand All @@ -83,6 +88,7 @@ class PointsMaterial extends THREE.RawShaderMaterial {
*/
constructor(options = {}) {
const intensityRange = options.intensityRange || new THREE.Vector2(0, 1);
const elevationRange = options.elevationRange || new THREE.Vector2(0, 1);
const oiMaterial = options.orientedImageMaterial;
const classification = options.classification || ClassificationScheme.DEFAULT;
const applyOpacityClassication = options.applyOpacityClassication == undefined ? false : options.applyOpacityClassication;
Expand All @@ -95,6 +101,7 @@ class PointsMaterial extends THREE.RawShaderMaterial {

delete options.orientedImageMaterial;
delete options.intensityRange;
delete options.elevationRange;
delete options.classification;
delete options.applyOpacityClassication;
delete options.size;
Expand All @@ -121,6 +128,7 @@ class PointsMaterial extends THREE.RawShaderMaterial {
CommonMaterial.setUniformProperty(this, 'opacity', this.opacity);
CommonMaterial.setUniformProperty(this, 'overlayColor', options.overlayColor || new THREE.Vector4(0, 0, 0, 0));
CommonMaterial.setUniformProperty(this, 'intensityRange', intensityRange);
CommonMaterial.setUniformProperty(this, 'elevationRange', elevationRange);
CommonMaterial.setUniformProperty(this, 'applyOpacityClassication', applyOpacityClassication);
CommonMaterial.setUniformProperty(this, 'sizeMode', sizeMode);
CommonMaterial.setUniformProperty(this, 'preSSE', 1.0);
Expand Down
39 changes: 35 additions & 4 deletions src/Renderer/Shader/PointsVS.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,33 @@
#include <common>
#include <logdepthbuf_pars_vertex>

// For now, we only consider 3-bits uint values for return numbers.
// On LAS 1.4 PDRF >= 6, return numbers are encoded on 4 bits, so we clamp them
// to 3 bits.
#define RETURN_NUMBER_MAX 7.

attribute vec3 color;
attribute float intensity;
attribute float classification;
attribute float returnNumber;
attribute float numberOfReturns;
attribute float pointSourceID;
attribute float gpsTime;

uniform mat4 modelMatrix;

uniform vec2 intensityRange;
uniform vec2 elevationRange;

uniform float size;
uniform float preSSE;

uniform bool picking;
uniform int mode;
uniform float opacity;
uniform vec4 overlayColor;
uniform vec2 intensityRange;
uniform bool applyOpacityClassication;
attribute vec3 color;
attribute vec4 unique_id;
attribute float intensity;
attribute float classification;
uniform sampler2D classificationLUT;
uniform int sizeMode;
uniform float minAttenuatedSize;
Expand All @@ -28,6 +42,7 @@ uniform float maxAttenuatedSize;
#if defined(NORMAL_OCT16)
attribute vec2 oct16Normal;
#elif defined(NORMAL_SPHEREMAPPED)

attribute vec2 sphereMappedNormal;
#else
attribute vec3 normal;
Expand Down Expand Up @@ -97,6 +112,22 @@ void main() {
} else if (mode == PNTS_MODE_COLOR) {
// default to color mode
vColor.rgb = mix(color, overlayColor.rgb, overlayColor.a);
} else if (mode == PNTS_MODE_RETURN_NUMBER) {
float n = returnNumber / RETURN_NUMBER_MAX;
vColor.rgb = vec3(n, n, n);
} else if (mode == PNTS_MODE_NUMBER_OF_RETURNS) {
float n = numberOfReturns / RETURN_NUMBER_MAX;
vColor.rgb = vec3(n, n, n);
} else if (mode == PNTS_MODE_POINT_SOURCE_ID) {
// group ids by their 4 least significant bits
float i = mod(pointSourceID, 16.) / 16.;
vColor.rgb = vec3(i, i, i);
} else if (mode == PNTS_MODE_ELEVATION) {
// apply scale and offset transform
vec4 model = modelMatrix * vec4(position, 1.0);
float z = (model.z - elevationRange.x) / (elevationRange.y - elevationRange.x);
// adapt the grayscale knowing the range
vColor.rgb = vec3(z, z, z);
}
}

Expand Down

0 comments on commit f5fad38

Please sign in to comment.