// Generated by ShaderCompiler from FrozenMask.shader. Do not edit manually.
#pragma once

#include "ShaderCompilerTypes.h"
#if defined(WITH_RHI_D3D11)
#	include "D3d11GeneratedShaders.h"
#endif
#if defined(WITH_RHI_VULKAN)
#	include "VulkanGeneratedShaders.h"
#endif

#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Jazz2::ShadersGen
{
#if defined(WITH_RHI_GL) && !defined(RHI_GL_PROFILE_ES2)
	inline constexpr char FrozenMask_Vs[] =
R"__SHDR__(#line 1

uniform mat4 uProjectionMatrix;
uniform mat4 uViewMatrix;

layout (std140) uniform InstanceBlock
{
	mat4 modelMatrix;
	vec4 color;
	vec4 texRect;
	vec2 spriteSize;
	// Flat index into the palette texture (added to the per-pixel index for the palette lookup). Lands in the
	// std140 tail padding after spriteSize, so the block stays 112 bytes. Only read by palette shaders.
	float palOffset;
};

out vec2 vTexCoords;
out vec4 vColor;
out highp float vPaletteOffset;

void main()
{
	vec2 aPosition = vec2(1.0 - float(gl_VertexID >> 1), float(gl_VertexID % 2));
	vec4 position = vec4(aPosition.x * spriteSize.x, aPosition.y * spriteSize.y, 0.0, 1.0);

	gl_Position = uProjectionMatrix * uViewMatrix * modelMatrix * position;
	vTexCoords = vec2(aPosition.x * texRect.x + texRect.y, aPosition.y * texRect.z + texRect.w);
	vColor = color;
	vPaletteOffset = palOffset;
}
)__SHDR__";
#endif

#if defined(WITH_RHI_GL) && defined(RHI_GL_PROFILE_ES2)
	inline constexpr char FrozenMask_Vs100[] =
R"__SHDR__(attribute vec2 aQuadCorner;
#line 1

uniform mat4 uProjectionMatrix;
uniform mat4 uViewMatrix;

	uniform mat4 modelMatrix;
	uniform vec4 color;
	uniform vec4 texRect;
	uniform vec2 spriteSize;
	// Flat index into the palette texture (added to the per-pixel index for the palette lookup). Lands in the
	// std140 tail padding after spriteSize, so the block stays 112 bytes. Only read by palette shaders.
	uniform float palOffset;

varying vec2 vTexCoords;
varying vec4 vColor;
varying highp float vPaletteOffset;

void main()
{
	vec2 aPosition = vec2(1.0 - (1.0 - aQuadCorner.x), aQuadCorner.y);
	vec4 position = vec4(aPosition.x * spriteSize.x, aPosition.y * spriteSize.y, 0.0, 1.0);

	gl_Position = uProjectionMatrix * uViewMatrix * modelMatrix * position;
	vTexCoords = vec2(aPosition.x * texRect.x + texRect.y, aPosition.y * texRect.z + texRect.w);
	vColor = color;
	vPaletteOffset = palOffset;
}
)__SHDR__";
#endif

#if defined(WITH_RHI_GL) && !defined(RHI_GL_PROFILE_ES2)
	inline constexpr char FrozenMask_Fs[] =
R"__SHDR__(#line 1

#ifdef GL_ES
precision mediump float;
#endif

in vec2 vTexCoords;
in vec4 vColor;
in highp float vPaletteOffset;

uniform sampler2D uTexture;
#ifdef USE_PALETTE
uniform sampler2D uTexturePalette;
#endif

float aastep(float threshold, float value) {
	float afwidth = length(vec2(dFdx(value), dFdy(value))) * 0.70710678118654757;
	return smoothstep(threshold - afwidth, threshold + afwidth, value);
}

vec4 maskSample(vec2 uv) {
	vec4 src = texture(uTexture, uv);
#ifdef USE_PALETTE
	highp float palIndex = floor(vPaletteOffset + 0.5) + floor(src.r * 255.0 + 0.5);
	highp float palX = (mod(palIndex, 256.0) + 0.5) / 256.0;
	highp float palY = (floor(palIndex / 256.0) + 0.5) / 256.0;
	vec4 c = texture(uTexturePalette, vec2(palX, palY));
	return vec4(c.rgb, c.a * src.a);
#else
	return src;
#endif
}

out vec4 COLOR;

void main() {
	COLOR = vColor;
	vec2 size = COLOR.xy * COLOR.a * 2.0;

	vec4 tex = maskSample(vTexCoords);
	vec4 tex1 = maskSample(vTexCoords + vec2(-size.x, 0));
	vec4 tex2 = maskSample(vTexCoords + vec2(0, size.y));
	vec4 tex3 = maskSample(vTexCoords + vec2(size.x, 0));
	vec4 tex4 = maskSample(vTexCoords + vec2(0, -size.y));

	float outline = tex1.a;
	outline += tex2.a;
	outline += tex3.a;
	outline += tex4.a;
	outline += maskSample(vTexCoords + vec2(-size.x, size.y)).a;
	outline += maskSample(vTexCoords + vec2(size.x, size.y)).a;
	outline += maskSample(vTexCoords + vec2(-size.x, -size.y)).a;
	outline += maskSample(vTexCoords + vec2(size.x, -size.y)).a;
	outline = aastep(1.0, outline);

	vec4 color = (tex + tex + tex1 + tex2 + tex3 + tex4) / 6.0;
	float grey = min((0.299 * color.r + 0.587 * color.g + 0.114 * color.b) * 2.6, 1.0);
	COLOR = mix(tex, vec4(0.2 * grey, 0.2 + grey * 0.62, 0.6 + 0.2 * grey, outline * 0.95), COLOR.a);
}

)__SHDR__";
#endif

