Browse Source

Move PPS to the new program resource

Panagiotis Christopoulos Charitos 8 years ago
parent
commit
772e3d3be0

+ 104 - 0
programs/FinalComposite.ankiprog

@@ -0,0 +1,104 @@
+<!-- 
+Copyright (C) 2009-2017, Panagiotis Christopoulos Charitos and contributors.
+All rights reserved.
+Code licensed under the BSD License.
+http://www.anki3d.org/LICENSE
+-->
+<shaderProgram>
+	<mutators>
+		<mutator name="BLUE_NOISE" values="0 1"/>
+		<mutator name="SHARPEN_ENABLED" values="0 1"/>
+		<mutator name="BLOOM_ENABLED" values="0 1"/>
+		<mutator name="DBG_ENABLED" values="0 1"/>
+	</mutators>
+
+	<shaders>
+		<shader type="vert">
+			<source><![CDATA[
+#include "shaders/Quad.vert.glsl"
+			]]></source>
+		</shader>
+
+		<shader type="frag">
+			<inputs>
+				<input name="LUT_SIZE" type="uint" const="1"/>
+				<input name="FB_SIZE" type="uvec2" const="1"/>
+			</inputs>
+
+			<source><![CDATA[
+#include "shaders/Common.glsl"
+#include "shaders/Tonemapping.glsl"
+#include "shaders/Functions.glsl"
+
+layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_isRt;
+layout(ANKI_TEX_BINDING(0, 1)) uniform sampler2D u_ppsBloomLfRt;
+layout(ANKI_TEX_BINDING(0, 2)) uniform sampler3D u_lut;
+layout(ANKI_TEX_BINDING(0, 3)) uniform sampler2DArray u_blueNoise;
+#if DBG_ENABLED
+layout(ANKI_TEX_BINDING(0, 5)) uniform sampler2D u_dbgRt;
+#endif
+
+layout(std140, ANKI_UBO_BINDING(0, 0)) uniform u0_
+{
+	vec4 u_blueNoiseLayerPad3;
+};
+
+layout(std140, ANKI_SS_BINDING(0, 0)) readonly buffer s0_
+{
+	vec4 u_averageLuminancePad3;
+};
+
+layout(location = 0) in vec2 in_uv;
+layout(location = 0) out vec3 out_color;
+
+vec3 colorGrading(in vec3 color)
+{
+	const vec3 LUT_SCALE = vec3((float(LUT_SIZE) - 1.0) / float(LUT_SIZE));
+	const vec3 LUT_OFFSET = vec3(1.0 / (2.0 * float(LUT_SIZE)));
+
+	color = min(color, vec3(1.0));
+	vec3 lutCoords = color * LUT_SCALE + LUT_OFFSET;
+	return textureLod(u_lut, lutCoords, 0.0).rgb;
+}
+
+void main()
+{
+	vec2 uv = in_uv.xy;
+
+#if SHARPEN_ENABLED
+	out_color = readSharpen(u_isRt, uv, 0.15, true);
+#else
+	out_color = textureLod(u_isRt, uv, 0.0).rgb;
+#endif
+
+	out_color = tonemap(out_color, readFirstInvocationARB(u_averageLuminancePad3.x), 0.0);
+
+#if BLOOM_ENABLED
+	vec3 bloom = textureLod(u_ppsBloomLfRt, uv, 0.0).rgb;
+	out_color += bloom;
+#endif
+
+	out_color = colorGrading(out_color);
+
+#if BLUE_NOISE
+	vec3 blueNoise = textureLod(u_blueNoise, vec3(FB_SIZE / vec2(64.0) * uv, u_blueNoiseLayerPad3.x), 0.0).rgb;
+	blueNoise = blueNoise * 2.0 - 1.0;
+	blueNoise = sign(blueNoise) * (1.0 - sqrt(1.0 - abs(blueNoise)));
+
+	out_color += blueNoise / 255.0;
+#endif
+
+#if 0
+	{
+		out_color = vec3(textureLod(u_isRt, uv, 0.0).r);
+	}
+#endif
+
+#if DBG_ENABLED
+	out_color += textureLod(u_dbgRt, uv, 0.0).rgb;
+#endif
+}
+			]]></source>
+		</shader>
+	</shaders>
+</shaderProgram>

