diff options
| author | yum <yum.food.vr@gmail.com> | 2025-02-20 19:57:54 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2025-02-20 19:57:54 -0800 |
| commit | 72806ff9f71bd98973f51a4b67de00c056fe8d89 (patch) | |
| tree | 2a7d1ed7a8cbb563ed79ef18e363ef3b4efccd3a | |
| parent | 14cdf12e17d2b17676135457e42bde391ff3f313 (diff) | |
add eye shader
| -rw-r--r-- | 2ner.cginc | 11 | ||||
| -rw-r--r-- | 2ner.shader | 14 | ||||
| -rw-r--r-- | Textures/HDR_RGB_0.png | bin | 0 -> 93696 bytes | |||
| -rw-r--r-- | eyes.cginc | 133 | ||||
| -rw-r--r-- | features.cginc | 4 | ||||
| -rw-r--r-- | globals.cginc | 11 | ||||
| -rw-r--r-- | interpolators.cginc | 13 | ||||
| -rw-r--r-- | oklab.cginc | 120 | ||||
| -rw-r--r-- | quilez.cginc | 168 |
9 files changed, 468 insertions, 6 deletions
@@ -4,6 +4,7 @@ #include "UnityCG.cginc"
#include "UnityLightingCommon.cginc"
+#include "eyes.cginc"
#include "features.cginc"
#include "globals.cginc"
#include "interpolators.cginc"
@@ -59,6 +60,7 @@ v2f vert(appdata v) { o.pos = UnityObjectToClipPos(v.vertex);
o.uv01 = v.uv01;
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
+ o.objPos = v.vertex;
o.eyeVec.xyz = normalize(o.worldPos - _WorldSpaceCameraPos);
// These are used to convert normals from tangent space to world space.
@@ -83,8 +85,17 @@ float4 frag(v2f i) : SV_Target { // Not necessarily normalized after interpolation
i.normal = normalize(i.normal);
+#if defined(_EYE_EFFECT_00)
+ EyeEffectOutput eye_effect_00 = EyeEffect_00(i);
+ i.uv01.xy = eye_effect_00.uv;
+#endif
+
YumPbr pbr = GetYumPbr(i);
+#if defined(_EYE_EFFECT_00)
+ pbr.normal = eye_effect_00.normal;
+#endif
+
UNITY_BRANCH
if (_Mode == 1) {
clip(pbr.albedo.a - _Clip);
diff --git a/2ner.shader b/2ner.shader index 3780ae6..9ef319c 100644 --- a/2ner.shader +++ b/2ner.shader @@ -237,6 +237,20 @@ Shader "yum_food/2ner" [HideInInspector] m_end_Vertex_Domain_Warping("Vertex domain warping", Float) = 0 //endex + //ifex _Eye_Effect_00_Enabled==0 + [HideInInspector] m_start_Eye_Effect_00("Eye effect 00", Float) = 0 + [ThryToggle(_EYE_EFFECT_00)]_Eye_Effect_00_Enabled("Enable", Float) = 0 + _Gimmick_Eye_Effect_00_Edge_Length("Edge length", Float) = 0.1 + _Gimmick_Eye_Effect_00_Period("Period", Vector) = (1.0, 1.0, 1.0) + _Gimmick_Eye_Effect_00_Count("Count", Vector) = (1.0, 1.0, 1.0) + _Gimmick_Eye_Effect_00_Noise("Noise", 2D) = "white" {} + _Gimmick_Eye_Effect_00_Domain_Warping_Octaves("Domain warping octaves", Float) = 1.0 + _Gimmick_Eye_Effect_00_Domain_Warping_Scale("Domain warping scale", Float) = 1.0 + _Gimmick_Eye_Effect_00_Domain_Warping_Speed("Domain warping speed", Float) = 1.0 + _Gimmick_Eye_Effect_00_Domain_Warping_Strength("Domain warping strength", Float) = 0.1 + [HideInInspector] m_end_Eye_Effect_00("Eye effect 00", Float) = 0 + //endex + [HideInInspector] m_lightingOptions("Lighting Options", Float) = 0 //ifex _Receive_Shadows_Enabled==0 [HideInInspector] m_start_Shadow_Receiving("Receive shadows", Float) = 0 diff --git a/Textures/HDR_RGB_0.png b/Textures/HDR_RGB_0.png Binary files differnew file mode 100644 index 0000000..a605ffb --- /dev/null +++ b/Textures/HDR_RGB_0.png diff --git a/eyes.cginc b/eyes.cginc new file mode 100644 index 0000000..81456d2 --- /dev/null +++ b/eyes.cginc @@ -0,0 +1,133 @@ +#ifndef __EYES_INC
+#define __EYES_INC
+
+#include "globals.cginc"
+#include "interpolators.cginc"
+#include "math.cginc"
+#include "oklab.cginc"
+#include "quilez.cginc"
+
+#if defined(_EYE_EFFECT_00)
+
+struct EyeEffectOutput {
+ float4 albedo;
+ float3 emission;
+ float3 normal;
+ float3 worldPos;
+ float4 fog;
+ float2 uv;
+ float metallic;
+ float roughness;
+};
+
+float eye_effect_00_map(float3 p)
+{
+ float edge = _Gimmick_Eye_Effect_00_Edge_Length;
+ float thickness = edge*10;
+ return distance_from_round_box(p - float3(0, thickness*.99, 0), float3(edge, thickness, edge), edge * .1);
+}
+
+float3 eye_effect_00_nudge_p(float3 p, float3 which)
+{
+ float noise = _Gimmick_Eye_Effect_00_Noise.SampleLevel(linear_repeat_s, which.xz * _Gimmick_Eye_Effect_00_Period.xz * .005 + _Time[0] * .05, 0);
+ return p - float3(0, noise * .01, 0);
+}
+
+float eye_effect_00_map_dr(
+ float3 p,
+ float3 period,
+ float3 count,
+ out float3 which
+ )
+{
+ which = floor(p / period);
+ // Direction to nearest neighboring cell.
+ float3 min_d = p - period * which;
+ float3 o = sign(min_d);
+
+ float d = 1E9;
+ float3 which_tmp = which;
+ for (uint xi = 0; xi < 1; xi++)
+ for (uint zi = 0; zi < 1; zi++)
+ {
+ float3 rid = which + float3(xi, 0, zi) * o;
+ rid = clamp(rid, ceil(-(count)*0.5), floor((count-1)*0.5));
+ float3 r = p - period * rid;
+ r = eye_effect_00_nudge_p(r, rid);
+ float cur_d = eye_effect_00_map(r);
+ which_tmp = cur_d < d ? rid : which_tmp;
+ d = min(d, cur_d);
+ }
+
+ which = which_tmp;
+ return d;
+}
+
+float3 eye_effect_00_calc_normal(float3 p)
+{
+ float3 small_step = float3(1E-5, 0.0, 0.0);
+ float3 which;
+ float center = eye_effect_00_map_dr(p, _Gimmick_Eye_Effect_00_Period.xyz, _Gimmick_Eye_Effect_00_Count.xyz, which);
+ return normalize(float3(
+ eye_effect_00_map_dr(p + small_step.xyz, _Gimmick_Eye_Effect_00_Period.xyz, _Gimmick_Eye_Effect_00_Count.xyz, which) - center,
+ eye_effect_00_map_dr(p + small_step.zxy, _Gimmick_Eye_Effect_00_Period.xyz, _Gimmick_Eye_Effect_00_Count.xyz, which) - center,
+ eye_effect_00_map_dr(p + small_step.yzx, _Gimmick_Eye_Effect_00_Period.xyz, _Gimmick_Eye_Effect_00_Count.xyz, which) - center
+ ));
+}
+
+// derived from downstairs_02.cginc effect 02
+EyeEffectOutput EyeEffect_00(inout v2f i)
+{
+ float3 camera_position = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1));
+ float3 ro = i.objPos;
+ float3 rd = normalize(i.objPos - camera_position);
+
+ float2 warping_speed_vector = normalize(float2(97, 101));
+ for (uint ii = 0; ii < _Gimmick_Eye_Effect_00_Domain_Warping_Octaves; ii++)
+ {
+ float2 noise = _Gimmick_Eye_Effect_00_Noise.SampleLevel(linear_repeat_s, ro.xz * _Gimmick_Eye_Effect_00_Domain_Warping_Scale + _Time[0] * _Gimmick_Eye_Effect_00_Domain_Warping_Speed * warping_speed_vector, 0) * 2 - 1;
+ ro.xz += noise * _Gimmick_Eye_Effect_00_Domain_Warping_Strength;
+ }
+
+ #define eye_effect_00_MARCH_STEPS 1
+ float total_distance_traveled = 0.0;
+ const float MINIMUM_HIT_DISTANCE = 1E-4;
+ const float MAXIMUM_TRACE_DISTANCE = 1E-1;
+ float distance_to_closest;
+ float3 which;
+ [loop]
+ for (uint ii = 0; ii < eye_effect_00_MARCH_STEPS; ii++)
+ {
+ float3 current_position = ro + total_distance_traveled * rd;
+ distance_to_closest = eye_effect_00_map_dr(current_position, _Gimmick_Eye_Effect_00_Period.xyz, _Gimmick_Eye_Effect_00_Count.xyz, which);
+ total_distance_traveled += distance_to_closest;
+ if (distance_to_closest < MINIMUM_HIT_DISTANCE ||
+ total_distance_traveled > MAXIMUM_TRACE_DISTANCE) {
+ break;
+ }
+ }
+
+ bool hit = distance_to_closest < MINIMUM_HIT_DISTANCE;
+ float3 final_position = ro + total_distance_traveled * rd;
+ float3 normal = hit ? UnityObjectToWorldNormal(eye_effect_00_calc_normal(final_position)) : i.normal;
+
+ float3 color = hit ? 1 : 0;
+
+ EyeEffectOutput o;
+ o.albedo = float4(color, hit);
+ o.emission = o.albedo;
+ o.fog = 0;
+ o.normal = normal;
+ o.metallic = 0;
+ o.roughness = 0;
+ // Depth gets all fucked up unless we use i.objPos instead of ro, which is domain warped.
+ o.worldPos = mul(unity_ObjectToWorld, float4(i.objPos + rd * total_distance_traveled, 1));
+ o.uv = ((which.xz + _Gimmick_Eye_Effect_00_Count.xz * .5) / _Gimmick_Eye_Effect_00_Count.xz) * float2(1, -1);
+ return o;
+}
+
+#endif // _EYE_EFFECT_00
+
+#endif // __EYES_INC
+
+
diff --git a/features.cginc b/features.cginc index 9d1be92..e42a768 100644 --- a/features.cginc +++ b/features.cginc @@ -71,5 +71,9 @@ #pragma shader_feature_local _VERTEX_DOMAIN_WARPING //endex +//ifex _Eye_Effect_00_Enabled==0 +#pragma shader_feature_local _EYE_EFFECT_00 +//endex + #endif // __FEATURES_INC diff --git a/globals.cginc b/globals.cginc index 08f0e34..50859c4 100644 --- a/globals.cginc +++ b/globals.cginc @@ -171,4 +171,15 @@ float _Vertex_Domain_Warping_Speed; float _Vertex_Domain_Warping_Temporal_Strength;
#endif // _VERTEX_DOMAIN_WARPING
+#if defined(_EYE_EFFECT_00)
+float _Gimmick_Eye_Effect_00_Edge_Length;
+float3 _Gimmick_Eye_Effect_00_Period;
+float3 _Gimmick_Eye_Effect_00_Count;
+texture2D _Gimmick_Eye_Effect_00_Noise;
+float _Gimmick_Eye_Effect_00_Domain_Warping_Octaves;
+float _Gimmick_Eye_Effect_00_Domain_Warping_Scale;
+float _Gimmick_Eye_Effect_00_Domain_Warping_Speed;
+float _Gimmick_Eye_Effect_00_Domain_Warping_Strength;
+#endif // _EYE_EFFECT_00
+
#endif // __GLOBALS_INC
diff --git a/interpolators.cginc b/interpolators.cginc index c75b725..285d042 100644 --- a/interpolators.cginc +++ b/interpolators.cginc @@ -15,12 +15,13 @@ struct appdata { struct v2f {
float4 pos : SV_POSITION;
float4 uv01 : TEXCOORD0;
- float3 worldPos : TEXCOORD1;
- float3 normal : TEXCOORD2;
- float3 tangent : TEXCOORD3;
- float3 binormal : TEXCOORD4;
- float4 eyeVec : TEXCOORD5; // eyeVec.xyz | fogCoord
- UNITY_LIGHTING_COORDS(6,7)
+ float3 objPos : TEXCOORD1;
+ float3 worldPos : TEXCOORD2;
+ float3 normal : TEXCOORD3;
+ float3 tangent : TEXCOORD4;
+ float3 binormal : TEXCOORD5;
+ float4 eyeVec : TEXCOORD6; // eyeVec.xyz | fogCoord
+ UNITY_LIGHTING_COORDS(7,8)
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
diff --git a/oklab.cginc b/oklab.cginc new file mode 100644 index 0000000..c5f87f6 --- /dev/null +++ b/oklab.cginc @@ -0,0 +1,120 @@ +/*
+ * MIT License
+ *
+ * Copyright (c) 2023-2025 yum_food
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE
+ * SOFTWARE.
+ */
+
+#ifndef __OKLAB_INC
+#define __OKLAB_INC
+
+#if defined(_EYE_EFFECT_00)
+
+// Utilities relating to the OKLAB color space, as defined here:
+// https://bottosson.github.io/posts/oklab/
+// Code is derived from the samples there, which are in the public domain.
+
+// Weights: https://en.wikipedia.org/wiki/SRGB
+float3 LRGBtoXYZ(float3 c) {
+ float3x3 rgb_to_xyz = float3x3(
+ 0.4124, 0.3576, 0.1805,
+ 0.2126, 0.7152, 0.0722,
+ 0.0193, 0.1192, 0.9505);
+ return saturate(mul(rgb_to_xyz, c));
+}
+
+// Weights: https://en.wikipedia.org/wiki/SRGB
+float3 XYZtoLRGB(float3 c) {
+ float3x3 xyz_to_rgb = float3x3(
+ 3.24062548, -1.53720797, -0.4986286,
+ -0.96893071, 1.87575606, 0.04151752,
+ 0.05571012, -0.20402105, 1.05699594);
+ return saturate(mul(xyz_to_rgb, c));
+}
+
+// Source: https://bottosson.github.io/posts/oklab/
+float3 XYZtoOKLAB(float3 c) {
+ float3x3 m1 = float3x3(
+ 0.8189330101, 0.3618667424, -0.1288597137,
+ 0.0329845436, 0.9293118715, 0.0361456387,
+ 0.0482003018, 0.2643662691, 0.6338517070);
+ float3x3 m2 = float3x3(
+ 0.2104542553, 0.7936177850, -0.0040720468,
+ 1.9779984951, -2.4285922050, 0.4505937099,
+ 0.0259040371, 0.7827717662, -0.8086757660);
+ c = mul(m1, c);
+ c = pow(c, 0.33333333333);
+ return mul(m2, c);
+}
+
+// Source: https://bottosson.github.io/posts/oklab/
+float3 OKLABtoXYZ(float3 c) {
+ float3x3 m1i = float3x3(
+ 1.22701385, -0.55779998, 0.28125615,
+ -0.04058018, 1.11225687, -0.07167668,
+ -0.07638128, -0.42148198, 1.58616322);
+ float3x3 m2i = float3x3(
+ 1.00000000, 0.39633779, 0.21580376,
+ 1.00000001, -0.10556134, -0.06385417,
+ 1.00000005, -0.08948418, -1.29148554);
+ c = mul(m2i, c);
+ c = pow(c, 3.0);
+ return mul(m1i, c);
+}
+
+// Source: https://bottosson.github.io/posts/oklab/
+float3 OKLABtoOKLCH(float3 c) {
+ float c_ = length(c.yz);
+ float h_ = atan2(c.z, c.y);
+ return float3(c.x, c_, h_);
+}
+
+// Source: https://bottosson.github.io/posts/oklab/
+// Note: hue must be in units of radians.
+float3 OKLCHtoOKLAB(float3 c) {
+ float a = c.y * cos(c.z);
+ float b = c.y * sin(c.z);
+ return float3(c.x, a, b);
+}
+
+float3 LRGBtoOKLAB(float3 c) {
+ return XYZtoOKLAB(LRGBtoXYZ(c));
+}
+
+float3 OKLABtoLRGB(float3 c) {
+ return XYZtoLRGB(OKLABtoXYZ(c));
+}
+
+float3 LRGBtoOKLCH(float3 c) {
+ return OKLABtoOKLCH(XYZtoOKLAB(LRGBtoXYZ(c)));
+}
+
+float3 OKLCHtoLRGB(float3 c) {
+ return XYZtoLRGB(OKLABtoXYZ(OKLCHtoOKLAB(c)));
+}
+
+#endif // _OKLAB
+
+#endif // __OKLAB_INC
+
diff --git a/quilez.cginc b/quilez.cginc new file mode 100644 index 0000000..e478db1 --- /dev/null +++ b/quilez.cginc @@ -0,0 +1,168 @@ +#include "pema99.cginc"
+
+#ifndef __QUILEZ_INC
+#define __QUILEZ_INC
+
+// The MIT License
+// Copyright © 2019-2024 Inigo Quilez
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+float distance_from_octahedron(in float3 p)
+{
+ float s = 1.0;
+ float3 pp = abs(p);
+ float m = pp.x+pp.y+pp.z-s;
+ float3 q;
+ if( 3.0*pp.x < m ) q = pp.xyz;
+ else if( 3.0*pp.y < m ) q = pp.yzx;
+ else if( 3.0*pp.z < m ) q = pp.zxy;
+ else return m*0.57735027;
+
+ float k = clamp(0.5*(q.z-q.y+s),0.0,s);
+ return length(float3(q.x,q.y-s+k,q.z-k));
+}
+
+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
+
+ float2 q = float2( length(p.xz), p.y );
+
+ float s = max( (h-r)*q.x*q.x+w*w*(h+r-2.0*q.y), h*q.x-w*q.y );
+
+ return (s<0.0) ? length(q)-r :
+ (q.x<w) ? h - q.y :
+ length(q-float2(w,h));
+}
+
+float distance_from_cut_hollow_sphere( float3 p, float r, float h, float t )
+{
+ float2 q = float2( length(p.xz), p.y );
+
+ float w = sqrt(r*r-h*h);
+
+ return ((h*q.x<w*q.y) ? length(q-float2(w,h)) :
+ abs(length(q)-r) ) - t;
+}
+
+float distance_from_box(float3 p, float3 b)
+{
+ float3 q = abs(p) - b;
+ return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);
+}
+
+float distance_from_round_box(float3 p, float3 b, float r)
+{
+ float3 q = abs(p) - b + r;
+ return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0) - r;
+}
+
+float distance_from_box_frame(float3 p, float3 b, float e)
+{
+ p = abs(p)-b;
+ float3 q = abs(p+e)-e;
+
+ return min(min(
+ length(max(float3(p.x,q.y,q.z),0.0))+min(max(p.x,max(q.y,q.z)),0.0),
+ length(max(float3(q.x,p.y,q.z),0.0))+min(max(q.x,max(p.y,q.z)),0.0)),
+ length(max(float3(q.x,q.y,p.z),0.0))+min(max(q.x,max(q.y,p.z)),0.0));
+}
+
+float distance_from_pyramid(float3 p, float h, bool invert)
+{
+ float m2 = h*h + 0.25;
+
+ // symmetry
+ p.xz = abs(p.xz); // do p=abs(p) instead for double pyramid
+ p.xz = (p.z>p.x) ? p.zx : p.xz;
+ p.xz -= 0.5;
+
+ // project into face plane (2D)
+ float3 q = float3( p.z, h*p.y-0.5*p.x, h*p.x+0.5*p.y);
+
+ float s = max(-q.x,0.0);
+ float t = clamp( (q.y-0.5*q.x)/(m2+0.25), 0.0, 1.0 );
+
+ float a = m2*(q.x+s)*(q.x+s) + q.y*q.y;
+ float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t);
+
+ float d2 = max(-q.y,q.x*m2+q.y*0.5) < 0.0 ? 0.0 : min(a,b);
+
+ // recover 3D and scale, and add sign
+ return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));;
+}
+
+float distance_from_plane(float3 p, float3 n, float h)
+{
+ // n must be normalized
+ return dot(p,n) + h;
+}
+
+float distance_from_cylinder(float3 p, float3 c)
+{
+ return length(p.xz-c.xy)-c.z;
+}
+
+float distance_from_capped_cylinder(float3 p, float h, float r)
+{
+ float2 d = abs(float2(length(p.xz),p.y)) - float2(r,h);
+ return min(max(d.x,d.y),0.0) + length(max(d,0.0));
+}
+
+float distance_from_hex_prism(float3 p, float2 h)
+{
+ float3 q = abs(p);
+
+ const float3 k = float3(-0.8660254, 0.5, 0.57735);
+ p = abs(p);
+ p.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy;
+ float2 d = float2(
+ length(p.xy - float2(clamp(p.x, -k.z*h.x, k.z*h.x), h.x))*sign(p.y - h.x),
+ 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 )
+{
+}
+*/
+
+float3 op_rep(in float3 p, in float3 c)
+{
+ return glsl_mod(p+0.5*c,c)-0.5*c;
+}
+
+float op_sub(float d1, float d2)
+{
+ return max(-d1,d2);
+}
+
+// End licensed section
+
+#endif // __QUILEZ_INC
|
