diff --git a/Assets/test/QRCode.mat b/Assets/test/QRCode.mat index c9b6cac..86e7e76 100644 --- a/Assets/test/QRCode.mat +++ b/Assets/test/QRCode.mat @@ -61,6 +61,7 @@ Material: m_Scale: {x: 1, y: 1} m_Offset: {x: 0, y: 0} m_Ints: + - _DisableMask: 0 - _Version: 15 m_Floats: - _BumpScale: 1 @@ -70,6 +71,7 @@ Material: - _GlossMapScale: 1 - _Glossiness: 0.5 - _GlossyReflections: 1 + - _Mask: 1 - _Metallic: 0 - _Mode: 0 - _OcclusionStrength: 1 diff --git a/Assets/test/QRCode.shader b/Assets/test/QRCode.shader index 3645021..388c93f 100644 --- a/Assets/test/QRCode.shader +++ b/Assets/test/QRCode.shader @@ -3,6 +3,9 @@ Properties { [HideInInspector] _("",2D)=""{} _Version("Version", Range(1, 40)) = 1 + _Mask("Mask type", Range(0, 7)) = 1 + [Toggle] + _DisableMask("Hide mask", Integer) = 0 _TimeSlider("Time", Range(0, 250)) = 0 } SubShader { @@ -12,6 +15,8 @@ CGPROGRAM #pragma surface s Standard struct Input{float2 uv_;}; uint _Version; + uint _Mask; + bool _DisableMask; float _TimeSlider; #define VERSION _Version @@ -32,7 +37,9 @@ CGPROGRAM #define EC_LEVEL_H 2 #define EC_LEVEL EC_LEVEL_L - #define MASK_TYPE 1 + #define MASK_TYPE _Mask + // ECI_MODE 0100 = byte + #define ECI_MODE 4 static const uint FORMAT_BIT_SETS[32] = {0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0, 0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976, 0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b, 0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed}; #define FORMAT_BITS_RAW ((EC_LEVEL << 3) | MASK_TYPE) @@ -49,7 +56,6 @@ CGPROGRAM #define BLACK 0 #define PINK float3(1, .3, .5) #define BLUE float3(0, .4, .7) - #define CYAN float3(0,1,1) float3 finder_pattern(uint x, uint y) { if (x < 6 && x > 0 && y < 6 && y > 0) return !(x < 5 && x > 1 && y < 5 && y > 1); @@ -57,11 +63,13 @@ CGPROGRAM } float3 main (float2 uv){ + // hell_o wo_rld! const uint data[] = {0x68656c6c,0x6f20776f,0x726c6421}; + const uint data_len = 12; 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; + if (uv.x < 0 || uv.x > 1 || uv.y < 0 || uv.y > 1) return 2; uint px = uv.x * PIXEL_WIDTH; uint py = uv.y * PIXEL_WIDTH; @@ -129,18 +137,56 @@ CGPROGRAM } if (px < 9) bit_index -= 16; // rightmost tiny column - // debugging worm - uint worm = abs(TIME % BIT_COUNT - bit_index); - const uint length = 4; - if (worm < length) return CYAN * (worm/(float)length); - return (float)(bit_index%BIT_COUNT)/(float)BIT_COUNT; + // data + uint bit = 0; + if (bit_index < 4){ + bit = (ECI_MODE >> (3-bit_index))&1; + } else if (bit_index < 12) { + bit = (data_len >> (7 - (bit_index - 4))) & 1; + } else if (bit_index < data_len*8 + 12){ + uint data_bit_index = bit_index - 12; + bit = ((data[data_bit_index/32] >> (31-(data_bit_index % 32))) & 1); + } - // return lerp(BLUE, PINK, column / (WIDTH/2.)); - return lerp(BLUE, PINK, (px+py)&1); - // return float3((px%5)/5., (px/10+py/10)&1, (py%5)/5.); - // return float3((px/8 + py/8) & 1, (px/2 + py/2) & 1, (px/4 + py/4) & 1, 1); - // return direction_up; - return 0.5; + // mask + uint mask; + switch (_Mask){ + case 0: + mask = (px+py) % 2 == 0; + break; + case 1: + mask = py % 2 == 0; + break; + case 2: + mask = px % 3 == 0; + break; + case 3: + mask = (px+py) % 3 == 0; + break; + case 4: + mask = (py/2 + px/3) % 2 == 0; + break; + case 5: + mask = (py*px)%2 + (px*py)%3 == 0; + break; + case 6: + mask = ((py*px)%2 + (px*py)%3) % 2 == 0; + break; + case 7: + mask = ((py+px)%2 + (px*py)%3) % 2 == 0; + break; + } + if (!_DisableMask) { + bit ^= mask; + } + + return !bit; + + // // bit index debugging worm + // uint worm = abs(TIME % BIT_COUNT - bit_index); + // const uint length = 4; + // if (worm < length) return BLUE * (worm/(float)length); + // return (float)(bit_index%BIT_COUNT)/(float)BIT_COUNT; } void s (Input IN, inout SurfaceOutputStandard o) { o.Albedo = main(IN.uv_); }