diff options
| -rw-r--r-- | Editor/tooner.cs | 111 | ||||
| -rw-r--r-- | feature_macros.cginc | 3 | ||||
| -rw-r--r-- | globals.cginc | 47 | ||||
| -rw-r--r-- | iq_sdf.cginc | 21 | ||||
| -rw-r--r-- | mochie_shadow_caster.cginc | 3 | ||||
| -rw-r--r-- | tooner.shader | 48 | ||||
| -rw-r--r-- | tooner_lighting.cginc | 18 | ||||
| -rw-r--r-- | zwrite_abomination.cginc | 247 |
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 |