#if defined(WITH_RHI_GL) && defined(RHI_GL_PROFILE_ES2)
	inline constexpr char FrozenMask_Fs100[] =
R"__SHDR__(#extension GL_OES_standard_derivatives : enable
#line 1

precision mediump float;

varying vec2 vTexCoords;
varying vec4 vColor;
varying highp float vPaletteOffset;

uniform sampler2D uTexture;
#ifdef USE_PALETTE
uniform sampler2D uTexturePalette;
#endif

float aastep(float threshold, float value) {
	float afwidth = length(vec2(dFdx(value), dFdy(value))) * 0.70710678118654757;
	return smoothstep(threshold - afwidth, threshold + afwidth, value);
}

vec4 maskSample(vec2 uv) {
	vec4 src = texture2D(uTexture, uv);
#ifdef USE_PALETTE
	highp float palIndex = floor(vPaletteOffset + 0.5) + floor(src.r * 255.0 + 0.5);
	highp float palX = (mod(palIndex, 256.0) + 0.5) / 256.0;
	highp float palY = (floor(palIndex / 256.0) + 0.5) / 256.0;
	vec4 c = texture2D(uTexturePalette, vec2(palX, palY));
	return vec4(c.rgb, c.a * src.a);
#else
	return src;
#endif
}


void main() {
	vec4 COLOR;
	COLOR = vColor;
	vec2 size = COLOR.xy * COLOR.a * 2.0;

	vec4 tex = maskSample(vTexCoords);
	vec4 tex1 = maskSample(vTexCoords + vec2(-size.x, 0));
	vec4 tex2 = maskSample(vTexCoords + vec2(0, size.y));
	vec4 tex3 = maskSample(vTexCoords + vec2(size.x, 0));
	vec4 tex4 = maskSample(vTexCoords + vec2(0, -size.y));

	float outline = tex1.a;
	outline += tex2.a;
	outline += tex3.a;
	outline += tex4.a;
	outline += maskSample(vTexCoords + vec2(-size.x, size.y)).a;
	outline += maskSample(vTexCoords + vec2(size.x, size.y)).a;
	outline += maskSample(vTexCoords + vec2(-size.x, -size.y)).a;
	outline += maskSample(vTexCoords + vec2(size.x, -size.y)).a;
	outline = aastep(1.0, outline);

	vec4 color = (tex + tex + tex1 + tex2 + tex3 + tex4) / 6.0;
	float grey = min((0.299 * color.r + 0.587 * color.g + 0.114 * color.b) * 2.6, 1.0);
	COLOR = mix(tex, vec4(0.2 * grey, 0.2 + grey * 0.62, 0.6 + 0.2 * grey, outline * 0.95), COLOR.a);
	gl_FragColor = COLOR;
}

)__SHDR__";
#endif

	inline constexpr ShaderCompiler::Uniform FrozenMask_Uniforms[] = {
		{ "uProjectionMatrix", ShaderCompiler::UniformType::Mat4, 0 },
		{ "uViewMatrix", ShaderCompiler::UniformType::Mat4, 0 },
	};

	inline constexpr ShaderCompiler::BlockMember FrozenMask_Block0_Members[] = {
		{ "modelMatrix", ShaderCompiler::UniformType::Mat4, 0, 0 },
		{ "color", ShaderCompiler::UniformType::Vec4, 0, 64 },
		{ "texRect", ShaderCompiler::UniformType::Vec4, 0, 80 },
		{ "spriteSize", ShaderCompiler::UniformType::Vec2, 0, 96 },
		{ "palOffset", ShaderCompiler::UniformType::Float, 0, 104 },
	};

	inline constexpr ShaderCompiler::UniformBlock FrozenMask_Blocks[] = {
		{ "InstanceBlock", 112, 0, 5, FrozenMask_Block0_Members },
	};

	inline constexpr ShaderCompiler::TextureBinding FrozenMask_Textures[] = {
		{ "uTexture", 0 },
	};

#if defined(WITH_RHI_GL) && !defined(RHI_GL_PROFILE_ES2)
	inline constexpr char FrozenMask_USE_PALETTE_Vs[] =
R"__SHDR__(#define USE_PALETTE (1)
#line 1

uniform mat4 uProjectionMatrix;
uniform mat4 uViewMatrix;

layout (std140) uniform InstanceBlock
{
	mat4 modelMatrix;
	vec4 color;
	vec4 texRect;
	vec2 spriteSize;
	// Flat index into the palette texture (added to the per-pixel index for the palette lookup). Lands in the
	// std140 tail padding after spriteSize, so the block stays 112 bytes. Only read by palette shaders.
	float palOffset;
};

out vec2 vTexCoords;
out vec4 vColor;
out highp float vPaletteOffset;

void main()
{
	vec2 aPosition = vec2(1.0 - float(gl_VertexID >> 1), float(gl_VertexID % 2));
	vec4 position = vec4(aPosition.x * spriteSize.x, aPosition.y * spriteSize.y, 0.0, 1.0);

	gl_Position = uProjectionMatrix * uViewMatrix * modelMatrix * position;
	vTexCoords = vec2(aPosition.x * texRect.x + texRect.y, aPosition.y * texRect.z + texRect.w);
	vColor = color;
	vPaletteOffset = palOffset;
}
)__SHDR__";
#endif

#if defined(WITH_RHI_GL) && defined(RHI_GL_PROFILE_ES2)
	inline constexpr char FrozenMask_USE_PALETTE_Vs100[] =
R"__SHDR__(attribute vec2 aQuadCorner;
#define USE_PALETTE (1)
#line 1

uniform mat4 uProjectionMatrix;
uniform mat4 uViewMatrix;

	uniform mat4 modelMatrix;
	uniform vec4 color;
	uniform vec4 texRect;
	uniform vec2 spriteSize;
	// Flat index into the palette texture (added to the per-pixel index for the palette lookup). Lands in the
	// std140 tail padding after spriteSize, so the block stays 112 bytes. Only read by palette shaders.
	uniform float palOffset;

varying vec2 vTexCoords;
varying vec4 vColor;
varying highp float vPaletteOffset;

void main()
{
	vec2 aPosition = vec2(1.0 - (1.0 - aQuadCorner.x), aQuadCorner.y);
	vec4 position = vec4(aPosition.x * spriteSize.x, aPosition.y * spriteSize.y, 0.0, 1.0);

	gl_Position = uProjectionMatrix * uViewMatrix * modelMatrix * position;
	vTexCoords = vec2(aPosition.x * texRect.x + texRect.y, aPosition.y * texRect.z + texRect.w);
	vColor = color;
	vPaletteOffset = palOffset;
}
)__SHDR__";
#endif

#if defined(WITH_RHI_GL) && !defined(RHI_GL_PROFILE_ES2)
	inline constexpr char FrozenMask_USE_PALETTE_Fs[] =
R"__SHDR__(#define USE_PALETTE (1)
#line 1

#ifdef GL_ES
precision mediump float;
#endif

in vec2 vTexCoords;
in vec4 vColor;
in highp float vPaletteOffset;

uniform sampler2D uTexture;
#ifdef USE_PALETTE
uniform sampler2D uTexturePalette;
#endif

float aastep(float threshold, float value) {
	float afwidth = length(vec2(dFdx(value), dFdy(value))) * 0.70710678118654757;
	return smoothstep(threshold - afwidth, threshold + afwidth, value);
}

vec4 maskSample(vec2 uv) {
	vec4 src = texture(uTexture, uv);
#ifdef USE_PALETTE
	highp float palIndex = floor(vPaletteOffset + 0.5) + floor(src.r * 255.0 + 0.5);
	highp float palX = (mod(palIndex, 256.0) + 0.5) / 256.0;
	highp float palY = (floor(palIndex / 256.0) + 0.5) / 256.0;
	vec4 c = texture(uTexturePalette, vec2(palX, palY));
	return vec4(c.rgb, c.a * src.a);
#else
	return src;
#endif
}

out vec4 COLOR;

void main() {
	COLOR = vColor;
	vec2 size = COLOR.xy * COLOR.a * 2.0;

	vec4 tex = maskSample(vTexCoords);
	vec4 tex1 = maskSample(vTexCoords + vec2(-size.x, 0));
	vec4 tex2 = maskSample(vTexCoords + vec2(0, size.y));
	vec4 tex3 = maskSample(vTexCoords + vec2(size.x, 0));
	vec4 tex4 = maskSample(vTexCoords + vec2(0, -size.y));

	float outline = tex1.a;
	outline += tex2.a;
	outline += tex3.a;
	outline += tex4.a;
	outline += maskSample(vTexCoords + vec2(-size.x, size.y)).a;
	outline += maskSample(vTexCoords + vec2(size.x, size.y)).a;
	outline += maskSample(vTexCoords + vec2(-size.x, -size.y)).a;
	outline += maskSample(vTexCoords + vec2(size.x, -size.y)).a;
	outline = aastep(1.0, outline);

	vec4 color = (tex + tex + tex1 + tex2 + tex3 + tex4) / 6.0;
	float grey = min((0.299 * color.r + 0.587 * color.g + 0.114 * color.b) * 2.6, 1.0);
	COLOR = mix(tex, vec4(0.2 * grey, 0.2 + grey * 0.62, 0.6 + 0.2 * grey, outline * 0.95), COLOR.a);
}

)__SHDR__";
#endif

#if defined(WITH_RHI_GL) && defined(RHI_GL_PROFILE_ES2)
	inline constexpr char FrozenMask_USE_PALETTE_Fs100[] =
R"__SHDR__(#extension GL_OES_standard_derivatives : enable
#define USE_PALETTE (1)
#line 1

precision mediump float;

varying vec2 vTexCoords;
varying vec4 vColor;
varying highp float vPaletteOffset;

uniform sampler2D uTexture;
#ifdef USE_PALETTE
uniform sampler2D uTexturePalette;
#endif

float aastep(float threshold, float value) {
	float afwidth = length(vec2(dFdx(value), dFdy(value))) * 0.70710678118654757;
	return smoothstep(threshold - afwidth, threshold + afwidth, value);
}

vec4 maskSample(vec2 uv) {
	vec4 src = texture2D(uTexture, uv);
#ifdef USE_PALETTE
	highp float palIndex = floor(vPaletteOffset + 0.5) + floor(src.r * 255.0 + 0.5);
	highp float palX = (mod(palIndex, 256.0) + 0.5) / 256.0;
	highp float palY = (floor(palIndex / 256.0) + 0.5) / 256.0;
	vec4 c = texture2D(uTexturePalette, vec2(palX, palY));
	return vec4(c.rgb, c.a * src.a);
#else
	return src;
#endif
}