+ 65 - 0
shaders/Functions.glsl

@@ -183,4 +183,69 @@ vec3 getCubemapDirection(vec2 norm, uint faceIdx)
 	return normalize(norm.x * xDir + norm.y * yDir + zDir);
 }
 
+vec3 grayScale(vec3 col)
+{
+	float grey = (col.r + col.g + col.b) * (1.0 / 3.0);
+	return vec3(grey);
+}
+
+vec3 saturate(vec3 col, float factor)
+{
+	const vec3 LUM_COEFF = vec3(0.2125, 0.7154, 0.0721);
+	vec3 intensity = vec3(dot(col, LUM_COEFF));
+	return mix(intensity, col, factor);
+}
+
+vec3 gammaCorrection(vec3 gamma, vec3 col)
+{
+	return pow(col, 1.0 / gamma);
+}
+
+// Can use 0.15 for sharpenFactor
+vec3 readSharpen(sampler2D tex, vec2 uv, float sharpenFactor, bool detailed)
+{
+	vec3 col = textureLod(tex, uv, 0.0).rgb;
+
+	vec3 col2 = textureLodOffset(tex, uv, 0.0, ivec2(1, 1)).rgb;
+	col2 += textureLodOffset(tex, uv, 0.0, ivec2(-1, -1)).rgb;
+	col2 += textureLodOffset(tex, uv, 0.0, ivec2(1, -1)).rgb;
+	col2 += textureLodOffset(tex, uv, 0.0, ivec2(-1, 1)).rgb;
+
+	float f = 4.0;
+	if(detailed)
+	{
+		col2 += textureLodOffset(tex, uv, 0.0, ivec2(0, 1)).rgb;
+		col2 += textureLodOffset(tex, uv, 0.0, ivec2(1, 0)).rgb;
+		col2 += textureLodOffset(tex, uv, 0.0, ivec2(-1, 0)).rgb;
+		col2 += textureLodOffset(tex, uv, 0.0, ivec2(0, -1)).rgb;
+
+		f = 8.0;
+	}
+
+	col = col * (f * sharpenFactor + 1.0) - sharpenFactor * col2;
+	return max(vec3(0.0), col);
+}
+
+vec3 readErosion(sampler2D tex, vec2 uv)
+{
+	vec3 minValue = textureLod(tex, uv, 0.0).rgb;
+
+#define ANKI_EROSION(x, y)                                                                                             \
+	col2 = textureLodOffset(tex, uv, 0.0, ivec2(x, y)).rgb;                                                            \
+	minValue = min(col2, minValue);
+
+	vec3 col2;
+	ANKI_EROSION(1, 1);
+	ANKI_EROSION(-1, -1);
+	ANKI_EROSION(1, -1);
+	ANKI_EROSION(-1, 1);
+	ANKI_EROSION(0, 1);
+	ANKI_EROSION(1, 0);
+	ANKI_EROSION(-1, 0);
+	ANKI_EROSION(0, -1);
+
+#undef ANKI_EROSION
+
+	return minValue;
+}
 #endif

+ 0 - 144
shaders/Pps.frag.glsl

