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