Add second ant texture with MRT for extended ant state
This commit is contained in:
parent
221606b527
commit
cff99b7f08
6 changed files with 59 additions and 41 deletions
|
|
@ -7,8 +7,8 @@ interface Resources {
|
|||
worldRenderTarget: THREE.WebGLRenderTarget;
|
||||
worldRenderTargetCopy: THREE.WebGLRenderTarget;
|
||||
worldBlurredRenderTarget: THREE.WebGLRenderTarget;
|
||||
antsDataRenderTarget0: THREE.WebGLRenderTarget;
|
||||
antsDataRenderTarget1: THREE.WebGLRenderTarget;
|
||||
antsComputeTarget0: THREE.WebGLRenderTarget;
|
||||
antsComputeTarget1: THREE.WebGLRenderTarget;
|
||||
antsDiscreteRenderTarget: THREE.WebGLRenderTarget;
|
||||
}
|
||||
|
||||
|
|
@ -59,28 +59,8 @@ export default class Renderer {
|
|||
minFilter: THREE.NearestFilter,
|
||||
},
|
||||
),
|
||||
antsDataRenderTarget0: new THREE.WebGLRenderTarget(
|
||||
antTextureSize,
|
||||
antTextureSize,
|
||||
{
|
||||
format: THREE.RGBAFormat,
|
||||
type: THREE.FloatType,
|
||||
depthBuffer: false,
|
||||
magFilter: THREE.NearestFilter,
|
||||
minFilter: THREE.NearestFilter,
|
||||
},
|
||||
),
|
||||
antsDataRenderTarget1: new THREE.WebGLRenderTarget(
|
||||
antTextureSize,
|
||||
antTextureSize,
|
||||
{
|
||||
format: THREE.RGBAFormat,
|
||||
type: THREE.FloatType,
|
||||
depthBuffer: false,
|
||||
magFilter: THREE.NearestFilter,
|
||||
minFilter: THREE.NearestFilter,
|
||||
},
|
||||
),
|
||||
antsComputeTarget0: Renderer.makeAntsMRT(antTextureSize),
|
||||
antsComputeTarget1: Renderer.makeAntsMRT(antTextureSize),
|
||||
antsDiscreteRenderTarget: new THREE.WebGLRenderTarget(
|
||||
Config.worldSize,
|
||||
Config.worldSize,
|
||||
|
|
@ -95,6 +75,23 @@ export default class Renderer {
|
|||
};
|
||||
}
|
||||
|
||||
private static makeAntsMRT(size: number): THREE.WebGLRenderTarget {
|
||||
const mrt = new THREE.WebGLRenderTarget(size, size, {
|
||||
count: 2,
|
||||
type: THREE.FloatType,
|
||||
magFilter: THREE.NearestFilter,
|
||||
minFilter: THREE.NearestFilter,
|
||||
depthBuffer: false,
|
||||
});
|
||||
// both attachments get the same texture params
|
||||
for (const texture of mrt.textures) {
|
||||
texture.type = THREE.FloatType;
|
||||
texture.magFilter = THREE.NearestFilter;
|
||||
texture.minFilter = THREE.NearestFilter;
|
||||
}
|
||||
return mrt;
|
||||
}
|
||||
|
||||
public renderSimulation(scenes: SceneCollection) {
|
||||
const [antsComputeSource, antsComputeTarget] =
|
||||
scenes.ants.getRenderTargets();
|
||||
|
|
@ -108,7 +105,9 @@ export default class Renderer {
|
|||
this.setViewportFromRT(antsComputeTarget);
|
||||
this.renderer.setRenderTarget(antsComputeTarget);
|
||||
scenes.ants.material.uniforms.tLastState.value =
|
||||
antsComputeSource.texture;
|
||||
antsComputeSource.textures[0];
|
||||
scenes.ants.material.uniforms.tLastExtState.value =
|
||||
antsComputeSource.textures[1];
|
||||
scenes.ants.material.uniforms.tWorld.value =
|
||||
this.resources.worldBlurredRenderTarget.texture;
|
||||
this.renderer.render(scenes.ants, scenes.ants.camera);
|
||||
|
|
@ -116,9 +115,11 @@ export default class Renderer {
|
|||
this.setViewportFromRT(this.resources.antsDiscreteRenderTarget);
|
||||
this.renderer.setRenderTarget(this.resources.antsDiscreteRenderTarget);
|
||||
scenes.discretize.material.uniforms.tDataCurrent.value =
|
||||
antsComputeTarget.texture;
|
||||
antsComputeTarget.textures[0];
|
||||
scenes.discretize.material.uniforms.tDataLast.value =
|
||||
antsComputeSource.texture;
|
||||
antsComputeSource.textures[0];
|
||||
scenes.discretize.material.uniforms.tDataExtCurrent.value =
|
||||
antsComputeTarget.textures[1];
|
||||
this.renderer.render(scenes.discretize, scenes.discretize.camera);
|
||||
|
||||
this.setViewportFromRT(this.resources.worldRenderTarget);
|
||||
|
|
@ -129,7 +130,8 @@ export default class Renderer {
|
|||
this.resources.antsDiscreteRenderTarget.texture;
|
||||
this.renderer.render(scenes.world, scenes.world.camera);
|
||||
|
||||
scenes.screen.material.uniforms.tData.value = antsComputeTarget.texture;
|
||||
scenes.screen.material.uniforms.tData.value =
|
||||
antsComputeTarget.textures[0];
|
||||
scenes.screen.groundMaterial.uniforms.map.value =
|
||||
this.resources.worldRenderTargetCopy.texture;
|
||||
}
|
||||
|
|
@ -220,18 +222,18 @@ export default class Renderer {
|
|||
this.renderer.setRenderTarget(this.resources.worldBlurredRenderTarget);
|
||||
this.renderer.clear();
|
||||
|
||||
this.resources.antsDataRenderTarget0.setSize(
|
||||
this.resources.antsComputeTarget0.setSize(
|
||||
antTextureSize,
|
||||
antTextureSize,
|
||||
);
|
||||
this.renderer.setRenderTarget(this.resources.antsDataRenderTarget0);
|
||||
this.renderer.setRenderTarget(this.resources.antsComputeTarget0);
|
||||
this.renderer.clear();
|
||||
|
||||
this.resources.antsDataRenderTarget1.setSize(
|
||||
this.resources.antsComputeTarget1.setSize(
|
||||
antTextureSize,
|
||||
antTextureSize,
|
||||
);
|
||||
this.renderer.setRenderTarget(this.resources.antsDataRenderTarget1);
|
||||
this.renderer.setRenderTarget(this.resources.antsComputeTarget1);
|
||||
this.renderer.clear();
|
||||
|
||||
this.resources.antsDiscreteRenderTarget.setSize(
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ export default class AntsComputeScene extends AbstractScene {
|
|||
uniforms: {
|
||||
uTime: { value: 0 },
|
||||
tLastState: { value: null },
|
||||
tLastExtState: { value: null },
|
||||
tWorld: { value: null },
|
||||
},
|
||||
vertexShader,
|
||||
|
|
@ -32,8 +33,8 @@ export default class AntsComputeScene extends AbstractScene {
|
|||
this.material = material;
|
||||
|
||||
this.renderTargets = [
|
||||
this.renderer.resources.antsDataRenderTarget0,
|
||||
this.renderer.resources.antsDataRenderTarget1,
|
||||
this.renderer.resources.antsComputeTarget0,
|
||||
this.renderer.resources.antsComputeTarget1,
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ export default class AntsDiscretizeScene extends AbstractScene {
|
|||
uniforms: {
|
||||
tDataCurrent: { value: null },
|
||||
tDataLast: { value: null },
|
||||
tDataExtCurrent: { value: null },
|
||||
},
|
||||
vertexShader,
|
||||
fragmentShader,
|
||||
|
|
@ -36,8 +37,8 @@ export default class AntsDiscretizeScene extends AbstractScene {
|
|||
this.mesh = new THREE.InstancedMesh(
|
||||
new THREE.BoxGeometry(1, 1, 1),
|
||||
this.material,
|
||||
this.renderer.resources.antsDataRenderTarget0.width *
|
||||
this.renderer.resources.antsDataRenderTarget0.height,
|
||||
this.renderer.resources.antsComputeTarget0.width *
|
||||
this.renderer.resources.antsComputeTarget0.height,
|
||||
);
|
||||
this.add(this.mesh);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,8 +60,8 @@ export default class ScreenScene extends AbstractScene {
|
|||
this.material = new THREE.ShaderMaterial({
|
||||
uniforms: {
|
||||
tData: {
|
||||
value: this.renderer.resources.antsDataRenderTarget0
|
||||
.texture,
|
||||
value: this.renderer.resources.antsComputeTarget0
|
||||
.textures[0],
|
||||
},
|
||||
tAnt: { value: antTexture },
|
||||
tFood: { value: foodTexture },
|
||||
|
|
@ -182,8 +182,8 @@ export default class ScreenScene extends AbstractScene {
|
|||
const ants = new THREE.InstancedMesh(
|
||||
new THREE.PlaneGeometry(scale, scale),
|
||||
this.material,
|
||||
this.renderer.resources.antsDataRenderTarget0.width *
|
||||
this.renderer.resources.antsDataRenderTarget0.height,
|
||||
this.renderer.resources.antsComputeTarget0.width *
|
||||
this.renderer.resources.antsComputeTarget0.height,
|
||||
);
|
||||
|
||||
ants.position.x = ants.position.y = -0.5;
|
||||
|
|
|
|||
|
|
@ -5,10 +5,12 @@ precision highp int;
|
|||
|
||||
in vec2 vUv;
|
||||
|
||||
out vec4 FragColor;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(location = 1) out vec4 FragColorExt;
|
||||
|
||||
uniform float uTime;
|
||||
uniform sampler2D tLastState;
|
||||
uniform sampler2D tLastExtState;
|
||||
uniform sampler2D tWorld;
|
||||
|
||||
const float sampleDistance = 20.;
|
||||
|
|
@ -73,6 +75,7 @@ float getMaxScentStorage(vec2 antDataUv) {
|
|||
|
||||
void main() {
|
||||
vec4 lastState = texture(tLastState, vUv);
|
||||
vec4 lastExtState = texture(tLastExtState, vUv);
|
||||
|
||||
float noise = rand(vUv * 1000. + fract(uTime / 1000.));
|
||||
|
||||
|
|
@ -82,6 +85,11 @@ void main() {
|
|||
float storage = float(int(lastState.w) >> 1);
|
||||
bool wasObstacle = isObstacle(pos);
|
||||
|
||||
float personality = lastExtState.r;
|
||||
float cargoQuality = lastExtState.g;
|
||||
float pathIntDx = lastExtState.b;
|
||||
float pathIntDy = lastExtState.a;
|
||||
|
||||
bool movementProcessed = false;
|
||||
|
||||
if (pos == vec2(0)) { // init new ant
|
||||
|
|
@ -89,6 +97,10 @@ void main() {
|
|||
angle = rand(vUv * 10000.) * 2. * PI;
|
||||
isCarrying = 0.;
|
||||
storage = 0.;
|
||||
personality = rand(vUv * 42069.); // 0.0 = pure follower, 1.0 = pure explorer
|
||||
cargoQuality = 0.;
|
||||
pathIntDx = 0.;
|
||||
pathIntDy = 0.;
|
||||
}
|
||||
|
||||
if (isCarrying == 0.) {
|
||||
|
|
@ -201,4 +213,5 @@ void main() {
|
|||
angle,
|
||||
float((uint(max(storage - SCENT_PER_MARKER, 0.)) << 1) + uint(isCarrying))
|
||||
);
|
||||
FragColorExt = vec4(personality, cargoQuality, pathIntDx, pathIntDy);
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ out float vIsCellCleared;
|
|||
|
||||
uniform sampler2D tDataCurrent;
|
||||
uniform sampler2D tDataLast;
|
||||
uniform sampler2D tDataExtCurrent;
|
||||
|
||||
const float cellSize = 1. / WORLD_SIZE;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue