Skip to content

Instantly share code, notes, and snippets.

@mickdekkers
Created April 29, 2020 14:28
Show Gist options
  • Save mickdekkers/68fdea99a448cd872b60d7962936479c to your computer and use it in GitHub Desktop.
Save mickdekkers/68fdea99a448cd872b60d7962936479c to your computer and use it in GitHub Desktop.
Sprite sheet/texture atlas sampling in OpenGL/GLSL with Shadron
// Sprite sheet/texture atlas sampling in OpenGL/GLSL with Shadron
// (c) 2020 Mick Dekkers
// This work is licensed under the terms of the MIT license. See https://opensource.org/licenses/MIT for a copy.
// Tested with the emoji spritesheets at https://github.com/iamcal/emoji-data , specifically:
// https://github.com/iamcal/emoji-data/blob/8930a29f7193cc7603765c9046edac7ca529de78/sheets-clean/sheet_apple_64_clean.png
parameter int outputSize = 300.0 : range(1, 1024);
parameter int spriteSize = 64 : range(1, 1024);
parameter int spritePadding = 2 : range(1, 100);
parameter int numSpritesPerDimension = 56 : range(1, 1024);
parameter ivec2 spriteIndex = ivec2(0, 0) : range(ivec2(0, 0), ivec2(56, 56));
parameter bool halfPixelCorrection = true;
// The input image - clamp so that edges don't wrap around
image Input = file() : map(clamp);
// The output image shader
glsl vec4 sampleSpriteSheet(vec2 position) {
vec2 sheetSize = vec2(textureSize(Input, 0));
vec2 spriteSizeInTextureSpace = spriteSize / sheetSize;
vec2 spritePaddingInTextureSpace = spritePadding / sheetSize;
// GLSL coordinates are bottom-up, but the sprite index is top-down
ivec2 correctedSpriteIndex = ivec2(spriteIndex.x, numSpritesPerDimension - spriteIndex.y);
vec2 texCoord = position +
spriteSizeInTextureSpace * correctedSpriteIndex * numSpritesPerDimension +
spritePaddingInTextureSpace * correctedSpriteIndex * numSpritesPerDimension;
vec2 scaledTexCoord = texCoord / numSpritesPerDimension;
vec2 halfPixelCorrectedTexCoord = halfPixelCorrection ? (scaledTexCoord - vec2(0.5) / sheetSize) : scaledTexCoord;
return texture2D(Input, halfPixelCorrectedTexCoord);
}
// The output image
image Output = glsl(sampleSpriteSheet, outputSize);
export png(Output, "output.png");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment