2
\$\begingroup\$

Ok, so - I'm a complete idiot when it comes to shader programming, and while I suspect someone with some experience here may find this easy, I'm at a bit of a loss.

I'd like to create a shader that would be applied to walls, and if the wall was closer to the camera than the player is, the wall would gain alpha transparency (probably 10-20% visible). I had tried some things with a camera that pans, zooms, and moves overhead as needed to not occlude the player, but it's sloppy and just doesn't feel very nice. I had used an x-ray shader, that showed an outline of the player through the wall, and while it was "cool", it also didn't quite feel right. The camera and player will always be a fixed distance and angle apart (well, at least at a given resolution). Is there some way to use the draw buffer or otherwise calculate world space position to determine when alpha should be applied?

Any help is very much appreciated. Thanks!

EDIT: I was looking and found a lot of solutions like this one: https://forum.unity3d.com/threads/global-shader-to-apply-transparency-on-objects-depending-how-far-is-the-camera.188632/

But I'd rather have it contained entirely in the shader. Preferably something I could build into a copy of the Standard (Specular Setup) shader in Unity - that copy being applied only to wall objects.

EDIT #2: I understand that this could be done with two separate materials, using code to swap them with Raycasting (though it seems that that would only work specifically for objects directly between the camera and the player rather than objects closer to the camera than the player). But I'm growing more uncertain that the shader can be told anything about the position of the player as an object.

\$\endgroup\$
1

1 Answer 1

1
\$\begingroup\$

So, I ended up going this route.

Basically I have my playerController setting a float for it's distance from the camera and making that publicly available through a method. Then on any objects I want to make transparent when they occlude the player, I have another script that takes an original material and a transparent material and swaps them when their distance to the camera is less than that of the player.

It's definitely a work in progress and needs some refinement, but I think it's a decent solution.

The script on objects that need to become transparent:

using UnityEngine;
 
public class TransMaterialSwap : MonoBehaviour {
 
     public Material _original;
     public Material _transparent;
     private GameObject player;
     private playerController pC;
     private Renderer rend;
 
     void Start()
     {
         player = GameObject.FindWithTag("Player");
         pC = player.GetComponent<playerController>();
         rend = this.GetComponent<Renderer>();
     }
 
     void Update()
     {
         if ((transform.position - Camera.main.transform.position).sqrMagnitude < pC.Dist())
         {
             rend.material = _transparent;
         }
         else
         {
             rend.material = _original;
         }
     }
 }
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thanks, this works really well. I have a pseudo-side scrolling thing with about 20 degrees of rotation on the camera, but will always point towards the z-axis, so only applied on relevant objects! \$\endgroup\$
    – Davers
    Commented Nov 24, 2019 at 13:30

You must log in to answer this question.

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