OverviewFilesCommitsIssuesDocsReleasesPeers

ifsrenderer-linux / IFSEngine / Rendering / Shaders / tonemap.frag.shader

77 lines · shader ref:
#version 430
#extension GL_ARB_explicit_attrib_location : enable

layout(location = 0) out vec4 color;

uniform int width = 1920;
uniform int height = 1080;
uniform uint max_density = 1;
uniform float brightness = 1.0;
uniform float inv_gamma = 1.0;
uniform float gamma_threshold = 0.0;
uniform float vibrancy = 1.0;
uniform vec3 bg_color = vec3(0.0, 0.0, 0.0);

layout(std140, binding = 0) buffer histogram_buffer
{
	vec4 histogram[];
};

float log10(float x)
{
	return 0.30102999565 * log(x);
}
//log density scaling
vec4 logscale(vec4 acc)
{
	float ls = log10(1.0 + brightness * acc.w / max_density) / acc.w;
	vec4 lh = acc * ls;
	return lh;
}

//tonemapping algo based on Apophysis
vec4 tonemap(vec4 fp)
{
	//xyz: accumulated color (log)
	//w: how many times this pixel was hit (log)

	//gamma linearization
	float funcval = 0.0;
	if (gamma_threshold != 0.0)
	{
		funcval = pow(gamma_threshold, inv_gamma - 1);
	}
	float alpha;
	if (fp.w < gamma_threshold)
	{
		float frac = fp.w / gamma_threshold;
		alpha = (1.0 - frac) * fp.w * funcval + frac * pow(fp.w, inv_gamma);
	}
	else
		alpha = pow(fp.w, inv_gamma);

	float ls = vibrancy * alpha / fp.w;
	alpha = clamp(alpha, 0.0, 1.0);

	vec3 o = ls * fp.rgb + (1.0 - vibrancy) * pow(fp.rgb, vec3(inv_gamma));
	o = clamp(o, vec3(0.0), vec3(1.0));

	o += (1.0 - alpha) * bg_color;
	o = clamp(o, vec3(0.0), vec3(1.0));

	return vec4(o, alpha);
}

void main(void)
{
	int px = int(gl_FragCoord.x);
	int py = int(gl_FragCoord.y);
	vec2 uv = vec2(gl_FragCoord.x/float(width),gl_FragCoord.y/float(height));
	int pxi = px+py*width;

	vec4 c = histogram[pxi];
	c = logscale(c);
	c = tonemap(c);
	color = c;
}