renderer: add generic scalar field color path

This commit is contained in:
OpenAI Codex
2026-09-10 22:41:55 +08:00
parent 9dabb95e44
commit 09ead7f201
10 changed files with 125 additions and 56 deletions

View File

@@ -47,9 +47,10 @@ float mercatorLatitudeRadians(float worldY) {
return atan(sinh(3.141592653589793 * (1.0 - 2.0 * worldY)));
}
vec3 weatherSpeedColor(float speed) {
// Fixed 0..30 m/s scale: no per-frame or per-dataset auto stretching.
float t = clamp(speed / 30.0, 0.0, 1.0);
vec3 weatherDefaultValueColor(float value) {
// Historical default ramp endpoints are 0 and 30 generic field-value
// units. Hosts provide explicit stops whenever another scale is needed.
float t = clamp(value / 30.0, 0.0, 1.0);
vec3 slow = vec3(0.08, 0.18, 0.65);
vec3 medium = vec3(0.08, 0.80, 0.78);
vec3 fast = vec3(0.98, 0.22, 0.10);
@@ -82,15 +83,15 @@ bool fieldVelocityAt(vec2 position, out vec2 velocity) {
length(velocity) > 0.00001;
}
vec4 weatherRampColor(float speed) {
vec4 weatherRampColor(float value) {
int count = int(u_weather_ramp.x);
if (count < 2) return vec4(weatherSpeedColor(speed), 1.0);
if (count < 2) return vec4(weatherDefaultValueColor(value), 1.0);
vec4 color = u_weather_colors[0];
for (int i = 1; i < 8; ++i) {
if (i >= count) break;
float lo = u_weather_stops[i - 1].x;
float hi = u_weather_stops[i].x;
if (speed <= hi) return mix(color, u_weather_colors[i], clamp((speed - lo) / (hi - lo), 0.0, 1.0));
if (value <= hi) return mix(color, u_weather_colors[i], clamp((value - lo) / (hi - lo), 0.0, 1.0));
color = u_weather_colors[i];
}
return color;
@@ -105,11 +106,20 @@ void main() {
vec4 field0 = texture(u_field_texture, uv);
vec4 field1 = texture(u_next_field_texture, uv);
if (field0.a < 0.5 || field1.a < 0.5) discard;
vec2 velocity = mix((field0.rg * 2.0 - 1.0) * u_field_scale.x,
(field1.rg * 2.0 - 1.0) * u_field_scale.y,
u_marker.x);
if (any(isnan(velocity))) discard;
vec4 color = weatherRampColor(length(velocity));
float fieldValue;
if (u_weather_ramp.y > 0.5) {
vec2 vectorValue = mix((field0.rg * 2.0 - 1.0) * u_field_scale.x,
(field1.rg * 2.0 - 1.0) * u_field_scale.y,
u_marker.x);
if (any(isnan(vectorValue))) discard;
fieldValue = length(vectorValue);
} else {
fieldValue = mix((field0.r * 2.0 - 1.0) * u_field_scale.x,
(field1.r * 2.0 - 1.0) * u_field_scale.y,
u_marker.x);
if (isnan(fieldValue)) discard;
}
vec4 color = weatherRampColor(fieldValue);
float alpha = color.a * u_visual.x;
fragColor = vec4(color.rgb * alpha, alpha);
return;