Skip to content

Instantly share code, notes, and snippets.

@d4rkc0d3r
Created February 23, 2023 16:08
Show Gist options
  • Select an option

  • Save d4rkc0d3r/4b85809d51ac9fdf61cc3f75b7e4286a to your computer and use it in GitHub Desktop.

Select an option

Save d4rkc0d3r/4b85809d51ac9fdf61cc3f75b7e4286a to your computer and use it in GitHub Desktop.
Shader "d4rkpl4y3r/RayMarching/Shpere Cut"
{
Properties
{
_Radius("Radius", Float) = 1
_Frequency("Frequency", Float) = 10
_PositionNoise("Position Noise", Range(0,1)) = .5
_MaxDist("Max View Distance", Float) = 150
[Gamma] _Metallic ("Metallic", Range(0, 1)) = 0
_Smoothness ("Smoothness", Range(0, 1)) = 0
_Color("Color", Color) = (1,1,1,1)
}
SubShader
{
Tags
{
"RenderType"="Transparent"
"Queue"="Geometry+501"
"DisableBatching"="True"
}
CGINCLUDE
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "UnityPBSLighting.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float3 worldPos : TEXCOORD0;
float3 worldNormal : TEXCOORD1;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
o.worldNormal = UnityObjectToWorldNormal(v.normal);
return o;
}
uniform float _Radius;
uniform float _Frequency;
uniform float _PositionNoise;
uniform float _MaxDist;
uniform float _Metallic;
uniform float _Smoothness;
uniform float4 _Color;
#define rlength(x) rsqrt(dot(x, x))
float2 traceSphere(float3 pos, float3 dir)
{
float a = dot(dir, pos);
float squared = a * a - (dot(pos, pos) - (_Radius * _Radius));
return squared >= 0 ? float2(-a - sqrt(squared), -a + sqrt(squared)) : float2(-1, -1);
}
float4 UpdatePositionAndNormal(inout float3 pos, inout float3 normal, float3 origin, float3 dir, float near, float far, bool isFrontFace);
float4 frag (v2f i
, bool isFrontFace : SV_IsFrontFace
#ifdef WRITE_DEPTH
, out float depth : SV_Depth
#endif
) : SV_Target
{
float3 pos = i.worldPos.xyz;
float3 normal = normalize(i.worldNormal);
float3 origin = _WorldSpaceCameraPos;
float3 dir = normalize(i.worldPos.xyz - origin);
float2 dist = traceSphere(origin, dir);
float4 col = UpdatePositionAndNormal(pos, normal, origin, dir, dist.x, dist.y, isFrontFace);
#ifdef WRITE_DEPTH
float4 clipPos = UnityWorldToClipPos(pos);
depth = clipPos.z / clipPos.w;
#endif
if (any(col != 0))
{
return col;
}
float ndotv = dot(normal, dir);
float ndotl = saturate(dot(normal, _WorldSpaceLightPos0.xyz));
float3 specularTint;
float oneMinusReflectivity;
float3 albedo = DiffuseAndSpecularFromMetallic(
_Color.rgb, _Metallic, specularTint, oneMinusReflectivity
);
UnityLight light;
light.color = _LightColor0.rgb * .9;
light.dir = _WorldSpaceLightPos0.xyz;
light.ndotl = ndotl;
UnityIndirect indirectLight;
indirectLight.diffuse = max(0, ShadeSH9(float4(normal, 1))) + _LightColor0.rgb * .1;
float3 reflectionDir = reflect(dir, normal);
Unity_GlossyEnvironmentData envData;
envData.roughness = 1 - _Smoothness;
envData.reflUVW = reflectionDir;
indirectLight.specular = Unity_GlossyEnvironment(
UNITY_PASS_TEXCUBE(unity_SpecCube0), unity_SpecCube0_HDR, envData
);
return UNITY_BRDF_PBS(
albedo, specularTint,
oneMinusReflectivity, _Smoothness,
normal, -dir,
light, indirectLight
);
}
ENDCG
Pass // stencil front face in front of sphere
{
Tags { "LightMode" = "ForwardBase" }
Cull Back
ZTest Off
ZWrite Off
ColorMask 0
Stencil
{
Ref 1
Comp Always
Pass Replace
}
CGPROGRAM
float4 UpdatePositionAndNormal(inout float3 pos, inout float3 normal, float3 origin, float3 dir, float near, float far, bool isFrontFace)
{
if (length(pos) <= _Radius || length(pos - origin) >= near)
{
discard;
}
return float4(0,1,0,1);
}
ENDCG
}
Pass // back face where front face is in front of sphere
{
Tags { "LightMode" = "ForwardBase" }
Cull Front
Stencil
{
Ref 1
Comp Equal
Pass Replace
}
CGPROGRAM
#pragma multi_compile_local WRITE_DEPTH
float4 UpdatePositionAndNormal(inout float3 pos, inout float3 normal, float3 origin, float3 dir, float near, float far, bool isFrontFace)
{
if (length(pos - origin) < near)
{
discard;
}
pos = origin + dir * near;
normal = normalize(pos);
return 0;
}
ENDCG
}
Pass // just regular front face
{
Tags { "LightMode" = "ForwardBase" }
Cull Back
CGPROGRAM
float4 UpdatePositionAndNormal(inout float3 pos, inout float3 normal, float3 origin, float3 dir, float near, float far, bool isFrontFace)
{
if (length(pos) > _Radius)
{
discard;
}
return 0;
}
ENDCG
}
Pass // clean up stencil
{
Tags { "LightMode" = "ForwardBase" }
Cull Off
ZTest Off
ZWrite Off
ColorMask 0
Stencil
{
Ref 0
Comp Always
Pass Replace
}
CGPROGRAM
float4 UpdatePositionAndNormal(inout float3 pos, inout float3 normal, float3 origin, float3 dir, float near, float far, bool isFrontFace)
{
return 0;
}
ENDCG
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment