diff --git a/src/shaders/fill_extrusion.fragment.glsl b/src/shaders/fill_extrusion.fragment.glsl index 34acd23c86b..239fbdf04a0 100644 --- a/src/shaders/fill_extrusion.fragment.glsl +++ b/src/shaders/fill_extrusion.fragment.glsl @@ -6,9 +6,11 @@ varying highp vec4 v_pos_light_view_1; varying float v_depth; #endif +uniform lowp float u_opacity; + #ifdef FAUX_AO uniform lowp vec2 u_ao; -varying vec3 v_ao; +varying vec2 v_ao; #endif #ifdef ZERO_ROOF_RADIUS @@ -19,9 +21,15 @@ varying vec4 v_roof_color; varying highp vec3 v_normal; #endif +uniform vec3 u_flood_light_color; uniform highp float u_vertical_scale; +#if defined(LIGHTING_3D_MODE) && defined(FLOOD_LIGHT) +varying float v_flood_radius; varying float v_has_floodlight; +#endif + +varying float v_height; void main() { @@ -37,9 +45,9 @@ vec4 color; #else color = v_color; #endif +float h = max(0.0, v_height); #ifdef FAUX_AO float intensity = u_ao[0]; - float h = max(0.0, v_ao.z); float h_floors = h / (u_ao[1] * u_vertical_scale); float y_shade = 1.0 - 0.9 * intensity * min(v_ao.y, 1.0); float shade = (1.0 - 0.08 * intensity) * (y_shade + (1.0 - y_shade) * (1.0 - pow(1.0 - min(h_floors / 16.0, 1.0), 16.0))) + 0.08 * intensity * min(h_floors / 160.0, 1.0); @@ -59,6 +67,13 @@ vec4 color; #endif #endif +#if defined(LIGHTING_3D_MODE) && defined(FLOOD_LIGHT) + vec3 flood_radiance = u_flood_light_color * (1.0 - min(h / v_flood_radius, 1.0)); + color.rgb += flood_radiance * v_has_floodlight; + color.rgb = linearTosRGB(color.rgb); + color *= u_opacity; +#endif + #ifdef RENDER_SHADOWS #ifdef ZERO_ROOF_RADIUS normal = mix(normal, vec3(0.0, 0.0, 1.0), z); diff --git a/src/shaders/fill_extrusion.vertex.glsl b/src/shaders/fill_extrusion.vertex.glsl index 9bcef466c22..7c7166cedf7 100644 --- a/src/shaders/fill_extrusion.vertex.glsl +++ b/src/shaders/fill_extrusion.vertex.glsl @@ -22,7 +22,6 @@ uniform vec3 u_up_dir; uniform float u_height_lift; #endif -uniform highp vec3 u_flood_light_color; uniform highp float u_vertical_scale; varying vec4 v_color; @@ -46,10 +45,15 @@ varying highp vec3 v_normal; #ifdef FAUX_AO uniform lowp vec2 u_ao; -varying vec3 v_ao; +varying vec2 v_ao; #endif +#if defined(LIGHTING_3D_MODE) && defined(FLOOD_LIGHT) +varying float v_flood_radius; varying float v_has_floodlight; +#endif + +varying float v_height; #pragma mapbox: define highp float base #pragma mapbox: define highp float height @@ -65,7 +69,6 @@ void main() { base *= u_vertical_scale; height *= u_vertical_scale; - wall_flood_light_radius *= u_vertical_scale; vec4 pos_nx = floor(a_pos_normal_ed * 0.5); // The least significant bits of a_pos_normal_ed hold: @@ -122,6 +125,7 @@ void main() { float hidden = float(centroid_pos.x == 0.0 && centroid_pos.y == 1.0); gl_Position = mix(u_matrix * vec4(pos, 1), AWAY, hidden); h = h - ele; + v_height = h; #ifdef RENDER_SHADOWS v_pos_light_view_0 = u_light_matrix_0 * vec4(pos, 1); @@ -176,7 +180,7 @@ void main() { top_height = mix(max(c_ele + height, ele + base + 2.0), ele + height, float(centroid_pos.x == 0.0)) - ele; y_ground += y_ground * 5.0 / max(3.0, top_height); #endif - v_ao = vec3(mix(concave, -concave, start), y_ground, h); + v_ao = vec2(mix(concave, -concave, start), y_ground); NdotL *= (1.0 + 0.05 * (1.0 - top_up_ny.y) * u_ao[0]); // compensate sides faux ao shading contribution #ifdef PROJECTION_GLOBE_VIEW @@ -189,13 +193,12 @@ void main() { #ifdef FLOOD_LIGHT float is_wall = 1.0 - float(t > 0.0 && top_up_ny.y > 0.0); - v_has_floodlight = float(wall_flood_light_radius > 0.0); + v_has_floodlight = float(wall_flood_light_radius > 0.0 && is_wall > 0.0); + v_flood_radius = wall_flood_light_radius * u_vertical_scale; v_color = apply_lighting_linear(color, NdotL); - vec3 flood_radiance = u_flood_light_color * (1.0 - min(max(0.0, h) / wall_flood_light_radius, 1.0)); - v_color.rgb += flood_radiance * v_has_floodlight * is_wall; - v_color.rgb = linearTosRGB(v_color.rgb); #else v_color = apply_lighting(color, NdotL); + v_color *= u_opacity; #endif #else @@ -203,9 +206,8 @@ void main() { // with lower bounds adjusted to hue of light // so that shading is tinted with the complementary (opposite) color to the light color v_color.rgb += clamp(color.rgb * NdotL * u_lightcolor, mix(vec3(0.0), vec3(0.3), 1.0 - u_lightcolor), vec3(1.0)); -#endif - v_color *= u_opacity; +#endif #ifdef ZERO_ROOF_RADIUS v_roof_color = vec4(0.0, 0.0, 0.0, 1.0); diff --git a/test/integration/render-tests/lighting-3d-mode/fill-extrusion/flood-light-fixed-radius/expected.png b/test/integration/render-tests/lighting-3d-mode/fill-extrusion/flood-light-fixed-radius/expected.png new file mode 100644 index 00000000000..4a61e6ea431 Binary files /dev/null and b/test/integration/render-tests/lighting-3d-mode/fill-extrusion/flood-light-fixed-radius/expected.png differ diff --git a/test/integration/render-tests/lighting-3d-mode/fill-extrusion/flood-light-fixed-radius/style.json b/test/integration/render-tests/lighting-3d-mode/fill-extrusion/flood-light-fixed-radius/style.json new file mode 100644 index 00000000000..bae223d1ed5 --- /dev/null +++ b/test/integration/render-tests/lighting-3d-mode/fill-extrusion/flood-light-fixed-radius/style.json @@ -0,0 +1,84 @@ +{ + "version": 8, + "metadata": { + "test": { + "width": 512, + "height": 512, + "allowed": 0.0006 + } + }, + "lights": [ + { + "type": "ambient", + "id": "environment", + "properties": { + "color": "rgba(200.0, 200.0, 255.0, 1.0)", + "intensity": 0.4 + } + }, + { + "type": "directional", + "id": "sun_light", + "properties": { + "color": "rgba(230.0, 230.0, 230.0, 1.0)", + "intensity": 0.9, + "direction": [ + 200.0, + 40.0 + ] + } + } + ], + "sources": { + "mapbox": { + "type": "vector", + "maxzoom": 16, + "tiles": [ + "local://tiles/{z}-{x}-{y}.mvt" + ] + } + }, + "pitch": 66.5, + "zoom": 17.5, + "bearing": 320, + "center": [ + -74.0125, + 40.7152 + ], + "layers": [ + { + "id": "background", + "type": "background", + "paint": { + "background-color": "lightgray" + } + }, + { + "id": "extrusion", + "type": "fill-extrusion", + "source": "mapbox", + "source-layer": "building", + "paint": { + "fill-extrusion-color": "white", + "fill-extrusion-height": [ + "get", + "height" + ], + "fill-extrusion-opacity": 1.0, + "fill-extrusion-wall-flood-light-radius": 20, + "fill-extrusion-flood-light-color": [ + "rgb", + 255, + 255, + 0 + ], + "fill-extrusion-flood-light-intensity": 0.7, + "fill-extrusion-ambient-occlusion-radius": 1, + "fill-extrusion-ambient-occlusion-intensity": 0.4 + }, + "layout": { + "fill-extrusion-edge-radius": 0.99 + } + } + ] +} \ No newline at end of file