2
\$\begingroup\$

I need some help. In my Unity5 game I'm using two cameras, First camera renders the actual terrain and game objects (wich has a far plane of a 1000 units) and the Second camera renders a 3d skybox of sorts, a miniature of the actual terrain (it's far plane is 3200 units, but it covers the entirety of the miniature). With this setup I'm able to fake the illusion of having a very far horizon, as in the image below:

faking a very far plane*

However, the far plane's edge is very harsh, and doesn't blend well with the 2nd camera's background. Is there anyway to blur this edge, so it trasition seamlessly with the backdrop, as in the image below (a mockup I made in photoshop)?

blurring the edge

*The blue line on the left image is just to outline the boundaries of the two cameras, it's not like this in the actual game nor is this the problem I'm talking about.

\$\endgroup\$
1
  • \$\begingroup\$ Maybe you could do that with the Depth Of Field post-processing effect. \$\endgroup\$
    – Philipp
    Commented Apr 25, 2016 at 9:00

1 Answer 1

1
\$\begingroup\$

Here is how I would do it :

  1. Modify the material used by the terrain rendered with first camera to enable alpha blending (Blend SrcAlpha OneMinusSrcAlpha).

  2. So now the fragmentshader needs to output something to the alpha component (gl_FragColor.a, or the equivalent in Unity), for now use 1.0.

  3. Modify the vertex shader to compute view space depth and store it into a varying, ex: varying float vViewSpaceDepth.

  4. Modify fragment shader to output an alpha of 1.0 most of the time, except when vViewSpaceDepth is near your border; in this case you lerp() an alpha value between 1.0 and 0.0.

  5. Make sure to render the terrain AFTER the skybox (Unity should in theory handle that automatically if Skybox has no alpha blending enabled, otherwise use render layers)

For example the fragment shader would do something like this :

if (vViewSpaceDepth > 900.0)
   final_alpha = (1000.0 - vViewSpaceDepth) / (1000.0 - 900.0);
else
   final_alpha = 1.0;
gl_FragColor.a = final_alpha;

What I present here is a naive and non optimized solution, but you should start anyway with a simple solution as a "proof of work" before thinking about optimizing.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .