# How to fake refraction - what is the math?

I did try searching on this, but most/all of the responses around refraction are tied to transparent materials. My case is a bit different as I want to know HOW to do it vs having problems WITH it… (refraction as a material-feature)

I have a landscape material. On this landscape I can already make puddles, water, fake blending into the ‘deep’ parts of the water. However, I tells myself that I’d like to simulate some kind of (convincing) refraction where there is water. Since this is all in the singular landscape material it cannot be an actual translucent material (it’s default lit). I get that anything I try might be imperfect, but even a slight effect might be nice to have.

To wit, consider:

That’s muh dude on my landscape. He’s looking into that carved-out stream. He’s looking at A but hits the waterline at B. I can math my way around the various opposing/complimentary angles, etc, etc, etc, - it’s more I don’t know what I ought to be doing WITH them…

I get that light is going to be bent at the surface, and I likely want to do something with UV maths, but does the refraction shift the coordinates back, forward, etc? Most of what I’ve found involves some texture-fakery to jiggle UV’s or the like. Just thinking about it before my head explodes suggests to me I want to use CameraVector coupled with the VectorNormalWS as well as PixelNormalWS… Any suggestions on what maths might apply here?

BTW, I also have the ability to read the players location to create reactive water (or snow) so that as the player moves through it, there are waves, etc. Thusly, I’d like to incorporate the normal at the surface into account as well if that is possible. Finally, to consider, the player would actually be moving down ‘into’ the stream as I can control the height of the landscape mesh independently from its collision. The water would be level with the ground as in the picture, eg: the mannie’s mesh would clip into the landscape as if he was stepping into deep water. Any kind of UV math would need to take that into account, but I can get access to any information from the actual landscape height (insofar as collision) vs the rendered height (for the ‘water’).

Anyone point me in the right direction here? Solution would be great if someone cares for the challenge, but I’m otherwise a bit out of my depth here (lulz) and could use a lead to chase down… Thanks in advance for anything anyone cares to contribute.

I think the math you are looking for is called Snell’s Law. Ryan Brucks actually made a blog post about an optimized version of it.

For any surface with a texture to it though (such as water) my advice would be to just multiply a noise or normal map texture by a scalar (to control the refraction intensity) and add it to your UV coordinates. Works really well when paired with some parallax.