This code assumes sharpness is a uniform float, and I remind you that wuv is a vec2. Wuv = norm * vec2(pow(norm2.x, sharpness), pow(norm2.y, sharpness)) + 0.5 Now we are going to apply the sharpen algorithm fromīeefster09 that you linked, but only to the fractional part of the pixel coordinates: vec2 norm = (wuv - 0.5) I start with fuv, but since fuv is in pixels we need to multiply by pixel_size: fuv * pixel_sizeĪnd I want to offset it by whole pixels, so I would something like this: fuv * pixel_size + vec2(off_x, off_y) * pixel_sizeĪs you can see pixel_size is a common factor, so we rewrite that: (fuv + vec2(off_x, off_y)) * pixel_size We are going to do bilinear filter later.įor reference, this is how you would query at uv: vec4 color = palette_swap(texture(TEXTURE, uv)) Īnd I'm making new coordinates to query the texture (i.e. I'm also assuming nearest-neighbor filtering. This would allow you to keep the approach you are currently using, or change if you need. I'm, of course, assuming you have a palette_swap function that takes a vec4 and outputs a vec4. Vec4 hix_hiy = palette_swap(texture(TEXTURE, (fuv + vec2(1.0, 1.0)) * pixel_size)) Vec4 hix_loy = palette_swap(texture(TEXTURE, (fuv + vec2(1.0, 0.0)) * pixel_size)) Vec4 lox_hiy = palette_swap(texture(TEXTURE, (fuv + vec2(0.0, 1.0)) * pixel_size)) We are going to query the four pixels around the uv and apply pallet swapping to the colors we get: vec4 lox_loy = palette_swap(texture(TEXTURE, (fuv + vec2(0.0, 0.0)) * pixel_size)) Here I'm assuming uv goes from (0.0, 0.0) to (1.0, 1.0), and pixel_size is the inverse of the size of the texture in pixels. Split the uv coordinates into integer and fractional and pixels: vec2 fuv = floor(uv / pixel_size) This is what I have been able to come up with: I'll be writing GLSL because I'm more familiar with it, and it is easier for me to test. I am still very much a novice when it comes to shaders, so any help here would be deeply appreciated! ![]() In other words the two aforementioned techniques seem to be completely incompatible with one another, yet I really need both of them.Īs far as I can tell the logical solution would be to perform the palette-swapping and similar effects on the texture before scaling and filtering it, however I have no idea of how to actually do this from within a shader, and what the performance implications of doing so would be. The problem is of course that you cannot do palette-swaps on a texture with bilinear filtering because the colors are all blended together. Here and here are a couple of open-source shaders using this technique. Luckily there is a way of scaling pixel-art that looks much smoother without taking away the crispness, which is to use a texture with bilinear filtering enabled but only use interpolated colors on the boundary between pixels. However, in the game there is quite a lot of floating-point camera scaling and movement going on, resulting in choppy-looking visuals when using nearest-neighbor filtering. ![]() (These effects are used in a very dynamic way, which is why they are done using a shader instead of, say, a separate texture-atlas for each color palette). ![]() Simple stuff as long as you use nearest-neighbor filtering on the texture. ![]() Most of these effects work by comparing the color of a texture coordinate with a reference color, and if they match then the color is swapped for another. I am creating a pixel-art game in MonoGame, and have written a shader to perform various effects on a sprite when rendering it, such as performing palette swaps, highlighting outlines, etc.
0 Comments
Leave a Reply. |
Details
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |