Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
145 lines
4.2 KiB
C++
145 lines
4.2 KiB
C++
#pragma once
|
|
|
|
#include <mln/shaders/shader_source.hpp>
|
|
#include <mln/shaders/vulkan/shader_program.hpp>
|
|
|
|
constexpr auto rasterShaderPrelude = R"(
|
|
|
|
#define idRasterDrawableUBO idDrawableReservedVertexOnlyUBO
|
|
#define idRasterEvaluatedPropsUBO layerUBOStartId
|
|
|
|
)";
|
|
|
|
namespace mln {
|
|
namespace shaders {
|
|
|
|
template <>
|
|
struct ShaderSource<BuiltIn::RasterShader, gfx::Backend::Type::Vulkan> {
|
|
static constexpr const char* name = "RasterShader";
|
|
|
|
static const std::array<AttributeInfo, 2> attributes;
|
|
static constexpr std::array<AttributeInfo, 0> instanceAttributes{};
|
|
static const std::array<TextureInfo, 2> textures;
|
|
|
|
static constexpr auto prelude = rasterShaderPrelude;
|
|
static constexpr auto vertex = R"(
|
|
|
|
layout(location = 0) in ivec2 in_position;
|
|
layout(location = 1) in ivec2 in_texture_position;
|
|
|
|
layout(push_constant) uniform Constants {
|
|
int ubo_index;
|
|
} constant;
|
|
|
|
struct RasterDrawableUBO {
|
|
mat4 matrix;
|
|
};
|
|
|
|
layout(std140, set = LAYER_SET_INDEX, binding = idRasterDrawableUBO) readonly buffer RasterDrawableUBOVector {
|
|
RasterDrawableUBO drawable_ubo[];
|
|
} drawableVector;
|
|
|
|
layout(set = LAYER_SET_INDEX, binding = idRasterEvaluatedPropsUBO) uniform RasterEvaluatedPropsUBO {
|
|
vec4 spin_weights;
|
|
vec2 tl_parent;
|
|
float scale_parent;
|
|
float buffer_scale;
|
|
float fade_t;
|
|
float opacity;
|
|
float brightness_low;
|
|
float brightness_high;
|
|
float saturation_factor;
|
|
float contrast_factor;
|
|
float pad1;
|
|
float pad2;
|
|
} props;
|
|
|
|
layout(location = 0) out vec2 frag_position0;
|
|
layout(location = 1) out vec2 frag_position1;
|
|
|
|
void main() {
|
|
const RasterDrawableUBO drawable = drawableVector.drawable_ubo[constant.ubo_index];
|
|
|
|
gl_Position = drawable.matrix * vec4(in_position, 0, 1);
|
|
applySurfaceTransform();
|
|
|
|
// We are using Int16 for texture position coordinates to give us enough precision for
|
|
// fractional coordinates. We use 8192 to scale the texture coordinates in the buffer
|
|
// as an arbitrarily high number to preserve adequate precision when rendering.
|
|
// This is also the same value as the EXTENT we are using for our tile buffer pos coordinates,
|
|
// so math for modifying either is consistent.
|
|
frag_position0 = (((in_texture_position / 8192.0) - 0.5) / props.buffer_scale ) + 0.5;
|
|
frag_position1 = (frag_position0 * props.scale_parent) + props.tl_parent;
|
|
}
|
|
)";
|
|
|
|
static constexpr auto fragment = R"(
|
|
|
|
layout(location = 0) in vec2 frag_position0;
|
|
layout(location = 1) in vec2 frag_position1;
|
|
|
|
layout(location = 0) out vec4 out_color;
|
|
|
|
layout(set = LAYER_SET_INDEX, binding = idRasterEvaluatedPropsUBO) uniform RasterEvaluatedPropsUBO {
|
|
vec4 spin_weights;
|
|
vec2 tl_parent;
|
|
float scale_parent;
|
|
float buffer_scale;
|
|
float fade_t;
|
|
float opacity;
|
|
float brightness_low;
|
|
float brightness_high;
|
|
float saturation_factor;
|
|
float contrast_factor;
|
|
float pad1;
|
|
float pad2;
|
|
} props;
|
|
|
|
layout(set = DRAWABLE_IMAGE_SET_INDEX, binding = 0) uniform sampler2D image0_sampler;
|
|
layout(set = DRAWABLE_IMAGE_SET_INDEX, binding = 1) uniform sampler2D image1_sampler;
|
|
|
|
void main() {
|
|
|
|
#if defined(OVERDRAW_INSPECTOR)
|
|
out_color = vec4(1.0);
|
|
return;
|
|
#endif
|
|
|
|
// read and cross-fade colors from the main and parent tiles
|
|
vec4 color0 = texture(image0_sampler, frag_position0);
|
|
vec4 color1 = texture(image1_sampler, frag_position1);
|
|
if (color0.a > 0.0) {
|
|
color0.rgb = color0.rgb / color0.a;
|
|
}
|
|
if (color1.a > 0.0) {
|
|
color1.rgb = color1.rgb / color1.a;
|
|
}
|
|
vec4 color = mix(color0, color1, props.fade_t);
|
|
color.a *= props.opacity;
|
|
vec3 rgb = color.rgb;
|
|
|
|
// spin
|
|
rgb = vec3(
|
|
dot(rgb, props.spin_weights.xyz),
|
|
dot(rgb, props.spin_weights.zxy),
|
|
dot(rgb, props.spin_weights.yzx));
|
|
|
|
// saturation
|
|
float average = (color.r + color.g + color.b) / 3.0;
|
|
rgb += (average - rgb) * props.saturation_factor;
|
|
|
|
// contrast
|
|
rgb = (rgb - 0.5) * props.contrast_factor + 0.5;
|
|
|
|
// brightness
|
|
vec3 high_vec = vec3(props.brightness_low, props.brightness_low, props.brightness_low);
|
|
vec3 low_vec = vec3(props.brightness_high, props.brightness_high, props.brightness_high);
|
|
|
|
out_color = vec4(vec3(mix(high_vec, low_vec, rgb) * color.a), color.a);
|
|
}
|
|
)";
|
|
};
|
|
|
|
} // namespace shaders
|
|
} // namespace mln
|