@@ -1,144 +0,0 @@
-// Copyright (C) 2009-2017, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include "shaders/Common.glsl"
-#include "shaders/Tonemapping.glsl"
-#include "shaders/Functions.glsl"
-
-#define BLUE_NOISE 1
-
-layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_isRt;
-layout(ANKI_TEX_BINDING(0, 1)) uniform sampler2D u_ppsBloomLfRt;
-layout(ANKI_TEX_BINDING(0, 2)) uniform sampler3D u_lut;
-layout(ANKI_TEX_BINDING(0, 3)) uniform sampler2DArray u_blueNoise;
-#if DBG_ENABLED
-layout(ANKI_TEX_BINDING(0, 5)) uniform sampler2D u_dbgRt;
-#endif
-
-layout(std140, ANKI_UBO_BINDING(0, 0)) uniform u0_
-{
-	vec4 u_blueNoiseLayerPad3;
-};
-
-layout(std140, ANKI_SS_BINDING(0, 0)) readonly buffer s0_
-{
-	vec4 u_averageLuminancePad3;
-};
-
-layout(location = 0) in vec2 in_uv;
-layout(location = 0) out vec3 out_color;
-
-const vec2 TEX_OFFSET = vec2(1.0 / float(FBO_WIDTH), 1.0 / float(FBO_HEIGHT));
-
-const vec2 KERNEL[8] = vec2[](vec2(TEX_OFFSET.x, TEX_OFFSET.y),
-	vec2(0.0, TEX_OFFSET.y),
-	vec2(-TEX_OFFSET.x, TEX_OFFSET.y),
-	vec2(-TEX_OFFSET.x, 0.0),
-	vec2(-TEX_OFFSET.x, -TEX_OFFSET.y),
-	vec2(0.0, -TEX_OFFSET.y),
-	vec2(TEX_OFFSET.x, -TEX_OFFSET.y),
-	vec2(TEX_OFFSET.x, 0.0));
-
-vec3 grayScale(in vec3 col)
-{
-	float grey = (col.r + col.g + col.b) * 0.333333333; // aka: / 3.0
-	return vec3(grey);
-}
-
-vec3 saturation(in vec3 col, in float factor)
-{
-	const vec3 lumCoeff = vec3(0.2125, 0.7154, 0.0721);
-
-	vec3 intensity = vec3(dot(col, lumCoeff));
-	return mix(intensity, col, factor);
-}
-
-vec3 gammaCorrection(in float gamma, in vec3 col)
-{
-	return pow(col, vec3(1.0 / gamma));
-}
-
-vec3 gammaCorrectionRgb(in vec3 gamma, in vec3 col)
-{
-	return pow(col, 1.0 / gamma);
-}
-
-vec3 sharpen(in sampler2D tex, in vec2 texCoords)
-{
-	const float sharpenFactor = 0.15;
-
-	vec3 col = textureLod(tex, texCoords, 0.0).rgb;
-
-	vec3 col2 = textureLod(tex, texCoords + KERNEL[0], 0.0).rgb;
-	for(int i = 1; i < 8; i++)
-	{
-		col2 += textureLod(tex, texCoords + KERNEL[i], 0.0).rgb;
-	}
-
-	col = col * (8.0 * sharpenFactor + 1.0) - sharpenFactor * col2;
-
-	return max(col, vec3(EPSILON));
-}
-
-vec3 erosion(in sampler2D tex, in vec2 texCoords)
-{
-	vec3 minValue = texture(tex, texCoords, 0.0).rgb;
-
-	for(int i = 0; i < 8; i++)
-	{
-		vec3 tmpCol = texture(tex, texCoords + KERNEL[i], 0.0).rgb;
-		minValue = min(tmpCol, minValue);
-	}
-
-	return minValue;
-}
-
-vec3 colorGrading(in vec3 color)
-{
-	const vec3 LUT_SCALE = vec3((LUT_SIZE - 1.0) / LUT_SIZE);
-	const vec3 LUT_OFFSET = vec3(1.0 / (2.0 * LUT_SIZE));
-
-	color = min(color, vec3(1.0));
-	vec3 lutCoords = color * LUT_SCALE + LUT_OFFSET;
-	return textureLod(u_lut, lutCoords, 0.0).rgb;
-}
-
-void main()
-{
-	vec2 uv = in_uv.xy;
-
-#if SHARPEN_ENABLED
-	out_color = sharpen(u_isRt, uv);
-#else
-	out_color = textureLod(u_isRt, uv, 0.0).rgb;
-#endif
-
-	out_color = tonemap(out_color, readFirstInvocationARB(u_averageLuminancePad3.x), 0.0);
-
-#if BLOOM_ENABLED
-	vec3 bloom = textureLod(u_ppsBloomLfRt, uv, 0.0).rgb;
-	out_color += bloom;
-#endif
-
-	out_color = colorGrading(out_color);
-
-#if BLUE_NOISE
-	vec3 blueNoise = textureLod(u_blueNoise, vec3(FB_SIZE / vec2(64.0) * uv, u_blueNoiseLayerPad3.x), 0.0).rgb;
-	blueNoise = blueNoise * 2.0 - 1.0;
-	blueNoise = sign(blueNoise) * (1.0 - sqrt(1.0 - abs(blueNoise)));
-
-	out_color += blueNoise / 255.0;
-#endif
-
-#if 0
-	{
-		out_color = vec3(textureLod(u_isRt, uv, 0.0).r);
-	}
-#endif
-
-#if DBG_ENABLED
-	out_color += textureLod(u_dbgRt, uv, 0.0).rgb;
-#endif
-}

