- Home /
How can I make the most efficient SDF Shader in unity
Basically, I want to have a shader that takes in a 3d array of colors (voxels), as well as a scaling factor, and a radius setting for each sphere. Then I would like it to render a sphere in the position of each of the colors in the array on screen. I found this shader however it cannot take an array as an input, and is not very efficient as it does not render a simple sphere it renders a weird half sphere half box shape. It also does not render directly on screen to a full screen quad.
Shader "SDF/CubesphereUnlit"
{
Properties
{
_Radius ("Radius", Float) = 1.0
_Center ("Center", Vector) = (0.0, 0.0, 0.0, 0.0)
_Color ("Color", Color) = (1.0, 0.0, 0.0, 1.0)
_SpecularPower ("Specular Power", Float) = 20.0
_Gloss ("Gloss", Float) = 5.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
float3 wPos : TEXCOORD1; // World position
};
float _Radius;
float4 _Center;
float4 _Color;
float _SpecularPower;
float _Gloss;
const float PI = 3.1415926;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.wPos = mul(unity_ObjectToWorld, v.vertex).xyz;
return o;
}
float rand(float3 co)
{
return frac(sin(dot(co.xyz, float3(12.9898, 78.233, 45.5432))) * 43758.5453);
}
float sdf_sphere(float3 p, float3 c, float r)
{
return distance(p, c) - r;
}
float sdf_box(float3 p, float3 c, float3 s)
{
float x = max(p.x - c.x - float3(s.x / 2., 0, 0),
c.x - p.x - float3(s.x / 2., 0, 0)
);
float y = max(p.y - c.y - float3(s.y / 2., 0, 0),
c.y - p.y - float3(s.y / 2., 0, 0)
);
float z = max(p.z - c.z - float3(s.z / 2., 0, 0),
c.z - p.z - float3(s.z / 2., 0, 0)
);
return max(max(x, y), z);
}
float sdf_smin(float a, float b, float k = 32)
{
float res = exp(-k*a) + exp(-k*b);
return -log(max(0.0001, res)) / k;
}
float sdf_blend(float d1, float d2, float a)
{
return a * d1 + (1 - a) * d2;
}
float map(float3 p)
{
return max(sdf_smin(
sdf_sphere(p, -float3 (1.5, 0, 0), 2), // left sphere
sdf_sphere(p, +float3 (1.5, 0, 0), 2) // right sphere
, 8), sdf_blend(sdf_sphere(p, 0, 2), sdf_box(p, 0, 2), 0.5));
}
float3 normal(float3 p)
{
const float eps = 0.001;
return normalize(float3
(map(p + float3(eps, 0, 0)) - map(p - float3(eps, 0, 0)),
map(p + float3(0, eps, 0)) - map(p - float3(0, eps, 0)),
map(p + float3(0, 0, eps)) - map(p - float3(0, 0, eps))
)
);
}
fixed4 renderSurface(float3 p, float3 viewDirection)
{
return _Color;
}
#define STEPS 128
#define MIN_DISTANCE 0.1
fixed4 raymarch(float3 position, float3 direction)
{
for (int i = 0; i < STEPS; i++)
{
float distance = map(position);
if (distance < MIN_DISTANCE)
{
return renderSurface(position, direction);
}
position += distance * direction;
}
discard;
return fixed4(1, 1, 1, 1);
}
fixed4 frag (v2f i) : SV_Target
{
float3 viewDirection = normalize(i.wPos - _WorldSpaceCameraPos);
return raymarch(i.wPos, viewDirection);
}
ENDCG
}
}
}
I don't want the shader to have lighting so the gloss and such can be ignored, thanks!
Edit: I'd also like help with making the shader as short and efficient as humanly possible thanks!
Answer by Namey5 · Jan 09, 2019 at 05:42 AM
SDF's are a moderately complex topic (especially if you are trying to implement them as a post effect; that requires a full understanding of TRS matrices and space transformations). Simply asking for a shader isn't quite how this site works, and you'd be hard-pressed to find someone willing to dedicate the time for a topic like this. Instead, I will point you to this article on implementing raymarching as post in Unity:
http://flafla2.github.io/2016/10/01/raymarching.html
IQ is the king of SDF raymarching, so if you're looking for SDF functions for all kinds of shapes you can look at his website here:
http://iquilezles.org/www/articles/distfunctions/distfunctions.htm
Your answer
Follow this Question
Related Questions
Fade object transparency evenly from the edge inward 0 Answers
URP Blit Render Feature not rendering in Single Pass Instanced VR 0 Answers
Problem with Image Effect shader for Virtual Reality 0 Answers
Is it possible to create a scrolling texture as an image effect (shader)? 2 Answers
Converting c# function to shader. 0 Answers