fix: keep particle density stable across zoom
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled

This commit is contained in:
OpenAI Codex
2026-09-05 12:23:15 +08:00
parent d9a9c8ed57
commit f8e715d080
8 changed files with 178 additions and 6 deletions

View File

@@ -4,6 +4,7 @@ layout (std140) uniform ParticleGpuValidationUBO {
highp vec4 u_mask;
highp vec4 u_visual;
highp vec4 u_field_bounds;
highp vec4 u_respawn_bounds;
highp vec4 u_field_scale;
highp mat4 u_matrix;
};
@@ -57,7 +58,12 @@ float particleHash(vec2 value) {
vec2 respawnSeed(vec2 particleUV, vec2 entropy, float attempt) {
vec2 salt = entropy * vec2(13.17, 19.91) + particleUV * vec2(97.23, 53.71) + attempt;
vec2 random = vec2(particleHash(salt), particleHash(salt.yx + 41.29));
return mix(u_field_bounds.xy, u_field_bounds.zw, random);
return mix(u_respawn_bounds.xy, u_respawn_bounds.zw, random);
}
bool outsideRespawnBounds(vec2 position) {
return position.x < u_respawn_bounds.x || position.x > u_respawn_bounds.z ||
position.y < u_respawn_bounds.y || position.y > u_respawn_bounds.w;
}
bool fieldVelocityAt(vec2 position, out vec2 velocity) {
@@ -111,7 +117,11 @@ void main() {
vec2 position = previous.rg;
vec2 velocity;
bool valid = !respawn && fieldVelocityAt(position, velocity);
if (!valid || age >= maxAge) {
// The field bounds remain the only sampling domain. Once the
// camera is stable, slots already outside the expanded viewport
// may recycle into its separate preferred respawn domain.
if (!valid || age >= maxAge ||
(u_field_scale.z > 0.5 && !initialSeed && outsideRespawnBounds(position))) {
respawn = true;
}