119 lines
5.1 KiB
C++
119 lines
5.1 KiB
C++
// Generated code, do not modify this file!
|
|
#pragma once
|
|
#include <mbgl/shaders/shader_source.hpp>
|
|
|
|
namespace mbgl {
|
|
namespace shaders {
|
|
|
|
template <>
|
|
struct ShaderSource<BuiltIn::ParticleGpuValidationShader, gfx::Backend::Type::OpenGL> {
|
|
static constexpr const char* name = "ParticleGpuValidationShader";
|
|
static constexpr const char* vertex = R"(layout (location = 0) in vec2 a_pos;
|
|
|
|
out vec2 v_uv;
|
|
out vec2 v_world;
|
|
|
|
layout (std140) uniform ParticleGpuValidationUBO {
|
|
highp vec4 u_pass;
|
|
highp vec4 u_marker;
|
|
highp vec4 u_mask;
|
|
highp mat4 u_matrix;
|
|
};
|
|
|
|
void main() {
|
|
v_uv = a_pos;
|
|
v_world = a_pos;
|
|
if (u_pass.x < 1.5) {
|
|
gl_Position = vec4(a_pos * 2.0 - 1.0, 0.0, 1.0);
|
|
} else {
|
|
// VALIDATION ONLY: a_pos is canonical z0 world geometry; u_matrix is
|
|
// PaintParameters::matrixForTile() for the selected MapLibre world copy.
|
|
gl_Position = u_matrix * vec4(a_pos * 8192.0, 0.0, 1.0);
|
|
}
|
|
}
|
|
)";
|
|
static constexpr const char* fragment = R"(layout (std140) uniform ParticleGpuValidationUBO {
|
|
highp vec4 u_pass;
|
|
highp vec4 u_marker;
|
|
highp vec4 u_mask;
|
|
highp mat4 u_matrix;
|
|
};
|
|
|
|
uniform sampler2D u_previous;
|
|
uniform sampler2D u_mask_texture;
|
|
uniform sampler2D u_field_texture;
|
|
uniform sampler2D u_next_field_texture;
|
|
uniform sampler2D u_state_texture;
|
|
in vec2 v_uv;
|
|
in vec2 v_world;
|
|
|
|
void main() {
|
|
vec4 previous = texture(u_previous, v_uv);
|
|
float mode = u_pass.x;
|
|
|
|
if (mode < 0.5) {
|
|
// 40-01: State A/B samples the uploaded OfflineFixture Particle Field.
|
|
// RG stores field-normalized position, B stores age, and the Field
|
|
// texture encodes canonical U-east/V-north at that geographic sample.
|
|
// u_mask.w is the explicit State lifecycle flag: new RenderTargets are
|
|
// cleared opaque by MapLibre, so sampled alpha cannot identify a seed.
|
|
vec2 position = u_mask.w > 0.5 ? v_uv : previous.rg;
|
|
// 40-02: decode each independent Field texture, then interpolate the
|
|
// velocity on GPU. u_marker.x is the clamped Layer timeMix property.
|
|
vec4 field0 = texture(u_field_texture, position);
|
|
vec4 field1 = texture(u_next_field_texture, position);
|
|
vec2 velocity = mix(field0.rg * 2.0 - 1.0, field1.rg * 2.0 - 1.0, u_marker.x);
|
|
if (field0.a < 0.5 || field1.a < 0.5) {
|
|
position = v_uv;
|
|
velocity = vec2(0.0);
|
|
}
|
|
position = fract(position + velocity * u_pass.y * 0.004);
|
|
if (any(isnan(velocity))) position = v_uv;
|
|
fragColor = vec4(position, fract(previous.b + 0.03125 * u_pass.y), 1.0);
|
|
} else if (mode < 1.5) {
|
|
// The trail consumes State B/A written by the real field-sampling pass.
|
|
// Four deterministic texels are enough for the Stage A visual proof.
|
|
float marker = 0.0;
|
|
marker = max(marker, 1.0 - smoothstep(0.0, u_marker.z, distance(v_uv, texture(u_state_texture, vec2(0.125, 0.125)).rg)));
|
|
marker = max(marker, 1.0 - smoothstep(0.0, u_marker.z, distance(v_uv, texture(u_state_texture, vec2(0.375, 0.375)).rg)));
|
|
marker = max(marker, 1.0 - smoothstep(0.0, u_marker.z, distance(v_uv, texture(u_state_texture, vec2(0.625, 0.625)).rg)));
|
|
marker = max(marker, 1.0 - smoothstep(0.0, u_marker.z, distance(v_uv, texture(u_state_texture, vec2(0.875, 0.875)).rg)));
|
|
vec3 color = previous.rgb * u_marker.w + marker * vec3(0.08, 0.55, 1.0);
|
|
fragColor = vec4(min(color, vec3(1.0)), 1.0);
|
|
} else {
|
|
// The formal RasterParticle layer displays the Trail texture written by
|
|
// the current State -> Trail pass. Legacy ParticleValidation keeps its
|
|
// independent 30-03 stripe/anchor diagnostic display below.
|
|
float intensity = max(previous.r, max(previous.g, previous.b));
|
|
float ocean = texture(u_mask_texture, v_world).a;
|
|
if (u_pass.z > 0.5 && ocean < 0.5) discard;
|
|
if (u_mask.z > 0.5) {
|
|
float alpha = clamp(intensity * 1.25, 0.0, 0.96);
|
|
fragColor = vec4(previous.rgb * alpha, alpha);
|
|
return;
|
|
}
|
|
|
|
// LEGACY VALIDATION DISPLAY: preserve the frozen 30-03
|
|
// stripe/anchor/world-wrap diagnostic for ParticleValidationLayer.
|
|
float stripe = 0.55 + 0.45 * sin((v_world.x + v_world.y) * 100.0 + u_pass.y * 0.07);
|
|
// A=(0°,0°), B=(-90°,approximately 0°), C/D straddle ±180°.
|
|
float anchors = 0.0;
|
|
anchors = max(anchors, 1.0 - smoothstep(0.0, 0.008, distance(v_world, vec2(0.50, 0.50))));
|
|
anchors = max(anchors, 1.0 - smoothstep(0.0, 0.008, distance(v_world, vec2(0.25, 0.50))));
|
|
anchors = max(anchors, 1.0 - smoothstep(0.0, 0.008, distance(v_world, vec2(0.02, 0.50))));
|
|
anchors = max(anchors, 1.0 - smoothstep(0.0, 0.008, distance(v_world, vec2(0.98, 0.50))));
|
|
vec3 color = u_pass.w < 1.5 ? vec3(0.10, 0.70, 1.00) : vec3(0.35, 1.00, 0.45);
|
|
fragColor = vec4(mix(color * stripe, vec3(1.00, 0.82, 0.15), anchors),
|
|
0.28 + min(intensity, 0.35) * 0.35 + anchors * 0.35);
|
|
}
|
|
|
|
#ifdef OVERDRAW_INSPECTOR
|
|
fragColor = vec4(1.0);
|
|
#endif
|
|
}
|
|
)";
|
|
};
|
|
|
|
} // namespace shaders
|
|
} // namespace mbgl
|