Shaders, Raymarching

Here is the minimal picture i have of how a graphics card works.

There are two main stages, the vertex shader and the fragment shader. The vertex shader is given a list of triangles basically. It computes and applies the transformations necessary to rotate and translate the camera position for the vertices and compute normal vectors and some other geometrical things.

The fragments shader is then passed info from the vertex shader. It has to output a color by setting a variable fragColor. There are variables called that are given the type annotation varyings that are automatically interpolated in the vertex (think of smoothly rotating vectors or colors between vertices). The fragment shader is called once per pixel on the screen.

Mostly information is passed around via pointer rather than function return (I guess that is kind of a common C paradigm and it does make sense.). What does suck about that is you’ll see variables appear out of nowhere. They are basically global variables from your codes perspective. I assume there is a limited number of them so you get used to it. is awesome. It draws a big rectangle and gives you easy access to the fragment shader with some useful extra variables available to you.

It feels like a big map in the functional sense. You write a shader function and then the gpu runs

pixelcolor = map shader pixelinfo

This is refreshing. The api I’m used to is an imperative api where you consecutively mutate some screen object by called line or point or circle on it. Not that that’s bad, necessarily. But I do like the newness.

This will draw a white circle.

void mainImage( out vec4 fragColor, in vec2 fragCoord )
    vec2 coord = fragCoord.xy - iResolution.xy/2.0; 
    if(length(coord) < 100.0){
    	fragColor = vec4(1);
    fragColor = vec4(0);


Also here is a raymarched sphere with a little lighting. Ray marching uses the distance function to push the ray smart distances. There are a ton of things you could do here. Could optimize the loop to break when rays get close enough, or when they fly off to infinity.


float sphere( in vec3 p){
 return length(p) - 0.5;

void mainImage( out vec4 fragColor, in vec2 fragCoord )
	vec2 uv = fragCoord.xy / iResolution.y;
    vec2 st = 2.0*uv -1.0;
	fragColor = vec4(uv,0.5+0.5*sin(iGlobalTime),1.0);
    vec3 cam = vec3(0.0, 0.0, -1.0);
    vec3 ray = vec3(st.x, st.y, 1);
    ray = normalize(ray);
    float depth = 0.0;
    for(int i=0; i<64; i++){
     vec3 p = cam + depth * ray;
     depth = depth += sphere(p);
    vec3 p = cam + depth * ray;
    if(abs(sphere(p)) < 0.1){
     fragColor = vec4(0.3+dot(normalize(p), normalize(vec3(1.0,1.0,0.0)))); 




Band Theory on a Mobius Strip

I’ve been toying with a slightly interesting twist on band theory.

If we put a chain on a circle, the usual band with nearest neighbor tunneling is

E(k)=t \cos (k)

Next nearest neighbor tunneling makes terms in the dispersion like cos(2k) that are more oscillatory.

You can dimerize to make the unit cell twice as large. That will cut the Brillouin zone in two and stack the original single band into two bands.

But what if we allow tunneling diametrically across the circle? Then the oscillations are so swift that a new interpretation opens up. If we consider the diametrically opposed positions to be the two components of a spinor, sort of we divide the circle size L in two. In k-space, this means our discretization of k is twice as coarse. In particular we split into antisymmetric and symmetric bands. There is a splitting between the even integers of k and the odd integers. This can be interpreted as a very fast modulation of the bands, but it is exactly fast enough (and always will be by design, regardless of N or L) that aliasing is in play. It is very easy to connect our dots naturally into two distinct bands rather than a highly oscillatory single band.

It’s a curious construction that feels similar to dimerization. But instead of cutting the Brillouin zone in half, we’ve maintained the same size. Instead we’ve doubled the spacing between k values.

If the total number of sites is even 2N, then antipodal is easy to achieve and we can split the two bands completely. If the total sites is odd 2N+1 then I think that the bands have to have dirac points? Also the dirac points are not degenerate. There is only 1 state at exactly the point.

Now an antipodal tunneling seems ridiculous. I’ve only got a couple defenses. 1 Just an theoretical interesting exercise that maybe can avoid some no go theorems that assume locality 2. count on some hail Mary quantum hocus pocus topological order to make the mean field hamiltonian  3. the mobius strip interpretation.

A mobius strip needs to be traversed twice in order to get back to where you were. Also, halfway around, you’re on the opposite side of the paper as you started, so in some sense you are very close to the beginning. This model has that feel. If you had a chain of atoms in a mobius strip configuration (a single chain that loops over itself twice) with kind of weak tunneling transverse to the chain, this doesn’t seem entirely crazy.

In all honesty, I’ve been playing around with this idea because I was trying to make a quantum model on the projective plane using the identification of antipodal points on the sphere. And the reason I was doing that was because I was trying to find a translation invariant form of dimerization (or making a pseudospin). That problems is harder though. I need to use spherical harmonics as best I can figure. But spherical harmonics don’t have finite N.

You can identify points on a torus. This is a 2d generalization that you can push through.

It’s not clear to me that the model has interesting topological properties or not. It is a funny fellow though. And it is sufficiently weird that one wonders if it avoids the assumptions of no-go theorems (Nelson-Ninomiya)