diff --git a/src/render/draw_atmosphere.js b/src/render/draw_atmosphere.js index bca63fb3094..87d0e170f82 100644 --- a/src/render/draw_atmosphere.js +++ b/src/render/draw_atmosphere.js @@ -9,7 +9,7 @@ import {atmosphereUniformValues} from '../terrain/globe_raster_program.js'; import type Painter from './painter.js'; import type {DynamicDefinesType} from '../render/program/program_uniforms.js'; import {degToRad, mapValue} from '../util/util.js'; -import {vec3} from 'gl-matrix'; +import {vec3, mat4, quat} from 'gl-matrix'; import Fog from '../style/fog.js'; export default drawAtmosphere; @@ -42,15 +42,21 @@ function drawAtmosphere(painter: Painter, fog: Fog) { const highColor = fog.properties.get('high-color').toArray01(); const spaceColor = fog.properties.get('space-color').toArray01PremultipliedAlpha(); + const orientation = quat.identity([]); + + quat.rotateY(orientation, orientation, -degToRad(tr._center.lng)); + quat.rotateX(orientation, orientation, degToRad(tr._center.lat)); + + quat.rotateZ(orientation, orientation, tr.angle); + quat.rotateX(orientation, orientation, -tr._pitch); + + const rotationMatrix = mat4.fromQuat(new Float32Array(16), orientation); + const starIntensity = mapValue(fog.properties.get('star-intensity'), 0.0, 1.0, 0.0, 0.25); // https://www.desmos.com/calculator/oanvvpr36d const horizonBlend = mapValue(fog.properties.get('horizon-blend'), 0.0, 1.0, 0.0, 0.25); const temporalOffset = (painter.frameCounter / 1000.0) % 1; - const latlon = [ - degToRad(tr._center.lat) / (Math.PI * 0.5), - degToRad(tr._center.lng) / Math.PI - ]; const globeCenterDistance = vec3.length(globeCenterInViewSpace); const distanceToHorizon = Math.sqrt(Math.pow(globeCenterDistance, 2.0) - Math.pow(globeRadius, 2.0)); @@ -70,10 +76,10 @@ function drawAtmosphere(painter: Painter, fog: Fog) { fogColor, highColor, spaceColor, - latlon, starIntensity, temporalOffset, - horizonAngle); + horizonAngle, + rotationMatrix); painter.prepareDrawProgram(context, program); diff --git a/src/shaders/atmosphere.fragment.glsl b/src/shaders/atmosphere.fragment.glsl index 054241c12bc..1922bbc2a6b 100644 --- a/src/shaders/atmosphere.fragment.glsl +++ b/src/shaders/atmosphere.fragment.glsl @@ -5,11 +5,11 @@ uniform vec3 u_start_color; uniform vec4 u_color; uniform vec4 u_space_color; uniform vec4 u_high_color; -uniform vec2 u_latlon; uniform float u_star_intensity; uniform float u_star_size; uniform float u_star_density; uniform float u_horizon_angle; +uniform mat4 u_rotation_matrix; varying highp vec3 v_ray_dir; varying highp vec3 v_horizon_dir; @@ -92,8 +92,21 @@ void main() { float a2 = mix(a0, a1, t); float a = mix(alpha_2, a2, t); - vec2 uv = (gl_FragCoord.xy / u_viewport) * (2.0 - 1.0); - vec3 D = vec3(uv + vec2(-u_latlon.y, -u_latlon.x), 1.0); + vec2 uv = gl_FragCoord.xy / u_viewport - 0.5; + float aspect_ratio = u_viewport.x / u_viewport.y; + + vec4 uv_dir = vec4(normalize(vec3(uv.x * aspect_ratio, uv.y, 1.0)), 1.0); + + uv_dir = u_rotation_matrix * uv_dir; + + vec3 n = abs(uv_dir.xyz); + vec2 uv_remap = (n.x > n.y && n.x > n.z) ? uv_dir.yz / uv_dir.x: + (n.y > n.x && n.y > n.z) ? uv_dir.zx / uv_dir.y: + uv_dir.xy / uv_dir.z; + + uv_remap.x /= aspect_ratio; + + vec3 D = vec3(uv_remap, 1.0); // Accumulate star field float star_field = 0.0; @@ -114,5 +127,7 @@ void main() { // Dither c = dither(c, gl_FragCoord.xy + u_temporal_offset); + // c = vec3(uv_remap, 1.0); + gl_FragColor = vec4(c, a); } diff --git a/src/terrain/globe_raster_program.js b/src/terrain/globe_raster_program.js index 7c4fe108836..ba18ca358e4 100644 --- a/src/terrain/globe_raster_program.js +++ b/src/terrain/globe_raster_program.js @@ -38,12 +38,12 @@ export type AtmosphereUniformsType = {| 'u_color': Uniform4f, 'u_high_color': Uniform4f, 'u_space_color': Uniform4f, - 'u_latlon': Uniform2f, 'u_star_intensity': Uniform1f, 'u_star_size': Uniform1f, 'u_star_density': Uniform1f, 'u_temporal_offset': Uniform1f, - 'u_horizon_angle': Uniform1f + 'u_horizon_angle': Uniform1f, + 'u_rotation_matrix': UniformMatrix4f |}; const globeRasterUniforms = (context: Context, locations: UniformLocations): GlobeRasterUniformsType => ({ @@ -70,12 +70,12 @@ const atmosphereUniforms = (context: Context, locations: UniformLocations): Atmo 'u_color': new Uniform4f(context, locations.u_color), 'u_high_color': new Uniform4f(context, locations.u_high_color), 'u_space_color': new Uniform4f(context, locations.u_space_color), - 'u_latlon': new Uniform2f(context, locations.u_latlon), 'u_star_intensity': new Uniform1f(context, locations.u_star_intensity), 'u_star_density': new Uniform1f(context, locations.u_star_density), 'u_star_size': new Uniform1f(context, locations.u_star_size), 'u_temporal_offset': new Uniform1f(context, locations.u_temporal_offset), - 'u_horizon_angle': new Uniform1f(context, locations.u_horizon_angle) + 'u_horizon_angle': new Uniform1f(context, locations.u_horizon_angle), + 'u_rotation_matrix': new UniformMatrix4f(context, locations.u_rotation_matrix) }); const globeRasterUniformValues = ( @@ -109,10 +109,10 @@ const atmosphereUniformValues = ( color: [number, number, number, number], skyColor: [number, number, number, number], spaceColor: [number, number, number, number], - latlon: [number, number], starIntensity: number, temporalOffset: number, - horizonAngle: number + horizonAngle: number, + rotationMatrix: Float32Array ): UniformValues => ({ 'u_frustum_tl': frustumDirTl, 'u_frustum_tr': frustumDirTr, @@ -127,12 +127,12 @@ const atmosphereUniformValues = ( 'u_color': color, 'u_high_color': skyColor, 'u_space_color': spaceColor, - 'u_latlon': latlon, 'u_star_intensity': starIntensity, 'u_star_size': 5.0 * browser.devicePixelRatio, 'u_star_density': 0.0, 'u_temporal_offset': temporalOffset, 'u_horizon_angle': horizonAngle, + 'u_rotation_matrix': rotationMatrix }); export {globeRasterUniforms, globeRasterUniformValues, atmosphereUniforms, atmosphereUniformValues};