summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Editor/tooner.cs111
-rw-r--r--feature_macros.cginc3
-rw-r--r--globals.cginc47
-rw-r--r--iq_sdf.cginc21
-rw-r--r--mochie_shadow_caster.cginc3
-rw-r--r--tooner.shader48
-rw-r--r--tooner_lighting.cginc18
-rw-r--r--zwrite_abomination.cginc247
8 files changed, 496 insertions, 2 deletions
diff --git a/Editor/tooner.cs b/Editor/tooner.cs
index 9edd3a7..041e096 100644
--- a/Editor/tooner.cs
+++ b/Editor/tooner.cs
@@ -2891,6 +2891,116 @@ public class ToonerGUI : ShaderGUI {
EditorGUI.indentLevel -= 1;
}
+ void DoGimmickZWriteAbomination() {
+ MaterialProperty bc;
+
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Enable_Static");
+ bool enabled = (bc.floatValue != 0.0);
+ EditorGUI.BeginChangeCheck();
+ enabled = Toggle("Zwrite abomination", enabled);
+ EditorGUI.EndChangeCheck();
+ bc.floatValue = enabled ? 1.0f : 0.0f;
+ SetKeyword("_GIMMICK_ZWRITE_ABOMINATION", enabled);
+
+ if (!enabled) {
+ return;
+ }
+
+ EditorGUI.indentLevel += 1;
+
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Min_Hit_Dist");
+ FloatProperty(bc, "Min hit dist");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_March_Steps");
+ FloatProperty(bc, "March steps");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Normal_Epsilon");
+ FloatProperty(bc, "Normal epsilon");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Initial_Step_Size");
+ FloatProperty(bc, "Initial step size");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Global_Scale");
+ FloatProperty(bc, "Global scale");
+
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Body_Half_Height");
+ FloatProperty(bc, "Body half height");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Body_Radius");
+ FloatProperty(bc, "Body radius");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Denim_Radius");
+ FloatProperty(bc, "Denim radius");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Denim_Half_Height");
+ FloatProperty(bc, "Denim half height");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Denim_Center");
+ VectorProperty(bc, "Denim center");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Denim_Strap_Theta");
+ FloatProperty(bc, "Denim strap theta");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Denim_Strap_RA");
+ FloatProperty(bc, "Denim strap RA");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Denim_Strap_RB");
+ FloatProperty(bc, "Denim strap RB");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Denim_Strap_Z_Theta");
+ FloatProperty(bc, "Denim strap z theta");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Denim_Strap_Center");
+ VectorProperty(bc, "Denim strap center");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Lens_Radius");
+ FloatProperty(bc, "Lens radius");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Lens_Depth");
+ FloatProperty(bc, "Lens depth");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Lens_Thickness");
+ FloatProperty(bc, "Lens thickness");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Lens_Strap_Height");
+ FloatProperty(bc, "Lens strap height");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Pupil_Radius");
+ FloatProperty(bc, "Pupil radius");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Eye_Center");
+ VectorProperty(bc, "Eye center");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Arm_Radius");
+ FloatProperty(bc, "Arm radius");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Arm_Half_Length");
+ FloatProperty(bc, "Arm half length");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Arm_Center");
+ VectorProperty(bc, "Arm center");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Leg_Radius");
+ FloatProperty(bc, "Leg radius");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Leg_Half_Length");
+ FloatProperty(bc, "Leg half length");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Leg_Center");
+ VectorProperty(bc, "Leg center");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Mouth_Theta");
+ FloatProperty(bc, "Mouth theta");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Mouth_RA");
+ FloatProperty(bc, "Mouth RA");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Mouth_RB");
+ FloatProperty(bc, "Mouth RB");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Mouth_Center");
+ VectorProperty(bc, "Mouth center");
+
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Lens_Strap_Color");
+ ColorProperty(bc, "Lens strap color");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Lens_Strap_Metallic");
+ FloatProperty(bc, "Lens strap metallic");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Lens_Strap_Roughness");
+ FloatProperty(bc, "Lens strap roughness");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Skin_Color");
+ ColorProperty(bc, "Skin color");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Skin_Metallic");
+ FloatProperty(bc, "Skin metallic");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Skin_Roughness");
+ FloatProperty(bc, "Skin roughness");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Lens_Color");
+ ColorProperty(bc, "Lens color");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Lens_Metallic");
+ FloatProperty(bc, "Lens metallic");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Lens_Roughness");
+ FloatProperty(bc, "Lens roughness");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Denim_Color");
+ ColorProperty(bc, "Denim color");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Denim_Metallic");
+ FloatProperty(bc, "Denim metallic");
+ bc = FindProperty("_Gimmick_ZWrite_Abomination_Denim_Roughness");
+ FloatProperty(bc, "Denim roughness");
+
+ EditorGUI.indentLevel -= 1;
+ }
+
+
void DoGimmickAurora() {
MaterialProperty bc;
@@ -3089,6 +3199,7 @@ public class ToonerGUI : ShaderGUI {
DoGimmickAudiolinkChroma00();
DoGimmickFog0();
DoGimmickFog1();
+ DoGimmickZWriteAbomination();
DoGimmickAurora();
DoGimmickGerstnerWater();
DoGimmickBoxDiscard();
diff --git a/feature_macros.cginc b/feature_macros.cginc
index f134e19..c5a4da7 100644
--- a/feature_macros.cginc
+++ b/feature_macros.cginc
@@ -268,8 +268,8 @@
#pragma shader_feature_local _ SSR_MASK
#pragma shader_feature_local _ _GIMMICK_FOG_00
#pragma shader_feature_local _ _GIMMICK_FOG_00_BOUNDARY_CYLINDER
-#pragma shader_feature_local _ _GIMMICK_FOG_00_BOUNDARY_PLANE
#pragma shader_feature_local _ _GIMMICK_FOG_00_BOUNDARY_SPHERE
+#pragma shader_feature_local _ _GIMMICK_FOG_00_BOUNDARY_PLANE
#pragma shader_feature_local _ _GIMMICK_FOG_00_NOISE_2D
#pragma shader_feature_local _ _GIMMICK_FOG_00_EMITTER_TEXTURE
#pragma shader_feature_local _ _GIMMICK_FOG_00_EMITTER_VARIABLE_DENSITY
@@ -285,6 +285,7 @@
#pragma shader_feature_local _ _GIMMICK_BOX_DISCARD
#pragma shader_feature_local _ _OPTIMIZE_INTERPOLATORS
#pragma shader_feature_local _ _ACES_FILMIC
+#pragma shader_feature_local _ _GIMMICK_ZWRITE_ABOMINATION
#endif // __FEATURE_MACROS_INC
diff --git a/globals.cginc b/globals.cginc
index 0364107..35a56d5 100644
--- a/globals.cginc
+++ b/globals.cginc
@@ -1010,6 +1010,53 @@ float _Gimmick_Fog_00_Emitter2_Scale_Y;
#endif
#endif
+#if defined(_GIMMICK_ZWRITE_ABOMINATION)
+float _Gimmick_ZWrite_Abomination_Min_Hit_Dist;
+float _Gimmick_ZWrite_Abomination_March_Steps;
+float _Gimmick_ZWrite_Abomination_Normal_Epsilon;
+float _Gimmick_ZWrite_Abomination_Initial_Step_Size;
+float _Gimmick_ZWrite_Abomination_Global_Scale;
+
+float _Gimmick_ZWrite_Abomination_Body_Half_Height;
+float _Gimmick_ZWrite_Abomination_Body_Radius;
+float _Gimmick_ZWrite_Abomination_Denim_Half_Height;
+float _Gimmick_ZWrite_Abomination_Denim_Radius;
+float3 _Gimmick_ZWrite_Abomination_Denim_Center;
+float _Gimmick_ZWrite_Abomination_Denim_Strap_Theta;
+float _Gimmick_ZWrite_Abomination_Denim_Strap_RA;
+float _Gimmick_ZWrite_Abomination_Denim_Strap_RB;
+float3 _Gimmick_ZWrite_Abomination_Denim_Strap_Center;
+float _Gimmick_ZWrite_Abomination_Denim_Strap_Z_Theta;
+float _Gimmick_ZWrite_Abomination_Lens_Radius;
+float _Gimmick_ZWrite_Abomination_Lens_Depth;
+float _Gimmick_ZWrite_Abomination_Lens_Thickness;
+float _Gimmick_ZWrite_Abomination_Lens_Strap_Height;
+float _Gimmick_ZWrite_Abomination_Pupil_Radius;
+float3 _Gimmick_ZWrite_Abomination_Eye_Center;
+float3 _Gimmick_ZWrite_Abomination_Arm_Center;
+float _Gimmick_ZWrite_Abomination_Arm_Radius;
+float _Gimmick_ZWrite_Abomination_Arm_Half_Length;
+float3 _Gimmick_ZWrite_Abomination_Leg_Center;
+float _Gimmick_ZWrite_Abomination_Leg_Radius;
+float _Gimmick_ZWrite_Abomination_Leg_Half_Length;
+float3 _Gimmick_ZWrite_Abomination_Mouth_Center;
+float _Gimmick_ZWrite_Abomination_Mouth_Theta;
+float _Gimmick_ZWrite_Abomination_Mouth_RA;
+float _Gimmick_ZWrite_Abomination_Mouth_RB;
+float4 _Gimmick_ZWrite_Abomination_Skin_Color;
+float _Gimmick_ZWrite_Abomination_Skin_Metallic;
+float _Gimmick_ZWrite_Abomination_Skin_Roughness;
+float4 _Gimmick_ZWrite_Abomination_Lens_Color;
+float _Gimmick_ZWrite_Abomination_Lens_Metallic;
+float _Gimmick_ZWrite_Abomination_Lens_Roughness;
+float4 _Gimmick_ZWrite_Abomination_Denim_Color;
+float _Gimmick_ZWrite_Abomination_Denim_Metallic;
+float _Gimmick_ZWrite_Abomination_Denim_Roughness;
+float4 _Gimmick_ZWrite_Abomination_Lens_Strap_Color;
+float _Gimmick_ZWrite_Abomination_Lens_Strap_Metallic;
+float _Gimmick_ZWrite_Abomination_Lens_Strap_Roughness;
+#endif
+
#if defined(_GIMMICK_FOG_01) || defined(_GIMMICK_DS2)
float _Gimmick_Fog_01_Density;
float _Gimmick_Fog_01_Overlay_Mode;
diff --git a/iq_sdf.cginc b/iq_sdf.cginc
index 4f5608e..d905b81 100644
--- a/iq_sdf.cginc
+++ b/iq_sdf.cginc
@@ -27,6 +27,19 @@ float distance_from_sphere(float3 p, float r)
return length(p) - r;
}
+float distance_from_torus(float3 p, float2 t)
+{
+ float2 q = float2(length(p.xz) - t.x, p.y);
+ return length(q) - t.y;
+}
+
+float distance_from_capped_torus(float3 p, float2 sc, float ra, float rb)
+{
+ p.x = abs(p.x);
+ float k = (sc.y*p.x>sc.x*p.y) ? dot(p.xy,sc) : length(p.xy);
+ return sqrt(dot(p,p) + ra*ra - 2.0*ra*k) - rb;
+}
+
float distance_from_cut_sphere( in float3 p, in float r, in float h )
{
float w = sqrt(r*r-h*h); // constant for a given shape
@@ -126,6 +139,14 @@ float distance_from_hex_prism(float3 p, float2 h)
p.z-h.y );
return min(max(d.x,d.y),0.0) + length(max(d,0.0));
}
+
+float distance_from_capsule(float3 p, float3 a, float3 b, float r)
+{
+ float3 pa = p - a, ba = b - a;
+ float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
+ return length( pa - ba*h ) - r;
+}
+
/*
float sdHexPrism( vec3 p, vec2 h )
{
diff --git a/mochie_shadow_caster.cginc b/mochie_shadow_caster.cginc
index 785c5bd..ea3d8fa 100644
--- a/mochie_shadow_caster.cginc
+++ b/mochie_shadow_caster.cginc
@@ -48,6 +48,9 @@ v2f vert (appdata v){
return (v2f) (0.0 / 0.0);
}
#endif
+#if defined(_GIMMICK_ZWRITE_ABOMINATION)
+ return (v2f) (0.0 / 0.0);
+#endif
#if defined(_GIMMICK_BOX_DISCARD)
if (_Gimmick_Box_Discard_Enable_Static) {
float3 p = getCenterCamPos();
diff --git a/tooner.shader b/tooner.shader
index a62e242..811cbff 100644
--- a/tooner.shader
+++ b/tooner.shader
@@ -3,7 +3,7 @@ Shader "yum_food/tooner"
// Unity fucking sucks ass and sometimes incorrectly uses an old cached
// version of the shader. Bump the nonce below to encourage it to use the
// current version.
- // Build nonce: 38
+ // Build nonce: 39
Properties
{
_Color("Base color", Color) = (0.8, 0.8, 0.8, 1)
@@ -1088,6 +1088,52 @@ Shader "yum_food/tooner"
_Gimmick_Fog_01_Activation_Center("Activation center", Vector) = (0, 0, 0, 0)
_Gimmick_Fog_01_Activation_Radius("Activation radius", Float) = 1
+ _Gimmick_ZWrite_Abomination_Enable_Static("Enable zwrite abomination", Float) = 0
+ _Gimmick_ZWrite_Abomination_Min_Hit_Dist("Min hit dist", Float) = 0.001
+ _Gimmick_ZWrite_Abomination_March_Steps("March steps", Float) = 30
+ _Gimmick_ZWrite_Abomination_Normal_Epsilon("Normal epsilon", Float) = 0.001
+ _Gimmick_ZWrite_Abomination_Initial_Step_Size("Initial step size", Float) = 0.001
+ _Gimmick_ZWrite_Abomination_Global_Scale("Global scale", Float) = 1
+
+ _Gimmick_ZWrite_Abomination_Body_Half_Height("Body half height", Float) = 0.1
+ _Gimmick_ZWrite_Abomination_Body_Radius("Body radius", Float) = 0.1
+ _Gimmick_ZWrite_Abomination_Denim_Half_Height("Denim half height", Float) = 0.1
+ _Gimmick_ZWrite_Abomination_Denim_Radius("Denim radius", Float) = 0.1
+ _Gimmick_ZWrite_Abomination_Denim_Center("Denim center", Vector) = (0, 0, 0, 0)
+ _Gimmick_ZWrite_Abomination_Denim_Strap_Theta("Denim strap theta", Float) = 0
+ _Gimmick_ZWrite_Abomination_Denim_Strap_RA("Denim strap RA", Float) = 0.01
+ _Gimmick_ZWrite_Abomination_Denim_Strap_RB("Denim strap RB", Float) = 0.01
+ _Gimmick_ZWrite_Abomination_Denim_Strap_Z_Theta("Denim strap z theta", Float) = 0
+ _Gimmick_ZWrite_Abomination_Denim_Strap_Center("Denim strap center", Vector) = (0, 0, 0, 0)
+ _Gimmick_ZWrite_Abomination_Lens_Radius("Lens radius", Float) = 0.05
+ _Gimmick_ZWrite_Abomination_Lens_Depth("Lens depth", Float) = 0.01
+ _Gimmick_ZWrite_Abomination_Lens_Thickness("Lens thickness", Float) = 0.01
+ _Gimmick_ZWrite_Abomination_Lens_Strap_Height("Lens strap height", Float) = 0.01
+ _Gimmick_ZWrite_Abomination_Pupil_Radius("Pupil radius", Float) = 0.01
+ _Gimmick_ZWrite_Abomination_Eye_Center("Eye center", Vector) = (0, 0, 0, 0)
+ _Gimmick_ZWrite_Abomination_Arm_Center("Arm center", Vector) = (0, 0, 0, 0)
+ _Gimmick_ZWrite_Abomination_Arm_Radius("Arm radius", Float) = 0.01
+ _Gimmick_ZWrite_Abomination_Arm_Half_Length("Arm half length", Float) = 0.05
+ _Gimmick_ZWrite_Abomination_Leg_Center("Leg center", Vector) = (0, 0, 0, 0)
+ _Gimmick_ZWrite_Abomination_Leg_Radius("Leg radius", Float) = 0.01
+ _Gimmick_ZWrite_Abomination_Leg_Half_Length("Leg half length", Float) = 0.05
+ _Gimmick_ZWrite_Abomination_Mouth_Center("Mouth center", Vector) = (0, 0, 0, 0)
+ _Gimmick_ZWrite_Abomination_Mouth_Theta("Mouth theta", Float) = 0
+ _Gimmick_ZWrite_Abomination_Mouth_RA("Mouth RA", Float) = 0.01
+ _Gimmick_ZWrite_Abomination_Mouth_RB("Mouth RB", Float) = 0.01
+ _Gimmick_ZWrite_Abomination_Skin_Color("Skin color", Color) = (1, 1, 1, 1)
+ _Gimmick_ZWrite_Abomination_Skin_Metallic("Skin metallic", Float) = 0
+ _Gimmick_ZWrite_Abomination_Skin_Roughness("Skin roughness", Float) = 0
+ _Gimmick_ZWrite_Abomination_Lens_Color("Lens color", Color) = (1, 1, 1, 1)
+ _Gimmick_ZWrite_Abomination_Lens_Metallic("Lens metallic", Float) = 0
+ _Gimmick_ZWrite_Abomination_Lens_Roughness("Lens roughness", Float) = 0
+ _Gimmick_ZWrite_Abomination_Denim_Color("Denim color", Color) = (1, 1, 1, 1)
+ _Gimmick_ZWrite_Abomination_Denim_Metallic("Denim metallic", Float) = 0
+ _Gimmick_ZWrite_Abomination_Denim_Roughness("Denim roughness", Float) = 0
+ _Gimmick_ZWrite_Abomination_Lens_Strap_Color("Lens strap color", Color) = (1, 1, 1, 1)
+ _Gimmick_ZWrite_Abomination_Lens_Strap_Metallic("Lens strap metallic", Float) = 0
+ _Gimmick_ZWrite_Abomination_Lens_Strap_Roughness("Lens strap roughness", Float) = 0
+
_Gimmick_Aurora_Enable_Static("Enable aurora", Float) = 0
_Gimmick_Gerstner_Water_Enable_Static("Enable water (gerstner)", Float) = 0
diff --git a/tooner_lighting.cginc b/tooner_lighting.cginc
index 9195a73..2e2a254 100644
--- a/tooner_lighting.cginc
+++ b/tooner_lighting.cginc
@@ -26,6 +26,7 @@
#include "tone.cginc"
#include "tooner_scroll.cginc"
#include "trochoid_math.cginc"
+#include "zwrite_abomination.cginc"
#ifndef TOONER_LIGHTING
#define TOONER_LIGHTING
@@ -1170,6 +1171,23 @@ float4 effect(inout v2f i, out float depth)
float roughness = _Roughness;
#endif
+#if defined(_GIMMICK_ZWRITE_ABOMINATION) && defined(FORWARD_BASE_PASS)
+ {
+ ZWriteAbominationPBR pbr = zwrite_abomination(i);
+ i.worldPos = pbr.worldPos;
+ albedo = pbr.albedo;
+ metallic = pbr.metallic;
+ roughness = pbr.roughness;
+ normal = pbr.normal;
+ depth = pbr.depth;
+#if 0
+ float3 c = 1;
+ c *= saturate(dot(normal, float3(0, -1, 1)));
+ return float4(c, albedo.a);
+#endif
+ }
+#endif
+
#if defined(VERTEXLIGHT_ON)
float4 vertex_light_color = float4(i.vertexLightColor, 1);
#else
diff --git a/zwrite_abomination.cginc b/zwrite_abomination.cginc
new file mode 100644
index 0000000..bba03e1
--- /dev/null
+++ b/zwrite_abomination.cginc
@@ -0,0 +1,247 @@
+#include "UnityCG.cginc"
+
+#include "globals.cginc"
+#include "iq_sdf.cginc"
+#include "interpolators.cginc"
+
+#ifndef __ZWRITE_ABOMINATION_INC
+#define __ZWRITE_ABOMINATION_INC
+
+#if defined(_GIMMICK_ZWRITE_ABOMINATION)
+
+struct ZWriteAbominationPBR {
+ float3 worldPos;
+ float3 normal;
+ float4 albedo;
+ float metallic;
+ float roughness;
+ float depth;
+};
+
+#define BODY_PART_BODY 0
+#define BODY_PART_LENS 1
+#define BODY_PART_EYE_WHITE 2
+#define BODY_PART_PUPIL 3
+#define BODY_PART_ARM 4
+#define BODY_PART_LEG 5
+#define BODY_PART_MOUTH 6
+#define BODY_PART_DENIM 7
+#define BODY_PART_DENIM_STRAP 7
+#define BODY_PART_EYE_STRAP 8
+
+float zwrite_abomination_map(float3 p, out uint body_part) {
+ float epsilon = 1E-4;
+ float d;
+
+ // Capsule representing body
+ {
+ float body_half_height = _Gimmick_ZWrite_Abomination_Body_Half_Height;
+ float body_radius = _Gimmick_ZWrite_Abomination_Body_Radius;
+ float body_d = distance_from_capsule(p, float3(0, -body_half_height, 0), float3(0, body_half_height, 0), body_radius);
+ body_part = BODY_PART_BODY;
+ d = body_d;
+ }
+
+ // Capsule representing denim
+ {
+ float3 denim_center = _Gimmick_ZWrite_Abomination_Denim_Center;
+ float3 pp = p - denim_center;
+ float denim_half_height = _Gimmick_ZWrite_Abomination_Denim_Half_Height;
+ float denim_radius = _Gimmick_ZWrite_Abomination_Denim_Radius;
+ float denim_d = distance_from_capsule(pp, float3(0, -denim_half_height, 0), float3(0, denim_half_height, 0), denim_radius);
+ body_part = denim_d < d ? BODY_PART_DENIM : body_part;
+ d = min(d, denim_d);
+ }
+
+ // Torus representing denim strap
+ {
+ float3 strap_center = _Gimmick_ZWrite_Abomination_Denim_Strap_Center;
+ float3 pp = p;
+ pp.x = abs(pp.x);
+ pp -= strap_center;
+ // Rotate about z axis
+ float theta = _Gimmick_ZWrite_Abomination_Denim_Strap_Z_Theta;
+ float2x2 rot = float2x2(float2(cos(theta), -sin(theta)), float2(sin(theta), cos(theta)));
+ pp.xy = mul(rot, pp.xy);
+ pp = pp.zyx;
+
+ float strap_theta = _Gimmick_ZWrite_Abomination_Denim_Strap_Theta;
+ float strap_ra = _Gimmick_ZWrite_Abomination_Denim_Strap_RA;
+ float strap_rb = _Gimmick_ZWrite_Abomination_Denim_Strap_RB;
+ float strap_d = distance_from_capped_torus(pp, float2(sin(strap_theta), cos(strap_theta)), strap_ra, strap_rb);
+ body_part = strap_d < d ? BODY_PART_DENIM_STRAP : body_part;
+ d = min(d, strap_d);
+ }
+
+ // Metal ring around the eye
+ {
+ float3 eye_center = _Gimmick_ZWrite_Abomination_Eye_Center;
+ float3 pp = (p - eye_center).xzy;
+ float lens_radius = _Gimmick_ZWrite_Abomination_Lens_Radius;
+ float lens_depth = _Gimmick_ZWrite_Abomination_Lens_Depth;
+ float lens_thickness = _Gimmick_ZWrite_Abomination_Lens_Thickness;
+ float lens_d0 = distance_from_capped_cylinder(pp, lens_depth, lens_radius);
+ // TODO do we need a capped cylinder? Can we use a more efficient SDF to cut out the middle?
+ float lens_d1 = distance_from_capped_cylinder(pp, lens_depth + 0.1, lens_radius - lens_thickness);
+ float lens_d = op_sub(lens_d1, lens_d0);
+ body_part = lens_d < d ? BODY_PART_LENS : body_part;
+ d = min(d, lens_d);
+
+ // White of eye
+ float eye_white_d = distance_from_capped_cylinder(pp, lens_depth * 0.5, lens_radius - lens_thickness * 0.5);
+ body_part = eye_white_d < d ? BODY_PART_EYE_WHITE : body_part;
+ d = min(d, eye_white_d);
+
+ // Pupil
+ float pupil_d = length(pp) - _Gimmick_ZWrite_Abomination_Pupil_Radius;
+ body_part = pupil_d < d ? BODY_PART_PUPIL : body_part;
+ d = min(d, pupil_d);
+ }
+
+ // Strap holding metal ring to head
+ {
+ float3 pp = p;
+ pp.y -= _Gimmick_ZWrite_Abomination_Eye_Center.y;
+ float strap_d = distance_from_capped_cylinder(pp, _Gimmick_ZWrite_Abomination_Lens_Strap_Height, _Gimmick_ZWrite_Abomination_Body_Radius * 1.001);
+ body_part = strap_d < d ? BODY_PART_EYE_STRAP : body_part;
+ d = min(d, strap_d);
+ }
+
+ // Mouth
+ {
+ float3 mouth_center = _Gimmick_ZWrite_Abomination_Mouth_Center;
+ float3 pp = p;
+ pp -= mouth_center;
+ pp.y = -pp.y;
+ float theta = _Gimmick_ZWrite_Abomination_Mouth_Theta;
+ float ra = _Gimmick_ZWrite_Abomination_Mouth_RA;
+ float rb = _Gimmick_ZWrite_Abomination_Mouth_RB;
+ float mouth_d = distance_from_capped_torus(pp, float2(sin(theta), cos(theta)), ra, rb);
+ body_part = mouth_d < d ? BODY_PART_MOUTH : body_part;
+ d = min(d, mouth_d);
+ }
+
+ // Arms
+ {
+ float3 arm_center = _Gimmick_ZWrite_Abomination_Arm_Center;
+ float3 pp = p;
+ pp.x = abs(pp.x); // Symmetrize along x axis
+ pp -= arm_center;
+ float arm_radius = _Gimmick_ZWrite_Abomination_Arm_Radius;
+ float arm_half_length = _Gimmick_ZWrite_Abomination_Arm_Half_Length;
+ float arm_d = distance_from_capsule(pp, float3(-arm_half_length, 0, 0), float3(arm_half_length, 0, 0), arm_radius);
+ body_part = arm_d < d ? BODY_PART_ARM : body_part;
+ d = min(d, arm_d);
+ }
+
+ // Legs
+ {
+ float3 leg_center = _Gimmick_ZWrite_Abomination_Leg_Center;
+ float3 pp = p.yxz;
+ pp.y = abs(pp.y); // Symmetrize
+ pp -= leg_center;
+ float leg_radius = _Gimmick_ZWrite_Abomination_Leg_Radius;
+ float leg_half_length = _Gimmick_ZWrite_Abomination_Leg_Half_Length;
+ float leg_d = distance_from_capsule(pp, float3(-leg_half_length, 0, 0), float3(leg_half_length, 0, 0), leg_radius);
+ body_part = leg_d < d ? BODY_PART_LEG : body_part;
+ d = min(d, leg_d);
+ }
+
+ return d;
+}
+
+// TODO tetrahedral normals
+float3 zwrite_abomination_normal(float3 p) {
+ float3 epsilon = float3(1, 0, 0) * _Gimmick_ZWrite_Abomination_Normal_Epsilon;
+ uint body_part;
+ return normalize(float3(
+ zwrite_abomination_map(p + epsilon.xyy, body_part) - zwrite_abomination_map(p - epsilon.xyy, body_part),
+ zwrite_abomination_map(p + epsilon.yxy, body_part) - zwrite_abomination_map(p - epsilon.yxy, body_part),
+ zwrite_abomination_map(p + epsilon.yyx, body_part) - zwrite_abomination_map(p - epsilon.yyx, body_part)
+ ));
+}
+
+ZWriteAbominationPBR zwrite_abomination(in v2f i)
+{
+ float3 cam_pos = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1));
+ float3 rd = normalize(i.objPos - cam_pos);
+ float3 ro = cam_pos + rd * _Gimmick_ZWrite_Abomination_Initial_Step_Size;
+
+ // TODO raytrace ro near the object
+
+ const float MIN_HIT_DIST = _Gimmick_ZWrite_Abomination_Min_Hit_Dist;
+ const float MAX_DIST = 1;
+ const uint MARCH_STEPS = _Gimmick_ZWrite_Abomination_March_Steps;
+ float total_dist = 0;
+ float d;
+ uint body_part;
+ for (uint ii = 0; ii < MARCH_STEPS; ++ii) {
+ float3 p = ro + rd * total_dist;
+ d = zwrite_abomination_map(p, body_part);
+ if (d < MIN_HIT_DIST) {
+ break;
+ }
+ total_dist += d;
+ }
+
+ ZWriteAbominationPBR pbr;
+ if (d < MIN_HIT_DIST) {
+ float3 p = ro + rd * total_dist;
+ pbr.worldPos = mul(unity_ObjectToWorld, float4(p, 1.0)).xyz;
+
+ float3 c = 1;
+ c = (body_part == BODY_PART_BODY) ? _Gimmick_ZWrite_Abomination_Skin_Color : c;
+ c = (body_part == BODY_PART_ARM) ? _Gimmick_ZWrite_Abomination_Skin_Color : c;
+ c = (body_part == BODY_PART_LEG) ? _Gimmick_ZWrite_Abomination_Skin_Color : c;
+ c = (body_part == BODY_PART_LENS) ? _Gimmick_ZWrite_Abomination_Lens_Color : c;
+ c = (body_part == BODY_PART_EYE_WHITE) ? 1 : c;
+ c = (body_part == BODY_PART_PUPIL) ? 0 : c;
+ c = (body_part == BODY_PART_MOUTH) ? 0 : c;
+ c = (body_part == BODY_PART_DENIM) ? _Gimmick_ZWrite_Abomination_Denim_Color : c;
+ c = (body_part == BODY_PART_DENIM_STRAP) ? _Gimmick_ZWrite_Abomination_Denim_Color : c;
+ c = (body_part == BODY_PART_EYE_STRAP) ? _Gimmick_ZWrite_Abomination_Lens_Strap_Color : c;
+
+ float metallic = 0;
+ metallic = (body_part == BODY_PART_BODY) ? _Gimmick_ZWrite_Abomination_Skin_Metallic : metallic;
+ metallic = (body_part == BODY_PART_ARM) ? _Gimmick_ZWrite_Abomination_Skin_Metallic : metallic;
+ metallic = (body_part == BODY_PART_LEG) ? _Gimmick_ZWrite_Abomination_Skin_Metallic : metallic;
+ metallic = (body_part == BODY_PART_LENS) ? _Gimmick_ZWrite_Abomination_Lens_Metallic : metallic;
+ metallic = (body_part == BODY_PART_EYE_WHITE) ? 0 : metallic;
+ metallic = (body_part == BODY_PART_PUPIL) ? 0 : metallic;
+ metallic = (body_part == BODY_PART_MOUTH) ? 0 : metallic;
+ metallic = (body_part == BODY_PART_DENIM) ? _Gimmick_ZWrite_Abomination_Denim_Metallic : metallic;
+ metallic = (body_part == BODY_PART_DENIM_STRAP) ? _Gimmick_ZWrite_Abomination_Denim_Metallic : metallic;
+ metallic = (body_part == BODY_PART_EYE_STRAP) ? _Gimmick_ZWrite_Abomination_Lens_Strap_Metallic : metallic;
+
+ float roughness = 0;
+ roughness = (body_part == BODY_PART_BODY) ? _Gimmick_ZWrite_Abomination_Skin_Roughness : roughness;
+ roughness = (body_part == BODY_PART_ARM) ? _Gimmick_ZWrite_Abomination_Skin_Roughness : roughness;
+ roughness = (body_part == BODY_PART_LEG) ? _Gimmick_ZWrite_Abomination_Skin_Roughness : roughness;
+ roughness = (body_part == BODY_PART_LENS) ? _Gimmick_ZWrite_Abomination_Lens_Roughness : roughness;
+ roughness = (body_part == BODY_PART_EYE_WHITE) ? 0 : roughness;
+ roughness = (body_part == BODY_PART_PUPIL) ? 0 : roughness;
+ roughness = (body_part == BODY_PART_MOUTH) ? 1 : roughness;
+ roughness = (body_part == BODY_PART_DENIM) ? _Gimmick_ZWrite_Abomination_Denim_Roughness : roughness;
+ roughness = (body_part == BODY_PART_DENIM_STRAP) ? _Gimmick_ZWrite_Abomination_Denim_Roughness : roughness;
+ roughness = (body_part == BODY_PART_EYE_STRAP) ? _Gimmick_ZWrite_Abomination_Lens_Strap_Roughness : roughness;
+
+ pbr.albedo = float4(c, 1);
+ pbr.metallic = metallic;
+ pbr.roughness = roughness;
+ pbr.normal = UnityObjectToWorldNormal(zwrite_abomination_normal(p));
+ float4 clip_pos = mul(UNITY_MATRIX_VP, float4(mul(unity_ObjectToWorld, float4(p, 1.0))));
+ pbr.depth = clip_pos.z / clip_pos.w;
+ } else {
+ pbr.worldPos = i.worldPos;
+ pbr.albedo = 0;
+ pbr.metallic = 0;
+ pbr.roughness = 1;
+ pbr.normal = i.normal;
+ pbr.depth = -1E6;
+ }
+
+ return pbr;
+}
+
+#endif // _GIMMICK_ZWRITE_ABOMINATION
+#endif // __ZWRITE_ABOMINATION_INC