module Render.Unlit.Sprite.Code ( vert , frag ) where import RIO import Render.Code (Code, glsl) import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding2) vert :: Code vert = fromString [glsl| #version 450 ${set0binding0} layout(location = 0) in vec4 iVert; layout(location = 1) in vec4 iFrag; layout(location = 2) in vec4 iTint; layout(location = 3) in vec4 iOutline; layout(location = 4) in vec4 iAnimation; layout(location = 5) in uvec2 iTextureSize; layout(location = 6) in ivec2 iTextureIds; layout(location = 0) out vec2 fTexCoord; layout(location = 1) flat out vec4 fTint; layout(location = 2) flat out vec4 fOutline; layout(location = 3) flat out vec2 fStepSize; layout(location = 4) flat out ivec2 fTextureIds; vec2 positions[6] = vec2[]( vec2(-0.5, -0.5), vec2(0.5, -0.5), vec2(-0.5, 0.5), vec2(0.5, 0.5), vec2(-0.5, 0.5), vec2(0.5, -0.5) ); vec2 texCoords[6] = vec2[]( vec2(0.0, 0.0), vec2(1.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(0.0, 1.0), vec2(1.0, 0.0) ); void main() { // pass-through fTint = iTint; fOutline = iOutline; fTextureIds = iTextureIds; fStepSize = 1.0 / vec2(iTextureSize); vec2 pos = positions[gl_VertexIndex]; gl_Position = scene.projection * scene.view * vec4(iVert.xy + pos * iVert.zw, 0, 1.0); vec2 uv = texCoords[gl_VertexIndex]; fTexCoord = iFrag.xy + uv * iFrag.zw; float time = 0; float frame = 0; if (iAnimation[0] > 1) { time = scene.tweaks.a + iAnimation[3]; frame = mod(trunc(time * iAnimation[1]), iAnimation[0]) - 1.0; fTexCoord += vec2( frame * iFrag.z + frame * iAnimation[2] / float(iTextureSize.x), 0 ); } } |] frag :: Code frag = fromString [glsl| #version 450 #extension GL_EXT_nonuniform_qualifier : enable ${set0binding1} ${set0binding2} layout(location = 0) in vec2 fTexCoord; layout(location = 1) flat in vec4 fTint; layout(location = 2) flat in vec4 fOutline; layout(location = 3) flat in vec2 fStepSize; layout(location = 4) flat in ivec2 fTextureIds; layout(location = 0) out vec4 outColor; layout(constant_id=0) const float discardAlpha = 0.0; layout(constant_id=1) const bool doOutline = false; vec4 tap(vec2 uv) { return textureLod( sampler2D( textures[nonuniformEXT(fTextureIds.t)], samplers[nonuniformEXT(fTextureIds.s)] ), fTexCoord + uv, 0 ); } void main() { vec4 texel = tap(vec2(0)); if (discardAlpha != 0.0) { if (texel.a < discardAlpha) { discard; } } outColor = texel * fTint * texel.a; if (doOutline) { if (fOutline.a > 0.0 && texel.a < 1.0) { float alpha = 0.0; alpha += tap(vec2(fStepSize.x, 0.0) ).a / 4.0; alpha += tap(vec2(-fStepSize.x, 0.0) ).a / 4.0; alpha += tap(vec2(0.0, fStepSize.y) ).a / 4.0; alpha += tap(vec2(0.0, -fStepSize.y)).a / 4.0; outColor += fOutline * alpha; } } } |]