void main() {
	vec4 COLOR;
	COLOR = vColor;
	vec2 size = COLOR.xy * COLOR.a * 2.0;

	vec4 tex = maskSample(vTexCoords);
	vec4 tex1 = maskSample(vTexCoords + vec2(-size.x, 0));
	vec4 tex2 = maskSample(vTexCoords + vec2(0, size.y));
	vec4 tex3 = maskSample(vTexCoords + vec2(size.x, 0));
	vec4 tex4 = maskSample(vTexCoords + vec2(0, -size.y));

	float outline = tex1.a;
	outline += tex2.a;
	outline += tex3.a;
	outline += tex4.a;
	outline += maskSample(vTexCoords + vec2(-size.x, size.y)).a;
	outline += maskSample(vTexCoords + vec2(size.x, size.y)).a;
	outline += maskSample(vTexCoords + vec2(-size.x, -size.y)).a;
	outline += maskSample(vTexCoords + vec2(size.x, -size.y)).a;
	outline = aastep(1.0, outline);

	vec4 color = (tex + tex + tex1 + tex2 + tex3 + tex4) / 6.0;
	float grey = min((0.299 * color.r + 0.587 * color.g + 0.114 * color.b) * 2.6, 1.0);
	COLOR = mix(tex, vec4(0.2 * grey, 0.2 + grey * 0.62, 0.6 + 0.2 * grey, outline * 0.95), COLOR.a);
	gl_FragColor = COLOR;
}

)__SHDR__";
#endif

	inline constexpr ShaderCompiler::Uniform FrozenMask_USE_PALETTE_Uniforms[] = {
		{ "uProjectionMatrix", ShaderCompiler::UniformType::Mat4, 0 },
		{ "uViewMatrix", ShaderCompiler::UniformType::Mat4, 0 },
	};

	inline constexpr ShaderCompiler::BlockMember FrozenMask_USE_PALETTE_Block0_Members[] = {
		{ "modelMatrix", ShaderCompiler::UniformType::Mat4, 0, 0 },
		{ "color", ShaderCompiler::UniformType::Vec4, 0, 64 },
		{ "texRect", ShaderCompiler::UniformType::Vec4, 0, 80 },
		{ "spriteSize", ShaderCompiler::UniformType::Vec2, 0, 96 },
		{ "palOffset", ShaderCompiler::UniformType::Float, 0, 104 },
	};

	inline constexpr ShaderCompiler::UniformBlock FrozenMask_USE_PALETTE_Blocks[] = {
		{ "InstanceBlock", 112, 0, 5, FrozenMask_USE_PALETTE_Block0_Members },
	};

	inline constexpr ShaderCompiler::TextureBinding FrozenMask_USE_PALETTE_Textures[] = {
		{ "uTexture", 0 },
		{ "uTexturePalette", 1 },
	};

	inline constexpr ShaderCompiler::ProgramVariant FrozenMask_Variants[] = {
		{ "", "",
#if defined(WITH_RHI_GL) && !defined(RHI_GL_PROFILE_ES2)
			FrozenMask_Vs, FrozenMask_Fs,
#else
			nullptr, nullptr,
#endif
			2, FrozenMask_Uniforms, 1, FrozenMask_Blocks, 1, FrozenMask_Textures, 0, nullptr,
#if defined(WITH_RHI_GL) && defined(RHI_GL_PROFILE_ES2)
			FrozenMask_Vs100, FrozenMask_Fs100,
#else
			nullptr, nullptr,
#endif
#if defined(WITH_RHI_D3D11)
			FrozenMask_VsHlsl, FrozenMask_FsHlsl,
			FrozenMask_VsDxbc, FrozenMask_VsDxbcSize, FrozenMask_FsDxbc, FrozenMask_FsDxbcSize,
#else
			nullptr, nullptr,
			nullptr, 0, nullptr, 0,
#endif
#if defined(WITH_RHI_VULKAN)
			FrozenMask_VkVs, FrozenMask_VkVsSize, FrozenMask_VkFs, FrozenMask_VkFsSize },
#else
			nullptr, 0, nullptr, 0 },
#endif
		{ "USE_PALETTE", "USE_PALETTE",
#if defined(WITH_RHI_GL) && !defined(RHI_GL_PROFILE_ES2)
			FrozenMask_USE_PALETTE_Vs, FrozenMask_USE_PALETTE_Fs,
#else
			nullptr, nullptr,
#endif
			2, FrozenMask_USE_PALETTE_Uniforms, 1, FrozenMask_USE_PALETTE_Blocks, 2, FrozenMask_USE_PALETTE_Textures, 0, nullptr,
#if defined(WITH_RHI_GL) && defined(RHI_GL_PROFILE_ES2)
			FrozenMask_USE_PALETTE_Vs100, FrozenMask_USE_PALETTE_Fs100,
#else
			nullptr, nullptr,
#endif
#if defined(WITH_RHI_D3D11)
			FrozenMask_USE_PALETTE_VsHlsl, FrozenMask_USE_PALETTE_FsHlsl,
			FrozenMask_USE_PALETTE_VsDxbc, FrozenMask_USE_PALETTE_VsDxbcSize, FrozenMask_USE_PALETTE_FsDxbc, FrozenMask_USE_PALETTE_FsDxbcSize,
#else
			nullptr, nullptr,
			nullptr, 0, nullptr, 0,
#endif
#if defined(WITH_RHI_VULKAN)
			FrozenMask_USE_PALETTE_VkVs, FrozenMask_USE_PALETTE_VkVsSize, FrozenMask_USE_PALETTE_VkFs, FrozenMask_USE_PALETTE_VkFsSize },
#else
			nullptr, 0, nullptr, 0 },
#endif
	};

	inline constexpr ShaderCompiler::Program FrozenMask = { "FrozenMask", 0, 2, FrozenMask_Variants };

#if defined(WITH_RHI_GL) && !defined(RHI_GL_PROFILE_ES2)
	inline constexpr char BatchedFrozenMask_Vs[] =
R"__SHDR__(#line 1

uniform mat4 uProjectionMatrix;
uniform mat4 uViewMatrix;

