‹ projects

reverb-m1

Native wired VR on Apple silicon: Reverb G1 display bring-up and stereo demo
git clone https://umhau.org/code/reverb-m1.git
Log | Files | Refs

Shaders.swift (1729B)


      1 // Metal shaders, compiled at runtime (the Command Line Tools have no offline `metal` compiler).
      2 let shaderSource = """
      3 #include <metal_stdlib>
      4 using namespace metal;
      5 
      6 struct Vertex { float3 pos; float3 normal; float3 color; };  // 16-byte aligned, matches Swift SIMD3<Float>
      7 struct Uniforms { float4x4 mvp; float4x4 model; float4 material; };
      8 struct VOut { float4 pos [[position]]; float3 normal; float3 color; float3 world; float grid [[flat]]; };
      9 
     10 vertex VOut vmain(uint vid [[vertex_id]], const device Vertex *v [[buffer(0)]], constant Uniforms &u [[buffer(1)]]) {
     11     VOut o;
     12     o.pos = u.mvp * float4(v[vid].pos, 1);
     13     o.normal = (u.model * float4(v[vid].normal, 0)).xyz;
     14     o.color = v[vid].color;
     15     o.world = (u.model * float4(v[vid].pos, 1)).xyz;
     16     o.grid = u.material.x;
     17     return o;
     18 }
     19 
     20 fragment float4 fmain(VOut in [[stage_in]]) {
     21     float3 l = normalize(float3(0.4, 0.8, 0.6));
     22     float d = max(dot(normalize(in.normal), l), 0.0);
     23     float3 color = in.color;
     24     if (in.grid > .5 && in.normal.y > .5) {
     25         float2 p = in.world.xz;
     26         float2 footprint = max(fwidth(p), float2(1e-5));
     27         float2 distanceToLine = abs(fract(p + .5) - .5);
     28         // Maintain a readable minimum footprint, then fade when adjacent lines become unresolved.
     29         float2 halfWidth = max(float2(.0075), footprint * .8);
     30         float2 coverage = 1 - smoothstep(halfWidth - footprint * .5, halfWidth + footprint * .5, distanceToLine);
     31         float2 resolvable = 1 - smoothstep(float2(.20), float2(.45), footprint);
     32         float line = max(coverage.x * resolvable.x, coverage.y * resolvable.y);
     33         color = mix(color, float3(.35, .40, .55), line);
     34     }
     35     return float4(color * (0.25 + 0.75 * d), 1);
     36 }
     37 """