Xor
banner
xordev.com
Xor
@xordev.com
Shaderboy
xordev.com
Pinned
Xor @xordev.com · 23h
Here are some techniques I discovered through 14 years of shader programming:
Honorable mentions:
Fast 3D pixel sorting: shadertoy.com/view/mdfyzl
Antialiasing with derivatives:
mini.gmshaders.com/p/antialiasing
Blocky turbulence:
x.com/XorDev/statu...
Noise tricks:
x.com/XorDev/statu...
February 10, 2026 at 11:38 PM
This concept can even be used for depth of field effects:

//Focus ratio should be small like 0.1 or 0.01
float focus = abs(depth - focal_point) * focal_ratio;
//Step through when out of focus
step_dist = max(step_dist - focus, focus);
February 10, 2026 at 11:37 PM
6. Glow Raymarching
I'm certainly not the first to use raymarching for glowing objects, but I think I found some interesting tricks for light rays that most people missed:
mini.gmshaders.com/p/volumetric
February 10, 2026 at 11:37 PM
5. fwidth outlines
Most people don't realize you can create outlines in a shader, almost for free, with derivative functions.
It's not the best quality, but it works well in a pinch:
February 10, 2026 at 11:36 PM
4. Fractal Texturing
If you're building a large-scale game, you have to figure out how to texture on both a micro and macro level.
I proposed a shader solution for natural textures that scales with any scene dynamically:
mini.gmshaders.com/p/gm-shaders...
February 10, 2026 at 11:36 PM
3. Dot Noise
We often need smooth noise functions for procedural generation and texturing, but we don't necessarily need to use Value, Perlin or Simplex noise.
I wrote a simpler 3D noise function that is super fast
mini.gmshaders.com/p/dot-noise
February 10, 2026 at 11:36 PM
2. Efficient Chaos
If you need to scatter objects (e.g. stars), most would break the world into cells and scatter within those cells. This requires sampling all neighboring cells and gets expensive quick. This trick works fast in any number of dimensions:
mini.gmshaders.com/p/chaos
February 10, 2026 at 11:35 PM
1. Turbulence
You're probably sick of me talking about this by now, but I can't get enough of it. It's a cheap, effective way to create fluidity without complicated formulas or resolution limitations
mini.gmshaders.com/p/turbulence
February 10, 2026 at 11:35 PM
Here are some techniques I discovered through 14 years of shader programming:
February 10, 2026 at 11:35 PM
Orchard
vec3 p,v=normalize(FC.rgb*2.-r.xyx),c=v/v.y;c.z+=.5*t;for(float z,i,b,g,m;i++<5e1;z+=.8*max(b=length((p.y-m)/1e2/(abs(sin(c.xz/.1))-.05/v.y)),min(4.-m,g=length(sin(p.xz)+1.-.1*(1.+sin(p.y-p.zx*.5))*m))-b),o.rgb+=(.7-v)/(g+b))p=z*v+1.,p.z-=t,m=abs(++p.y);o=tanh(o/5e2);
February 10, 2026 at 9:13 PM
Reef
for(float z,d,i;i++<5e1;z+=d,o+=(.9+sin(i*.1-vec4(6,1,2,0)))/d/d/z+d*z/vec4(4,2,1,0)){vec3 p=z*normalize(FC.rgb*2.-r.xyx);for(d=0.;d++<9.;)p+=.4*sin(p.yzx*d-z+t+i)/d+.5;d=length(vec4(abs(p.y+p.z*.5),sin(p-z)/7.))/(4.+z*z/1e2);}o=tanh(o/2e3);
February 10, 2026 at 4:22 PM
Port
vec3 w,p;for(float z,d=.1,i,f;i++<1e2;o+=.03/abs(mix(p,w,.1).y+vec4(0,1,2,3)/1e2)*d,z+=d=.3*(length(cos(p.xz))-.4))for(p=z*(FC.rgb*2.-r.xyy)/r.y+1.,w=p,f=0.;f++<5.;)w+=sin(w.zxy*f-9.*exp(-d/.1)+t)/f;o=tanh(o);
February 10, 2026 at 3:43 PM
The start of greatness:
for(float i,d,z...
February 10, 2026 at 1:26 AM
Game devs, look at your game in grayscale. How does the contrast look? Is lighting used intentionally (e.g. to separate elements from the background)? Also use texture sharpness for focus points and lower detail for backgrounds
February 6, 2026 at 6:47 PM
Good point
February 6, 2026 at 1:59 PM
Mini: 3D Rotation
How to rotate with Euler Angles and Axis Angles
mini.gmshaders.com
February 6, 2026 at 12:13 AM
I like the simplified version for code golfing that rotates a fixed 90 degrees with a moving axis:

dot(pos, axis) * axis + cross(axis, pos);
February 6, 2026 at 12:12 AM
vec3 rotate(vec3 pos, vec3 axis, float angle)
{
return mix(dot(pos, axis) * axis, pos, sin(angle)) + cos(angle) * cross(axis, pos);
}
February 6, 2026 at 12:12 AM
For quick, noisy motion blur, you can offset the camera position by some noise in the direction you want to blur:

pos.z += noise(FC);

My compact pseudo noise is:
noise = mod(dot(FC, sin(FC.yxyx)), 1.)

Here amplitude is the 1. and can animate with time in the sine wave.
twigl.app?ol=true&ss=-...
February 5, 2026 at 4:17 PM
For shadows add a small bias and save the total
z+=d+=.01,
Multiply the light by the tuned penumbra
color *= exp(d/z*.2-.06) :
Add the soft shading from above
color +=exp(-d*1e4)/5e1

twigl.app?ol=true&ss=-...
twigl.app
twigl.app is an online editor for One tweet shader, with gif or webm generator and sound shader.
twigl.app
February 5, 2026 at 4:15 PM
Shadows are tricky to tune, but probably the coolest.

The idea is to raymarch 50 steps from the camera, then 50 steps to the light and use the ratio of the step distance to the total distance for a penumbra effect:

After 50 steps, set the vector to vec3(1):
l>5e1? v/=v,
February 5, 2026 at 4:15 PM
For easy, solid, soft shading, add light for each sample close to the surface. I use an exponential fall off like so:

color += exp(-d*1e4) / 1e2

The 1e4 (10,000) controls the fall off and the 1e2 (100) is because there are 1e2 samples, so it computes the average

twigl.app?ol=true&ss=-...
February 5, 2026 at 4:15 PM
And then tonemap the output color
color = 1.0-exp(-color/4e3);

The overall brightness will need to be tuned for your scene, depending on the scale of units and number of steps
February 5, 2026 at 4:14 PM
Moving away from derivatives, I love this glassy effect.
You can make any raymarcher hollow by stepping the absolute of the signed distance, plus a small offset:

d = .005+abs(d);

Each step, add a color divided by the step distance:
color += vec3(1)/d;
February 5, 2026 at 4:14 PM
fwidth is powerful for creating quick and easy outlines.
Anywhere where there is a unit change, you could create a 1-pixel outline. for example, dividing the world into blocks:

color = fwidth(round(p))

Lots of possibilities here
February 5, 2026 at 4:13 PM