struct Instance
{
	mat4 modelMatrix;
	vec4 color;
	vec4 texRect;
	vec2 spriteSize;
	// Flat index into the palette texture; lands in the std140 tail padding, so the stride stays 112 bytes
	float palOffset;
};

layout (std140) uniform InstancesBlock
{
#ifndef BATCH_SIZE
	#define BATCH_SIZE (585) // 64 Kb / 112 b
#endif
	Instance[BATCH_SIZE] instances;
} block;

out vec2 vTexCoords;
out vec4 vColor;
out highp float vPaletteOffset;

#define i block.instances[gl_VertexID / 6]

void main()
{
	vec2 aPosition = vec2(1.0 - float(((gl_VertexID + 2) / 3) % 2), 1.0 - float(((gl_VertexID + 1) / 3) % 2));
	vec4 position = vec4(aPosition.x * i.spriteSize.x, aPosition.y * i.spriteSize.y, 0.0, 1.0);

	gl_Position = uProjectionMatrix * uViewMatrix * i.modelMatrix * position;
	vTexCoords = vec2(aPosition.x * i.texRect.x + i.texRect.y, aPosition.y * i.texRect.z + i.texRect.w);
	vColor = i.color;
	vPaletteOffset = i.palOffset;
}
)__SHDR__";
#endif

#if defined(WITH_RHI_GL) && defined(RHI_GL_PROFILE_ES2)
	inline constexpr char BatchedFrozenMask_Vs100[] =
R"__SHDR__(attribute vec2 aQuadCorner;
attribute float aInstanceIndex;
#line 1

uniform mat4 uProjectionMatrix;
uniform mat4 uViewMatrix;

struct Instance
{
	mat4 modelMatrix;
	vec4 color;
	vec4 texRect;
	vec2 spriteSize;
	// Flat index into the palette texture; lands in the std140 tail padding, so the stride stays 112 bytes
	float palOffset;
};

#ifndef BATCH_SIZE
	#define BATCH_SIZE (585) // 64 Kb / 112 b
#endif
	uniform Instance instances[BATCH_SIZE];

varying vec2 vTexCoords;
varying vec4 vColor;
varying highp float vPaletteOffset;

#define i instances[int(aInstanceIndex)]

void main()
{
	vec2 aPosition = vec2(1.0 - (1.0 - aQuadCorner.x), 1.0 - (1.0 - aQuadCorner.y));
	vec4 position = vec4(aPosition.x * i.spriteSize.x, aPosition.y * i.spriteSize.y, 0.0, 1.0);

	gl_Position = uProjectionMatrix * uViewMatrix * i.modelMatrix * position;
	vTexCoords = vec2(aPosition.x * i.texRect.x + i.texRect.y, aPosition.y * i.texRect.z + i.texRect.w);
	vColor = i.color;
	vPaletteOffset = i.palOffset;
}
)__SHDR__";
#endif

#if defined(WITH_RHI_GL) && !defined(RHI_GL_PROFILE_ES2)
	inline constexpr char BatchedFrozenMask_Fs[] =
R"__SHDR__(#line 1

#ifdef GL_ES
precision mediump float;
#endif

in vec2 vTexCoords;
in vec4 vColor;
in highp float vPaletteOffset;

uniform sampler2D uTexture;
#ifdef USE_PALETTE
uniform sampler2D uTexturePalette;
#endif

float aastep(float threshold, float value) {
	float afwidth = length(vec2(dFdx(value), dFdy(value))) * 0.70710678118654757;
	return smoothstep(threshold - afwidth, threshold + afwidth, value);
}

vec4 maskSample(vec2 uv) {
	vec4 src = texture(uTexture, uv);
#ifdef USE_PALETTE
	highp float palIndex = floor(vPaletteOffset + 0.5) + floor(src.r * 255.0 + 0.5);
	highp float palX = (mod(palIndex, 256.0) + 0.5) / 256.0;
	highp float palY = (floor(palIndex / 256.0) + 0.5) / 256.0;
	vec4 c = texture(uTexturePalette, vec2(palX, palY));
	return vec4(c.rgb, c.a * src.a);
#else
	return src;
#endif
}

out vec4 COLOR;

void main() {
	COLOR = vColor;
	vec2 size = COLOR.xy * COLOR.a * 2.0;

	vec4 tex = maskSample(vTexCoords);
	vec4 tex1 = maskSample(vTexCoords + vec2(-size.x, 0));
	vec4 tex2 = maskSample(vTexCoords + vec2(0, size.y));
	vec4 tex3 = maskSample(vTexCoords + vec2(size.x, 0));
	vec4 tex4 = maskSample(vTexCoords + vec2(0, -size.y));

	float outline = tex1.a;
	outline += tex2.a;
	outline += tex3.a;
	outline += tex4.a;
	outline += maskSample(vTexCoords + vec2(-size.x, size.y)).a;
	outline += maskSample(vTexCoords + vec2(size.x, size.y)).a;
	outline += maskSample(vTexCoords + vec2(-size.x, -size.y)).a;
	outline += maskSample(vTexCoords + vec2(size.x, -size.y)).a;
	outline = aastep(1.0, outline);

	vec4 color = (tex + tex + tex1 + tex2 + tex3 + tex4) / 6.0;
	float grey = min((0.299 * color.r + 0.587 * color.g + 0.114 * color.b) * 2.6, 1.0);
	COLOR = mix(tex, vec4(0.2 * grey, 0.2 + grey * 0.62, 0.6 + 0.2 * grey, outline * 0.95), COLOR.a);
}

)__SHDR__";
#endif