+ 1 - 1
src/anki/renderer/Is.cpp

@@ -96,7 +96,7 @@ Error Is::initInternal(const ConfigSet& config)
 	//
 	ANKI_CHECK(getResourceManager().loadResource("programs/Is.ankiprog", m_prog));
 
-	ShaderProgramResourceConstantValues<5> consts(m_prog);
+	ShaderProgramResourceConstantValueInitList<5> consts(m_prog);
 	consts.add("CLUSTER_COUNT_X", U32(m_clusterCounts[0]))
 		.add("CLUSTER_COUNT_Y", U32(m_clusterCounts[1]))
 		.add("CLUSTER_COUNT", U32(m_clusterCount))

+ 21 - 35
src/anki/renderer/Pps.cpp

@@ -59,6 +59,26 @@ Error Pps::initInternal(const ConfigSet& config)
 
 	ANKI_CHECK(getResourceManager().loadResource("engine_data/BlueNoiseLdrRgb64x64.ankitex", m_blueNoise));
 
+	// Progs
+	ANKI_CHECK(getResourceManager().loadResource("programs/FinalComposite.ankiprog", m_prog));
+
+	ShaderProgramResourceMutationInitList<4> mutations(m_prog);
+	mutations.add("BLUE_NOISE", 1)
+		.add("SHARPEN_ENABLED", m_sharpenEnabled)
+		.add("BLOOM_ENABLED", 1)
+		.add("DBG_ENABLED", 0);
+
+	ShaderProgramResourceConstantValueInitList<2> consts(m_prog);
+	consts.add("LUT_SIZE", U32(LUT_SIZE)).add("FB_SIZE", UVec2(m_r->getWidth(), m_r->getHeight()));
+
+	const ShaderProgramResourceVariant* variant;
+	m_prog->getOrCreateVariant(mutations.m_mutations, consts.m_constantValues, variant);
+	m_grProgs[0] = variant->getProgram();
+
+	mutations.m_mutations[3].m_value = 1;
+	m_prog->getOrCreateVariant(mutations.m_mutations, consts.m_constantValues, variant);
+	m_grProgs[1] = variant->getProgram();
+
 	return ErrorCode::NONE;
 }
 
@@ -92,40 +112,6 @@ Error Pps::run(RenderingContext& ctx)
 	Bool drawToDefaultFb = ctx.m_outFb.isCreated();
 	Bool dbgEnabled = m_r->getDbg().getEnabled();
 
-	// Get or create the ppline
-	ShaderProgramPtr& prog = m_prog[drawToDefaultFb][dbgEnabled];
-
-	if(!prog)
-	{
-		// Need to create it
-
-		ShaderResourcePtr& frag = m_frag[drawToDefaultFb][dbgEnabled];
-		if(!frag)
-		{
-			ANKI_CHECK(m_r->createShaderf("shaders/Pps.frag.glsl",
-				frag,
-				"#define BLOOM_ENABLED %u\n"
-				"#define SHARPEN_ENABLED %u\n"
-				"#define FBO_WIDTH %u\n"
-				"#define FBO_HEIGHT %u\n"
-				"#define LUT_SIZE %u.0\n"
-				"#define DBG_ENABLED %u\n"
-				"#define DRAW_TO_DEFAULT %u\n"
-				"#define FB_SIZE vec2(float(%u), float(%u))\n",
-				true,
-				m_sharpenEnabled,
-				m_r->getWidth(),
-				m_r->getHeight(),
-				LUT_SIZE,
-				dbgEnabled,
-				drawToDefaultFb,
-				m_r->getWidth(),
-				m_r->getHeight()));
-		}
-
-		m_r->createDrawQuadShaderProgram(frag->getGrShader(), prog);
-	}
-
 	// Bind stuff
 	cmdb->bindTextureAndSampler(
 		0, 0, m_r->getTaa().getRt(), (drawToDefaultFb) ? m_r->getNearestSampler() : m_r->getLinearSampler());
