// Generated by ShaderCompiler from CombineWithWaterLow.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 CombineWithWaterLow_Vs[] =
R"__SHDR__(#line 1

out vec2 vTexCoords;
out vec2 vViewSizeInv;

uniform mat4 uProjectionMatrix;
uniform mat4 uViewMatrix;

layout (std140) uniform InstanceBlock
{
	mat4 modelMatrix;
	vec4 color;
	vec4 texRect;
	vec2 spriteSize;
};



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);
	vViewSizeInv = vec2(1.0) / spriteSize;
}
)__SHDR__";
#endif

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

varying vec2 vTexCoords;
varying vec2 vViewSizeInv;

uniform mat4 uProjectionMatrix;
uniform mat4 uViewMatrix;

	uniform mat4 modelMatrix;
	uniform vec4 color;
	uniform vec4 texRect;
	uniform vec2 spriteSize;



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);
	vViewSizeInv = vec2(1.0) / spriteSize;
}
)__SHDR__";
#endif

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

#ifdef GL_ES
precision mediump float;
#endif

in vec2 vTexCoords;
in vec2 vViewSizeInv;

uniform sampler2D uTexture;
uniform sampler2D uTextureLighting;
uniform sampler2D uTextureBlurHalf;
uniform sampler2D uTextureBlurQuarter;

uniform vec4 uAmbientColor;
uniform float uTime;
uniform vec2 uCameraPos;
uniform float uWaterLevel;

vec2 hash2D(in vec2 p) {
	float h = dot(p, vec2(12.9898, 78.233));
	float h2 = dot(p, vec2(37.271, 377.632));
	return -1.0 + 2.0 * vec2(fract(sin(h) * 43758.5453), fract(sin(h2) * 43758.5453));
}

vec2 noiseTexCoords(vec2 position) {
	vec2 seed = position + fract(uTime * 0.01);
	return clamp(position + hash2D(seed) * vViewSizeInv * 1.4, vec2(0.0), vec2(1.0));
}

out vec4 COLOR;

void main() {
	vec3 waterColor = vec3(0.4, 0.6, 0.8);

	vec2 uvLocal = vTexCoords;
	vec2 uvWorldCenter = (uCameraPos.xy * vViewSizeInv.xy);
	vec2 uvWorld = uvLocal + uvWorldCenter;

	float isTexelBelow = 1.0 - step(uvLocal.y, uWaterLevel);
	float isTexelAbove = 1.0 - isTexelBelow;

	vec2 uv = clamp(uvLocal + vec2(0.008 * sin(uTime * 16.0 + uvWorld.y * 20.0) * isTexelBelow, 0.0), vec2(0.0), vec2(1.0));
	vec4 main = texture(uTexture, uv);

	// Waves
	float topDist = abs(uvLocal.y - uWaterLevel);
	float topGradient = max(1.0 - topDist, 0.0);
	float isNearTop = 0.2 * topGradient * topGradient;
	float isVeryNearTop = 1.0 - step(vViewSizeInv.y, topDist);
	main.rgb = mix(main.rgb, waterColor, vec3(isTexelBelow * 0.4)) + vec3((isNearTop + 0.2 * isVeryNearTop) * isTexelBelow);

	// Lighting
	vec4 blur1 = texture(uTextureBlurHalf, uv);
	vec4 blur2 = texture(uTextureBlurQuarter, uv);
	vec4 light = texture(uTextureLighting, noiseTexCoords(uv));

	vec4 blur = (blur1 + blur2) * vec4(0.5);

	float gray = dot(blur.rgb, vec3(0.299, 0.587, 0.114));
	blur = vec4(gray, gray, gray, blur.a);

	float darknessStrength = (1.0 - light.r);

	// Darkness above water
	if (uWaterLevel < 0.4) {
		float aboveWaterDarkness = isTexelAbove * (0.4 - uWaterLevel);
		darknessStrength = min(1.0, darknessStrength + aboveWaterDarkness);
	}

	COLOR = mix(mix(
		main * (1.0 + light.g) + max(light.g - 0.7, 0.0) * vec4(1.0),
		blur,
		vec4(clamp((1.0 - light.r) / sqrt(max(uAmbientColor.w, 0.35)), 0.0, 1.0))
	), uAmbientColor, vec4(darknessStrength));
	COLOR.a = 1.0;
}

)__SHDR__";
#endif

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

precision mediump float;

varying vec2 vTexCoords;
varying vec2 vViewSizeInv;

uniform sampler2D uTexture;
uniform sampler2D uTextureLighting;
uniform sampler2D uTextureBlurHalf;
uniform sampler2D uTextureBlurQuarter;

uniform vec4 uAmbientColor;
uniform float uTime;
uniform vec2 uCameraPos;
uniform float uWaterLevel;

vec2 hash2D(in vec2 p) {
	float h = dot(p, vec2(12.9898, 78.233));
	float h2 = dot(p, vec2(37.271, 377.632));
	return -1.0 + 2.0 * vec2(fract(sin(h) * 43758.5453), fract(sin(h2) * 43758.5453));
}

vec2 noiseTexCoords(vec2 position) {
	vec2 seed = position + fract(uTime * 0.01);
	return clamp(position + hash2D(seed) * vViewSizeInv * 1.4, vec2(0.0), vec2(1.0));
}


