jckarter

everyone already knows i'm a dog

the swift programming language is my fault to some degree. mostly here to see dogs, shitpost, fix old computers, and/or talk about math and weird computer programming things. for effortposts check the #longpost pinned tag. asks are open.


email
mailto:joe@duriansoftware.com
discord
jckarter

NoelBWrites
@NoelBWrites

*limited amounts only, 4 per household *if you're in the US

Order yours here: https://www.covid.gov/tests

Government restarted their better than nothing but still abysmally insufficient free test mailing program, I recommend taking advantage of it before they take it away...again


eladnarra
@eladnarra

We got sent a bunch last time that said they expired in August, but when we checked the lot numbers using an FDA website we found out they're actually good until February. So check 'em before you chuck 'em!



torcado
@torcado

i've been working on a thing the past several days. this is an idea ive had for many years, and i'm extremely pleased with the result (though i have some more ideas and may continue working on it)

I made a pixel art upscaling algorithm, specifically for better pixel sprite rotation (but it looks pretty good just as an upscaler as well)

it upscales without adding any new colors, and when scaled down to the original resolution it displays identical to the source image. the idea is that as an artist i can draw a sprite at normal scale, ensure it will look exactly as i drew it when displayed normally, and will have a better result when rotated (not as jumbled, etc.) and also not introduce any new colors. (the ideal case for something like this is if you made art as a vector image, it'd have all the information needed to display at any angle without holes. this system is an approximation of that)

the current version takes the form of a shader, so i can just plop this onto any sprite in a game that will be rotated and it'll look a lot nicer. alternatively i could pre-process sprites with it and scale them down in-game
here are some more examples. it looks particularly good with solid lines/edges, which was the main focus

i think it looks pretty nice :)

here's the current version in the form of a godot glsl shader. (it should be fairly easy to convert to whatever system you're using, but if you want help feel free to ask!)

shader code
shader_type canvas_item;

//the color with the highest priority. // other colors will be tested based on distance to this // color to determine which colors take priority for overlaps. uniform vec3 highestColor = vec3(1.,1.,1.);

//how close two colors should be to be considered "similar". // can group shapes of visually similar colors, but creates // some artifacting and should be kept as low as possible. uniform float similarThreshold = 0.0;

const float scale = 4.0; const mat3 yuv_matrix = mat3(vec3(0.299, 0.587, 0.114), vec3(-0.169, -0.331, 0.5), vec3(0.5, -0.419, -0.081));

vec3 yuv(vec3 col){     mat3 yuv = transpose(yuv_matrix);     return yuv * col; }

bool similar(vec4 col1, vec4 col2){     return (col1.a == 0. && col2.a == 0.) || distance(col1, col2) <= similarThreshold; }

//multiple versions because godot doesn't support function overloading //note: inner check should ideally check between all permutations //  but this is good enough, and faster bool similar3(vec4 col1, vec4 col2, vec4 col3){     return similar(col1, col2) && similar(col2, col3); }

bool similar4(vec4 col1, vec4 col2, vec4 col3, vec4 col4){     return similar(col1, col2) && similar(col2, col3) && similar(col3, col4); }

bool similar5(vec4 col1, vec4 col2, vec4 col3, vec4 col4, vec4 col5){     return similar(col1, col2) && similar(col2, col3) && similar(col3, col4) && similar(col4, col5); }

