qr shader: correct data bit layout for all but leftmost column of aligners

This commit is contained in:
Crispy 2024-08-18 17:59:26 +02:00
parent f51e0dff07
commit 7e4d06169c

View file

@ -6,8 +6,11 @@ Properties {
_Mask("Mask type", Range(0, 7)) = 1
[Toggle]
_DisableMask("Hide mask", Integer) = 0
// _TimeSlider("Time", Range(150, 300)) = 0
_TimeSlider("Time", Range(0, 300)) = 0
[Toggle]
_Animate("Animate debug worm", Integer) = 0
_AnimationSpeed("Speed", Range(1, 100)) = 0
_TimeSlider("Time", Range(0, 200)) = 0
_TimeSliderCoarse("Time Coarse", Range(0, 250)) = 0
}
SubShader {
Tags { "RenderType"="Opaque" }
@ -18,7 +21,10 @@ CGPROGRAM
uint _Version;
uint _Mask;
bool _DisableMask;
bool _Animate;
float _TimeSlider;
float _TimeSliderCoarse;
float _AnimationSpeed;
#define VERSION _Version
#define WIDTH (17 + VERSION * 4)
@ -29,8 +35,8 @@ CGPROGRAM
#define ALIGNER_SPACING (ALIGNER_SPACING_IDEAL + ALIGNER_SPACING_IDEAL % 2)
#define MISALIGNMENT ((WIDTH - 13) - ALIGNER_SPACING * ALIGNERS)
#define BIT_COUNT (WIDTH * WIDTH - 225 - (WIDTH - 17)*2 - 25 * (ALIGNERS * ALIGNERS - 3) * (VERSION > 1))
#define TIME (_Time.y*24)
#define TIME (uint)(_TimeSlider)
#define TIME_MANUAL (_TimeSlider + _TimeSliderCoarse*100)
#define TIME (uint)(_Animate ? _Time.y * _AnimationSpeed + TIME_MANUAL : TIME_MANUAL)
#define EC_LEVEL_L 1
#define EC_LEVEL_M 0
@ -67,9 +73,9 @@ CGPROGRAM
const uint data_len = 3*4;
const uint total_len = 7*4;
uv.y = 1 - uv.y;
uv = uv * 1.5 - 0.25;
uv = uv * 1.2 - 0.1;
// Quiet zone/frame
if (uv.x < 0 || uv.x > 1 || uv.y < 0 || uv.y > 1) return 1.2;
if (uv.x < 0 || uv.x > 1 || uv.y < 0 || uv.y > 1) return 1;
uint px = uv.x * PIXEL_WIDTH;
uint py = uv.y * PIXEL_WIDTH;
@ -129,11 +135,14 @@ CGPROGRAM
bit_index += tiny_columns * (WIDTH - 17) * 2;
bit_index += (px + (px < 6)) % 2;
uint column_progress;
if (direction_up)
uint y_relative;
if (direction_up) {
y_relative = WIDTH - py - 1;
column_progress = WIDTH - py - 1 - (py < 7);
else
} else {
y_relative = py;
column_progress = py - ((full_columns == 0) ? 9 : (py > 6));
}
bit_index += column_progress * 2;
if (px < 9) bit_index -= 16; // rightmost tiny column
@ -143,24 +152,75 @@ CGPROGRAM
// aligners always cover a half column to the left and two full columns to the right
// outer aligners are always 4 from all edges
// rightmost column of aligners
uint passed_up = (column_progress - 9 + ALIGNER_SPACING) / ALIGNER_SPACING;
if (column == 2) {
uint aligner_col = (column - 2) / (ALIGNER_SPACING/2);
uint aligner_col_mod = (column - 2) % (ALIGNER_SPACING/2);
if (aligner_col > 0) { // full columns passed
bit_index -= (ALIGNERS - 1) * aligner_col*25;
if (aligner_col > 1) {
// top row only obstructs 20 since it overlaps the timing stripe
bit_index -= (aligner_col - 1)*20;
}
}
uint passed_up = (y_relative - 9 + ALIGNER_SPACING - (!direction_up * (MISALIGNMENT+ALIGNER_SPACING))) / ALIGNER_SPACING;
passed_up = min(passed_up, ALIGNERS-1);
if (aligner_col_mod == 0) {
bit_index -= passed_up * 10;
} else if (column == 3) {
uint passed_down = (column_progress) / ALIGNER_SPACING;
if (direction_up && py < 5){
bit_index -= 8;
}
if (!direction_up && py > 5){
bit_index += 2;
if (py > WIDTH-5){
bit_index -= 10;
}
}
} else if (aligner_col_mod == 1) {
uint passed_down = (y_relative - 8 + ALIGNER_SPACING - !direction_up*MISALIGNMENT) / ALIGNER_SPACING;
bit_index -= (passed_down + ALIGNERS - 1) * 10;
} else if (column == 4) {
if (!direction_up)
bit_index += 10;
if (aligner_col > 0) {
bit_index -= 8;
} else {
bit_index += 8;
}
if (direction_up ? py < 5 : py > 5){
bit_index += 2;
}
} else if (aligner_col_mod == 2) {
bit_index -= (ALIGNERS - 1) * 20;
uint offset = (column_progress + ALIGNER_SPACING - 3) % ALIGNER_SPACING;
if (offset < 6) {
if (aligner_col > 0) {
bit_index -= 16; // most of the current column top aligner, excluding the left 4 pixels
if (py < 9) {// top aligner
if (direction_up){
bit_index -= min(9-py, 5) - (py < 6);
} else if (py > 3) {
bit_index -= py - 3 - (py > 6);
}
} else {
bit_index += !direction_up;
}
if (!direction_up && py > WIDTH-5){
bit_index-=5;
}
}
uint offset = (column_progress + ALIGNER_SPACING - 3 - !direction_up*0 + (!direction_up * (-MISALIGNMENT+1))) % ALIGNER_SPACING;
// left side of regular aligners
if (offset < 6 && py > 9 && px > 9) {
bit_index -= offset;
}
bit_index -= passed_up * 5;
} else {
bit_index -= (ALIGNERS-1)*25;
}
} else { // include the full row
bit_index -= (ALIGNERS - 1)*25;
if (aligner_col > 0){
// return PINK;
bit_index -= 20;
}
}
}
// data
@ -209,9 +269,13 @@ CGPROGRAM
// 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);
uint worm = TIME % BIT_COUNT - bit_index;
worm %= 200;
const uint length = 6;
if (worm == 0) return float3(3,0,0);
if (worm < length) return lerp(PINK, BLUE, (worm/(float)length));
if (bit_index > BIT_COUNT) return float3(1,0,0);
// #define BIT_COUNT 24
return (float)(bit_index%BIT_COUNT)/(float)BIT_COUNT;
}