yum/3ner

A toon shader for Unity's BIRP.

git clone https://git.yummers.dev/yum/3ner

yumImpostors: begin optimization work50e4514

master
2.2 KiB64 linesraw
1#ifndef __RAY_MARCHING_MAPS_INC
2#define __RAY_MARCHING_MAPS_INC
3
4#include "math.cginc"
5#include "pema99.cginc"
6
7// Macros for transforming normal and tangent using autodiff.
8// r3r1 refers to "r3 to r1 transform", aka a mapping from a 3d real-valued
9// space to a 1d space. This is intended for use with a ray marcher.
10#define R3R1_DECLARE_BASIS_VECTORS(xyz) \
11  DifferentialPair<float3> dp_x = diffPair(xyz, float3(1, 0, 0)); \
12  DifferentialPair<float3> dp_y = diffPair(xyz, float3(0, 1, 0)); \
13  DifferentialPair<float3> dp_z = diffPair(xyz, float3(0, 0, 1))
14
15#define R3R1_AUTODIFF_BASIS_VECTORS(fun, ...) \
16  DifferentialPair<float> dp_x_out = fwd_diff(fun)(dp_x, __VA_ARGS__); \
17  DifferentialPair<float> dp_y_out = fwd_diff(fun)(dp_y, __VA_ARGS__); \
18  DifferentialPair<float> dp_z_out = fwd_diff(fun)(dp_z, __VA_ARGS__)
19
20#define R3R1_DEFORM_NORMAL_AND_TANGENT(normal, tangent) \
21  { \
22    float3 gradient = float3(dp_x_out.d, dp_y_out.d, dp_z_out.d); \
23    normal = normalize(gradient); \
24    float3 helper = abs(normal.z) < 0.999 ? float3(0, 0, 1) : float3(0, 1, 0); \
25    tangent = normalize(cross(helper, normal)); \
26  }
27
28// Syntactic sugar - wraps the previous three macros.
29#define R3R1_RAY_MARCH_NORMALS(xyz, normal, tangent, fun, ...)  \
30  R3R1_DECLARE_BASIS_VECTORS(xyz);                              \
31  R3R1_AUTODIFF_BASIS_VECTORS(fun, __VA_ARGS__);              \
32  R3R1_DEFORM_NORMAL_AND_TANGENT(normal, tangent)
33
34[Differentiable]
35public float map_ball(float3 p, no_diff float r) {
36  return length(p) - r;
37}
38
39public void map_ball_normal(float r, inout float3 xyz, inout float3 normal,
40    inout float3 tangent) {
41  R3R1_RAY_MARCH_NORMALS(xyz, normal, tangent, map_ball, r);
42}
43
44[Differentiable]
45public float map_hexagon(float3 p, no_diff float2 h)
46{
47  float3 q = abs(p);
48
49  const float3 k = float3(-0.8660254, 0.5, 0.57735);
50  p = abs(p);
51  p.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy;
52  float2 d = float2(
53      length(p.xy - float2(clamp(p.x, -k.z*h.x, k.z*h.x), h.x))*sign(p.y - h.x),
54      p.z-h.y );
55  return min(max(d.x,d.y),0.0) + length(max(d,0.0));
56}
57
58public void map_hexagon_normal(float2 h, inout float3 xyz, inout float3 normal,
59    inout float3 tangent) {
60  R3R1_RAY_MARCH_NORMALS(xyz, normal, tangent, map_hexagon, h);
61}
62
63#endif  // __RAY_MARCHING_MAPS_INC
64