Hey Unity Peoples,
This is my first post and I have about 2 months working with Unity at this point. I really think this is a simple problem and I was hoping I could ask the experts. I have no doubt I am doing something really dumb.
What I am trying to do is run a pseudo “ray marching” algorithm on top of my existing game. This way I can do fog, glass coloration, lighting and some other volumetric effects. I am using an image effect shader on a camera because this will basically go over the screen and fill in the spaces I want with the fog etc. The only problem is I can’t get the angle of a ray from each pixel correct.
I have gone through several awesome tutorials (Like this one) and was able to get one working but the way it worked was by placing a quad in front of the camera. This of course obstructed the rest of the game lol. Others were unlit shaders on objects not on the camera so also not what I’m looking for. All I want is to have a float3 with the direction of the ray from that pixel in my fragment shader. Obviously in world space corrected for camera rotation etc. I think I can do the rest of my trig from there. Here is what I have…
HLSL
Shader "RayShader/RayShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
//_CamAng;
//_FOV;
//_FOVXAng;
//_FOVYAng;
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex;
uniform float3 _CamAng;
uniform float3 _FOV;
uniform float2 _FOVXAng;
uniform float2 _FOVYAng;
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
float3 WorldSpaceDirection = 0;//This is where i want the angle of a ray from this pixel in world space!
col = 0.5;
float PixXAng = lerp(_FOVYAng.y, _FOVYAng.x, i.uv.x);//This is junk.
float PixYAng = lerp(_FOVXAng.y, _FOVXAng.x, i.uv.y);//Im just grasping at straws at this point.
PixXAng = (sin(PixXAng) * 0.5) + 0.5;
PixYAng = (sin(PixYAng) * 0.5) + 0.5;
col *= fixed4(PixXAng, PixYAng,0, 0);
return col;
}
ENDCG
}
}
}
C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class CamToShader : MonoBehaviour
{
public Material MyMat;
public Shader MyShade;
public Camera MyCamera;
private Vector3 _CamAng;
private Vector3 _FOV;
private Vector2 _FOVXAng;
private Vector2 _FOVYAng;
private Vector2 Flip = new Vector2(-1, 1);
private Vector2 TempAng;
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if (!MyMat)
{
Graphics.Blit(source, destination);
return;
}
else
{
_CamAng = Mathf.Deg2Rad * MyCamera.transform.eulerAngles;
_FOV.y = Mathf.Deg2Rad * MyCamera.fieldOfView * 0.5f;
_FOV.x = _FOV.y * MyCamera.aspect;
_FOVXAng = new Vector2(-_FOV.x, _FOV.x);
_FOVXAng += new Vector2(_CamAng.x, _CamAng.x);
_FOVYAng = new Vector2(-_FOV.y, _FOV.y);
_FOVYAng += new Vector2(_CamAng.y, _CamAng.y);
MyMat.SetVector("_CamAng", _CamAng);
MyMat.SetVector("_FOV", _FOV);
MyMat.SetVector("_FOVXAng", _FOVXAng);
MyMat.SetVector("_FOVYAng", _FOVYAng);
Graphics.Blit(source, destination, MyMat);
return;
}
}
}
I was very excited when I got this together because at first the colors on the screen tracked with the camera rotation but if I rotate beyond straight up the colors flip and camera rotation on z does nothing. Is there a built in shaderlab variable that has the vector of each frag?
Anything will help thanks in advance. I’ve got to head to bed for work but I appreciate any help and will check in tomorrow.