mirror of
https://github.com/DaedalusX64/daedalus.git
synced 2025-04-02 10:21:48 -04:00
297 lines
8.3 KiB
Text
297 lines
8.3 KiB
Text
#version 310 es
|
||
|
||
precision highp float;
|
||
precision highp int;
|
||
|
||
// --------------------------------------------------------
|
||
// 1. Macro trick to avoid redefinition of built-in in ES 3.0
|
||
// --------------------------------------------------------
|
||
#ifdef GL_ES
|
||
#if __VERSION__ < 310
|
||
// Only apply if we really end up at ES 3.0 environment
|
||
#define texelFetch myTexelFetch
|
||
#endif
|
||
#endif
|
||
|
||
// --------------------------------------------------------
|
||
// 2. Provide the actual function body for our "texelFetch" calls
|
||
// --------------------------------------------------------
|
||
vec4 myTexelFetch(sampler2D tex, ivec2 coords, int lod)
|
||
{
|
||
// Emulate texelFetch(...) on a float sampler2D
|
||
ivec2 size = textureSize(tex, 0);
|
||
vec2 uv = (vec2(coords) + 0.5) / vec2(size);
|
||
return textureLod(tex, uv, 0.0);
|
||
}
|
||
|
||
// --------------------------------------------------------
|
||
// Your original uniform declarations
|
||
// --------------------------------------------------------
|
||
uniform sampler2D uTexture0;
|
||
uniform sampler2D uTexture1;
|
||
|
||
uniform vec2 uTexScale0;
|
||
uniform vec2 uTexScale1;
|
||
uniform vec4 uPrimColour;
|
||
uniform vec4 uEnvColour;
|
||
uniform float uPrimLODFrac;
|
||
|
||
// Inputs from the vertex shader
|
||
in vec2 v_st;
|
||
in vec4 v_col;
|
||
|
||
// Final fragment color
|
||
out vec4 fragcol;
|
||
|
||
// Tiling / Clamping
|
||
uniform bvec2 uTileClampEnable0;
|
||
uniform ivec2 uTileTL0; // 10.2 fixed point
|
||
uniform ivec2 uTileBR0; // 10.2 fixed point
|
||
uniform vec2 uTileShift0; // floating point
|
||
uniform ivec2 uTileMask0; // 10.5 fixed point
|
||
uniform ivec2 uTileMirror0;// 10.5 fixed point
|
||
|
||
uniform bvec2 uTileClampEnable1;
|
||
uniform ivec2 uTileTL1;
|
||
uniform ivec2 uTileBR1;
|
||
uniform vec2 uTileShift1;
|
||
uniform ivec2 uTileMask1;
|
||
uniform ivec2 uTileMirror1;
|
||
|
||
// Example uniform
|
||
uniform int uFoo;
|
||
|
||
// --------------------------------------------------------
|
||
// Helper Functions (optimized)
|
||
// --------------------------------------------------------
|
||
|
||
// Replace mix on ivec2 by using the ternary operator for each component.
|
||
ivec2 imix(ivec2 a, ivec2 b, bvec2 c)
|
||
{
|
||
return ivec2(c.x ? b.x : a.x, c.y ? b.y : a.y);
|
||
}
|
||
|
||
// Multiply an integer vector by a float vector.
|
||
ivec2 shift(ivec2 coord, vec2 shift_scale)
|
||
{
|
||
return ivec2(float(coord.x) * shift_scale.x, float(coord.y) * shift_scale.y);
|
||
}
|
||
|
||
ivec2 clampPoint(ivec2 coord,
|
||
ivec2 tile_tl,
|
||
ivec2 tile_br,
|
||
bvec2 clamp_enable)
|
||
{
|
||
ivec2 coord_clamped = clamp(coord, tile_tl << 3, tile_br << 3);
|
||
ivec2 coord_out = imix(coord, coord_clamped, clamp_enable);
|
||
ivec2 coord_relative = ((coord_out >> 3) - tile_tl) >> 2;
|
||
return coord_relative;
|
||
}
|
||
|
||
ivec2 clampBilinear(ivec2 coord,
|
||
ivec2 tile_tl,
|
||
ivec2 tile_br,
|
||
bvec2 clamp_enable,
|
||
out ivec2 frac)
|
||
{
|
||
ivec2 tl = tile_tl << 3; // Precompute shifted tile top‐left.
|
||
ivec2 br = tile_br << 3;
|
||
ivec2 coord_clamped = clamp(coord, tl, br);
|
||
ivec2 coord_out = imix(coord, coord_clamped, clamp_enable);
|
||
ivec2 coord_relative = coord_out - tl; // Use tl instead of recomputing (tile_tl << 3)
|
||
frac = coord_relative & 0x1f;
|
||
return coord_relative >> 5;
|
||
}
|
||
|
||
ivec2 mask(ivec2 coord, ivec2 mirror_bits, ivec2 mask_bits)
|
||
{
|
||
bvec2 mirror = notEqual(coord & mirror_bits, ivec2(0));
|
||
coord = imix(coord, ~coord, mirror);
|
||
coord &= mask_bits;
|
||
return coord;
|
||
}
|
||
|
||
vec4 bilinear(vec4 col_00, vec4 col_01,
|
||
vec4 col_10, vec4 col_11,
|
||
ivec2 frac)
|
||
{
|
||
vec2 fracf = vec2(frac) / 32.0;
|
||
vec4 a = mix(col_00, col_10, fracf.x);
|
||
vec4 b = mix(col_01, col_11, fracf.x);
|
||
return mix(a, b, fracf.y);
|
||
}
|
||
|
||
vec4 bilinear_n64(vec4 col_00, vec4 col_01,
|
||
vec4 col_10, vec4 col_11,
|
||
ivec2 frac)
|
||
{
|
||
bool upper = (frac.x + frac.y) >= 0x20;
|
||
bvec4 uppersel = bvec4(upper);
|
||
vec4 col0 = mix(col_00, col_11, uppersel);
|
||
vec4 col1 = mix(col_10, col_01, uppersel);
|
||
vec4 col2 = mix(col_01, col_10, uppersel);
|
||
vec2 fracf = vec2(imix(frac, 0x20 - frac, bvec2(upper, upper))) / 32.0;
|
||
vec4 colA = col0 + (fracf.x * (col1 - col0));
|
||
vec4 colB = col0 + (fracf.y * (col2 - col0));
|
||
return clamp(colA + colB - col0, 0.0, 1.0);
|
||
}
|
||
|
||
// --------------------------------------------------------
|
||
// Texture Fetch Functions
|
||
// --------------------------------------------------------
|
||
|
||
vec4 fetchBilinear(ivec2 st_in,
|
||
vec2 shift_scale,
|
||
ivec2 mirror_bits,
|
||
ivec2 mask_bits,
|
||
ivec2 tile_tl,
|
||
ivec2 tile_br,
|
||
bvec2 clamp_enable,
|
||
sampler2D tex,
|
||
vec2 tex_scale)
|
||
{
|
||
ivec2 frac;
|
||
ivec2 uv0 = st_in;
|
||
uv0 = shift(uv0, shift_scale);
|
||
uv0 = clampBilinear(uv0, tile_tl, tile_br, clamp_enable, frac);
|
||
ivec2 uv1 = uv0 + ivec2(1);
|
||
uv0 = mask(uv0, mirror_bits, mask_bits);
|
||
uv1 = mask(uv1, mirror_bits, mask_bits);
|
||
vec4 col_00 = texelFetch(tex, uv0, 0);
|
||
vec4 col_01 = texelFetch(tex, ivec2(uv0.x, uv1.y), 0);
|
||
vec4 col_10 = texelFetch(tex, ivec2(uv1.x, uv0.y), 0);
|
||
vec4 col_11 = texelFetch(tex, uv1, 0);
|
||
return bilinear(col_00, col_01, col_10, col_11, frac);
|
||
}
|
||
|
||
vec4 fetchBilinearClampedCommon(
|
||
vec2 st_in,
|
||
vec2 shift_scale,
|
||
ivec2 mirror_bits,
|
||
ivec2 mask_bits,
|
||
ivec2 tile_tl,
|
||
ivec2 tile_br,
|
||
bvec2 clamp_enable,
|
||
sampler2D tex,
|
||
vec2 tex_scale,
|
||
ivec2 bilerp_wrap_enable)
|
||
{
|
||
ivec2 frac;
|
||
ivec2 uv0 = ivec2(st_in);
|
||
uv0 = shift(uv0, shift_scale);
|
||
uv0 = clampBilinear(uv0, tile_tl, tile_br, clamp_enable, frac);
|
||
ivec2 uv1 = uv0 + ivec2(1);
|
||
uv0 = mask(uv0, mirror_bits, mask_bits);
|
||
uv1 = mask(uv1, mirror_bits, mask_bits);
|
||
// If uv1 < uv0, remove some fractional bits.
|
||
frac = imix(frac, frac & bilerp_wrap_enable, lessThan(uv1, uv0));
|
||
vec4 col_00 = texelFetch(tex, uv0, 0);
|
||
vec4 col_01 = texelFetch(tex, ivec2(uv0.x, uv1.y), 0);
|
||
vec4 col_10 = texelFetch(tex, ivec2(uv1.x, uv0.y), 0);
|
||
vec4 col_11 = texelFetch(tex, uv1, 0);
|
||
return bilinear(col_00, col_01, col_10, col_11, frac);
|
||
}
|
||
|
||
vec4 fetchBilinearClampedS(
|
||
vec2 st_in,
|
||
vec2 shift_scale,
|
||
ivec2 mirror_bits,
|
||
ivec2 mask_bits,
|
||
ivec2 tile_tl,
|
||
ivec2 tile_br,
|
||
bvec2 clamp_enable,
|
||
sampler2D tex,
|
||
vec2 tex_scale)
|
||
{
|
||
return fetchBilinearClampedCommon(
|
||
st_in, shift_scale, mirror_bits, mask_bits,
|
||
tile_tl, tile_br, clamp_enable, tex, tex_scale,
|
||
ivec2(0, -1));
|
||
}
|
||
|
||
vec4 fetchBilinearClampedT(
|
||
vec2 st_in,
|
||
vec2 shift_scale,
|
||
ivec2 mirror_bits,
|
||
ivec2 mask_bits,
|
||
ivec2 tile_tl,
|
||
ivec2 tile_br,
|
||
bvec2 clamp_enable,
|
||
sampler2D tex,
|
||
vec2 tex_scale)
|
||
{
|
||
return fetchBilinearClampedCommon(
|
||
st_in, shift_scale, mirror_bits, mask_bits,
|
||
tile_tl, tile_br, clamp_enable, tex, tex_scale,
|
||
ivec2(-1, 0));
|
||
}
|
||
|
||
vec4 fetchBilinearClampedST(
|
||
vec2 st_in,
|
||
vec2 shift_scale,
|
||
ivec2 mirror_bits,
|
||
ivec2 mask_bits,
|
||
ivec2 tile_tl,
|
||
ivec2 tile_br,
|
||
bvec2 clamp_enable,
|
||
sampler2D tex,
|
||
vec2 tex_scale)
|
||
{
|
||
return fetchBilinearClampedCommon(
|
||
st_in, shift_scale, mirror_bits, mask_bits,
|
||
tile_tl, tile_br, clamp_enable, tex, tex_scale,
|
||
ivec2(0, 0));
|
||
}
|
||
|
||
vec4 fetchPoint(
|
||
ivec2 st_in,
|
||
vec2 shift_scale,
|
||
ivec2 mirror_bits,
|
||
ivec2 mask_bits,
|
||
ivec2 tile_tl,
|
||
ivec2 tile_br,
|
||
bvec2 clamp_enable,
|
||
sampler2D tex,
|
||
vec2 tex_scale)
|
||
{
|
||
ivec2 uv = st_in;
|
||
uv = shift(uv, shift_scale);
|
||
uv = clampPoint(uv, tile_tl, tile_br, clamp_enable);
|
||
uv = mask(uv, mirror_bits, mask_bits);
|
||
return texelFetch(tex, uv, 0);
|
||
}
|
||
|
||
vec4 fetchCopy(
|
||
ivec2 st_in,
|
||
vec2 shift_scale,
|
||
ivec2 mirror_bits,
|
||
ivec2 mask_bits,
|
||
ivec2 tile_tl,
|
||
ivec2 tile_br,
|
||
bvec2 clamp_enable,
|
||
sampler2D tex,
|
||
vec2 tex_scale)
|
||
{
|
||
ivec2 uv = st_in;
|
||
uv = shift(uv, shift_scale);
|
||
uv = (((uv >> 3) - tile_tl) >> 2) & ivec2(0x1fff);
|
||
uv = mask(uv, mirror_bits, mask_bits);
|
||
return texelFetch(tex, uv, 0);
|
||
}
|
||
|
||
vec4 fetchSimple(
|
||
vec2 st_in,
|
||
vec2 shift_scale,
|
||
ivec2 mirror_bits,
|
||
ivec2 mask_bits,
|
||
ivec2 tile_tl,
|
||
ivec2 tile_br,
|
||
bvec2 clamp_enable,
|
||
sampler2D tex,
|
||
vec2 tex_scale)
|
||
{
|
||
ivec2 uv = ivec2(st_in);
|
||
uv = shift(uv, shift_scale);
|
||
vec2 uvf = (vec2(uv) - vec2(tile_tl << 3)) * (tex_scale / 32.0);
|
||
return texture(tex, uvf);
|
||
}
|