godot/servers/rendering/renderer_rd/shaders/blit.glsl
clayjohn 57eb762bae Add option to enable HDR rendering in 2D
This is needed to allow 2D to fully make use of 3D effects (e.g. glow), and can be used to substantially improve quality of 2D rendering at the cost of performance

Additionally, the 2D rendering pipeline is done in linear space (we skip linear_to_srgb conversion in 3D tonemapping) so the entire Viewport can be kept linear.
This is necessary for proper HDR screen support in the future.
2023-08-07 11:24:03 +02:00

109 lines
2.3 KiB
GLSL

#[vertex]
#version 450
#VERSION_DEFINES
layout(push_constant, std140) uniform Pos {
vec4 src_rect;
vec4 dst_rect;
vec2 eye_center;
float k1;
float k2;
float upscale;
float aspect_ratio;
uint layer;
uint pad1;
}
data;
layout(location = 0) out vec2 uv;
void main() {
vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
uv = data.src_rect.xy + base_arr[gl_VertexIndex] * data.src_rect.zw;
vec2 vtx = data.dst_rect.xy + base_arr[gl_VertexIndex] * data.dst_rect.zw;
gl_Position = vec4(vtx * 2.0 - 1.0, 0.0, 1.0);
}
#[fragment]
#version 450
#VERSION_DEFINES
layout(push_constant, std140) uniform Pos {
vec4 src_rect;
vec4 dst_rect;
vec2 eye_center;
float k1;
float k2;
float upscale;
float aspect_ratio;
uint layer;
bool convert_to_srgb;
}
data;
layout(location = 0) in vec2 uv;
layout(location = 0) out vec4 color;
#ifdef USE_LAYER
layout(binding = 0) uniform sampler2DArray src_rt;
#else
layout(binding = 0) uniform sampler2D src_rt;
#endif
vec3 linear_to_srgb(vec3 color) {
// If going to srgb, clamp from 0 to 1.
color = clamp(color, vec3(0.0), vec3(1.0));
const vec3 a = vec3(0.055f);
return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f)));
}
void main() {
#ifdef APPLY_LENS_DISTORTION
vec2 coords = uv * 2.0 - 1.0;
vec2 offset = coords - data.eye_center;
// take aspect ratio into account
offset.y /= data.aspect_ratio;
// distort
vec2 offset_sq = offset * offset;
float radius_sq = offset_sq.x + offset_sq.y;
float radius_s4 = radius_sq * radius_sq;
float distortion_scale = 1.0 + (data.k1 * radius_sq) + (data.k2 * radius_s4);
offset *= distortion_scale;
// reapply aspect ratio
offset.y *= data.aspect_ratio;
// add our eye center back in
coords = offset + data.eye_center;
coords /= data.upscale;
// and check our color
if (coords.x < -1.0 || coords.y < -1.0 || coords.x > 1.0 || coords.y > 1.0) {
color = vec4(0.0, 0.0, 0.0, 1.0);
} else {
// layer is always used here
coords = (coords + vec2(1.0)) / vec2(2.0);
color = texture(src_rt, vec3(coords, data.layer));
}
#elif defined(USE_LAYER)
color = texture(src_rt, vec3(uv, data.layer));
#else
color = texture(src_rt, uv);
#endif
if (data.convert_to_srgb) {
color.rgb = linear_to_srgb(color.rgb); // Regular linear -> SRGB conversion.
}
}