bool higher(vec4 thisCol, vec4 otherCol){     if(similar(thisCol, otherCol)) return false;     if(thisCol.a == otherCol.a){ //      return yuv(thisCol.rgb).x > yuv(otherCol.rgb).x; //      return distance(yuv(thisCol.rgb), yuv(highestColor)) < distance(yuv(otherCol.rgb), yuv(highestColor));         return distance(thisCol.rgb, highestColor) < distance(otherCol.rgb, highestColor);     } else {         return thisCol.a > otherCol.a;     } }

void fragment() {     vec2 size = 1.0/TEXTURE_PIXEL_SIZE+0.00001; //???     vec2 px = UV*size;     vec2 local = floor(mod(px,1.0)*scale);     vec2 localDiff = (local/1.0) - vec2(1.5, 1.5);     vec2 edge = floor(local/(scale/2.0))*(scale/2.0) - vec2(1.0, 1.0);     px = ceil(px);          vec4 baseCol = texture(TEXTURE, px/size);

    vec4 col = baseCol;          vec4 c = baseCol;           //  vec4 c = texture(TEXTURE, floor(px+(vec2(0.5,0.5)+edge/4.0))/size);     vec2 ot = vec2(edge.x, edge.y * 4.0);     vec4 t = texture(TEXTURE, floor(px+(vec2(0.5,0.5)+ot/4.0))/size);     vec2 otl = vec2(edge.x * 4.0, edge.y * 4.0);     vec4 tl = texture(TEXTURE, floor(px+(vec2(0.5,0.5)+otl/4.0))/size);     vec2 otr = vec2(-edge.x * 4.0, edge.y * 4.0);     vec4 tr = texture(TEXTURE, floor(px+(vec2(0.5,0.5)+otr/4.0))/size);     vec2 ol = vec2(edge.x * 4.0, edge.y);     vec4 l = texture(TEXTURE, floor(px+(vec2(0.5,0.5)+ol/4.0))/size);     vec2 ob = vec2(edge.x, -edge.y * 4.0);     vec4 b = texture(TEXTURE, floor(px+(vec2(0.5,0.5)+ob/4.0))/size);     vec2 obl = vec2(edge.x * 4.0, -edge.y * 4.0);     vec4 bl = texture(TEXTURE, floor(px+(vec2(0.5,0.5)+obl/4.0))/size);     vec2 obr = vec2(-edge.x * 4.0, -edge.y * 4.0);     vec4 br = texture(TEXTURE, floor(px+(vec2(0.5,0.5)+obr/4.0))/size);     vec2 or = vec2(-edge.x * 4.0, edge.y);     vec4 r = texture(TEXTURE, floor(px+(vec2(0.5,0.5)+or/4.0))/size);          vec2 os = vec2(localDiff.x, localDiff.y);     vec4 s = texture(TEXTURE, floor(px+(vec2(0.5,0.5)+os/2.0))/size);               //checkerboard special case     if(similar5(c, tl, tr, bl, br) && similar4(t, r, b, l) && higher(t, c)){ //      if(local == vec2(0.,0.)){ //          col = l; //      } else if(local == vec2(3.,0.)){ //          col = r; //      } else if(local == vec2(0.,3.)){ //          col = l; //      } else if(local == vec2(3.,3.)){ //          col = r; //      }     } else {         //corner         if(length(localDiff) > 2.1){             if(similar(t, l) && !(similar(tl, c) && !higher(t, c))){                 col = t;             } else if(higher(c, l) && higher(c, t) && (similar(tr, c) || similar(bl, c)) && !similar(tl, c)){                 if(higher(t, l)){                     col = t;                 } else {                     col = l;                 }             }         //edge         } else if(length(localDiff) > 1.58) {                          if(similar(t, l)){                 if(higher(s, c)){                     col = s;                 }             }                          if(similar3(r, s, tl) && similar3(br, c, l) && higher(s, c)/* && !similar(b, t)*/){                 col = t;             }             if(!similar(tl, c) && similar3(r, c, bl) && similar3(tr, t, l) && higher(c, l)){                 col = s;             }             if(!similar(tr, c) && similar3(l, c, br) && similar3(tl, s, r) && higher(c, r)){                 col = s;             }                          if(similar3(b, s, tl) && similar3(br, c, t) && higher(b, c)/* && !similar(r, l)*/){                 col = s;             }             if(!similar(tl, c) && similar3(tr, c, b) && similar3(t, l, bl) && higher(c, l)){                 col = s;             }             if(!similar(bl, c) && similar3(br, c, t) && similar3(b, s, tl) && higher(c, s)){                 col = s;             }         }     }     //set alpha back to full, for manually adjusted pixels      if(col.a > 0.00001){         col.a = 1.0;     }     COLOR = col; }