Browse Source

Don't compute any specular terms on cube reflections & GI

Panagiotis Christopoulos Charitos 6 years ago
parent
commit
8e7403e6bd

+ 6 - 0
shaders/TraditionalDeferredShading.glslp

@@ -6,6 +6,7 @@
 // Classic deferred lighting shader
 
 #pragma anki mutator LIGHT_TYPE 0 1 2
+#pragma anki mutator SPECULAR 0 1
 
 #define POINT_LIGHT_TYPE 0
 #define SPOT_LIGHT_TYPE 1
@@ -110,7 +111,12 @@ void main()
 	const Vec3 l = normalize(frag2Light);
 	const F32 nol = max(0.0, dot(gbuffer.m_normal, l));
 #endif
+
+#if SPECULAR == 1
 	const Vec3 specC = computeSpecularColorBrdf(gbuffer, viewDir, l);
+#else
+	const Vec3 specC = Vec3(0.0);
+#endif
 
 	// Compute factors
 #if LIGHT_TYPE == POINT_LIGHT_TYPE

+ 1 - 0
src/anki/gr/ShaderCompiler.cpp

@@ -523,6 +523,7 @@ Error ShaderCompilerCache::compileInternal(
 	}
 	else
 	{
+		ANKI_GR_LOGI("%s not found in cache. Will compile", fname.cstr());
 		ANKI_CHECK(m_compiler.compile(source, options, bin));
 
 		File file;

+ 16 - 14
src/anki/renderer/GlobalIllumination.cpp

@@ -677,20 +677,22 @@ void GlobalIllumination::runLightShading(RenderPassWorkContext& rgraphCtx, Inter
 		rgraphCtx.bindTexture(0, 8, giCtx.m_shadowsRt, TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
 	}
 
-	m_lightShading.m_deferred.drawLights(rqueue.m_viewProjectionMatrix,
-		rqueue.m_viewProjectionMatrix.getInverse(),
-		rqueue.m_cameraTransform.getTranslationPart(),
-		UVec4(faceIdx * m_tileSize, 0, m_tileSize, m_tileSize),
-		Vec2(1.0f / F32(m_tileSize * 6), 1.0f / F32(m_tileSize)),
-		Vec2(0.0f, 0.0f),
-		Vec2(1.0f / F32(m_tileSize), 1.0f / F32(m_tileSize)),
-		Vec2(-F32(faceIdx), 0.0f),
-		probe.m_renderQueues[faceIdx]->m_cameraNear,
-		probe.m_renderQueues[faceIdx]->m_cameraFar,
-		(hasDirLight) ? &probe.m_renderQueues[faceIdx]->m_directionalLight : nullptr,
-		rqueue.m_pointLights,
-		rqueue.m_spotLights,
-		cmdb);
+	TraditionalDeferredLightShadingDrawInfo dsInfo;
+	dsInfo.m_viewProjectionMatrix = rqueue.m_viewProjectionMatrix;
+	dsInfo.m_invViewProjectionMatrix = rqueue.m_viewProjectionMatrix.getInverse();
+	dsInfo.m_cameraPosWSpace = rqueue.m_cameraTransform.getTranslationPart();
+	dsInfo.m_viewport = UVec4(faceIdx * m_tileSize, 0, m_tileSize, m_tileSize);
+	dsInfo.m_gbufferTexCoordsScale = Vec2(1.0f / F32(m_tileSize * 6), 1.0f / F32(m_tileSize));
+	dsInfo.m_gbufferTexCoordsBias = Vec2(0.0f, 0.0f);
+	dsInfo.m_lightbufferTexCoordsScale = Vec2(1.0f / F32(m_tileSize), 1.0f / F32(m_tileSize));
+	dsInfo.m_lightbufferTexCoordsBias = Vec2(-F32(faceIdx), 0.0f);
+	dsInfo.m_cameraNear = probe.m_renderQueues[faceIdx]->m_cameraNear;
+	dsInfo.m_cameraFar = probe.m_renderQueues[faceIdx]->m_cameraFar;
+	dsInfo.m_directionalLight = (hasDirLight) ? &probe.m_renderQueues[faceIdx]->m_directionalLight : nullptr;
+	dsInfo.m_pointLights = rqueue.m_pointLights;
+	dsInfo.m_spotLights = rqueue.m_spotLights;
+	dsInfo.m_commandBuffer = cmdb;
+	m_lightShading.m_deferred.drawLights(dsInfo);
 }
 
 void GlobalIllumination::runIrradiance(RenderPassWorkContext& rgraphCtx, InternalContext& giCtx)

+ 18 - 14
src/anki/renderer/ProbeReflections.cpp

@@ -399,20 +399,24 @@ void ProbeReflections::runLightShading(U32 faceIdx, RenderPassWorkContext& rgrap
 		rgraphCtx.bindTexture(0, 8, m_ctx.m_shadowMapRt, TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
 	}
 
-	m_lightShading.m_deferred.drawLights(rqueue.m_viewProjectionMatrix,
-		rqueue.m_viewProjectionMatrix.getInverse(),
-		rqueue.m_cameraTransform.getTranslationPart(),
-		UVec4(0, 0, m_lightShading.m_tileSize, m_lightShading.m_tileSize),
-		Vec2(1.0f / F32(m_lightShading.m_tileSize * 6), 1.0f / F32(m_lightShading.m_tileSize)),
-		Vec2(F32(faceIdx) * (1.0f / 6.0f), 0.0f),
-		Vec2(1.0f / F32(m_lightShading.m_tileSize), 1.0f / F32(m_lightShading.m_tileSize)),
-		Vec2(0.0f, 0.0f),
-		probe.m_renderQueues[faceIdx]->m_cameraNear,
-		probe.m_renderQueues[faceIdx]->m_cameraFar,
-		(hasDirLight) ? &probe.m_renderQueues[faceIdx]->m_directionalLight : nullptr,
-		rqueue.m_pointLights,
-		rqueue.m_spotLights,
-		cmdb);
+	TraditionalDeferredLightShadingDrawInfo dsInfo;
+	dsInfo.m_viewProjectionMatrix = rqueue.m_viewProjectionMatrix;
+	dsInfo.m_invViewProjectionMatrix = rqueue.m_viewProjectionMatrix.getInverse();
+	dsInfo.m_cameraPosWSpace = rqueue.m_cameraTransform.getTranslationPart();
+	dsInfo.m_viewport = UVec4(0, 0, m_lightShading.m_tileSize, m_lightShading.m_tileSize);
+	dsInfo.m_gbufferTexCoordsScale =
+		Vec2(1.0f / F32(m_lightShading.m_tileSize * 6), 1.0f / F32(m_lightShading.m_tileSize));
+	dsInfo.m_gbufferTexCoordsBias = Vec2(F32(faceIdx) * (1.0f / 6.0f), 0.0f);
+	dsInfo.m_lightbufferTexCoordsScale =
+		Vec2(1.0f / F32(m_lightShading.m_tileSize), 1.0f / F32(m_lightShading.m_tileSize));
+	dsInfo.m_lightbufferTexCoordsBias = Vec2(0.0f, 0.0f);
+	dsInfo.m_cameraNear = probe.m_renderQueues[faceIdx]->m_cameraNear;
+	dsInfo.m_cameraFar = probe.m_renderQueues[faceIdx]->m_cameraFar;
+	dsInfo.m_directionalLight = (hasDirLight) ? &probe.m_renderQueues[faceIdx]->m_directionalLight : nullptr;
+	dsInfo.m_pointLights = rqueue.m_pointLights;
+	dsInfo.m_spotLights = rqueue.m_spotLights;
+	dsInfo.m_commandBuffer = cmdb;
+	m_lightShading.m_deferred.drawLights(dsInfo);
 }
 
 void ProbeReflections::runMipmappingOfLightShading(U32 faceIdx, RenderPassWorkContext& rgraphCtx)

+ 53 - 60
src/anki/renderer/TraditionalDeferredShading.cpp

@@ -28,20 +28,24 @@ Error TraditionalDeferredLightShading::init()
 	{
 		ANKI_CHECK(getResourceManager().loadResource("shaders/TraditionalDeferredShading.glslp", m_lightProg));
 
-		ShaderProgramResourceMutationInitList<1> mutators(m_lightProg);
-		mutators.add("LIGHT_TYPE", 0);
+		for(U32 specular = 0; specular <= 1; ++specular)
+		{
+			ShaderProgramResourceMutationInitList<2> mutators(m_lightProg);
+			mutators.add("LIGHT_TYPE", 0);
+			mutators.add("SPECULAR", specular);
 
-		const ShaderProgramResourceVariant* variant;
-		m_lightProg->getOrCreateVariant(mutators.get(), variant);
-		m_plightGrProg = variant->getProgram();
+			const ShaderProgramResourceVariant* variant;
+			m_lightProg->getOrCreateVariant(mutators.get(), variant);
+			m_plightGrProg[specular] = variant->getProgram();
 
-		mutators[0].m_value = 1;
-		m_lightProg->getOrCreateVariant(mutators.get(), variant);
-		m_slightGrProg = variant->getProgram();
+			mutators[0].m_value = 1;
+			m_lightProg->getOrCreateVariant(mutators.get(), variant);
+			m_slightGrProg[specular] = variant->getProgram();
 
-		mutators[0].m_value = 2;
-		m_lightProg->getOrCreateVariant(mutators.get(), variant);
-		m_dirLightGrProg = variant->getProgram();
+			mutators[0].m_value = 2;
+			m_lightProg->getOrCreateVariant(mutators.get(), variant);
+			m_dirLightGrProg[specular] = variant->getProgram();
+		}
 	}
 
 	// Init meshes
@@ -76,52 +80,41 @@ void TraditionalDeferredLightShading::bindVertexIndexBuffers(
 	cmdb->bindIndexBuffer(buff, offset, idxType);
 }
 
-void TraditionalDeferredLightShading::drawLights(const Mat4& vpMat,
-	const Mat4& invViewProjMat,
-	const Vec4& cameraPosWSpace,
-	const UVec4& viewport,
-	const Vec2& gbufferTexCoordsScale,
-	const Vec2& gbufferTexCoordsBias,
-	const Vec2& lightbufferTexCoordsScale,
-	const Vec2& lightbufferTexCoordsBias,
-	F32 cameraNear,
-	F32 cameraFar,
-	DirectionalLightQueueElement* directionalLight,
-	ConstWeakArray<PointLightQueueElement> plights,
-	ConstWeakArray<SpotLightQueueElement> slights,
-	CommandBufferPtr& cmdb)
+void TraditionalDeferredLightShading::drawLights(TraditionalDeferredLightShadingDrawInfo& info)
 {
 	// Set common state for all lights
+	CommandBufferPtr& cmdb = info.m_commandBuffer;
 	cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ONE);
-	cmdb->setViewport(viewport.x(), viewport.y(), viewport.z(), viewport.w());
+	cmdb->setViewport(info.m_viewport.x(), info.m_viewport.y(), info.m_viewport.z(), info.m_viewport.w());
 
 	// Dir light
-	if(directionalLight)
+	if(info.m_directionalLight)
 	{
-		ANKI_ASSERT(directionalLight->m_uuid && directionalLight->m_shadowCascadeCount == 1);
+		ANKI_ASSERT(info.m_directionalLight->m_uuid && info.m_directionalLight->m_shadowCascadeCount == 1);
 
-		cmdb->bindShaderProgram(m_dirLightGrProg);
+		cmdb->bindShaderProgram(m_dirLightGrProg[info.m_computeSpecular]);
 
 		DeferredDirectionalLightUniforms* unis = allocateAndBindUniforms<DeferredDirectionalLightUniforms*>(
 			sizeof(DeferredDirectionalLightUniforms), cmdb, 0, 1);
 
-		unis->m_inputTexUvScale = gbufferTexCoordsScale;
-		unis->m_inputTexUvBias = gbufferTexCoordsBias;
-		unis->m_fbUvScale = lightbufferTexCoordsScale;
-		unis->m_fbUvBias = lightbufferTexCoordsBias;
-		unis->m_invViewProjMat = invViewProjMat;
-		unis->m_camPos = cameraPosWSpace.xyz();
+		unis->m_inputTexUvScale = info.m_gbufferTexCoordsScale;
+		unis->m_inputTexUvBias = info.m_gbufferTexCoordsBias;
+		unis->m_fbUvScale = info.m_lightbufferTexCoordsScale;
+		unis->m_fbUvBias = info.m_lightbufferTexCoordsBias;
+		unis->m_invViewProjMat = info.m_invViewProjectionMatrix;
+		unis->m_camPos = info.m_cameraPosWSpace.xyz();
 
-		unis->m_diffuseColor = directionalLight->m_diffuseColor;
-		unis->m_lightDir = directionalLight->m_direction;
-		unis->m_lightMatrix = directionalLight->m_textureMatrices[0];
+		unis->m_diffuseColor = info.m_directionalLight->m_diffuseColor;
+		unis->m_lightDir = info.m_directionalLight->m_direction;
+		unis->m_lightMatrix = info.m_directionalLight->m_textureMatrices[0];
 
-		unis->m_near = cameraNear;
-		unis->m_far = cameraFar;
+		unis->m_near = info.m_cameraNear;
+		unis->m_far = info.m_cameraFar;
 
-		if(directionalLight->m_shadowCascadeCount > 0)
+		if(info.m_directionalLight->m_shadowCascadeCount > 0)
 		{
-			unis->m_effectiveShadowDistance = directionalLight->m_shadowRenderQueues[0]->m_effectiveShadowDistance;
+			unis->m_effectiveShadowDistance =
+				info.m_directionalLight->m_shadowRenderQueues[0]->m_effectiveShadowDistance;
 		}
 		else
 		{
@@ -137,9 +130,9 @@ void TraditionalDeferredLightShading::drawLights(const Mat4& vpMat,
 	// Do point lights
 	U32 indexCount;
 	bindVertexIndexBuffers(m_plightMesh, cmdb, indexCount);
-	cmdb->bindShaderProgram(m_plightGrProg);
+	cmdb->bindShaderProgram(m_plightGrProg[info.m_computeSpecular]);
 
-	for(const PointLightQueueElement& plightEl : plights)
+	for(const PointLightQueueElement& plightEl : info.m_pointLights)
 	{
 		// Update uniforms
 		DeferredVertexUniforms* vert =
@@ -147,17 +140,17 @@ void TraditionalDeferredLightShading::drawLights(const Mat4& vpMat,
 
 		Mat4 modelM(plightEl.m_worldPosition.xyz1(), Mat3::getIdentity(), plightEl.m_radius);
 
-		vert->m_mvp = vpMat * modelM;
+		vert->m_mvp = info.m_viewProjectionMatrix * modelM;
 
 		DeferredPointLightUniforms* light =
 			allocateAndBindUniforms<DeferredPointLightUniforms*>(sizeof(DeferredPointLightUniforms), cmdb, 0, 1);
 
-		light->m_inputTexUvScale = gbufferTexCoordsScale;
-		light->m_inputTexUvBias = gbufferTexCoordsBias;
-		light->m_fbUvScale = lightbufferTexCoordsScale;
-		light->m_fbUvBias = lightbufferTexCoordsBias;
-		light->m_invViewProjMat = invViewProjMat;
-		light->m_camPos = cameraPosWSpace.xyz();
+		light->m_inputTexUvScale = info.m_gbufferTexCoordsScale;
+		light->m_inputTexUvBias = info.m_gbufferTexCoordsBias;
+		light->m_fbUvScale = info.m_lightbufferTexCoordsScale;
+		light->m_fbUvBias = info.m_lightbufferTexCoordsBias;
+		light->m_invViewProjMat = info.m_invViewProjectionMatrix;
+		light->m_camPos = info.m_cameraPosWSpace.xyz();
 		light->m_position = plightEl.m_worldPosition;
 		light->m_oneOverSquareRadius = 1.0f / (plightEl.m_radius * plightEl.m_radius);
 		light->m_diffuseColor = plightEl.m_diffuseColor;
@@ -168,9 +161,9 @@ void TraditionalDeferredLightShading::drawLights(const Mat4& vpMat,
 
 	// Do spot lights
 	bindVertexIndexBuffers(m_slightMesh, cmdb, indexCount);
-	cmdb->bindShaderProgram(m_slightGrProg);
+	cmdb->bindShaderProgram(m_slightGrProg[info.m_computeSpecular]);
 
-	for(const SpotLightQueueElement& splightEl : slights)
+	for(const SpotLightQueueElement& splightEl : info.m_spotLights)
 	{
 		// Compute the model matrix
 		//
@@ -188,18 +181,18 @@ void TraditionalDeferredLightShading::drawLights(const Mat4& vpMat,
 		// Update vertex uniforms
 		DeferredVertexUniforms* vert =
 			allocateAndBindUniforms<DeferredVertexUniforms*>(sizeof(DeferredVertexUniforms), cmdb, 0, 0);
-		vert->m_mvp = vpMat * modelM;
+		vert->m_mvp = info.m_viewProjectionMatrix * modelM;
 
 		// Update fragment uniforms
 		DeferredSpotLightUniforms* light =
 			allocateAndBindUniforms<DeferredSpotLightUniforms*>(sizeof(DeferredSpotLightUniforms), cmdb, 0, 1);
 
-		light->m_inputTexUvScale = gbufferTexCoordsScale;
-		light->m_inputTexUvBias = gbufferTexCoordsBias;
-		light->m_fbUvScale = lightbufferTexCoordsScale;
-		light->m_fbUvBias = lightbufferTexCoordsBias;
-		light->m_invViewProjMat = invViewProjMat;
-		light->m_camPos = cameraPosWSpace.xyz();
+		light->m_inputTexUvScale = info.m_gbufferTexCoordsScale;
+		light->m_inputTexUvBias = info.m_gbufferTexCoordsBias;
+		light->m_fbUvScale = info.m_lightbufferTexCoordsScale;
+		light->m_fbUvBias = info.m_lightbufferTexCoordsBias;
+		light->m_invViewProjMat = info.m_invViewProjectionMatrix;
+		light->m_camPos = info.m_cameraPosWSpace.xyz();
 
 		light->m_position = splightEl.m_worldTransform.getTranslationPart().xyz();
 		light->m_oneOverSquareRadius = 1.0f / (splightEl.m_distance * splightEl.m_distance);

+ 25 - 17
src/anki/renderer/TraditionalDeferredShading.h

@@ -13,6 +13,27 @@ namespace anki
 /// @addtogroup renderer
 /// @{
 
+/// Parameters to be passed to TraditionalDeferredLightShading::drawLights.
+class TraditionalDeferredLightShadingDrawInfo
+{
+public:
+	Mat4 m_viewProjectionMatrix;
+	Mat4 m_invViewProjectionMatrix;
+	Vec4 m_cameraPosWSpace;
+	UVec4 m_viewport;
+	Vec2 m_gbufferTexCoordsScale;
+	Vec2 m_gbufferTexCoordsBias;
+	Vec2 m_lightbufferTexCoordsScale;
+	Vec2 m_lightbufferTexCoordsBias;
+	F32 m_cameraNear;
+	F32 m_cameraFar;
+	DirectionalLightQueueElement* m_directionalLight ANKI_DEBUG_CODE(= numberToPtr<DirectionalLightQueueElement*>(1));
+	ConstWeakArray<PointLightQueueElement> m_pointLights;
+	ConstWeakArray<SpotLightQueueElement> m_spotLights;
+	CommandBufferPtr m_commandBuffer;
+	Bool m_computeSpecular = false;
+};
+
 /// Helper for drawing using traditional deferred shading.
 class TraditionalDeferredLightShading : public RendererObject
 {
@@ -25,26 +46,13 @@ public:
 
 	/// Run the light shading. It will iterate over the lights and draw them. It doesn't bind anything related to
 	/// GBuffer or the output buffer.
-	void drawLights(const Mat4& vpMat,
-		const Mat4& invViewProjMat,
-		const Vec4& cameraPosWSpace,
-		const UVec4& viewport,
-		const Vec2& gbufferTexCoordsScale,
-		const Vec2& gbufferTexCoordsBias,
-		const Vec2& lightbufferTexCoordsScale,
-		const Vec2& lightbufferTexCoordsBias,
-		F32 cameraNear,
-		F32 cameraFar,
-		DirectionalLightQueueElement* directionalLight,
-		ConstWeakArray<PointLightQueueElement> plights,
-		ConstWeakArray<SpotLightQueueElement> slights,
-		CommandBufferPtr& cmdb);
+	void drawLights(TraditionalDeferredLightShadingDrawInfo& info);
 
 private:
 	ShaderProgramResourcePtr m_lightProg;
-	ShaderProgramPtr m_plightGrProg;
-	ShaderProgramPtr m_slightGrProg;
-	ShaderProgramPtr m_dirLightGrProg;
+	Array<ShaderProgramPtr, 2> m_plightGrProg;
+	Array<ShaderProgramPtr, 2> m_slightGrProg;
+	Array<ShaderProgramPtr, 2> m_dirLightGrProg;
 
 	/// @name Meshes of light volumes.
 	/// @{