#if defined(WITH_RHI_GL) && defined(RHI_GL_PROFILE_ES2)
	inline constexpr char BatchedFrozenMask_Fs100[] =
R"__SHDR__(#extension GL_OES_standard_derivatives : enable
#line 1

precision mediump float;

varying vec2 vTexCoords;
varying vec4 vColor;
varying highp float vPaletteOffset;

uniform sampler2D uTexture;
#ifdef USE_PALETTE
uniform sampler2D uTexturePalette;
#endif

float aastep(float threshold, float value) {
	float afwidth = length(vec2(dFdx(value), dFdy(value))) * 0.70710678118654757;
	return smoothstep(threshold - afwidth, threshold + afwidth, value);
}

vec4 maskSample(vec2 uv) {
	vec4 src = texture2D(uTexture, uv);
#ifdef USE_PALETTE
	highp float palIndex = floor(vPaletteOffset + 0.5) + floor(src.r * 255.0 + 0.5);
	highp float palX = (mod(palIndex, 256.0) + 0.5) / 256.0;
	highp float palY = (floor(palIndex / 256.0) + 0.5) / 256.0;
	vec4 c = texture2D(uTexturePalette, vec2(palX, palY));
	return vec4(c.rgb, c.a * src.a);
#else
	return src;
#endif
}


void main() {
	vec4 COLOR;
	COLOR = vColor;
	vec2 size = COLOR.xy * COLOR.a * 2.0;

	vec4 tex = maskSample(vTexCoords);
	vec4 tex1 = maskSample(vTexCoords + vec2(-size.x, 0));
	vec4 tex2 = maskSample(vTexCoords + vec2(0, size.y));
	vec4 tex3 = maskSample(vTexCoords + vec2(size.x, 0));
	vec4 tex4 = maskSample(vTexCoords + vec2(0, -size.y));

	float outline = tex1.a;
	outline += tex2.a;
	outline += tex3.a;
	outline += tex4.a;
	outline += maskSample(vTexCoords + vec2(-size.x, size.y)).a;
	outline += maskSample(vTexCoords + vec2(size.x, size.y)).a;
	outline += maskSample(vTexCoords + vec2(-size.x, -size.y)).a;
	outline += maskSample(vTexCoords + vec2(size.x, -size.y)).a;
	outline = aastep(1.0, outline);

	vec4 color = (tex + tex + tex1 + tex2 + tex3 + tex4) / 6.0;
	float grey = min((0.299 * color.r + 0.587 * color.g + 0.114 * color.b) * 2.6, 1.0);
	COLOR = mix(tex, vec4(0.2 * grey, 0.2 + grey * 0.62, 0.6 + 0.2 * grey, outline * 0.95), COLOR.a);
	gl_FragColor = COLOR;
}

)__SHDR__";
#endif

	inline constexpr ShaderCompiler::Uniform BatchedFrozenMask_Uniforms[] = {
		{ "uProjectionMatrix", ShaderCompiler::UniformType::Mat4, 0 },
		{ "uViewMatrix", ShaderCompiler::UniformType::Mat4, 0 },
	};

	inline constexpr ShaderCompiler::BlockMember BatchedFrozenMask_Block0_Members[] = {
		{ "instances", ShaderCompiler::UniformType::Struct, ShaderCompiler::SymbolicArraySize, 0 },
	};

	inline constexpr ShaderCompiler::UniformBlock BatchedFrozenMask_Blocks[] = {
		{ "InstancesBlock", 0, 112, 1, BatchedFrozenMask_Block0_Members },
	};

	inline constexpr ShaderCompiler::TextureBinding BatchedFrozenMask_Textures[] = {
		{ "uTexture", 0 },
	};

#if defined(WITH_RHI_GL) && !defined(RHI_GL_PROFILE_ES2)
	inline constexpr char BatchedFrozenMask_USE_PALETTE_Vs[] =
R"__SHDR__(#define USE_PALETTE (1)
#line 1

uniform mat4 uProjectionMatrix;
uniform mat4 uViewMatrix;

struct Instance
{
	mat4 modelMatrix;
	vec4 color;
	vec4 texRect;
	vec2 spriteSize;
	// Flat index into the palette texture; lands in the std140 tail padding, so the stride stays 112 bytes
	float palOffset;
};

layout (std140) uniform InstancesBlock
{
#ifndef BATCH_SIZE
	#define BATCH_SIZE (585) // 64 Kb / 112 b
#endif
	Instance[BATCH_SIZE] instances;
} block;

out vec2 vTexCoords;
out vec4 vColor;
out highp float vPaletteOffset;

#define i block.instances[gl_VertexID / 6]

void main()
{
	vec2 aPosition = vec2(1.0 - float(((gl_VertexID + 2) / 3) % 2), 1.0 - float(((gl_VertexID + 1) / 3) % 2));
	vec4 position = vec4(aPosition.x * i.spriteSize.x, aPosition.y * i.spriteSize.y, 0.0, 1.0);

	gl_Position = uProjectionMatrix * uViewMatrix * i.modelMatrix * position;
	vTexCoords = vec2(aPosition.x * i.texRect.x + i.texRect.y, aPosition.y * i.texRect.z + i.texRect.w);
	vColor = i.color;
	vPaletteOffset = i.palOffset;
}
)__SHDR__";
#endif

#if defined(WITH_RHI_GL) && defined(RHI_GL_PROFILE_ES2)
	inline constexpr char BatchedFrozenMask_USE_PALETTE_Vs100[] =
R"__SHDR__(attribute vec2 aQuadCorner;
attribute float aInstanceIndex;
#define USE_PALETTE (1)
#line 1

uniform mat4 uProjectionMatrix;
uniform mat4 uViewMatrix;

