Activate dormant ants from spawn buffer in shader
This commit is contained in:
parent
b8f49afcc4
commit
aa3c94091b
1 changed files with 56 additions and 25 deletions
|
|
@ -15,6 +15,7 @@ uniform sampler2D tWorld;
|
||||||
uniform sampler2D tPresence;
|
uniform sampler2D tPresence;
|
||||||
uniform float uForagerRatio;
|
uniform float uForagerRatio;
|
||||||
uniform sampler2D uMaterialProps;
|
uniform sampler2D uMaterialProps;
|
||||||
|
uniform vec4 uAntSpawn;
|
||||||
|
|
||||||
const float ANT_CARRY_STRENGTH = 1.0;
|
const float ANT_CARRY_STRENGTH = 1.0;
|
||||||
const float sampleDistance = 20.;
|
const float sampleDistance = 20.;
|
||||||
|
|
@ -94,38 +95,68 @@ void main() {
|
||||||
int antIndex = int(vUv.y * float(texSize.y)) * texSize.x + int(vUv.x * float(texSize.x));
|
int antIndex = int(vUv.y * float(texSize.y)) * texSize.x + int(vUv.x * float(texSize.x));
|
||||||
|
|
||||||
if (pos == vec2(0)) { // init new ant
|
if (pos == vec2(0)) { // init new ant
|
||||||
// only activate ants within the start count
|
bool spawnRequested = (uAntSpawn.w > 0.5);
|
||||||
if (antIndex >= ANTS_START_COUNT) {
|
|
||||||
// dormant ant — output zeros and skip everything
|
if (antIndex >= ANTS_START_COUNT && !spawnRequested) {
|
||||||
|
// dormant ant, no spawn request — skip
|
||||||
FragColor = vec4(0);
|
FragColor = vec4(0);
|
||||||
FragColorExt = vec4(0);
|
FragColorExt = vec4(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if VIEW_MODE_SIDE
|
if (antIndex >= ANTS_START_COUNT && spawnRequested) {
|
||||||
// spawn on sand surface: random X, scan down from top to find first non-air cell
|
// probabilistic activation: ~brushRadius ants per frame
|
||||||
float spawnX = rand(vUv * 10000.);
|
float activationChance = uAntSpawn.z / float(ANT_BUDGET);
|
||||||
float pixelSize = 1.0 / float(textureSize(tWorld, 0).x);
|
float roll = rand(vUv * 50000. + fract(uTime / 1000.));
|
||||||
float surfaceY = 0.6; // fallback if scan finds nothing
|
if (roll > activationChance) {
|
||||||
for (float scanY = 1.0; scanY > 0.0; scanY -= pixelSize) {
|
// not selected this frame — stay dormant
|
||||||
float matId = texture(tWorld, vec2(spawnX, scanY)).x;
|
FragColor = vec4(0);
|
||||||
if (matId > 0.5) { // non-air cell found
|
FragColorExt = vec4(0);
|
||||||
surfaceY = scanY + pixelSize; // one cell above the surface
|
return;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
// activate at spawn position with scatter
|
||||||
|
float scatter = uAntSpawn.z / WORLD_SIZE;
|
||||||
|
float rngX = rand(vUv * 10000. + fract(uTime / 1000.));
|
||||||
|
float rngY = rand(vUv * 20000. + fract(uTime / 1000.) + 0.5);
|
||||||
|
pos = vec2(
|
||||||
|
uAntSpawn.x + (rngX - 0.5) * scatter,
|
||||||
|
uAntSpawn.y + (rngY - 0.5) * scatter
|
||||||
|
);
|
||||||
|
pos = clamp(pos, 0., 1.);
|
||||||
|
angle = rand(vUv * 42069.) * 2.0 * PI;
|
||||||
|
isCarrying = 0.;
|
||||||
|
storage = 0.;
|
||||||
|
personality = rand(vUv * 42069.);
|
||||||
|
cargoMaterialId = 0.;
|
||||||
|
pathIntDx = 0.;
|
||||||
|
pathIntDy = 0.;
|
||||||
|
} else {
|
||||||
|
// normal init for starting ants
|
||||||
|
#if VIEW_MODE_SIDE
|
||||||
|
// spawn on sand surface: random X, scan down from top to find first non-air cell
|
||||||
|
float spawnX = rand(vUv * 10000.);
|
||||||
|
float pixelSize = 1.0 / float(textureSize(tWorld, 0).x);
|
||||||
|
float surfaceY = 0.6; // fallback if scan finds nothing
|
||||||
|
for (float scanY = 1.0; scanY > 0.0; scanY -= pixelSize) {
|
||||||
|
float matId = texture(tWorld, vec2(spawnX, scanY)).x;
|
||||||
|
if (matId > 0.5) { // non-air cell found
|
||||||
|
surfaceY = scanY + pixelSize; // one cell above the surface
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pos = vec2(spawnX, surfaceY);
|
||||||
|
angle = -PI * 0.5; // face downward initially
|
||||||
|
#else
|
||||||
|
pos = vec2(0.5);
|
||||||
|
angle = rand(vUv * 10000.) * 2. * PI;
|
||||||
|
#endif
|
||||||
|
isCarrying = 0.;
|
||||||
|
storage = 0.;
|
||||||
|
personality = rand(vUv * 42069.); // 0.0 = pure follower, 1.0 = pure explorer
|
||||||
|
cargoMaterialId = 0.;
|
||||||
|
pathIntDx = 0.;
|
||||||
|
pathIntDy = 0.;
|
||||||
}
|
}
|
||||||
pos = vec2(spawnX, surfaceY);
|
|
||||||
angle = -PI * 0.5; // face downward initially
|
|
||||||
#else
|
|
||||||
pos = vec2(0.5);
|
|
||||||
angle = rand(vUv * 10000.) * 2. * PI;
|
|
||||||
#endif
|
|
||||||
isCarrying = 0.;
|
|
||||||
storage = 0.;
|
|
||||||
personality = rand(vUv * 42069.); // 0.0 = pure follower, 1.0 = pure explorer
|
|
||||||
cargoMaterialId = 0.;
|
|
||||||
pathIntDx = 0.;
|
|
||||||
pathIntDy = 0.;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- GRAVITY AND SURFACE CHECK ---
|
// --- GRAVITY AND SURFACE CHECK ---
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue