How to make shader not affect anything between it and camera?
I've written code that creates a black hole that warps everything around it, and if the pixels are close enough, mkes them completely black. Now this black hole shows up in front of everything, while real black holes only warp space behind them (from our POV). How can I make this shader only affect everything behind it, and affect nothing between it and the camera?
Here's my code:
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,)' with 'UnityObjectToClipPos()'
Shader "Hidden/NewImageEffectShader" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { // No culling or depth Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform float2 _Position;
uniform float _Rad;
uniform float _Ratio;
uniform float _Distance;
struct v2f
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
v2f vert (appdata_img v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}
fixed4 frag(v2f i) : COLOR
{
float2 offset = i.uv - _Position;
float2 ratio = { _Ratio, 1 };
float rad = length(offset / ratio);
float deformation = 1 / pow(rad * pow(_Distance, 0.5), 2) * _Rad * 0.1;
offset = offset * (1 - deformation);
offset += _Position;
half4 res = tex2D(_MainTex, offset);
if (rad * _Distance < _Rad)
{
res = half4( 0, 0, 0, 1 );
}
return res;
}
ENDCG
}
}
}
And the script attached to the camera object:
using System.Collections; using System.Collections.Generic; using UnityEngine;
[RequireComponent(typeof(Camera))] public class BlackHoleEffect : MonoBehaviour {
// PUBLIC SETTINGS
public Shader shader;
public Transform blackHole;
public float ratio; // Aspect ratio of the screen
public float radius; // Size of black hole in scene
// PRIVATE SETTINGS
private Camera cam;
private Material _material; // Will be procedurally generated
Material material
{
get
{
if (_material == null)
{
_material = new Material(shader);
_material.hideFlags = HideFlags.HideAndDontSave; // Doesn't save material to assets, maybe
}
return _material;
}
}
void OnEnable()
{
cam = GetComponent<Camera>();
ratio = 1f / cam.aspect;
}
void OnDisable()
{
if (_material)
{
DestroyImmediate(_material);
}
}
Vector3 wtsp;
Vector2 pos;
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if (shader && material && blackHole)
{
wtsp = cam.WorldToScreenPoint(blackHole.position);
// is the black hole in front of the camera?
if (wtsp.z > 0)
{
pos = new Vector2(wtsp.x / cam.pixelWidth, wtsp.y / cam.pixelHeight);
// apply shader parameters
_material.SetVector("_Position", pos);
_material.SetFloat("_Ratio", ratio);
_material.SetFloat("_Rad", radius);
_material.SetFloat("_Distance", Vector3.Distance(blackHole.position, transform.position));
}
// apply the shader to the image
Graphics.Blit(source, destination, material);
}
}
}
Your answer
![](https://koobas.hobune.stream/wayback/20220612211800im_/https://answers.unity.com/themes/thub/images/avi.jpg)