void main() {
	vec4 COLOR;
	vec3 waterColor = vec3(0.4, 0.6, 0.8);

	vec2 uvLocal = vTexCoords;
	vec2 uvWorldCenter = (uCameraPos.xy * vViewSizeInv.xy);
	vec2 uvWorld = uvLocal + uvWorldCenter;

	float isTexelBelow = 1.0 - step(uvLocal.y, uWaterLevel);
	float isTexelAbove = 1.0 - isTexelBelow;

	vec2 uv = clamp(uvLocal + vec2(0.008 * sin(uTime * 16.0 + uvWorld.y * 20.0) * isTexelBelow, 0.0), vec2(0.0), vec2(1.0));
	vec4 main = texture2D(uTexture, uv);

	// Waves
	float topDist = abs(uvLocal.y - uWaterLevel);
	float topGradient = max(1.0 - topDist, 0.0);
	float isNearTop = 0.2 * topGradient * topGradient;
	float isVeryNearTop = 1.0 - step(vViewSizeInv.y, topDist);
	main.rgb = mix(main.rgb, waterColor, vec3(isTexelBelow * 0.4)) + vec3((isNearTop + 0.2 * isVeryNearTop) * isTexelBelow);

	// Lighting
	vec4 blur1 = texture2D(uTextureBlurHalf, uv);
	vec4 blur2 = texture2D(uTextureBlurQuarter, uv);
	vec4 light = texture2D(uTextureLighting, noiseTexCoords(uv));

	vec4 blur = (blur1 + blur2) * vec4(0.5);

	float gray = dot(blur.rgb, vec3(0.299, 0.587, 0.114));
	blur = vec4(gray, gray, gray, blur.a);

	float darknessStrength = (1.0 - light.r);

	// Darkness above water
	if (uWaterLevel < 0.4) {
		float aboveWaterDarkness = isTexelAbove * (0.4 - uWaterLevel);
		darknessStrength = min(1.0, darknessStrength + aboveWaterDarkness);
	}

	COLOR = mix(mix(
		main * (1.0 + light.g) + max(light.g - 0.7, 0.0) * vec4(1.0),
		blur,
		vec4(clamp((1.0 - light.r) / sqrt(max(uAmbientColor.w, 0.35)), 0.0, 1.0))
	), uAmbientColor, vec4(darknessStrength));
	COLOR.a = 1.0;
	gl_FragColor = COLOR;
}

)__SHDR__";
#endif

	inline constexpr ShaderCompiler::Uniform CombineWithWaterLow_Uniforms[] = {
		{ "uProjectionMatrix", ShaderCompiler::UniformType::Mat4, 0 },
		{ "uViewMatrix", ShaderCompiler::UniformType::Mat4, 0 },
		{ "uAmbientColor", ShaderCompiler::UniformType::Vec4, 0 },
		{ "uTime", ShaderCompiler::UniformType::Float, 0 },
		{ "uCameraPos", ShaderCompiler::UniformType::Vec2, 0 },
		{ "uWaterLevel", ShaderCompiler::UniformType::Float, 0 },
	};

	inline constexpr ShaderCompiler::BlockMember CombineWithWaterLow_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 },
	};

	inline constexpr ShaderCompiler::UniformBlock CombineWithWaterLow_Blocks[] = {
		{ "InstanceBlock", 112, 0, 4, CombineWithWaterLow_Block0_Members },
	};

	inline constexpr ShaderCompiler::TextureBinding CombineWithWaterLow_Textures[] = {
		{ "uTexture", 0 },
		{ "uTextureLighting", 1 },
		{ "uTextureBlurHalf", 2 },
		{ "uTextureBlurQuarter", 3 },
	};

	inline constexpr ShaderCompiler::ProgramVariant CombineWithWaterLow_Variants[] = {
		{ "", "",
#if defined(WITH_RHI_GL) && !defined(RHI_GL_PROFILE_ES2)
			CombineWithWaterLow_Vs, CombineWithWaterLow_Fs,
#else
			nullptr, nullptr,
#endif
			6, CombineWithWaterLow_Uniforms, 1, CombineWithWaterLow_Blocks, 4, CombineWithWaterLow_Textures, 0, nullptr,
#if defined(WITH_RHI_GL) && defined(RHI_GL_PROFILE_ES2)
			CombineWithWaterLow_Vs100, CombineWithWaterLow_Fs100,
#else
			nullptr, nullptr,
#endif
#if defined(WITH_RHI_D3D11)
			CombineWithWaterLow_VsHlsl, CombineWithWaterLow_FsHlsl,
			CombineWithWaterLow_VsDxbc, CombineWithWaterLow_VsDxbcSize, CombineWithWaterLow_FsDxbc, CombineWithWaterLow_FsDxbcSize,
#else
			nullptr, nullptr,
			nullptr, 0, nullptr, 0,
#endif
#if defined(WITH_RHI_VULKAN)
			CombineWithWaterLow_VkVs, CombineWithWaterLow_VkVsSize, CombineWithWaterLow_VkFs, CombineWithWaterLow_VkFsSize },
#else
			nullptr, 0, nullptr, 0 },
#endif
	};

	inline constexpr ShaderCompiler::Program CombineWithWaterLow = { "CombineWithWaterLow", 0, 1, CombineWithWaterLow_Variants };
}
#endif
