Closed jdolan closed 2 years ago
This can / should also be done for mesh models. Just like we can use the lightmap to color caustics on BSP draw elements, we can use the lightgrid to modulate caustics on mesh models. The r_mesh_program struct will also need to hold a reference to any caustics images.
@SpineyPete I see that we have a ton of "caustics" sprites. I'm not sure if these are intended for underwater caustics. If they are, was the idea to have one for each liquid type (water, slime, lava)? Our old system had a single image for this, but still looked quite good.
Artist-controllable image?
I'm not sure that's necessary or even desirable? Maybe allowing the artist to control the intensity of the effect with a simple scalar in the mat file?
caustics .6
@jdolan The sprites are a 3d texture (stored as layers). They can animate if you scroll (add + modulo) the z-world-coordinate in the shader.
Using 3d textures is a pretty expensive way of doing it though, there's an alternative trick described here: https://80.lv/articles/caustic-surface-production-guide/ Just uses one or two textures and looks pretty good. Could maybe even be part of the warp shader.
That's more like what I was thinking. And warp is actually just a material stage, which is also how I was thinking about this....
I'm tackling this next. If someone has an idea / opinion on the shader implementation, I can hand off with a uniform variable in place that activates a material stage. Otherwise I'll probably try to go back in time and dig up the old effect and just re-apply it in our current material stages.
This is now implemented in https://github.com/jdolan/quetoo/pull/644
An additional static lighting pass is performed for both the lightmaps and lightgrid. It calculates proximity to translucent liquids, and authors a texture with RGB corresponding to lava, slime and water, respectively (kinda nice how that works out 😊). These textures are then used to additively blend caustic effects to diffuse lighting in both the BSP and mesh shaders. The BSP draw elements use the lightmap textures, while mesh models use the lightgrid. Inline BSP model entities receive a mix of lightmap and lightgrid caustic lighting, in case they move. This allows movers that interact with water to receive caustics while they are near or in water, and lose them if their proximity to water goes away.
Right now, we're not doing anything fancy or interesting with the different caustics channels. It's just one global effect. It would be cool if someone wanted to adjust the effect based on the presence of lava (r), slime (g) or water (b). The shadertoy that we borrowed our 3D noise function from actually shows how to do this:
BSP draw elements are broken up by contents, and draw elements that are underwater will have a
contents
that hitsCONTENTS_MASK_LIQUID
. I did this so that we can easily draw caustics on underwater faces without forfeiting draw elements batching.We should add a function that draws a hard-coded caustics material stage on any
r_bsp_draw_elements_t
, and call this function after diffuse and materials passes on draw elements with `CONTENTS_MASK_LIQUID. I think the materials shader is the easiest place to do this.CONTENTS_MASK_LIQUID
.The stage can use a slower scroll effect for lava than water, etc.. if we want to get cute, but I'd like for this to essentially look and behave like the caustics that @kaadmy implemented years ago.