Clip Environment Shader

Preventing the character from being blocked by environment.

What happens when a character goes behind geometry? I've worked on projects with lots of different approaches. A lot of it depends on the environments and you are working with. Generally, my typical go-to is to use a raycast from a camera to detect anything obstruting the view, then moving the camera on the same side as the player. I find it the most flexible and appealing, even if there are lots of edge cases you are constantly finding yourself working through.

The problem, of course, is what if you have a fixed camera and you can't (or for aesthetic reasons, don't want to) modify your environment geometry to prevent obstructions. In these cases, a tried and true approach is to clip geometry to hide it when the player becomes obstructed.

I've never really gotten a solution to this that I like. I've seen several games do it well, but some combination of my ability and the time investment I've made has left something to be desired.

This is no exception.

Technical Approach

This approach is different from some of my previous ones in that I'm leveraging Unity's depth buffer directly rather than the stencil buffer. It's the most basic approach I can imagine.

Inputs: I animate the fade amount and the distance to player from the camera perspective.

  • Generate noise for doing the wipe affect.
  • Calculate the pixel position in both world and view space
  • Generate a mask that centers on the character (in my case center of the screen, nice and easy.)
  • Determine the depth of the pixel, and only fade those that are infront of the player (remember, due to the depth buffer not being in linear space, you have more resolution closer to the camera, which works in our favor here)
  • Apply the dissolve at the intersection of the mask, depth, and wipe effect.
  • Fade the wipe in, and use the clip function to prevent rendering that pixel
  • Use emission to highlight the edge (the only concession I made to making it not ugly.)

As always, parameterize just about everything - for me shader building is 90% grabbing a slider and swinging it back and forth to see exactly how that variable is changing the overall effect. When debugging, disable lighting, use emission and albedo to help debug.

Anyway, sorry for the short explanation, but gotta get back to the grind!

Here's the code.