Last active
November 14, 2024 19:57
-
-
Save partybusiness/cd0f5a35c65f5b6ad637baff0dc6fe26 to your computer and use it in GitHub Desktop.
Displays square particles that round off their position to the nearest on-screen square and disaplays the computer text
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| shader_type spatial; | |
| render_mode unshaded, depth_test_disabled; | |
| // will need to assign this in code because I can't get Godot to save it as a property of material | |
| uniform uint tilemap[1024]; // up to 128 8-byte 8x8 tiles | |
| uniform int screenWidth = 168; | |
| uniform int screenHeight = 64; | |
| varying vec4 calcscreen; //calculated screen size and | |
| uniform sampler2D depth_texture : source_color, hint_depth_texture, filter_nearest, repeat_disable; | |
| //gets whether a pixel within a given tile is foreground or background | |
| bool getPixel (uint x, uint y, uint tileIndex) { //x and y within 8x8 tile, index of tile in tilemap | |
| uint tileAddress = (tileIndex << 3u); //8 bytes per tile | |
| uint chunk = tilemap[tileAddress + y]; | |
| uint sample = chunk >> x & 1u; | |
| return sample > 0u; | |
| } | |
| void vertex() { | |
| // get position of vertex on screen | |
| vec4 vert = vec4(VERTEX, 1.0); | |
| vec4 screenPos = (PROJECTION_MATRIX * VIEW_MATRIX * MODEL_MATRIX * vec4(VERTEX, 1.0)); | |
| vec2 offset = vec2(0.5); | |
| // flatten image and align from corner | |
| screenPos.xy = screenPos.xy / screenPos.w + offset; | |
| float sw = float(screenWidth)/2.0;//VIEWPORT_SIZE.x / round(VIEWPORT_SIZE.x/float(screenWidth))/2.0; | |
| float sh = float(screenHeight)/2.0;//VIEWPORT_SIZE.y / round(VIEWPORT_SIZE.y/float(screenHeight))/2.0; | |
| // round that position off to nearest square | |
| screenPos.x = (round((screenPos.x) * sw) ) / sw; | |
| screenPos.y = (round((screenPos.y) * sh) ) / sh; | |
| // pass this along to fragment shader for depth sampling | |
| calcscreen = vec4((screenPos.xy)+0.5, sw, sh); | |
| // unflatten image and align from corner again | |
| screenPos.xy = (screenPos.xy - offset) * screenPos.w; | |
| POSITION = screenPos; | |
| } | |
| void fragment() { | |
| float sw = calcscreen.z; | |
| float sh = calcscreen.w; | |
| //get current tile | |
| uint tilex = uint(floor(calcscreen.x * sw)); | |
| uint tiley = uint(floor(calcscreen.y * sh)); | |
| vec2 flooredUV = vec2(float(tilex)/sw, float(tiley) / sh); | |
| //get x and y pixel within current tile | |
| vec2 tileUV = (calcscreen.xy - flooredUV) * vec2(sw, sh); | |
| uint xindex = uint(floor(tileUV.x * 8.)); | |
| uint yindex = uint(floor(tileUV.y * 8.)); //max = 4294967295 //2147483648 | |
| // calculates index based on tile on-screen | |
| // other ideas are get an index from particle ID or by sampling the screen_texture | |
| uint index = ( tilex * 7u * tiley * 13u + tilex ) % 128u; | |
| // this uses the byte array for pixel data | |
| // I guess I could make a version that just uses a texture | |
| bool ispixel = getPixel(xindex, yindex, index); | |
| ALBEDO.rgb = vec3(0.0, ispixel?0.7:0.0, 0.0); | |
| // sample depth | |
| float depth = textureLod(depth_texture, (round(calcscreen.xy / 2.0 * vec2(sw, sh)) + vec2(0.5)) / vec2(sw, sh), 0.0).x; | |
| vec3 ndc = vec3(calcscreen.xy * 2.0 - 1.0 + vec2(0.0, 0.1), depth); //assumes vulkan | |
| vec4 view = INV_PROJECTION_MATRIX * vec4(ndc, 1.0); | |
| view.xyz /= view.w; | |
| float linear_depth = -view.z; | |
| ALPHA = (-VERTEX.z > linear_depth)?0.0:1.0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment