I'm trying to make a raymarching shader in unity thats currently only meant to display a simple circle. But for some reason it just doesn't want to work and is only showing the background colour i set. Dies anybody have any reason why this is?
Shader "Unlit/RayMarcher"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_MaxMarchSteps ("Max Marching Steps", int) = 255
_Epsilion ("Epsilion", float) = 0.001
_Pos ("Position", Vector) = (0.0,0.0,-5.0)
}
SubShader
{
Tags { "RenderType"="Opaque" }
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;
float3 ro : TEXCOORD1;
float3 hitPos : TEXCOORD2;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _MaxMarchSteps;
float _Epsilion;
float minDist = 0.0;
float maxDist = 1000.0;
float3 _Pos;
float sphereSDF(float3 p){
return length(p) - 1.0;
}
float sceneSDF(float3 p){
return sphereSDF(p);
}
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.ro = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1));
o.hitPos = v.vertex;
return o;
}
float getDist(float3 cam, float3 dir, float start, float end){
float depth = start;
for(int i = 0; i < _MaxMarchSteps; i++){
float dist = sceneSDF(cam + depth * dir);
if(dist < _Epsilion){
return depth;
}
depth += dist;
if(depth >= end)
return end;
}
return end;
}
float3 rayDir(float FOV, float2 resolution, float2 fragCoord){
float2 xy = fragCoord - resolution / 2.0;
float z = resolution.y / tan(radians(FOV) / 2.0);
return normalize(float3(xy, -z));
}
fixed4 frag (v2f i) : SV_Target
{
float2 resolution = float2(1920,1080);
float3 dir = rayDir(45, resolution, i.uv);
float3 camPos = _Pos;
float dist = getDist(camPos, dir, 0, 1000);
if(dist > maxDist - _Epsilion){
return fixed4(0.0, 0.0, 0.0, 1.0);
}
return fixed4(1.0, 0.0, 0.0, 1.0);
}
ENDCG
}
}
}
↧