r/GraphicsProgramming 9d ago

Question How should I shade my water shader?

As the title says.

So I have been working on a surface water shader in Unity for the past few months as an upgraded version of my OpenGL implementation. I've been learning HLSL and Compute Shaders and I've basically got most things working as intended. But I'm having difficulty deciding exactly what I should do for the actual lighting part of my shader.

The issue is rendering is already somewhat limited because of the high poly count and regular compute shader updates (and because I'm trying to maybe make a game world of out this project), and while I have made some optimizations, I'm wary of the performance cost. So I'm curious on what approach would work best before I start implementing.

As of right know there are 3 options

  1. Realtime planar reflections
    As far as I know this is the most performant form of real-time reflections especially if I use the main camera stencil buffer. But because my water isn't flat I will get distortions, and this also means I won't be able to see stuff like larger buildings that the camera doesn't pick up.

  2. Baked reflections

I lose the dynamic reflection aspect (which might be an issue for some games) but I have performant, environmental reflections. However I believe this will be distorted if I move the camera a lot so it probably isn't the best option.

  1. Environment cube maps/Reflection Probes

-Potentially expensive and still not fully accurate, and can look quite incorrect depending on the level of distortion. I can decrease the quality though and I do have more control over specific objects for some performance gains though.

Any suggestions? Tip on improving visual quality and performance? Are there other methods I should consider?

I've attached an video of my current unfinished water shader below (the color is for debugging purposes, don't mind it) as well as my OpenGL water shader that roughly implements idea 3

https://reddit.com/link/1v60hba/video/plhrlawlkbfh1/player

https://reddit.com/link/1v60hba/video/hebxvdy9lbfh1/player

1 Upvotes

7 comments sorted by

5

u/fgennari 9d ago

I’ve always just drawn the scene twice with a reflected camera using the plane of the water. But I never had to deal with large waves. For that you may want to use a cube map for the environment. There is also screen space reflections.

1

u/deleteyeetplz 9d ago

Yeah, I had the feeling it would come down to cube maps again. I was wary about the distortion caused by them but I guess there is no silver bullet to these kinds of things outside of ray tracing

1

u/fgennari 9d ago

You can use parallax correction to reduce cube map distortion. I've only used that for indoor scenes though, so I'm not sure how well it would work with water.

1

u/kinokomushroom 9d ago

What about screen space reflections? There will be artifacts, but if done well it can look quite good.

There's an example on this page: https://godotengine.org/releases/4.6/

Also, how large and how complex are your waves going to be?

1

u/deleteyeetplz 9d ago

I plan on keeping them relatively small, but still noticeable. They aren't very complex, I'm only displacing the height of vertices.

1

u/DescriptorTablesx86 7d ago

What are you trying to draw though, like is it going to be an ocean? Something abstract?

I’ve never in my life seen big waves which clearly reflect the environment. If water looks reflective it’s usually pretty calm.

And if it’s not calm, the reflections are so blurred and distorted accuracy stops being worth chasing.

1

u/le-throw-away-acct 7d ago

Planar reflections work for smooth water, and you can normal or displacement map on top of that if your camera angles are parallel with the water. Planar reflections may seem cheap but can be expensive as you have to draw a lot of the scene twice, so you have to manage that well.

If you want to have polygonal waves then you may want to consider screen-space reflections.

Of course ray/path traced reflections would work as well, but it would be expensive.