Skip to content

Commit

Permalink
added(display): introduce [fillIntensity](https://heremaps.github.io/…
Browse files Browse the repository at this point in the history
…xyz-maps/docs/interfaces/core.polygonstyle.html#fillIntensity) to control color intensity of 3D styles under directional lighting

Signed-off-by: Tim Deubler <tim.deubler@here.com>
  • Loading branch information
TerminalTim committed Sep 6, 2024
1 parent dd1c171 commit c3dd04f
Show file tree
Hide file tree
Showing 11 changed files with 85 additions and 20 deletions.
13 changes: 13 additions & 0 deletions packages/core/src/styles/BoxStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,4 +268,17 @@ export interface BoxStyle {
* @defaultValue 32
*/
shininess?: number;

/**
* Controls the intensity of the fill color under directional lighting.
*
* `fillIntensity` determines how much the `"Box"`'s fill color is affected by the directional lighting in the scene.
* A higher value increases the intensity of the fill color, making it more vibrant under strong lighting,
* while a lower value reduces the effect, resulting in a more muted color.
*
* The value should range from 0 to 1, where 0 means no color intensity and 1 represents full intensity.
*
* @defaultValue 1
*/
fillIntensity?: number;
}
15 changes: 15 additions & 0 deletions packages/core/src/styles/GenericStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -677,4 +677,19 @@ export interface Style {
* @defaultValue 32
*/
shininess?: number;

/**
* Controls the intensity of the fill color under directional lighting.
*
* `fillIntensity` determines how much the feature's fill color is affected by the directional lighting in the scene.
* A higher value increases the intensity of the fill color, making it more vibrant under strong lighting,
* while a lower value reduces the effect, resulting in a more muted color.
*
* This property is only applicable for Styles of type `"Polygon"`, `"Box"` or `"Sphere"`;
*
* The value should range from 0 to 1, where 0 means no color intensity and 1 represents full intensity.
*
* @defaultValue 1
*/
fillIntensity?: number;
}
13 changes: 13 additions & 0 deletions packages/core/src/styles/PolygonStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,4 +257,17 @@ export interface PolygonStyle {
* @defaultValue 32
*/
shininess?: number;

/**
* Controls the intensity of the fill color under directional lighting.
*
* `fillIntensity` determines how much the polygon's fill color is affected by the directional lighting in the scene.
* A higher value increases the intensity of the fill color, making it more vibrant under strong lighting,
* while a lower value reduces the effect, resulting in a more muted color.
*
* The value should range from 0 to 1, where 0 means no color intensity and 1 represents full intensity.
*
* @defaultValue 1
*/
fillIntensity?: number;
}
13 changes: 13 additions & 0 deletions packages/core/src/styles/SphereStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,17 @@ export interface SphereStyle {
* @defaultValue 32
*/
shininess?: number;

/**
* Controls the intensity of the fill color under directional lighting.
*
* `fillIntensity` determines how much the `"Sphere"`'s fill color is affected by the directional lighting in the scene.
* A higher value increases the intensity of the fill color, making it more vibrant under strong lighting,
* while a lower value reduces the effect, resulting in a more muted color.
*
* The value should range from 0 to 1, where 0 means no color intensity and 1 represents full intensity.
*
* @defaultValue 1
*/
fillIntensity?: number;
}
6 changes: 5 additions & 1 deletion packages/display/src/displays/webgl/buffer/FeatureFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const {toRGB} = ColorUtils;
type RGBA = ColorUtils.RGBA;

const DEFAULT_SPECULAR_SHININESS = 32;
const DEFAULT_COLOR_INTENSITY = 1;
const DEFAULT_STROKE_WIDTH = 1;
const DEFAULT_LINE_CAP = 'round';
const DEFAULT_LINE_JOIN = 'round';
Expand Down Expand Up @@ -95,6 +96,7 @@ type DrawGroup = {
unit: string;
font: string;
fill: Float32Array;
fillIntensity: number;
// fill: Float32Array|LinearGradient;
opacity: number;
stroke: Float32Array;
Expand Down Expand Up @@ -536,6 +538,7 @@ export class FeatureFactory {
let specular;
let light: string;
let processAdvancedLight = false;
let colorIntensity = 1;

rotation = getValue('rotation', style, feature, level) ^ 0;
let altitude = getValue('altitude', style, feature, level);
Expand Down Expand Up @@ -731,7 +734,6 @@ export class FeatureFactory {

if (stroke) {
strokeRGBA = this.toRGBA(stroke, opacity);

if (type == 'Text') {
// don't apply stroke-scale to text rendering
strokeScale = 1;
Expand Down Expand Up @@ -783,6 +785,7 @@ export class FeatureFactory {
groupId += specular + shininess;
specular = this.toRGBA(specular).slice(0, 3);
}
colorIntensity = getValue('fillIntensity', style, feature, level) ?? DEFAULT_COLOR_INTENSITY;
}

groupId += (opacity * 100) ^ 0;
Expand Down Expand Up @@ -832,6 +835,7 @@ export class FeatureFactory {
unit: sizeUnit,
font,
fill: fillRGBA, // && fillRGBA.slice(0, 3),
fillIntensity: colorIntensity,
opacity,
stroke: strokeRGBA, // && strokeRGBA.slice(0, 3),
strokeWidth,
Expand Down
2 changes: 2 additions & 0 deletions packages/display/src/displays/webgl/buffer/createBuffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ const createBuffer = (
} else {
if (type == 'Polygon' || type == 'Extrude') {
geoBuffer.addUniform('u_fill', shared.fill);
geoBuffer.addUniform('u_fillIntensity', shared.fillIntensity);

if (type == 'Extrude') {
geoBuffer.addUniform('u_strokePass', 0);
Expand Down Expand Up @@ -283,6 +284,7 @@ const createBuffer = (
const fill = shared.fill || COLOR_UNDEFINED;

geoBuffer.addUniform('u_fill', fill);
geoBuffer.addUniform('u_fillIntensity', shared.fillIntensity);

if (stroke) {
geoBuffer.addUniform('u_stroke', stroke);
Expand Down
3 changes: 2 additions & 1 deletion packages/display/src/displays/webgl/glsl/box_fragment.glsl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
precision mediump float;

uniform vec4 u_fill;
uniform float u_fillIntensity;
uniform vec4 u_stroke;
varying vec3 vSize;

Expand Down Expand Up @@ -59,7 +60,7 @@ void main(void){
normal = normalize(v_normal);
#endif

color = computeBaseLighting(normal, color.rgb, u_fill.a);
color = computeBaseLighting(normal, color.rgb, u_fillIntensity, u_fill.a);

#ifdef SPECULAR
color = addSpecularHighlights(
Expand Down
23 changes: 13 additions & 10 deletions packages/display/src/displays/webgl/glsl/extrude_vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ attribute vec3 a_normal;
uniform mat4 u_matrix;
uniform vec2 u_topLeft;
uniform vec4 u_fill;
uniform float u_fillIntensity;
uniform bool u_strokePass;
uniform vec4 u_stroke;
uniform vec3 u_camWorld;
Expand All @@ -24,17 +25,19 @@ void main(void) {
vec3 worldPos = vec3(u_topLeft + a_position.xy, -a_position.z);
gl_Position = u_matrix * vec4(worldPos, 1.0);

vec4 color = u_strokePass ? u_stroke : u_fill;
if(u_strokePass){
v_fill = u_stroke;
}else{
// because exterior normals are stores as vec2 int8, when .xy equals 0 it must be top surfce normal, otherwise exterior normal (.z=0)
vec3 normal = a_normal.xy == TopSurfaceNormal.xy ? TopSurfaceNormal : a_normal;

// because exterior normals are stores as vec2 int8, when .xy equals 0 it must be top surfce normal, otherwise exterior normal (.z=0)
vec3 normal = a_normal.xy == TopSurfaceNormal.xy ? TopSurfaceNormal : a_normal;
vec4 light = computeBaseLighting(normal, u_fill.rgb, u_fillIntensity, u_fill.a);

vec4 light = computeBaseLighting(normal, color.rgb, color.a);
#ifdef SPECULAR
vec3 surfaceToCam = normalize(u_camWorld - worldPos);
light = addSpecularHighlights(normal, light, surfaceToCam, shininess, specular);
#endif

#ifdef SPECULAR
vec3 surfaceToCam = normalize(u_camWorld - worldPos);
light = addSpecularHighlights(normal, light, surfaceToCam, shininess, specular);
#endif

v_fill = light;
v_fill = light;
}
}
12 changes: 6 additions & 6 deletions packages/display/src/displays/webgl/glsl/light.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ uniform DirectionalLight u_directionalLight[MAX_DIR_LIGTHS];
uniform int u_numDirectionalLights;


vec4 computeBaseLighting(vec3 normal, vec3 color, float alpha) {
vec4 computeBaseLighting(vec3 normal, vec3 color, float colorIntensity, float alpha) {
vec3 totalLighting = color * u_ambient.color * u_ambient.intensity;

//Directional/diffuse Lights
for (int i = 0; i < MAX_DIR_LIGTHS; i++) {
if (i >= u_numDirectionalLights) break;
vec3 lightDir = normalize(u_directionalLight[i].direction);
float diff = max(dot(normal, lightDir), 0.0);
vec3 directionalColor = u_directionalLight[i].color * color; // * colorIntensity;
vec3 directionalColor = u_directionalLight[i].color * color * colorIntensity;
vec3 diffuse = diff * directionalColor * u_directionalLight[i].intensity;
totalLighting += diffuse;
}
Expand All @@ -56,13 +56,13 @@ vec4 addSpecularHighlights(vec3 normal, vec4 totalLighting, vec3 surfaceToCam, f
return totalLighting;
}
#ifdef SPECULAR
vec4 computeLighting(vec3 normal, vec3 color, float alpha, vec3 surfaceToCam, float shininess, vec3 specular) {
vec4 light = computeBaseLighting(normal, color, alpha);
vec4 computeLighting(vec3 normal, vec3 color, float colorIntensity, float alpha, vec3 surfaceToCam, float shininess, vec3 specular) {
vec4 light = computeBaseLighting(normal, color, colorIntensity, alpha);
light = addSpecularHighlights(normal, light, surfaceToCam, shininess, specular);
return light;
}
#else
vec4 computeLighting(vec3 normal, vec3 color, float alpha) {
return computeBaseLighting(normal, color, alpha);
vec4 computeLighting(vec3 normal, vec3 color, float colorIntensity, float alpha) {
return computeBaseLighting(normal, color, colorIntensity, alpha);
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void main() {

vec4 diffuseMapColor = texture2D(diffuseMap, v_texCoord);
vec3 color = diffuse * diffuseMapColor.rgb * v_color.rgb;
vec4 totalColor = computeBaseLighting(normal, color, opacity * v_color.a);
vec4 totalColor = computeBaseLighting(normal, color, 1.0, opacity * v_color.a);

#ifdef SPECULAR
totalColor = addSpecularHighlights(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
precision lowp float;

uniform vec4 u_fill;
uniform float u_fillIntensity;

#ifdef SPECULAR
#include "light.glsl"
Expand All @@ -18,7 +19,7 @@ void main(void) {

#ifdef SPECULAR
// Compute lighting with specular component
vec4 light = computeBaseLighting(surfaceNormal, u_fill.rgb, u_fill.a);
vec4 light = computeBaseLighting(surfaceNormal, u_fill.rgb, u_fillIntensity, u_fill.a);
light = addSpecularHighlights(surfaceNormal, light, v_surfaceToCam, shininess, specular);

gl_FragColor = light;
Expand Down

0 comments on commit c3dd04f

Please sign in to comment.