You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-04 17:04:49 +00:00
125 lines
3.6 KiB
GLSL
125 lines
3.6 KiB
GLSL
#[versions]
|
|
|
|
version_float = "#define VER_FLOAT";
|
|
version_half = "#define VER_HALF";
|
|
version_unorm8 = "#define VER_UINT8";
|
|
version_unorm16 = "#define VER_UINT16";
|
|
|
|
#[compute]
|
|
#version 450
|
|
|
|
#VERSION_DEFINES
|
|
|
|
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
|
|
|
layout(std430, binding = 0) buffer Source {
|
|
#if defined(VER_FLOAT)
|
|
float data[];
|
|
#else
|
|
uint data[];
|
|
#endif
|
|
}
|
|
source;
|
|
|
|
#if defined(VER_FLOAT)
|
|
layout(binding = 1, rgba32f) uniform writeonly image2D dest;
|
|
#elif defined(VER_HALF)
|
|
layout(binding = 1, rgba16f) uniform writeonly image2D dest;
|
|
#elif defined(VER_UINT8)
|
|
layout(binding = 1, rgba8) uniform writeonly image2D dest;
|
|
#elif defined(VER_UINT16)
|
|
layout(binding = 1, rgba16) uniform writeonly image2D dest;
|
|
#endif
|
|
|
|
layout(push_constant, std430) uniform Params {
|
|
uint p_width;
|
|
uint p_height;
|
|
uint p_padding[2];
|
|
}
|
|
params;
|
|
|
|
void main() {
|
|
// gl_GlobalInvocationID is equivalent to the current texel coordinates.
|
|
if (gl_GlobalInvocationID.x >= params.p_width || gl_GlobalInvocationID.y >= params.p_height) {
|
|
return;
|
|
}
|
|
|
|
// The index of a texel in the source buffer, NOT an index of source.data[]
|
|
const int texel_index = int(gl_GlobalInvocationID.y * params.p_width + gl_GlobalInvocationID.x);
|
|
|
|
#if defined(VER_FLOAT)
|
|
// Since 32-bit floats are aligned with RGBF texel data, just retrieve the values from the array.
|
|
// Multiply by 3 to align with the components.
|
|
|
|
int data_index = texel_index * 3;
|
|
vec3 color_rgb = vec3(source.data[data_index], source.data[data_index + 1], source.data[data_index + 2]);
|
|
|
|
#elif defined(VER_UINT8)
|
|
// RGB8 texel data and 32-bit uints are not aligned, so we have to use a bit of magic.
|
|
// The source texel can be in either of 4 alignment 'states':
|
|
// 0 - [ XYZ_-____ ]
|
|
// 1 - [ _YZW-____ ]
|
|
// 2 - [ __ZW-X___ ]
|
|
// 3 - [ ___W-XY__ ]
|
|
// The texel index additionally needs to be decremented after every 'cycle' in order to properly fit into the source array.
|
|
|
|
vec3 color_rgb = vec3(0.0);
|
|
int data_index = texel_index - (texel_index / 4);
|
|
|
|
switch ((texel_index * 3) % 4) {
|
|
case 0:
|
|
color_rgb = unpackUnorm4x8(source.data[data_index]).xyz;
|
|
break;
|
|
case 1:
|
|
color_rgb = unpackUnorm4x8(source.data[data_index - 1]).yzw;
|
|
break;
|
|
case 2:
|
|
color_rgb.rg = unpackUnorm4x8(source.data[data_index - 1]).zw;
|
|
color_rgb.b = unpackUnorm4x8(source.data[data_index]).x;
|
|
break;
|
|
case 3:
|
|
color_rgb.r = unpackUnorm4x8(source.data[data_index - 1]).w;
|
|
color_rgb.gb = unpackUnorm4x8(source.data[data_index]).xy;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
#else
|
|
// In a similar vein to RGB8, the RGBH/RGB16 source texel can be in either of 2 alignment 'states':
|
|
// 0 - [ XY-X_ ]
|
|
// 1 - [ _Y-XY ]
|
|
// The texel index has to be incremented this time, as the size of a texel (6 bytes) is greater than that of a 32-bit uint (4 bytes).
|
|
|
|
vec3 color_rgb = vec3(0.0);
|
|
int data_index = texel_index + (texel_index / 2);
|
|
|
|
switch ((texel_index * 3) % 2) {
|
|
#if defined(VER_HALF)
|
|
case 0:
|
|
color_rgb.xy = unpackHalf2x16(source.data[data_index]);
|
|
color_rgb.z = unpackHalf2x16(source.data[data_index + 1]).x;
|
|
break;
|
|
case 1:
|
|
color_rgb.x = unpackHalf2x16(source.data[data_index]).y;
|
|
color_rgb.yz = unpackHalf2x16(source.data[data_index + 1]);
|
|
break;
|
|
#elif defined(VER_UINT16)
|
|
case 0:
|
|
color_rgb.xy = unpackUnorm2x16(source.data[data_index]);
|
|
color_rgb.z = unpackUnorm2x16(source.data[data_index + 1]).x;
|
|
break;
|
|
case 1:
|
|
color_rgb.x = unpackUnorm2x16(source.data[data_index]).y;
|
|
color_rgb.yz = unpackUnorm2x16(source.data[data_index + 1]);
|
|
break;
|
|
#endif
|
|
default:
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
// Store the resulting RGBA color.
|
|
imageStore(dest, ivec2(gl_GlobalInvocationID.xy), vec4(color_rgb, 1.0));
|
|
}
|