Last active
January 15, 2026 14:09
-
-
Save Lokno/99d29e8b7f6e72d9f936693148c6d0d5 to your computer and use it in GitHub Desktop.
OBS filter using OBS-shaderfilter to render goblindotbest with distance functions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // The MIT License | |
| // Copyright © 2018 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. | |
| uniform float4 ambient_color = {0.1,0.1,0.1,1.0}; | |
| uniform float4 diffuse_color = {0.13, 0.59, 0.25,1.0}; | |
| uniform float scale< | |
| string label = "Scale"; | |
| string widget_type = "slider"; | |
| float minimum = 0.25; | |
| float maximum = 4.0; | |
| float step = 0.01; | |
| > = 1.25; | |
| uniform float speed< | |
| string label = "Speed"; | |
| string widget_type = "slider"; | |
| float minimum = 0.0; | |
| float maximum = 100.0; | |
| float step = 0.01; | |
| > = 1.0; | |
| uniform float offset_x< | |
| string label = "Offset X"; | |
| string widget_type = "slider"; | |
| float minimum = 0.0; | |
| float maximum = 1.0; | |
| float step = 0.01; | |
| > = 0.0; | |
| uniform float offset_y< | |
| string label = "Offset Y"; | |
| string widget_type = "slider"; | |
| float minimum = 0.0; | |
| float maximum = 1.0; | |
| float step = 0.01; | |
| > = 0.09; | |
| uniform float arm_angle< | |
| string label = "Arm Position"; | |
| string widget_type = "slider"; | |
| float minimum = 0.0; | |
| float maximum = 1.0; | |
| float step = 0.01; | |
| > = 0.5; | |
| uniform float tail_angle< | |
| string label = "Tail Position"; | |
| string widget_type = "slider"; | |
| float minimum = 0.0; | |
| float maximum = 1.0; | |
| float step = 0.01; | |
| > = 0.5; | |
| // List of other 3D SDFs: https://www.shadertoy.com/playlist/43cXRl | |
| // | |
| // and https://iquilezles.org/articles/distfunctions | |
| // https://iquilezles.org/articles/distfunctions | |
| float dot2(in float3 v ) { return dot(v,v); } | |
| float sdRoundCone(float3 p, float3 a, float3 b, float r1, float r2) | |
| { | |
| // sampling independent computations (only depend on shape) | |
| float3 ba = b - a; | |
| float l2 = dot(ba,ba); | |
| float rr = r1 - r2; | |
| float a2 = l2 - rr*rr; | |
| float il2 = 1.0/l2; | |
| // sampling dependant computations | |
| float3 pa = p - a; | |
| float y = dot(pa,ba); | |
| float z = y - l2; | |
| float x2 = dot2( pa*l2 - ba*y ); | |
| float y2 = y*y*l2; | |
| float z2 = z*z*l2; | |
| // single square root! | |
| float k = sign(rr)*rr*rr*x2; | |
| if( sign(z)*a2*z2 > k ) return sqrt(x2 + z2) *il2 - r2; | |
| if( sign(y)*a2*y2 < k ) return sqrt(x2 + y2) *il2 - r1; | |
| return (sqrt(x2*a2*il2)+y*rr)*il2 - r1; | |
| } | |
| //------------------------------------------------------------------ | |
| // ellipsoid SDF approximation | |
| //------------------------------------------------------------------ | |
| // https://iquilezles.org/articles/ellipsoids/ | |
| float sdEllipsoid( in float3 p, in float3 r ) | |
| { | |
| float k0 = length(p/r); | |
| float k1 = length(p/(r*r)); | |
| return k0*(k0-1.0)/k1; | |
| } | |
| float smin( float a, float b, float k ) | |
| { | |
| float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 ); | |
| return lerp( b, a, h ) - k*h*(1.0-h); | |
| } | |
| float3x3 angleAxis3x3(float angle, float3 axis) { | |
| float c, s; | |
| sincos(angle, s, c); // HLSL's sincos is efficient for both sin and cos | |
| float t = 1.0 - c; // (1 - cos(angle)) | |
| float x = axis.x; | |
| float y = axis.y; | |
| float z = axis.z; | |
| // Rodrigues' Rotation Formula for matrix construction | |
| return float3x3( | |
| t * x * x + c, t * x * y - s * z, t * x * z + s * y, | |
| t * x * y + s * z, t * y * y + c, t * y * z - s * x, | |
| t * x * z - s * y, t * y * z + s * x, t * z * z + c | |
| ); | |
| } | |
| #define PI 3.14159265 | |
| // goblin dot best | |
| float map( in float3 pos, out float pupdist ) | |
| { | |
| float gob = 0.0; | |
| pupdist=1e4; | |
| float3 arm_vector = {0.0,0.073,0.176}; | |
| float armAngle = arm_angle * (PI) - PI*0.5; | |
| float3x3 armRot = angleAxis3x3(armAngle, float3(1,0,0)); | |
| arm_vector = mul(armRot, arm_vector); | |
| float3 tail_vector = {-0.427,0.095,0.0}; | |
| float tailAngle = tail_angle * (PI*0.5) - PI*0.25; | |
| float3x3 tailRot = angleAxis3x3(tailAngle, float3(0,1,0)); | |
| tail_vector = mul(tailRot, tail_vector); | |
| // head | |
| gob = sdRoundCone(pos + float3(0.0,-0.29,0.0), float3(0.0,0.0,0.0), float3(0.3,0.0,0.0), 0.190, 0.03 ); | |
| // left ear | |
| gob = smin(gob, sdRoundCone(pos + float3(0.05,-0.39,0.06), float3(0.0,0.0,0.0), float3(0.0,0.139,0.0), 0.065, 0.006 ), 0.02); | |
| // right ear | |
| gob = smin(gob, sdRoundCone(pos + float3(0.05,-0.39,-0.06), float3(0.0,0.0,0.0), float3(0.0,0.139,0.0), 0.065, 0.006 ), 0.02); | |
| // left eye | |
| pupdist = smin(pupdist, sdEllipsoid(pos + float3(-0.05,-0.37,0.16), float3(0.018,0.018,0.018) ), 0.0); | |
| // right eye | |
| pupdist = smin(pupdist, sdEllipsoid(pos + float3(-0.05,-0.37,-0.16), float3(0.018,0.018,0.018) ), 0.0); | |
| gob = smin(gob, pupdist, 0.006); | |
| // body | |
| gob = smin(gob, sdEllipsoid( pos, float3(0.26,0.26,0.26)), 0.025 ); | |
| // left arm | |
| gob = smin(gob, sdRoundCone(pos + float3(0.0,-0.12,0.19), float3(0.0,0.0,0.0), float3(arm_vector.x,arm_vector.y,-arm_vector.z), 0.080, 0.016 ), 0.02); | |
| // right arm | |
| gob = smin(gob, sdRoundCone(pos + float3(0.0,-0.12,-0.19), float3(0.0,0.0,0.0), float3(arm_vector.x,arm_vector.y,arm_vector.z), 0.080, 0.016 ), 0.02); | |
| // left leg | |
| gob = smin(gob, sdRoundCone(pos + float3(0.00,0.15,0.09), float3(0.0,0.0,0.0), float3(0.0,-0.294,0.0), 0.116, 0.018 ), 0.06); | |
| // right leg | |
| gob = smin(gob, sdRoundCone(pos + float3(0.00,0.15,-0.09), float3(0.0,0.0,0.0), float3(0.0,-0.294,0.0), 0.116, 0.018 ), 0.06); | |
| // tail | |
| gob = smin(gob, sdRoundCone(pos + float3(0.00,0.12,0.00), float3(0.0,0.0,0.0), tail_vector, 0.168, 0.022 ), 0.02); | |
| return gob; | |
| } | |
| // https://iquilezles.org/articles/normalsSDF | |
| float3 calcNormal( in float3 pos, out float pupdist ) | |
| { | |
| float2 e = float2(1.0,-1.0)*0.5773; | |
| const float eps = 0.0005; | |
| return normalize( e.xyy*map( pos + e.xyy*eps, pupdist ) + | |
| e.yyx*map( pos + e.yyx*eps, pupdist ) + | |
| e.yxy*map( pos + e.yxy*eps, pupdist ) + | |
| e.xxx*map( pos + e.xxx*eps, pupdist ) ); | |
| } | |
| float4 mainImage(VertData v_in) : TARGET | |
| { | |
| float2 iResolution = uv_size.xy; | |
| float iTime = elapsed_time_active; | |
| float2 fragCoord = float2((v_in.uv.x+offset_x-0.5)*(1.0/scale)+0.5,(1.0-v_in.uv.y+offset_y-0.5)*(1.0/scale)+0.5) * uv_size.xy; | |
| // camera movement | |
| float an = 0.5*iTime*speed; | |
| float3 ro = float3( 1.0*cos(an), 0.4, 1.0*sin(an) ); | |
| float3 ta = float3( 0.0, 0.0, 0.0 ); | |
| // camera matrix | |
| float3 ww = normalize( ta - ro ); | |
| float3 uu = normalize( cross(ww,float3(0.0,1.0,0.0) ) ); | |
| float3 vv = normalize( cross(uu,ww)); | |
| float2 p = (-iResolution.xy + 2.0*fragCoord)/iResolution.y; | |
| // create view ray | |
| float3 rd = normalize( p.x*uu + p.y*vv + 1.5*ww ); | |
| // raymarch | |
| const float tmax = 2.0; | |
| float t = 0.0; | |
| float pupdist; | |
| for( int i=0; i<256; i++ ) | |
| { | |
| float3 pos = ro + t*rd; | |
| float h = map(pos, pupdist); | |
| if( h<0.0001 || t>tmax ) break; | |
| t += h; | |
| } | |
| // shading/lighting | |
| float4 col = float4(0.0,0.0,0.0,0.0); | |
| if( t<tmax ) | |
| { | |
| float pupdist; | |
| float3 pos = ro + t*rd; | |
| float3 nor = calcNormal(pos, pupdist); | |
| float dif = clamp( dot(nor,float3(0.57703,0.57703,0.57703)), 0.0, 1.0 ); | |
| float amb = 0.5 + 0.5*dot(nor,float3(0.0,1.0,0.0)); | |
| col = ambient_color*amb + diffuse_color*dif; | |
| col=col*lerp(.1,1.,smoothstep(0.0,.01,pupdist)) * float4(0.13, 0.59, 0.25,1.0); | |
| } | |
| // gamma | |
| col = sqrt( col ); | |
| return col; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment