summaryrefslogtreecommitdiffstats
path: root/halos.cginc
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2024-09-10 23:45:40 -0700
committeryum <yum.food.vr@gmail.com>2024-09-10 23:45:40 -0700
commitdfb1ece3e78cf013866d18a3a234e2f4bf8834f8 (patch)
tree81bbb45d39d6e2758b9b62632a4873821ac8d278 /halos.cginc
parent2712f07c0d06a15e6624b3045207d301a1592886 (diff)
Start work on new halo tech
Diffstat (limited to 'halos.cginc')
-rw-r--r--halos.cginc137
1 files changed, 137 insertions, 0 deletions
diff --git a/halos.cginc b/halos.cginc
new file mode 100644
index 0000000..aa0b731
--- /dev/null
+++ b/halos.cginc
@@ -0,0 +1,137 @@
+#ifndef __HALOS_INC
+#define __HALOS_INC
+
+#include "globals.cginc"
+#include "interpolators.cginc"
+#include "math.cginc"
+
+#if defined(_GIMMICK_HALO_00)
+struct Halo00Params {
+ float3 period;
+ float3 count;
+ float2 uv;
+};
+struct Halo00PBR {
+ float4 albedo;
+ float3 normal;
+};
+
+float halo00_map(float3 p, float2 e)
+{
+ return length(p) - 0.1;
+}
+
+float halo00_map_dr(
+ float3 p,
+ Halo00Params params,
+ out float3 which
+ )
+{
+ which = round(p / params.period);
+ // Direction to nearest neighboring cell.
+ float3 min_d = p - params.period * which;
+ float3 o = sign(min_d);
+
+ float d = 1E9;
+ float3 which_tmp = which;
+ for (int xi = 0; xi < 1; xi++)
+ for (int yi = 0; yi < 1; yi++)
+ {
+ float3 rid = which + float3(xi, yi, 0) * o;
+ rid = clamp(rid, ceil(-(params.count)*0.5), floor((params.count-1)*0.5));
+ float3 r = p - params.period * rid;
+ float2 e = 0;
+ /*
+ float2 e = float2(
+ rand3(rid / 100.0),
+ rand3(rid / 100.0 + 1));
+ */
+ float cur_d = halo00_map(r, e);
+ which_tmp =
+ (cur_d < d ? rid : which_tmp);
+ d = min(d, cur_d);
+ }
+
+ which = which_tmp;
+ return d;
+}
+
+float3 halo00_calc_normal(float3 p, Halo00Params params)
+{
+ const float3 small_step = float3(0.0001, 0.0, 0.0);
+
+ // TODO do we need full central differences?
+ float3 which;
+ float gradient_x = halo00_map_dr(p + small_step.xyy, params, which) -
+ halo00_map_dr(p - small_step.xyy, params, which);
+ float gradient_y = halo00_map_dr(p + small_step.yxy, params, which) -
+ halo00_map_dr(p - small_step.yxy, params, which);
+ float gradient_z = halo00_map_dr(p + small_step.yyx, params, which) -
+ halo00_map_dr(p - small_step.yyx, params, which);
+
+ float3 normal = float3(gradient_x, gradient_y, gradient_z);
+
+ return normalize(normal);
+}
+
+void __halo00_march(float3 ro, float3 rd, Halo00Params params, out Halo00PBR result)
+{
+ float total_distance_traveled = 0.0;
+ const float MINIMUM_HIT_DISTANCE = 0.001;
+ const float MAXIMUM_TRACE_DISTANCE = 10.0;
+
+ ro -= (1 - (params.count % 2)) * params.period * 0.5;
+
+#define HALO00_MARCH_STEPS 30
+ float distance_to_closest;
+ float3 current_position;
+ float3 which;
+ for (int i = 0; i < HALO00_MARCH_STEPS; i++)
+ {
+ current_position = ro + total_distance_traveled * rd;
+
+ distance_to_closest = halo00_map_dr(current_position, params, which);
+
+ if (distance_to_closest < MINIMUM_HIT_DISTANCE)
+ {
+ break;
+ }
+
+ if (total_distance_traveled > MAXIMUM_TRACE_DISTANCE)
+ {
+ break;
+ }
+ total_distance_traveled += distance_to_closest;
+ }
+
+ if (distance_to_closest < MINIMUM_HIT_DISTANCE) {
+ result.albedo = 1;
+ result.normal = halo00_calc_normal(current_position, params);
+ return;
+ }
+
+ result.albedo = 0;
+ result.normal = 0;
+ return;
+}
+
+Halo00PBR halo00_march(float3 worldPos, float2 uv)
+{
+ Halo00PBR result;
+ Halo00Params params;
+ params.period = 0.2;
+ params.count = 5;
+ params.uv = uv;
+
+ float3 camera_position = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos.xyz, 1));
+ float3 ro = camera_position;
+ float3 rd = normalize(mul(unity_WorldToObject, float4(worldPos - _WorldSpaceCameraPos.xyz, 1)));
+
+ __halo00_march(ro, rd, params, result);
+
+ return result;
+}
+
+#endif // _GIMMICK_HALO_00
+
+#endif // _HALOS_INC