fenomas / noa

Experimental voxel game engine.
MIT License
611 stars 87 forks source link

How to make water get darker closer to the bottom #124

Closed csf30816 closed 3 years ago

csf30816 commented 4 years ago

I am wondering how I can make the water get darker and have less visibility the farther down it goes. I tried using fog to get this effect but I couldn't get the results I wanted. Any help is appreciated greatly!

image

I'd like it to get less transparent and darker that's all :) Oh I also tried creating multiple shades of water and assigning them based on distance from the waterline but because of how the fluid works in this engine that only changes the visibility once you are under water.

fenomas commented 4 years ago

Hi, this would be a really nice feature! I don't have any good ideas offhand for how to implement it though. Certainly open to ideas.

csf30816 commented 4 years ago

yeah, I got no clue, other than darkening blocks that are farther away and underwater, that might work.

With logic like this:

if (underWaterBlock(x, y, z)) {
    return blockType("sand" + Math.min(distanceFromPlayer(x, y, z) / someValue, maxShades))
} else return blockType("sand");

the only problem is you'd have to update that every player move.

johnhorsema commented 4 years ago

What if the logic becomes


if (notSwimming) {
  for(block in visibleWaterBlocks) {
    return blockType("sand" + Math.min(distanceFromGround / someValue, maxShades))
  }
}
else {
  for(block in visibleWaterBlocks) {
    return blockType("sand" + Math.min(distanceFromPlayer(x, y, z) / someValue, maxShades))
  }
}
fenomas commented 4 years ago

So the problem with those last two ideas is that you'd need to be re-meshing large amounts of terrain as the player moved around, which would not scale.

Having thought more about this, an effect like this could be achieved by changing the way the terrain mesher works. The terrain mesher works by creating polygons between voxels where needed, but currently it never creates any geometry between two voxels with the same ID/material. So when you have a pool of water, a layer of geometry is created between the water and air, and between the water and ground, but no geometry is created between any adjacent water blocks. If instead the mesher created a terrain face between vertically adjacent fluid blocks, then when you looked down into water you'd look through multiple horizontal layers of transparent blocks, creating a sort of "gets darker as it gets deeper" effect.

There are some drawbacks though - I guess it would probably perform badly for large bodies of water, and I'm not sure that the depth-sorting for transparent layers would work as expected. Also doing this properly would mean some fairly fiddly engine logic that would be very hard to expose such that the client could customize it.

Anyway I don't currently have the cycles to work on this, but if someone is forking the engine for their own work I think the above approach could work.

fenomas commented 3 years ago

On thinking more about this, I don't think there's any realistic way except for the engine to support a lighting model, and have dark water be a subset of that. So, closing for now.

csf30816 commented 3 years ago

Ok, thanks for looking into it.

On Wed, Jun 2, 2021, 1:29 AM Andy Hall @.***> wrote:

On thinking more about this, I don't think there's any realistic way except for the engine to support a lighting model, and have dark water be a subset of that. So, closing for now.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/andyhall/noa/issues/124#issuecomment-852735859, or unsubscribe https://github.com/notifications/unsubscribe-auth/AENJRKBHJRKV5JH72ODNWQ3TQW6UXANCNFSM4O6VOMFQ .