struct Instance
{
	mat4 modelMatrix;
	vec4 color;
	vec4 texRect;
	vec2 spriteSize;
	// Flat index into the palette texture; lands in the std140 tail padding, so the stride stays 112 bytes
	float palOffset;
};

#ifndef BATCH_SIZE
	#define BATCH_SIZE (585) // 64 Kb / 112 b
#endif
	uniform Instance instances[BATCH_SIZE];

varying vec2 vTexCoords;
varying vec4 vColor;
varying highp float vPaletteOffset;

#define i instances[int(aInstanceIndex)]

void main()
{
	vec2 aPosition = vec2(1.0 - (1.0 - aQuadCorner.x), 1.0 - (1.0 - aQuadCorner.y));
	vec4 position = vec4(aPosition.x * i.spriteSize.x, aPosition.y * i.spriteSize.y, 0.0, 1.0);

	gl_Position = uProjectionMatrix * uViewMatrix * i.modelMatrix * position;
	vTexCoords = vec2(aPosition.x * i.texRect.x + i.texRect.y, aPosition.y * i.texRect.z + i.texRect.w);
	vColor = i.color;
	vPaletteOffset = i.palOffset;
}
)__SHDR__";
#endif

#if defined(WITH_RHI_GL) && !defined(RHI_GL_PROFILE_ES2)
	inline constexpr char BatchedFrozenMask_USE_PALETTE_Fs[] =
R"__SHDR__(#define USE_PALETTE (1)
#line 1

#ifdef GL_ES
precision mediump float;
#endif

in vec2 vTexCoords;
in vec4 vColor;
in highp float vPaletteOffset;

uniform sampler2D uTexture;
#ifdef USE_PALETTE
uniform sampler2D uTexturePalette;
#endif

float aastep(float threshold, float value) {
	float afwidth = length(vec2(dFdx(value), dFdy(value))) * 0.70710678118654757;
	return smoothstep(threshold - afwidth, threshold + afwidth, value);
}

vec4 maskSample(vec2 uv) {
	vec4 src = texture(uTexture, uv);
#ifdef USE_PALETTE
	highp float palIndex = floor(vPaletteOffset + 0.5) + floor(src.r * 255.0 + 0.5);
	highp float palX = (mod(palIndex, 256.0) + 0.5) / 256.0;
	highp float palY = (floor(palIndex / 256.0) + 0.5) / 256.0;
	vec4 c = texture(uTexturePalette, vec2(palX, palY));
	return vec4(c.rgb, c.a * src.a);
#else
	return src;
#endif
}

out vec4 COLOR;

void main() {
	COLOR = vColor;
	vec2 size = COLOR.xy * COLOR.a * 2.0;

	vec4 tex = maskSample(vTexCoords);
	vec4 tex1 = maskSample(vTexCoords + vec2(-size.x, 0));
	vec4 tex2 = maskSample(vTexCoords + vec2(0, size.y));
	vec4 tex3 = maskSample(vTexCoords + vec2(size.x, 0));
	vec4 tex4 = maskSample(vTexCoords + vec2(0, -size.y));

	float outline = tex1.a;
	outline += tex2.a;
	outline += tex3.a;
	outline += tex4.a;
	outline += maskSample(vTexCoords + vec2(-size.x, size.y)).a;
	outline += maskSample(vTexCoords + vec2(size.x, size.y)).a;
	outline += maskSample(vTexCoords + vec2(-size.x, -size.y)).a;
	outline += maskSample(vTexCoords + vec2(size.x, -size.y)).a;
	outline = aastep(1.0, outline);

	vec4 color = (tex + tex + tex1 + tex2 + tex3 + tex4) / 6.0;
	float grey = min((0.299 * color.r + 0.587 * color.g + 0.114 * color.b) * 2.6, 1.0);
	COLOR = mix(tex, vec4(0.2 * grey, 0.2 + grey * 0.62, 0.6 + 0.2 * grey, outline * 0.95), COLOR.a);
}

)__SHDR__";
#endif

#if defined(WITH_RHI_GL) && defined(RHI_GL_PROFILE_ES2)
	inline constexpr char BatchedFrozenMask_USE_PALETTE_Fs100[] =
R"__SHDR__(#extension GL_OES_standard_derivatives : enable
#define USE_PALETTE (1)
#line 1

precision mediump float;

varying vec2 vTexCoords;
varying vec4 vColor;
varying highp float vPaletteOffset;

uniform sampler2D uTexture;
#ifdef USE_PALETTE
uniform sampler2D uTexturePalette;
#endif

float aastep(float threshold, float value) {
	float afwidth = length(vec2(dFdx(value), dFdy(value))) * 0.70710678118654757;
	return smoothstep(threshold - afwidth, threshold + afwidth, value);
}

vec4 maskSample(vec2 uv) {
	vec4 src = texture2D(uTexture, uv);
#ifdef USE_PALETTE
	highp float palIndex = floor(vPaletteOffset + 0.5) + floor(src.r * 255.0 + 0.5);
	highp float palX = (mod(palIndex, 256.0) + 0.5) / 256.0;
	highp float palY = (floor(palIndex / 256.0) + 0.5) / 256.0;
	vec4 c = texture2D(uTexturePalette, vec2(palX, palY));
	return vec4(c.rgb, c.a * src.a);
#else
	return src;
#endif
}


