Created
April 15, 2025 16:49
-
-
Save CharStiles/d1574348f4e4be2a84e3be6097d4a0d1 to your computer and use it in GitHub Desktop.
This file contains 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
#ifdef GL_ES | |
precision highp float; | |
#endif | |
uniform float time; | |
uniform vec2 resolution; | |
uniform vec2 mouse; | |
uniform vec3 spectrum; | |
uniform sampler2D texture0; | |
uniform sampler2D texture1; | |
uniform sampler2D texture2; | |
uniform sampler2D texture3; | |
uniform sampler2D prevFrame; | |
uniform sampler2D prevPass; | |
varying vec3 v_normal; | |
varying vec2 v_texcoord; | |
float rand(vec2 co){ | |
return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453); | |
} | |
// Same, but mirror every second cell at the diagonal as well | |
vec2 pModGrid2(inout vec2 p, vec2 size) { | |
vec2 c = floor((p + size*0.5)/size); | |
p = mod(p + size*0.5, size) - size*0.5; | |
p *= mod(c,vec2(2))*2. - vec2(1); | |
p -= size/2.; | |
if (p.x > p.y) p.xy = p.yx; | |
return floor(c/2.); | |
} | |
vec2 pModMirror2(inout vec2 p, vec2 size) { | |
vec2 halfsize = size*0.5; | |
vec2 c = floor((p + halfsize)/size); | |
p = mod(p + halfsize, size) - halfsize; | |
p *= mod(c,vec2(2))*2. - vec2(1); | |
return c; | |
} | |
void pR(inout vec2 p, float a) { | |
p = cos(a)*p + sin(a)*vec2(p.y, -p.x); | |
} | |
// Maximum/minumum elements of a vector | |
float vmax(vec2 v) { | |
return max(v.x, v.y); | |
} | |
float vmax(vec3 v) { | |
return max(max(v.x, v.y), v.z); | |
} | |
float vmax(vec4 v) { | |
return max(max(v.x, v.y), max(v.z, v.w)); | |
} | |
// Box: correct distance to corners | |
float fBox(vec3 p, vec3 b) { | |
vec3 d = abs(p) - b; | |
return length(max(d, vec3(0))) + vmax(min(d, vec3(0))); | |
} | |
// Smooth minimum function for rounding | |
// Smooth minimum function for rounding | |
float smin(float a, float b, float k) { | |
float h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0); | |
return mix(b, a, h) - k * h * (1.0 - h); | |
} | |
// Smooth maximum function for rounding | |
float smax(float a, float b, float k) { | |
return -smin(-a, -b, k); | |
} | |
// Rounded box function | |
float fBoxRound(vec3 p, vec3 b, float r) { | |
vec3 q = abs(p) - b + vec3(r); | |
return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0) - r; | |
} | |
float sdRandomCoinCylinders(vec3 p) { | |
// Number of coin cylinders | |
const int NUM_COINS = 8; | |
// Coin parameters | |
const float coinRadius = 0.5; | |
const float coinThickness = 0.2; | |
// Minimum distance to the center | |
float minDist = 1000.0; | |
// Generate coin cylinders from random directions | |
for (int i = 0; i < NUM_COINS; i++) { | |
// Generate random direction vector | |
vec3 dir = normalize(vec3( | |
cos(float(i) * 2.3), // Use golden ratio for pseudo-randomness | |
sin(float(i) * 1.7), | |
cos(float(i) * 2.1) | |
)); | |
// Project point onto the direction vector | |
vec3 projectedPoint = p - dot(p, dir) * dir; | |
// Create cylinder oriented along the direction | |
vec3 localPoint = p - dir * clamp(mod(((-time*3. + float(i))+0.8 ),10.),0.,10.); // Move cylinders away from center | |
// Cylindrical SDF | |
float cylinderDist = length(cross(localPoint, dir)) - coinRadius; | |
float heightDist = abs(dot(localPoint, dir)) - coinThickness; | |
// Combine cylindrical and height distance | |
float coinDist = max(cylinderDist, heightDist); | |
// Track minimum distance | |
minDist = min(minDist, coinDist); | |
} | |
return minDist; | |
}struct SurfaceInfo { | |
float distance; | |
bool isHole; | |
}; | |
SurfaceInfo scene(vec3 pos) { | |
// | |
// | |
pR(pos.zx,2.3); | |
pR(pos.xy,-.8); | |
pR(pos.zy,-.10); | |
// Parameters for the wavy surface | |
float amplitude = 01.1; // Height of the waves | |
float frequency = 01.0; // Frequency of the waves | |
float thickness = 0.5; // Thickness of the surface | |
// Create primary wave in x direction | |
float wave1 = sin(pos.z+9. * frequency) * amplitude; | |
// Create secondary wave in z direction for the cross-wave effect | |
// float wave2 = sin(pos.z * frequency ) * (amplitude * 0.5); | |
// Combine waves | |
// float combinedWave = wave1 + wave2; | |
// Calculate distance to the wavy surface | |
float surfaceDist = abs(pos.y - wave1) - thickness; | |
// Create perforations (dots) | |
float dotSpacing = 0.6; | |
vec2 dotGrid = mod(vec2(pos.x, pos.z), dotSpacing) - dotSpacing * 0.3; | |
float dotDist = length(dotGrid) - 0.05; | |
// Detect if we're in a hole | |
bool isHole = (dotDist < 0.0) && (abs(surfaceDist) < thickness * 2.0); | |
// Limit the surface to a reasonable size | |
float bounds = max(abs(pos.x) - 5.0, abs(pos.z) - 5.0); | |
surfaceDist = max(surfaceDist, bounds); | |
return SurfaceInfo(surfaceDist, isHole); | |
} | |
// Helper function to get just the distance for normal estimation | |
float sceneDistance(vec3 pos) { | |
return scene(pos).distance; | |
} | |
vec3 estimateNormal(vec3 p) { | |
float smallNumber = 0.002; | |
vec3 n = vec3( | |
sceneDistance(vec3(p.x + smallNumber, p.yz)) - | |
sceneDistance(vec3(p.x - smallNumber, p.yz)), | |
sceneDistance(vec3(p.x, p.y + smallNumber, p.z)) - | |
sceneDistance(vec3(p.x, p.y - smallNumber, p.z)), | |
sceneDistance(vec3(p.xy, p.z + smallNumber)) - | |
sceneDistance(vec3(p.xy, p.z - smallNumber)) | |
); | |
return normalize(n); | |
} | |
vec4 lighting(vec3 ray, vec2 id, bool isHole) { | |
// If this is a hole, return white | |
if (isHole) { | |
return vec4(1.0, 1.0, 1.0, 1.0); | |
} | |
vec3 norm = estimateNormal(ray); | |
vec3 light = vec3(0, 0.2, 0.); | |
float dif = max(dot(norm, light), 0.0); | |
vec4 retCol = vec4(dif); | |
// Add ambient light to prevent pure black | |
float ambient = 0.321; | |
retCol += vec4(ambient); | |
vec3 lightRayDir = normalize(light - ray); | |
retCol += norm.y; | |
return ((retCol * vec4(norm, 1.0))-0.13 ); | |
} | |
vec4 trace(vec3 rayO, vec3 dir) { | |
vec3 ray = rayO; | |
float dist = 0.; | |
float totalDist = 0.; | |
bool isHole = false; | |
for(int i = 0; i < 128; ++i) { | |
SurfaceInfo surfInfo = scene(ray); | |
dist = surfInfo.distance; | |
isHole = surfInfo.isHole; | |
totalDist += dist; | |
ray += dist * dir; | |
if(dist < 0.01) { | |
vec4 retCol = 1.0 - (vec4(totalDist) / 5.0); | |
return (clamp(lighting(ray, ray.xy, isHole) +0.51,0.,1.)).rrrr+0.5; | |
} | |
if(totalDist > 2.){ | |
mix(vec4(9./255.,31./255.,117./255.,1.),vec4(9./255.,31./255.,117./255.,1.),rayO.x); | |
} | |
} | |
return mix(vec4(9./255.,31./255.,117./255.,1.),vec4(9./255.,31./255.,117./255.,1.),rayO.x); | |
} | |
vec3 integrate(vec3 cur, float dt){ | |
float dx,dy,dz; | |
dx = (cur.y - cur.x)*.01; | |
dy = 3.*cur.z*(cur.x) - 8.*cur.y; | |
dz = cur.y*cur.z - 10.*cur.z; | |
cur.x += dx*dt; | |
cur.y += dy*dt; | |
cur.z += dz*dt; | |
return cur; | |
} | |
vec3 getRdIsometric(inout vec3 ro, vec3 lookAt, vec2 uv){ | |
vec3 rd = normalize( | |
lookAt - | |
ro | |
); | |
vec3 right = normalize(cross(vec3(0,1,0), rd)); | |
vec3 up = normalize(cross(rd, right)); | |
float zoom = 11.; | |
ro += right*uv.x*zoom; | |
ro += up*uv.y*zoom; | |
return rd; | |
} | |
void main(void) | |
{ | |
vec2 uv = -1. + 2. * v_texcoord; | |
// uv.y -=0.3; | |
uv.y*= resolution.y/resolution.x; | |
pR(uv,0.591); | |
// uv.y*= 1.2; | |
// vec3 cam =vec3(cos(time)*time *0.5,(cos(4.*time + 20.) + 1.)*0.3,-5.); | |
vec3 lookAt = vec3(0,-1.,-1); | |
vec3 ro = vec3(0,2,0); | |
vec3 dir = getRdIsometric(ro, lookAt, uv); | |
//vec3 dir = ro - ro; | |
vec4 col = trace(ro, dir); | |
gl_FragColor =col ; | |
} |
This file contains 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
#ifdef GL_ES | |
precision highp float; | |
#endif | |
uniform float time; | |
uniform vec2 resolution; | |
uniform vec2 mouse; | |
uniform vec3 spectrum; | |
uniform sampler2D prevFrame; | |
uniform sampler2D prevPass; | |
varying vec3 v_normal; | |
varying vec2 v_texcoord; | |
// Simple 1D Gaussian weight function | |
float gaussian(float x, float sigma) { | |
return exp(-(x * x) / (2.0 * sigma * sigma)); | |
} | |
void main(void) | |
{ | |
// Gaussian blur parameters | |
float sigma = 10.0; // Blur radius | |
float blurSize = 1.0 / resolution.x; // Size of one pixel | |
// Number of samples to take | |
const int samples = 10; | |
// Initialize color accumulator | |
vec4 color = vec4(0.0); | |
float weight_sum = 0.0; | |
// Sample original texture | |
// Apply horizontal and vertical blur in one pass | |
for (int i = -samples/2; i <= samples/2; i++) { | |
for (int j = -samples/2; j <= samples/2; j++) { | |
// Calculate weight based on distance from center | |
float distance = sqrt(float(i*i + j*j)); | |
float weight = gaussian(distance, sigma); | |
// Sample the texture with offset | |
vec2 offset = vec2(float(i), float(j)) * blurSize; | |
vec4 sample = texture2D(prevPass, v_texcoord + offset); | |
// Accumulate weighted sample | |
color += sample * weight; | |
vec4 originalColor = texture2D(prevPass, v_texcoord); | |
// Edge detection using fwidth() | |
vec3 edgeValue = fwidth(color.rgb); | |
float edgeIntensity = (edgeValue.r + edgeValue.g + edgeValue.b) * 3.0; | |
// Simple edge enhancement | |
float edgeThreshold = 0.8; // Adjust for more/less edge sensitivity | |
float edgeContrast = 1.; // Adjust for stronger/weaker edge effect | |
// Create a clean edge mask | |
float edgeMask = smoothstep(edgeThreshold, edgeThreshold + 99.9, edgeIntensity); | |
weight_sum += (weight) + ((( edgeMask))*.2); | |
// weight_sum = mix(weight_sum+weight*(edgeContrast+edgeMask ), 1.-weight_sum, weight_sum); | |
} | |
} | |
// Normalize by the sum of weights | |
vec4 blurredColor = color / weight_sum; | |
// Apply contrast to edges - make them darker | |
// vec4 finalColor = mix(blurredColor, vec4(0.0, 0.0, 0.0, 1.0), edgeMask * edgeContrast); | |
gl_FragColor = blurredColor; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment