OverviewFilesCommitsIssuesDocsReleasesPeers

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

66 lines · shader ref:
#version 430

layout(location = 0) out vec4 color;

uniform sampler2D histogram_tex;//in logarithmic scale
uniform int width = 1920;
uniform int height = 1080;
uniform float de_max_radius = 9.0;
uniform float de_power = 0.2;
uniform float de_threshold = 0.4;
uniform uint max_density = 1;

//similar to flame, but uses cone filter
//ref: https://github.com/scottdraves/flam3/wiki/Density-Estimation
vec4 density_estimation()
{
	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));


	float w = de_max_radius / de_threshold * clamp(de_threshold - texture(histogram_tex, uv).w, 0.0, 1.0);

	//experiment:
	//float w = de_max_radius / de_threshold * clamp(de_threshold - texture(histogram_tex, uv).w, 0.0, 1.0);
	//float w = de_max_radius * clamp(1.0 / pow(texture(histogram_tex, uv).w*max_density, de_power), 0.0, 1.0);
	//experiment:
	//float d = texture(histogram_tex, uv).w;//actual density
	//if (d > de_threshold)
	//	return texture(histogram_tex, uv);//do not estimate dense enough areas
	//float mult = de_max_radius / pow(de_threshold, 1.0 / de_power);//TODO: calc on cpu
	//float w = mult * pow(de_threshold - d, 1.0 / de_power);

	w = clamp(w, 0.0, de_max_radius);
	const int kSize = int(w);
	if (kSize == 0)
		discard;//spare a histogram_tex read/write 

	vec4 de = vec4(0.0);
	float wnorm = 0.0;
	for (int i = -kSize; i <= kSize; i++)
	{
		if (px + i < 0 || px + i > width - 1)
			continue;

		for (int j = -kSize; j <= kSize; j++)
		{
			if (py + j < 0 || py + j > height - 1)
				continue;

			float cw = clamp(1.0 - sqrt(float(i * i + j * j)) / float(kSize*sqrt(2)), 0.0, 1.0);
			de += cw * texture(histogram_tex, uv + vec2(float(i), float(j)) / vec2(float(width), float(height)));
			wnorm += cw;
		}
	}
	de /= wnorm;

	return de;
}

void main(void)
{
	//float de = density_estimation();
	//de_color = vec4(c.xyz / c.w * de, de);
	color = density_estimation();
}