I am working on a hex-based game. I am currently trying to add a "fog of war" effect where certain tiles lay under an alpha mask to show that information is unknown. Unfortunately I'm running into some problems achieving the effect that I want. The way I'm implementing the fog is to create a mesh over all the tiles that has no alpha if the tile is "visible" and .7 if it is not. I think adjust the mesh position based on the camera position so it always stays in perspective. This is the effect:
Unfortunately, the first way I tried to do this has an undesired effect at low viewing angles. Because I'm shifting the fog to lay over tiles even as perspective changes, at low angles it will also cover the tops of mountains and trees. See below:
The second thing I tried was implementing a two scene solution from How to change the zOrder of object with Threejs?. I put the fog and the unseen tiles in one scene, and the seen tiles in another, and then rendered the seen tiles on top of the unseen. That solved the darkness problem for far tiles, however it now introduces another problem for near tiles. See below:
I'm a little stumped what to do. I'm fairly new to THREE.js (at least the more advanced parts of the library) so I'm wondering if there's something I'm missing that might work.
For reference, here's my vertex shader for the fog:
varying vec4 vColor;
void main() {
vec3 cRel = cameraPosition - position;
float dx = (20.0 * cRel.x) / cRel.y;
float dz = (20.0 * cRel.z) / cRel.y;
gl_Position = projectionMatrix *
modelViewMatrix *
vec4(
position.x + dx,
position.y,
position.z + dz,
1.0
);
if(color.x == 1.0 && color.y == 1.0 && color.z == 1.0) {
vColor = vec4(0.0, 0.0, 0.0, 0.0);
} else {
vColor = vec4(color, 0.7);
}
}
and my fragment shader:
varying vec4 vColor;
float expGradient(float val, float max) {
return (max + 1.0 / 10.0) * val / (val + 1.0 / 10.0);
}
void main() {
gl_FragColor = vec4(
vColor.x,
vColor.y,
vColor.z,
expGradient(vColor.w, 0.7)
);
}
I'm using the color of (1.0, 1.0, 1.0) to signify that it should be "seen".