Skip to content

Commit

Permalink
refacto(points): material as superset of three PointsMaterial
Browse files Browse the repository at this point in the history
BREAKING CHANGE:
* Remove overlayColor property (replaced by the standard diffuse property)
  • Loading branch information
Desplandis committed Jul 9, 2024
1 parent c93a2cd commit 63af9e2
Show file tree
Hide file tree
Showing 4 changed files with 278 additions and 87 deletions.
194 changes: 128 additions & 66 deletions src/Renderer/PointsMaterial.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,57 +186,56 @@ class PointsMaterial extends THREE.ShaderMaterial {
* pointMaterial.recomputeClassification();
*/
constructor(options = {}) {
const intensityRange = options.intensityRange || new THREE.Vector2(1, 65536);
const elevationRange = options.elevationRange || new THREE.Vector2(0, 1000);
const angleRange = options.angleRange || new THREE.Vector2(-90, 90);
const classificationScheme = options.classification || ClassificationScheme.DEFAULT;
const discreteScheme = options.discreteScheme || DiscreteScheme.DEFAULT;
const size = options.size || 0;
const mode = options.mode || PNTS_MODE.COLOR;
const shape = options.shape || PNTS_SHAPE.CIRCLE;
const sizeMode = size === 0 ? PNTS_SIZE_MODE.ATTENUATED : (options.sizeMode || PNTS_SIZE_MODE.VALUE);
const minAttenuatedSize = options.minAttenuatedSize || 3;
const maxAttenuatedSize = options.maxAttenuatedSize || 10;
let gradients = Gradients;
if (options.gradient) {
gradients = {
...options.gradient,
...Gradients,
};
}
const gradients = {
...options.gradient,
...Gradients,
};
options.gradient = Object.values(gradients)[0];

const {
intensityRange = new THREE.Vector2(1, 65536),
elevationRange = new THREE.Vector2(0, 1000),
angleRange = new THREE.Vector2(-90, 90),
classificationScheme = ClassificationScheme.DEFAULT,
discreteScheme = DiscreteScheme.DEFAULT,
size = 1,
mode = PNTS_MODE.COLOR,
shape = PNTS_SHAPE.CIRCLE,
sizeMode = PNTS_SIZE_MODE.ATTENUATED,
minAttenuatedSize = 3,
maxAttenuatedSize = 10,
gradient,
scale = 0.05 * 0.5 / Math.tan(1.0 / 2.0),
...materialOptions
} = options;

super({
...materialOptions,
fog: true,
precision: 'highp',
vertexColors: true,
});
this.uniforms = THREE.UniformsUtils.merge([
// THREE.PointsMaterial uniforms
THREE.UniformsLib.points,
THREE.UniformsLib.fog,
]);
this.vertexShader = PointsVS;
this.fragmentShader = PointsFS;

delete options.intensityRange;
delete options.elevationRange;
delete options.angleRange;
delete options.classification;
delete options.discreteScheme;
delete options.size;
delete options.mode;
delete options.shape;
delete options.sizeMode;
delete options.minAttenuatedSize;
delete options.maxAttenuatedSize;
delete options.gradient;

super(options);
this.userData.needTransparency = {};
this.gradients = gradients;
this.gradientTexture = new THREE.CanvasTexture();

this.vertexShader = PointsVS;

const scale = options.scale || 0.05 * 0.5 / Math.tan(1.0 / 2.0); // autosizing scale

CommonMaterial.setDefineMapping(this, 'PNTS_MODE', PNTS_MODE);
CommonMaterial.setDefineMapping(this, 'PNTS_SHAPE', PNTS_SHAPE);
CommonMaterial.setDefineMapping(this, 'PNTS_SIZE_MODE', PNTS_SIZE_MODE);

CommonMaterial.setUniformProperty(this, 'size', size);
this.size = size;
CommonMaterial.setUniformProperty(this, 'mode', mode);
CommonMaterial.setUniformProperty(this, 'shape', shape);
CommonMaterial.setUniformProperty(this, 'picking', false);
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, 'angleRange', angleRange);
Expand Down Expand Up @@ -268,16 +267,104 @@ class PointsMaterial extends THREE.ShaderMaterial {
this.recomputeDiscreteTexture();

// Gradient texture for continuous values
this.gradient = Object.values(gradients)[0];
this.gradient = gradient;
CommonMaterial.setUniformProperty(this, 'gradientTexture', this.gradientTexture);

this.fragmentShader = PointsFS;

if (__DEBUG__) {
this.defines.DEBUG = 1;
}
}

/**
* Copy the parameters from the passed material into this material.
* @override
* @param {THREE.PointsMaterial} source
* @returns {this}
*/
copy(source) {
if (source.isShaderMaterial) {
super.copy(source);
} else {
THREE.Material.prototype.copy.call(this, source);
}

// Parameters of THREE.PointsMaterial
this.color.copy(source.color);
this.map = source.map;
this.alphaMap = source.alphaMap;
this.size = source.size;
this.sizeAttenuation = source.sizeAttenuation;
this.fog = source.fog;

return this;
}

/** @returns {THREE.Color} */
get color() {
return this.uniforms.diffuse.value;
}

/** @param {THREE.Color} color */
set color(color) {
this.uniforms.diffuse.value.copy(color);
}

/** @returns {THREE.Texture | null} */
get map() {
return this.uniforms.map.value;
}

/** @param {THREE.Texture | null} map */
set map(map) {
this.uniforms.map.value = map;
if (!map) { return; }

if (map.matrixAutoUpdate) {
map.updateMatrix();
}

this.uniforms.uvTransform.value.copy(map.matrix);
}

/** @returns {THREE.Texture | null} */
get alphaMap() {
return this.uniforms.alphaMap.value;
}

/** @param {THREE.Texture | null} map */
set alphaMap(map) {
this.uniforms.alphaMap.value = map;
if (!map) { return; }

if (map.matrixAutoUpdate) {
map.updateMatrix();
}

this.uniforms.alphaMapTransform.value.copy(map.matrix);
}

/** @returns {number} */
get size() {
return this.uniforms.size.value;
}

/** @param {number} size */
set size(size) {
this.uniforms.size.value = size;
}

/** @returns {boolean} */
get sizeAttenuation() {
return this.sizeMode !== PNTS_SIZE_MODE.VALUE;
}

/** @param {boolean} value */
set sizeAttenuation(value) {
this.sizeMode = value ?
PNTS_SIZE_MODE.ATTENUATED :
PNTS_SIZE_MODE.VALUE;
}

recomputeClassification() {
const needTransparency = recomputeTexture(this.classificationScheme, this.classificationTexture, 256);
this.userData.needTransparency[PNTS_MODE.CLASSIFICATION] = needTransparency;
Expand All @@ -299,36 +386,11 @@ class PointsMaterial extends THREE.ShaderMaterial {
});
}

