Shader "CrispyPin/QRCode" { Properties { [HideInInspector] _("",2D)="" _Version("Version", Integer) = 1 } SubShader { Tags { "RenderType"="Opaque" } LOD 100 CGPROGRAM #pragma surface s Standard struct Input{float2 uv_;}; uint _Version; #define VERSION _Version #define WIDTH (17 + VERSION * 4) #define ALIGNERS ((VERSION / 7) + 2) #define ALIGNER_SPACING ((WIDTH - 13) / (ALIGNERS-1)) #define MISALIGNMENT ((WIDTH - 13) % (ALIGNERS-1)) #define EC_LEVEL (3) #define MASK_TYPE (4) #define FORMAT_BITS ((EC_LEVEL << 3) | MASK_TYPE) /* v = 15 width = 77 aligners = 4 spacing = (77-13)/3 */ #define WHITE 1 #define BLACK 0 #define PINK float4(1, .3, .5, 1) #define BLUE float4(0, .4, .7, 1) float4 finder_pattern(uint x, uint y) { if (x < 6 && x > 0 && y < 6 && y > 0) return !(x < 5 && x > 1 && y < 5 && y > 1); return (x > 6 || y > 6); } float4 main (float2 uv){ const uint data[] = {0x68656c6c,0x6f20776f,0x726c6421}; uv.y = 1 - uv.y; uv = uv * 1.5 - 0.25; // Quiet zone if (uv.x < 0 || uv.x > 1 || uv.y < 0 || uv.y > 1) return 1; uint px = uv.x * WIDTH; uint py = uv.y * WIDTH; // Finder patterns if (px < 8 && py < 8) return finder_pattern(px, py); if (px < 8 && py > WIDTH - 9) return finder_pattern(px, py - WIDTH + 7); if (px > WIDTH - 9 && py < 8) return finder_pattern(px - WIDTH + 7, py); // filler pixel if (px == 8 && py == WIDTH - 8) return 0; // Timing patterns if (px == 6) return py & 1; if (py == 6) return px & 1; // Aligners if (VERSION > 1 && (px > 8 || py > 8) // top left && (px < WIDTH - 9 || py > 8) // top right && (py < WIDTH - 9 || px > 8) // bottom left ) { // if (MISALIGNMENT != 0) return PINK; uint x = px + ALIGNER_SPACING - 4;// - MISALIGNMENT; uint y = py + ALIGNER_SPACING - 4;// - MISALIGNMENT; // if (px > WIDTH-15) x -= MISALIGNMENT; // if (py > WIDTH-15) y -= MISALIGNMENT; // if (px < 10) { // x += MISALIGNMENT; // } // if (py < 10) { // y += MISALIGNMENT; // } uint ax = x % ALIGNER_SPACING; uint ay = y % ALIGNER_SPACING; if (ax < 5 && ay < 5) { return (ax < 4 && ax > 0 && ay < 4 && ay > 0 && !(ax == 2 && ay == 2)); } } // Format bits if (px < 5 && py == 8) return (FORMAT_BITS & (1 << (4 - px))) == 0; if (px == 8 && py > WIDTH - 6) return (FORMAT_BITS & (1 << py + 5 - WIDTH)) == 0; if (px == 8 && (py < 9 || py > WIDTH - 9)) return PINK; if (py == 8 && (px < 9 || px > WIDTH - 9)) return PINK; uint column = (WIDTH - px - (px > 6))/2; uint direction_up = column & 1; return lerp(BLUE, PINK, column / (WIDTH/2.)); // return direction_up; return 0.5; } void s (Input IN, inout SurfaceOutputStandard o) { o.Albedo = main(IN.uv_); } ENDCG }}