@@ -160,7 +146,7 @@ Error Pps::run(RenderingContext& ctx)
 
 	cmdb->beginRenderPass(*fb);
 	cmdb->setViewport(0, 0, width, height);
-	cmdb->bindShaderProgram(prog);
+	cmdb->bindShaderProgram(m_grProgs[dbgEnabled]);
 	m_r->drawQuad(cmdb);
 	cmdb->endRenderPass();
 

+ 3 - 2
src/anki/renderer/Pps.h

@@ -44,10 +44,11 @@ private:
 	static const U LUT_SIZE = 16;
 
 	FramebufferPtr m_fb;
-	Array2d<ShaderResourcePtr, 2, 2> m_frag; ///< One with Dbg and one without
-	Array2d<ShaderProgramPtr, 2, 2> m_prog; ///< With Dbg, Default FB or not
 	TexturePtr m_rt;
 
+	ShaderProgramResourcePtr m_prog;
+	Array<ShaderProgramPtr, 2> m_grProgs; ///< One with Dbg and one without
+
 	TextureResourcePtr m_lut; ///< Color grading lookup texture.
 	TextureResourcePtr m_blueNoise;
 

+ 2 - 2
src/anki/renderer/Ssao.cpp

@@ -53,8 +53,8 @@ Error SsaoMain::init(const ConfigSet& config)
 
 	// Shader
 	ANKI_CHECK(getResourceManager().loadResource("programs/Ssao.ankiprog", m_prog));
-	
-	ShaderProgramResourceConstantValues<6> consts(m_prog);
+
+	ShaderProgramResourceConstantValueInitList<6> consts(m_prog);
 	consts.add("NOISE_MAP_SIZE", U32(m_noiseTex->getWidth()))
 		.add("FB_SIZE", UVec2(m_ssao->m_width, m_ssao->m_height))
 		.add("RADIUS", F32(HEMISPHERE_RADIUS))

+ 30 - 3
src/anki/resource/ShaderProgramResource.h

@@ -424,18 +424,18 @@ private:
 
 /// Smart initializer of multiple ShaderProgramResourceConstantValue.
 template<U count>
-class ShaderProgramResourceConstantValues
+class ShaderProgramResourceConstantValueInitList
 {
 public:
 	Array<ShaderProgramResourceConstantValue, count> m_constantValues;
 
-	ShaderProgramResourceConstantValues(ShaderProgramResourcePtr ptr)
+	ShaderProgramResourceConstantValueInitList(ShaderProgramResourcePtr ptr)
 		: m_ptr(ptr)
 	{
 	}
 
 	template<typename T>
-	ShaderProgramResourceConstantValues& add(CString name, const T& t)
+	ShaderProgramResourceConstantValueInitList& add(CString name, const T& t)
 	{
 		const ShaderProgramResourceInputVariable* in = m_ptr->tryFindInputVariable(name);
 		ANKI_ASSERT(in);
@@ -447,6 +447,33 @@ public:
 		return *this;
 	}
 
+private:
+	ShaderProgramResourcePtr m_ptr;
+	U m_count = 0;
+};
+
+/// Smart initializer of multiple ShaderProgramResourceMutation.
+template<U count>
+class ShaderProgramResourceMutationInitList
+{
+public:
+	Array<ShaderProgramResourceMutation, count> m_mutations;
+
+	ShaderProgramResourceMutationInitList(ShaderProgramResourcePtr ptr)
+		: m_ptr(ptr)
+	{
+	}
+
+	ShaderProgramResourceMutationInitList& add(CString name, ShaderProgramResourceMutatorValue t)
+	{
+		const ShaderProgramResourceMutator* m = m_ptr->tryFindMutator(name);
+		ANKI_ASSERT(m);
+		m_mutations[m_count].m_mutator = m;
+		m_mutations[m_count].m_value = t;
+		++m_count;
+		return *this;
+	}
+
 private:
 	ShaderProgramResourcePtr m_ptr;
 	U m_count = 0;