copy(source) {
super.copy(source);
return this;
}

enablePicking(picking) {
this.picking = picking;
this.blending = picking ? THREE.NoBlending : THREE.NormalBlending;
}

update(source) {
this.visible = source.visible;
this.opacity = source.opacity;
this.transparent = source.transparent;
this.size = source.size;
this.mode = source.mode;
this.shape = source.shape;
this.sizeMode = source.sizeMode;
this.minAttenuatedSize = source.minAttenuatedSize;
this.maxAttenuatedSize = source.maxAttenuatedSize;
this.picking = source.picking;
this.scale = source.scale;
this.overlayColor.copy(source.overlayColor);
this.intensityRange.copy(source.intensityRange);
this.elevationRange.copy(source.elevationRange);
this.angleRange.copy(source.angleRange);
Object.assign(this.defines, source.defines);
return this;
}

set gradient(value) {
this.gradientTexture = generateGradientTexture(value);
}
Expand Down
34 changes: 29 additions & 5 deletions src/Renderer/Shader/PointsFS.glsl
Original file line number Diff line number Diff line change
@@ -1,19 +1,43 @@
#include <itowns/precision_qualifier>
#define USE_COLOR_ALPHA

#include <color_pars_fragment>
#include <map_particle_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <fog_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>

uniform vec3 diffuse;
uniform float opacity;

