shell of new raymarching lib
This commit is contained in:
parent
814488620f
commit
b9159d9e7c
7 changed files with 269 additions and 73 deletions
|
@ -529,7 +529,7 @@ GameObject:
|
||||||
m_Icon: {fileID: 0}
|
m_Icon: {fileID: 0}
|
||||||
m_NavMeshLayer: 0
|
m_NavMeshLayer: 0
|
||||||
m_StaticEditorFlags: 0
|
m_StaticEditorFlags: 0
|
||||||
m_IsActive: 0
|
m_IsActive: 1
|
||||||
--- !u!65 &683266144
|
--- !u!65 &683266144
|
||||||
BoxCollider:
|
BoxCollider:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|
|
@ -63,8 +63,8 @@ Material:
|
||||||
- _GlossMapScale: 1
|
- _GlossMapScale: 1
|
||||||
- _Glossiness: 0.5
|
- _Glossiness: 0.5
|
||||||
- _GlossyReflections: 1
|
- _GlossyReflections: 1
|
||||||
- _MaxDist: 256
|
- _MaxDist: 128
|
||||||
- _MaxSteps: 256
|
- _MaxSteps: 128
|
||||||
- _Metallic: 0
|
- _Metallic: 0
|
||||||
- _Mode: 0
|
- _Mode: 0
|
||||||
- _OcclusionStrength: 1
|
- _OcclusionStrength: 1
|
||||||
|
|
|
@ -1,61 +1,229 @@
|
||||||
struct appdata
|
#ifndef LIBGARBAGE_INCLUDED
|
||||||
{
|
#define LIBGARBAGE_INCLUDED
|
||||||
float4 vertex : POSITION;
|
#include "UnityCG.cginc"
|
||||||
};
|
|
||||||
|
|
||||||
struct v2f
|
/*
|
||||||
{
|
# defines with no defaults
|
||||||
float4 vertex : SV_POSITION;
|
USE_WORLD_SPACE
|
||||||
float3 vCamPos : TEXCOORD1;
|
DISCARD_ON_MISS
|
||||||
float3 vHitPos : TEXCOORD2;
|
USE_MATERIALS_IN_RAYMARCH // TODO: implement, this is easier to work with but more expensive
|
||||||
};
|
DISABLE_DEPTH
|
||||||
|
START_RAYS_IN_BOX // TODO: implement
|
||||||
|
START_RAYS_IN_SPHERE // TODO: implement
|
||||||
|
*/
|
||||||
|
|
||||||
struct fragOut
|
// scene sdf with only distance
|
||||||
{
|
#ifndef DISTANCE_FN
|
||||||
fixed4 col : SV_Target;
|
#define DISTANCE_FN default_distance_sdf
|
||||||
// float depth : SV_Depth;
|
|
||||||
};
|
|
||||||
|
|
||||||
v2f vert (appdata v)
|
|
||||||
{
|
|
||||||
v2f o;
|
|
||||||
o.vertex = UnityObjectToClipPos(v.vertex);
|
|
||||||
#ifdef USE_WORLD_SPACE
|
|
||||||
o.vCamPos = _WorldSpaceCameraPos;
|
|
||||||
o.vHitPos = mul(unity_ObjectToWorld, v.vertex);
|
|
||||||
#else
|
|
||||||
o.vCamPos = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1));
|
|
||||||
o.vHitPos = v.vertex;
|
|
||||||
#endif
|
#endif
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
fragOut frag (v2f i)
|
// scene sdf that includes material data
|
||||||
{
|
#ifndef MATERIAL_FN
|
||||||
fragOut o;
|
#define MATERIAL_FN default_material_sdf
|
||||||
o.col = 1;
|
#endif
|
||||||
o.col.r = 0;
|
|
||||||
|
// calculates a color from a Ray
|
||||||
|
#ifndef LIGHT_FN
|
||||||
|
#define LIGHT_FN default_lighting
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// max ray steps, from last bounce (reset on each reflection)
|
||||||
|
#ifndef MAX_STEPS
|
||||||
|
#define MAX_STEPS 128
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// max ray length, from last bounce (length is reset on each reflection)
|
||||||
|
#ifndef MAX_DIST
|
||||||
|
#define MAX_DIST 128
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// the largest surface distance that is counted as a hit
|
||||||
|
#ifndef SURF_DIST
|
||||||
|
#define SURF_DIST 0.001
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO: implement
|
||||||
|
#ifndef REFLECTIONS
|
||||||
|
#define REFLECTIONS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO: implement
|
||||||
|
#ifndef SCENE_SCALE
|
||||||
|
#define SCENE_SCALE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO: implement
|
||||||
|
#ifndef AMBIENT_OCCLUSION_STEPS
|
||||||
|
#define AMBIENT_OCCLUSION_STEPS 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
struct AppData {
|
||||||
|
float4 vertex : POSITION;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct V2F {
|
||||||
|
float4 vertex : SV_POSITION;
|
||||||
|
float3 cam_pos : TEXCOORD0;
|
||||||
|
float3 hit_pos : TEXCOORD1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FragOut {
|
||||||
|
fixed3 col : SV_Target;
|
||||||
|
#ifndef DISABLE_DEPTH
|
||||||
|
float depth : SV_Depth;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Material {
|
||||||
|
float3 col;
|
||||||
|
float gloss;
|
||||||
|
};
|
||||||
|
#define DEFAULT_MAT {float3(0.2, 0.2, 0.2), 0}
|
||||||
|
|
||||||
|
struct SurfacePoint {
|
||||||
|
float dist;
|
||||||
|
Material mat;
|
||||||
|
};
|
||||||
|
|
||||||
|
//used for lighting a point
|
||||||
|
struct Ray {
|
||||||
|
float dist;
|
||||||
|
int steps;
|
||||||
|
Material mat;
|
||||||
|
float3 start;
|
||||||
|
float3 dir;
|
||||||
|
float3 hit_pos;
|
||||||
|
float3 normal;
|
||||||
|
bool missed;
|
||||||
|
float min_dist; // smallest distance encountered along the path (only useful for misses; shadow calculations)
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "libgarbage_shapes.cginc"
|
||||||
|
|
||||||
|
float DISTANCE_FN(float3 p);
|
||||||
|
SurfacePoint MATERIAL_FN(float3 p);
|
||||||
|
float3 LIGHT_FN(Ray ray);
|
||||||
|
Ray cast_ray(float3 p, float3 d, float startDist = 0);
|
||||||
|
|
||||||
|
V2F vert (AppData v) {
|
||||||
|
V2F o;
|
||||||
|
o.vertex = UnityObjectToClipPos(v.vertex);
|
||||||
|
#ifdef USE_WORLD_SPACE
|
||||||
|
o.cam_pos = _WorldSpaceCameraPos;
|
||||||
|
o.hit_pos = mul(unity_ObjectToWorld, v.vertex);
|
||||||
|
#else
|
||||||
|
o.cam_pos = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1));
|
||||||
|
o.hit_pos = v.vertex;
|
||||||
|
#endif
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
// #define SOME_MAGIC(main_fn) float3 main1()\
|
FragOut frag (V2F i) {
|
||||||
// main_fn \
|
float ray_len = 0;
|
||||||
|
float3 ray_dir = normalize(i.hit_pos - i.cam_pos);
|
||||||
|
|
||||||
#define SOME_MAGIC(PASS, function_definition) float3 main##PASS() function_definition
|
float3 last_bounce = i.cam_pos;
|
||||||
|
SurfacePoint point_data;
|
||||||
|
Ray ray;
|
||||||
|
|
||||||
#define DO_MAGIC MAIN_FN(1)
|
float3 col;
|
||||||
|
float color_used = 0;// what amount of the final color has been calculated
|
||||||
|
float prev_gloss = 0;
|
||||||
|
float3 first_hit;
|
||||||
|
|
||||||
// #define SECOND_PASS 1
|
for (int ray_num = 0; ray_num < REFLECTIONS + 1; ray_num++) {
|
||||||
// #define AA MAIN_FN
|
ray = cast_ray(last_bounce, ray_dir);
|
||||||
// #define BB MAIN_FN
|
if (ray_num == 0) { // before any bounces
|
||||||
|
col = LIGHT_FN(ray);
|
||||||
|
first_hit = ray.hit_pos;
|
||||||
|
} else {
|
||||||
|
float col_amount = color_used + ((1 - prev_gloss) * (1 - color_used));
|
||||||
|
col = lerp(LIGHT_FN(ray), col, col_amount);
|
||||||
|
color_used = col_amount;
|
||||||
|
}
|
||||||
|
if (ray.missed || ray.mat.gloss < 0.01) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev_gloss = ray.mat.gloss;
|
||||||
|
ray_dir = reflect(ray_dir, ray.normal);
|
||||||
|
last_bounce = ray.hit_pos + ray_dir * 0.01;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DISCARD_ON_MISS
|
||||||
|
if (ray.missed && ray_num == 0) discard;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FragOut o;
|
||||||
|
o.col = col;
|
||||||
|
|
||||||
|
#ifndef DISABLE_DEPTH
|
||||||
|
float4 clip_pos = mul(UNITY_MATRIX_VP, mul(unity_ObjectToWorld, float4(first_hit, 1)));
|
||||||
|
o.depth = clip_pos.z / clip_pos.w;
|
||||||
|
#ifndef UNITY_REVERSED_Z // basically only OpenGL (unity editor on linux)
|
||||||
|
o.depth = o.depth * 0.5 + 0.5; // remap -1 to 1 range to 0.0 to 1.0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float3 get_normal(float3 pos, float surface_distance, float epsilon = 0.001) {
|
||||||
|
// if epsilon is smaller than 0.001, there are often artifacts
|
||||||
|
const float2 e = float2(epsilon, 0);
|
||||||
|
float3 n = surface_distance - float3(
|
||||||
|
DISTANCE_FN(pos - e.xyy),
|
||||||
|
DISTANCE_FN(pos - e.yxy),
|
||||||
|
DISTANCE_FN(pos - e.yyx));
|
||||||
|
return normalize(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ray cast_ray(float3 start, float3 dir, float start_len) {
|
||||||
|
float ray_len = start_len;
|
||||||
|
|
||||||
|
Ray ray;
|
||||||
|
ray.dir = dir;
|
||||||
|
ray.start = start;
|
||||||
|
ray.min_dist = 100100100; // budget "infinity"
|
||||||
|
ray.missed = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_STEPS; i++) {
|
||||||
|
ray.hit_pos = start + ray_len * dir;
|
||||||
|
ray.dist = DISTANCE_FN(ray.hit_pos);
|
||||||
|
if (ray.dist < SURF_DIST) {
|
||||||
|
ray.missed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ray.min_dist = min(ray.min_dist, ray.dist);
|
||||||
|
ray_len += ray.dist;
|
||||||
|
if (ray_len > MAX_DIST) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ray.steps = i;
|
||||||
|
if (ray.missed) {
|
||||||
|
ray.normal = float3(0, 0, 0);
|
||||||
|
} else {
|
||||||
|
ray.normal = get_normal(ray.hit_pos, ray.dist);
|
||||||
|
ray.mat = MATERIAL_FN(ray.hit_pos).mat;
|
||||||
|
}
|
||||||
|
return ray;
|
||||||
|
}
|
||||||
|
|
||||||
|
float default_distance_sdf(float3 p) {
|
||||||
|
return sdSphere(p, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
SurfacePoint default_material_sdf(float3 p) {
|
||||||
|
return mSphere(p, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 default_lighting(Ray ray) {
|
||||||
|
float3 sun_dir = normalize(float3(1, 0.5, 0));
|
||||||
|
if (ray.missed)
|
||||||
|
return 0.1;
|
||||||
|
float3 col = 0;
|
||||||
|
col = ray.mat.col * dot(ray.normal, sun_dir);
|
||||||
|
return col;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// float3 main2() \
|
#endif // LIBGARBAGE_INCLUDED
|
||||||
// main_fn
|
|
||||||
|
|
||||||
// \
|
|
||||||
// float3 main2() \
|
|
||||||
// main_fn\
|
|
||||||
|
|
||||||
|
|
||||||
// #define SECOND_PASS \
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
#define DO_MAGIC(p) MAIN_FN(p)
|
|
|
@ -2,17 +2,16 @@ Shader "CrispyPin/LibGarbageExample"
|
||||||
{
|
{
|
||||||
Properties
|
Properties
|
||||||
{
|
{
|
||||||
|
|
||||||
[Header(Raymarcher Properties)]
|
[Header(Raymarcher Properties)]
|
||||||
_MaxSteps ("Max steps", Int) = 256
|
_MaxSteps ("Max steps", Int) = 128
|
||||||
_MaxDist ("Max distance", Float) = 256
|
_MaxDist ("Max distance", Float) = 128
|
||||||
_SurfDist ("Surface distance threshold", Range(0.00001, 0.05)) = 0.001
|
_SurfDist ("Surface distance threshold", Range(0.00001, 0.05)) = 0.001
|
||||||
|
|
||||||
}
|
}
|
||||||
SubShader
|
SubShader
|
||||||
{
|
{
|
||||||
Tags { "RenderType"="Opaque" }
|
Tags { "RenderType"="Opaque" }
|
||||||
Cull Off
|
Cull Front
|
||||||
LOD 100
|
LOD 100
|
||||||
|
|
||||||
Pass
|
Pass
|
||||||
|
@ -21,23 +20,13 @@ Shader "CrispyPin/LibGarbageExample"
|
||||||
#pragma vertex vert
|
#pragma vertex vert
|
||||||
#pragma fragment frag
|
#pragma fragment frag
|
||||||
|
|
||||||
|
int _MaxSteps;
|
||||||
|
#define MAX_STEPS _MaxSteps
|
||||||
|
|
||||||
|
// #define DISABLE_DEPTH
|
||||||
|
// #define DISCARD_ON_MISS
|
||||||
#include "libgarbage.cginc"
|
#include "libgarbage.cginc"
|
||||||
|
|
||||||
// #define MAIN_FN(PASS) float3 main##PASS ()\
|
|
||||||
|
|
||||||
#define MAIN_FN(PASS) SOME_MAGIC(PASS,\
|
|
||||||
{\
|
|
||||||
return float3(1,0,0);\
|
|
||||||
}\
|
|
||||||
)
|
|
||||||
// #include "libgarbage_end.cginc"
|
|
||||||
// #define DO_MAGIC(p) MAIN_FN(p)
|
|
||||||
DO_MAGIC
|
|
||||||
|
|
||||||
// {return 0;}
|
|
||||||
// MAIN_FN(1) {return 0;}
|
|
||||||
|
|
||||||
|
|
||||||
ENDCG
|
ENDCG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
40
Assets/raymarched/lib/libgarbage_shapes.cginc
Normal file
40
Assets/raymarched/lib/libgarbage_shapes.cginc
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
|
||||||
|
#define _MAT_VARIANT1(NEW_NAME, BASE_FN, TYPE_1, ARG_1) \
|
||||||
|
SurfacePoint NEW_NAME(float3 p, TYPE_1 ARG_1, Material mat = DEFAULT_MAT) {\
|
||||||
|
SurfacePoint o;\
|
||||||
|
o.dist = BASE_FN(p, ARG_1);\
|
||||||
|
o.mat = mat;\
|
||||||
|
return o;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define _MAT_VARIANT2(NEW_NAME, BASE_FN, TYPE_1, ARG_1, TYPE_2, ARG_2) \
|
||||||
|
SurfacePoint NEW_NAME(float3 p, TYPE_1 ARG_1, TYPE_2 ARG_2, Material mat = DEFAULT_MAT) {\
|
||||||
|
SurfacePoint o;\
|
||||||
|
o.dist = BASE_FN(p, ARG_1, ARG_2);\
|
||||||
|
o.mat = mat;\
|
||||||
|
return o;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define _MAT_VARIANT3(NEW_NAME, BASE_FN, TYPE_1, ARG_1, TYPE_2, ARG_2, TYPE_3, ARG_3) \
|
||||||
|
SurfacePoint NEW_NAME(float3 p, TYPE_1 ARG_1, TYPE_2 ARG_2, TYPE_3 ARG_3, Material mat = DEFAULT_MAT) {\
|
||||||
|
SurfacePoint o;\
|
||||||
|
o.dist = BASE_FN(p, ARG_1, ARG_2, ARG_3);\
|
||||||
|
o.mat = mat;\
|
||||||
|
return o;\
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Most of these are taken from https://iquilezles.org/articles/distfunctions/
|
||||||
|
// Thank you Inigo Quilez <3
|
||||||
|
|
||||||
|
float sdBox(float3 p, float3 size) {
|
||||||
|
float3 q = abs(p) - size / 2.0;
|
||||||
|
return length(max(q, 0)) + min(max(q.x, max(q.y, q.z)), 0);
|
||||||
|
}
|
||||||
|
_MAT_VARIANT1(mBox, sdBox, float3, size)
|
||||||
|
|
||||||
|
float sdSphere(float3 p, float radius) {
|
||||||
|
return length(p) - radius;
|
||||||
|
}
|
||||||
|
_MAT_VARIANT1(mSphere, sdSphere, float, radius)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 26203816190e7e521a12959d895d68a3
|
guid: 4d08637fa3f7e141190ffd1bdbca2c19
|
||||||
ShaderImporter:
|
ShaderImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
defaultTextures: []
|
defaultTextures: []
|
Loading…
Reference in a new issue