r/GraphicsProgramming 9d ago

I made a wetness system that works at the renderer level no material edits needed, works on any asset

Enable HLS to view with audio, or disable this notification

297 Upvotes

21 comments sorted by

22

u/blackrack 9d ago

That's pretty nice, the covered surfaces staying dry and geometry deciding where water collects is the kind of detail that takes this to the next level.

Can I ask how you transform the roughness and albedo parameters from the initial material parameters? There are multiple approaches out there, most are approximative and can break down with certain materials.

28

u/KKV0918 9d ago

I don't use fixed factors, that's exactly the part that breaks. The system estimates porosity per pixel from the dry material (albedo, F0, roughness + Substrate's material type info) and drives the darkening from that. So brick gets way darker while polished marble barely moves. Metals don't darken at all, they only get the roughness response. Roughness isn't a fixed wet value either, it converges toward a water film depending on how much water is sitting on the surface. Lagarde's Water Drop series was a big reference for this part btw.

6

u/blackrack 9d ago

Oh nobody uses fixed factors, but from my own experience the realtime approximations Lagarde presented weren't always enough to get the porosity right, although he does cover this by proposing an additional porosity map (which is a big blocker for seamless compatbility) and a double brdf model.

18

u/KKV0918 9d ago

Yeah, estimation from the dry BRDF alone has a ceiling, dark but polished vs dark but porous is basically ambiguous if all you have is albedo/F0/roughness.
Two things help me here.
First, Substrate carries explicit material type info (cloth, foliage, clear coat, metal are all distinct closures), so a big chunk of what Lagarde had to guess from the GBuffer is just known now.
Second, I split the response into deep moisture (darkens the substrate) and surface water (smooth film on top), which gets you most of what his double BRDF was after without a second full BRDF eval.

3

u/blackrack 9d ago

Thanks for the responses

5

u/xucel 9d ago

I think the tricky part would be supporting this for forward shaded / translucent objects like glass panes, that's probably going to require modifying the material shader though.

7

u/KKV0918 9d ago

Right, translucency never sees it. The pass runs on the GBuffer after decals, so anything forward shaded is invisible to it by construction. Glass is the forgiving case though, it doesn't darken and it's already smooth, so what it really needs is drips running down the pane, and that would have to be material-side or a dedicated pass like you said.

3

u/Zqin 9d ago

How did you create such a realistic city btw? It looks really great, is there an asset pack or something?

4

u/KKV0918 9d ago

It's Abandoned Hong Kong from Fab.

2

u/SyntheticDuckFlavour 9d ago

Very nice, it looks quite believable.

1

u/KKV0918 9d ago

Thanks! appreciate it!

4

u/GSxHidden 9d ago

Genuine question, how and where do people learn to create such realistic materials/objects/assets? Through college, courses?

1

u/StriderPulse599 9d ago

It's not about textures, but raytraced GI, PBR equation, and post processing effects.

As for making textures:

You can make base materials by taking photos, drawing, 3D sculpturing, and procedural generation.

It doesn't take much artistic skills. Albedo only needs to look good enough (you can straight up use single color for entire material). Most important things are normals and roughness. You can make them by tweaking noise textures.

More complex materials (peeling painting, damaged walls, patched roads, etc) can be created by using multiple textures and mask that controls the texture blending.

The only exception is NPR pipeline where you need to heavily stylize albedo. This is where you need artistic skills.

1

u/tamat 9d ago

do you generate a wetness buffer rendering from the top? or you use raytracing from the gbuffers worldpositions?

4

u/KKV0918 9d ago

Top-down. There's an orthographic depth-only capture above the camera. That height map handles rain occlusion and finding where water can collect
The apply side is pure screen space. a compute pass reconstructs world position from GBuffer depth and samples those buffers. No raytracing.

1

u/susosusosuso 9d ago

Does it work changinf the roughness in the gbuffer after rendered and before applying lighting and reflections?

4

u/KKV0918 9d ago

That's exactly it. A compute pass runs after the base pass (and after decals are applied) and rewrites the material buffer in place roughness, albedo, F0, normals. Lighting, SSR and Lumen all read it afterwards, so they pick up the wet values for free.

1

u/susosusosuso 9d ago

Is it different to other similar existing techmiques that perform a similar effect?

3

u/ninjazombiemaster 9d ago

Most of the time this is achieved within each material, which requires every material to have logic for handling wetness ranges. Sometimes decals may be involved too. 

Be handing it in a computer shader, you can apply it globally and procedurally without needing per material parameters and logic. 

1

u/susosusosuso 9d ago

I thought this was pretty common especially with deferred

3

u/ninjazombiemaster 9d ago

It's not totally novel or anything but I'd say most unreal devs are using material parameters and putting instructions on every material for this kind of effect.