varying vec4 vColor;
uniform bool picking;
uniform int shape;

void main() {
#include <logdepthbuf_fragment>
//square shape does not require any change.

// Early discard (clipping planes and shape)
#include <clipping_planes_pars_fragment>
if (shape == PNTS_SHAPE_CIRCLE) {
//circular rendering in glsl
if ((length(gl_PointCoord - 0.5) > 0.5) || (vColor.a == 0.0)) {
discard;
}
}

gl_FragColor = vColor;
#include <logdepthbuf_fragment>

vec4 diffuseColor = vec4(diffuse, opacity);
#include <map_particle_fragment>
#include <color_fragment>

#include <alphatest_fragment>
#include <alphahash_fragment>

vec3 outgoingLight = diffuseColor.rgb;
#include <opaque_fragment> // gl_FragColor
#include <tonemapping_fragment>
#include <fog_fragment>
#include <premultiplied_alpha_fragment>

}
40 changes: 24 additions & 16 deletions src/Renderer/Shader/PointsVS.glsl
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
#include <itowns/precision_qualifier>
#include <common>
#include <fog_pars_vertex>
#include <morphtarget_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
varying vec4 vColor; // color_pars_vertex

#ifdef USE_POINTS_UV
varying vec2 vUv;
uniform mat3 uvTransform;
#endif

#define NB_CLASS 8.

Expand All @@ -9,8 +17,6 @@ uniform float scale;

uniform bool picking;
uniform int mode;
uniform float opacity;
uniform vec4 overlayColor;

uniform vec2 elevationRange;
uniform vec2 intensityRange;
Expand All @@ -23,8 +29,6 @@ uniform int sizeMode;
uniform float minAttenuatedSize;
uniform float maxAttenuatedSize;

attribute vec3 color;
attribute vec2 range;
attribute vec4 unique_id;
attribute float intensity;
attribute float classification;
Expand All @@ -34,22 +38,22 @@ attribute float returnNumber;
attribute float numberOfReturns;
attribute float scanAngle;

varying vec4 vColor;

void main() {

vColor = vec4(1.0);
if (picking) {
vColor = unique_id;
} else {
vColor.a = 1.0;
if (mode == PNTS_MODE_CLASSIFICATION) {
vec2 uv = vec2(classification/255., 0.5);
vColor = texture2D(classificationTexture, uv);
} else if (mode == PNTS_MODE_NORMAL) {
vColor.rgb = abs(normal);
} else if (mode == PNTS_MODE_COLOR) {
// default to color mode
vColor.rgb = mix(color, overlayColor.rgb, overlayColor.a);
#if defined(USE_COLOR)
vColor.rgb = color.rgb;
#elif defined(USE_COLOR_ALPHA)
vColor = color;
#endif
} else if (mode == PNTS_MODE_RETURN_NUMBER) {
vec2 uv = vec2(returnNumber/255., 0.5);
vColor = texture2D(discreteTexture, uv);
Expand Down Expand Up @@ -96,12 +100,13 @@ void main() {
vec2 uv = vec2(i, (1. - i));
vColor = texture2D(gradientTexture, uv);
}

vColor.a *= opacity;
}

#include <begin_vertex>
#include <project_vertex>
#define USE_COLOR_ALPHA
#include <morphcolor_vertex>
#include <begin_vertex>
#include <morphtarget_vertex>
#include <project_vertex>

gl_PointSize = size;

Expand All @@ -114,5 +119,8 @@ void main() {
}
}

#include <logdepthbuf_vertex>
#include <logdepthbuf_vertex>
#include <clipping_planes_vertex>
#include <worldpos_vertex>
#include <fog_vertex>
}
Loading

0 comments on commit 63af9e2

Please sign in to comment.