void main() {
	vec4 COLOR;
	COLOR = vColor;
	vec2 size = COLOR.xy * COLOR.a * 2.0;

	vec4 tex = maskSample(vTexCoords);
	vec4 tex1 = maskSample(vTexCoords + vec2(-size.x, 0));
	vec4 tex2 = maskSample(vTexCoords + vec2(0, size.y));
	vec4 tex3 = maskSample(vTexCoords + vec2(size.x, 0));
	vec4 tex4 = maskSample(vTexCoords + vec2(0, -size.y));

	float outline = tex1.a;
	outline += tex2.a;
	outline += tex3.a;
	outline += tex4.a;
	outline += maskSample(vTexCoords + vec2(-size.x, size.y)).a;
	outline += maskSample(vTexCoords + vec2(size.x, size.y)).a;
	outline += maskSample(vTexCoords + vec2(-size.x, -size.y)).a;
	outline += maskSample(vTexCoords + vec2(size.x, -size.y)).a;
	outline = aastep(1.0, outline);

	vec4 color = (tex + tex + tex1 + tex2 + tex3 + tex4) / 6.0;
	float grey = min((0.299 * color.r + 0.587 * color.g + 0.114 * color.b) * 2.6, 1.0);
	COLOR = mix(tex, vec4(0.2 * grey, 0.2 + grey * 0.62, 0.6 + 0.2 * grey, outline * 0.95), COLOR.a);
	gl_FragColor = COLOR;
}

)__SHDR__";
#endif

	inline constexpr ShaderCompiler::Uniform BatchedFrozenMask_USE_PALETTE_Uniforms[] = {
		{ "uProjectionMatrix", ShaderCompiler::UniformType::Mat4, 0 },
		{ "uViewMatrix", ShaderCompiler::UniformType::Mat4, 0 },
	};

	inline constexpr ShaderCompiler::BlockMember BatchedFrozenMask_USE_PALETTE_Block0_Members[] = {
		{ "instances", ShaderCompiler::UniformType::Struct, ShaderCompiler::SymbolicArraySize, 0 },
	};

	inline constexpr ShaderCompiler::UniformBlock BatchedFrozenMask_USE_PALETTE_Blocks[] = {
		{ "InstancesBlock", 0, 112, 1, BatchedFrozenMask_USE_PALETTE_Block0_Members },
	};

	inline constexpr ShaderCompiler::TextureBinding BatchedFrozenMask_USE_PALETTE_Textures[] = {
		{ "uTexture", 0 },
		{ "uTexturePalette", 1 },
	};

	inline constexpr ShaderCompiler::ProgramVariant BatchedFrozenMask_Variants[] = {
		{ "", "",
#if defined(WITH_RHI_GL) && !defined(RHI_GL_PROFILE_ES2)
			BatchedFrozenMask_Vs, BatchedFrozenMask_Fs,
#else
			nullptr, nullptr,
#endif
			2, BatchedFrozenMask_Uniforms, 1, BatchedFrozenMask_Blocks, 1, BatchedFrozenMask_Textures, 0, nullptr,
#if defined(WITH_RHI_GL) && defined(RHI_GL_PROFILE_ES2)
			BatchedFrozenMask_Vs100, BatchedFrozenMask_Fs100,
#else
			nullptr, nullptr,
#endif
#if defined(WITH_RHI_D3D11)
			BatchedFrozenMask_VsHlsl, BatchedFrozenMask_FsHlsl,
			BatchedFrozenMask_VsDxbc, BatchedFrozenMask_VsDxbcSize, BatchedFrozenMask_FsDxbc, BatchedFrozenMask_FsDxbcSize,
#else
			nullptr, nullptr,
			nullptr, 0, nullptr, 0,
#endif
#if defined(WITH_RHI_VULKAN)
			BatchedFrozenMask_VkVs, BatchedFrozenMask_VkVsSize, BatchedFrozenMask_VkFs, BatchedFrozenMask_VkFsSize },
#else
			nullptr, 0, nullptr, 0 },
#endif
		{ "USE_PALETTE", "USE_PALETTE",
#if defined(WITH_RHI_GL) && !defined(RHI_GL_PROFILE_ES2)
			BatchedFrozenMask_USE_PALETTE_Vs, BatchedFrozenMask_USE_PALETTE_Fs,
#else
			nullptr, nullptr,
#endif
			2, BatchedFrozenMask_USE_PALETTE_Uniforms, 1, BatchedFrozenMask_USE_PALETTE_Blocks, 2, BatchedFrozenMask_USE_PALETTE_Textures, 0, nullptr,
#if defined(WITH_RHI_GL) && defined(RHI_GL_PROFILE_ES2)
			BatchedFrozenMask_USE_PALETTE_Vs100, BatchedFrozenMask_USE_PALETTE_Fs100,
#else
			nullptr, nullptr,
#endif
#if defined(WITH_RHI_D3D11)
			BatchedFrozenMask_USE_PALETTE_VsHlsl, BatchedFrozenMask_USE_PALETTE_FsHlsl,
			BatchedFrozenMask_USE_PALETTE_VsDxbc, BatchedFrozenMask_USE_PALETTE_VsDxbcSize, BatchedFrozenMask_USE_PALETTE_FsDxbc, BatchedFrozenMask_USE_PALETTE_FsDxbcSize,
#else
			nullptr, nullptr,
			nullptr, 0, nullptr, 0,
#endif
#if defined(WITH_RHI_VULKAN)
			BatchedFrozenMask_USE_PALETTE_VkVs, BatchedFrozenMask_USE_PALETTE_VkVsSize, BatchedFrozenMask_USE_PALETTE_VkFs, BatchedFrozenMask_USE_PALETTE_VkFsSize },
#else
			nullptr, 0, nullptr, 0 },
#endif
	};

	inline constexpr ShaderCompiler::Program BatchedFrozenMask = { "BatchedFrozenMask", 0, 2, BatchedFrozenMask_Variants };
}
#endif
