Sfoglia il codice sorgente

Adding compute shader for light rejection (WIP). Minor refactoring

Panagiotis Christopoulos Charitos 12 anni fa
parent
commit
129434ec3a

+ 2 - 2
include/anki/gl/GlState.h

@@ -89,6 +89,7 @@ public:
 	void setBlendFunctions(const GLenum sFactor, const GLenum dFactor);
 
 	void setDepthMaskEnabled(const Bool enable);
+	void setDepthFunc(const GLenum val);
 	/// @}
 
 private:
@@ -100,10 +101,9 @@ private:
 	GLint clearStencilValue;
 	Array<GLenum, 2> blendFuncs;
 
-	// XXX
-	GLenum depthFunc; 
 	Array<GLint, 4> colorMask;
 	GLint depthMask;
+	GLenum depthFunc;
 	/// @}
 
 	/// Sync the local members with the opengl ones

+ 2 - 1
include/anki/renderer/Drawer.h

@@ -2,6 +2,7 @@
 #define ANKI_RENDERER_DRAWER_H
 
 #include "anki/util/StdTypes.h"
+#include "anki/resource/PassLevelKey.h"
 
 namespace anki {
 
@@ -35,7 +36,7 @@ public:
 	void render(
 		SceneNode& frsn,
 		RenderingStage stage, 
-		U32 pass, 
+		Pass pass, 
 		SceneNode& renderableSceneNode,
 		U32* subSpatialIndices,
 		U subSpatialIndicesCount);

+ 0 - 1
include/anki/renderer/Is.h

@@ -75,7 +75,6 @@ private:
 
 	/// Light shaders
 	ShaderProgramResourcePointer lightPassProg;
-	ShaderProgramResourcePointer tilerProg;
 
 	/// Shadow mapping
 	Sm sm;

+ 3 - 3
include/anki/resource/Model.h

@@ -43,19 +43,19 @@ public:
 
 	const Obb& getBoundingShape() const
 	{
-		PassLevelKey key(0, 0);
+		PassLevelKey key(COLOR_PASS, 0);
 		return getMeshBase(key).getBoundingShape();
 	}
 
 	const Obb& getBoundingShapeSub(U32 subMeshId) const
 	{
-		PassLevelKey key(0, 0);
+		PassLevelKey key(COLOR_PASS, 0);
 		return getMeshBase(key).getBoundingShapeSub(subMeshId);
 	}
 
 	U32 getSubMeshesCount() const
 	{
-		PassLevelKey key(0, 0);
+		PassLevelKey key(COLOR_PASS, 0);
 		return getMeshBase(key).getSubMeshesCount();
 	}
 

+ 16 - 2
include/anki/resource/PassLevelKey.h

@@ -7,13 +7,27 @@
 
 namespace anki {
 
+/// The AnKi passes
+enum Pass
+{
+	COLOR_PASS, ///< For MS
+	DEPTH_PASS, ///< For shadows
+
+	/// For MS color pass after early Z. It's different than COLOR because it
+	/// doesn't do any discard, earlyZ did it before
+	//COLOR_EARLYZ_PASS,
+
+	PASS_COUNT
+};
+
 /// A key that consistst of the rendering pass and the level of detail
 struct PassLevelKey
 {
-	U8 pass = 0;
-	U8 level = 0;
+	U8 pass;
+	U8 level;
 
 	PassLevelKey()
+		: pass(COLOR_PASS), level(0)
 	{}
 
 	PassLevelKey(const PassLevelKey& b)

+ 85 - 0
shaders/IsRejectLights.glsl

@@ -0,0 +1,85 @@
+// This compute shader rejects lights
+
+#pragma anki start computeShader
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+
+#define TILE_W (DEPTHMAP_WIDTH / TILES_X_COUNT)
+#define TILE_H (DEPTHMAP_HEIGHT / TILES_Y_COUNT)
+
+#define tileX gl_WorkGroupID.x
+#define tileY gl_WorkGroupID.y
+
+uniform highp sampler2D depthMap;
+
+layout(std430) buffer tilesBlock
+{
+	Tile tiles[TILES_Y_COUNT][TILES_X_COUNT];
+};
+
+layout(std140) buffer pointLightsBlock
+{
+	PointLight pointLights[MAX_POINT_LIGHTS];
+};
+
+// Common uniforms 
+layout(std430) uniform commonBlock
+{
+	/// Packs:
+	/// - xy: Planes. For the calculation of frag pos in view space
+	uniform vec2 planes;
+};
+
+void main()
+{
+	//
+	// First calculate the z of the near plane
+	//
+	float minDepth = 10000.0; // min depth of tile
+
+	uvec2 coord = uvec2(uvec2(tileX, tileY) * uvec2(TILE_W, TILE_H));
+
+	for(uint x = 0; x < TILE_W; x++)
+	{
+		for(uint y = 0; y < TILE_H; i++)
+		{
+			float depth = texelFetch(depthMap, coord + uvec2(x, y)).r;
+
+			minDepth = min(depth, minDepth);
+		}
+	}
+
+	// Convert to view space
+	float nearZ = -planes.y / (planes.x + minDepth);
+
+	//
+	//
+	//
+	uint newPointLightIndices[MAX_POINT_LIGHTS_PER_TILE];
+	uint newPointLightsCount = 0;
+
+	uint pointLightsCount = tiles[vInstanceId].lightsCount[0];
+	for(uint i = 0U; i < pointLightsCount; ++i)
+	{
+		uint lightId = tiles[tileY][tileX].pointLightIndices[i];
+
+		vec4 posRadius = pointLights[lightId].posRadius;
+		vec3 pos = posRadius.xyz;
+		float radius = posRadius.w;
+		
+		// Should reject?
+		if(pos.z - radius <= nearZ)
+		{
+			// No
+
+			newPointLightIndices[newPointLightsCount++] = lightId;
+		}
+	}
+
+	// Copy back
+	for(uint i = 0U; i < newPointLightsCount; i++)
+	{
+		tiles[tileY][tileX].pointLightIndices[i] = newPointLightIndices[i];
+	}
+	tiles[vInstanceId].lightsCount[0] = newPointLightsCount;
+}

+ 18 - 0
src/gl/GlState.cpp

@@ -218,6 +218,8 @@ void GlState::sync()
 
 	// depth mask
 	glGetIntegerv(GL_DEPTH_WRITEMASK, &depthMask);
+	// depth func
+	glGetIntegerv(GL_DEPTH_FUNC, (GLint*)&depthFunc);
 }
 
 //==============================================================================
@@ -309,4 +311,20 @@ void GlState::setDepthMaskEnabled(const Bool enable)
 	}
 }
 
+//==============================================================================
+void GlState::setDepthFunc(const GLenum val)
+{
+#if ANKI_DEBUG
+	GLint real;
+	glGetIntegerv(GL_DEPTH_FUNC, &real);
+	ANKI_ASSERT(real == depthFunc);
+#endif
+
+	if(val != depthFunc)
+	{
+		glDepthFunc(val);
+		depthFunc = val;
+	}
+}
+
 } // end namespace anki

+ 1 - 1
src/renderer/Bs.cpp

@@ -31,7 +31,7 @@ void Bs::run()
 		++it)
 	{
 		drawer.render(scene.getActiveCamera(), RenderableDrawer::RS_BLEND,
-			0, *(*it).node, (*it).subSpatialIndices, 
+			COLOR_PASS, *(*it).node, (*it).subSpatialIndices, 
 			(*it).subSpatialIndicesCount);
 	}
 

+ 1 - 1
src/renderer/Drawer.cpp

@@ -279,7 +279,7 @@ void RenderableDrawer::setupShaderProg(const PassLevelKey& key_,
 
 //==============================================================================
 void RenderableDrawer::render(SceneNode& frsn, RenderingStage stage,
-	U32 pass, SceneNode& rsn, U32* subSpatialIndices,
+	Pass pass, SceneNode& rsn, U32* subSpatialIndices,
 	U subSpatialIndicesCount)
 {
 	ANKI_ASSERT(frsn.getFrustumable());

+ 1 - 21
src/renderer/Ez.cpp

@@ -35,30 +35,10 @@ void Ez::run()
 		it != vi.getRenderablesEnd() && count < maxObjectsToDraw; ++it)
 	{
 		r->getSceneDrawer().render(cam, RenderableDrawer::RS_MATERIAL,
-			0, *(*it).node, (*it).subSpatialIndices, 
+			DEPTH_PASS, *(*it).node, (*it).subSpatialIndices, 
 			(*it).subSpatialIndicesCount);
 		++count;
 	}
-
-	/*Camera& cam = r.getCamera();
-
-	fbo.bind();
-
-	GlStateMachineSingleton::get().setViewport(0, 0,
-		r.getWidth(), r.getHeight());
-
-	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-	GlStateMachineSingleton::get().enable(GL_DEPTH_TEST, true);
-	GlStateMachineSingleton::get().enable(GL_BLEND, false);
-
-	glClear(GL_DEPTH_BUFFER_BIT);
-
-	for(RenderableNode* node, cam.getVisibleMsRenderableNodes())
-	{
-		r.getSceneDrawer().renderRenderableNode(cam, 1, *node);
-	}
-
-	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);*/
 }
 
 } // end namespace anki

+ 2 - 1
src/renderer/Is.cpp

@@ -580,11 +580,12 @@ void Is::initInternal(const RendererInitializer& initializer)
 void Is::rejectLights()
 {
 #if ANKI_GL == ANKI_GL_DESKTOP
-	if(!useCompute())
+	if(ANKI_UNLIKELY(!useCompute()))
 	{
 		return;
 	}
 
+	
 #endif
 }
 

+ 1 - 1
src/renderer/MainRenderer.cpp

@@ -66,7 +66,7 @@ void MainRenderer::initGl()
 	GlStateSingleton::get().disable(GL_STENCIL_TEST);
 	//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 	GlStateSingleton::get().setDepthMaskEnabled(true);
-	glDepthFunc(GL_LESS);
+	GlStateSingleton::get().setDepthFunc(GL_LESS);
 
 	glDisable(GL_DITHER);
 

+ 15 - 29
src/renderer/Ms.cpp

@@ -43,33 +43,25 @@ void Ms::init(const RendererInitializer& initializer)
 //==============================================================================
 void Ms::run()
 {
+	GlState& gl = GlStateSingleton::get();
+
 	fbo.bind();
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
 
-	/*if(ez.getEnabled())
-	{
-		ez.run();
-	}*/
-
-	/*if(!ez.getEnabled())
-	{
-		glClear(GL_DEPTH_BUFFER_BIT);
-	}*/
-
-	GlStateSingleton::get().setViewport(0, 0, r->getWidth(), r->getHeight());
-	GlStateSingleton::get().disable(GL_BLEND);
-	GlStateSingleton::get().enable(GL_DEPTH_TEST);
-
-	//GlStateMachineSingleton::get().enable(GL_DEPTH_TEST, true);
-	//app->getSceneGraph().skybox.Render(cam.getViewMatrix().getRotationPart());
-	//glDepthFunc(GL_LEQUAL);
+	gl.setViewport(0, 0, r->getWidth(), r->getHeight());
+	gl.disable(GL_BLEND);
+	gl.enable(GL_DEPTH_TEST);
+	gl.setDepthFunc(GL_LESS);
+	gl.setDepthMaskEnabled(true);
 
-	// if ez then change the default depth test and disable depth writing
-	/*if(ez.getEnabled())
+	if(ez.getEnabled())
 	{
-		glDepthMask(false);
-		glDepthFunc(GL_EQUAL);
-	}*/
+		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+		ez.run();
+		gl.setDepthFunc(GL_LEQUAL);
+		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+		//gl.setDepthMaskEnabled(false);
+	}
 
 	// render all
 	r->getSceneDrawer().prepareDraw();
@@ -79,16 +71,10 @@ void Ms::run()
 	for(auto it = vi.getRenderablesBegin(); it != vi.getRenderablesEnd(); ++it)
 	{
 		r->getSceneDrawer().render(r->getSceneGraph().getActiveCamera(),
-			RenderableDrawer::RS_MATERIAL, 0, *(*it).node, 
+			RenderableDrawer::RS_MATERIAL, COLOR_PASS, *(*it).node, 
 			(*it).subSpatialIndices, (*it).subSpatialIndicesCount);
 	}
 
-	// restore depth
-	/*if(ez.getEnabled())
-	{
-		glDepthMask(true);
-		glDepthFunc(GL_LESS);
-	}*/
 	ANKI_CHECK_GL_ERROR();
 }
 

+ 2 - 1
src/renderer/Sm.cpp

@@ -76,6 +76,7 @@ void Sm::prepareDraw()
 	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
 	GlStateSingleton::get().enable(GL_DEPTH_TEST);
 	GlStateSingleton::get().disable(GL_BLEND);
+	GlStateSingleton::get().setDepthMaskEnabled(true);
 
 	// for artifacts
 	glPolygonOffset(2.0, 2.0); // keep the values as low as possible!!!!
@@ -207,7 +208,7 @@ Sm::Shadowmap* Sm::doLight(Light& light)
 	for(auto it = vi.getRenderablesBegin(); it != vi.getRenderablesEnd(); ++it)
 	{
 		r->getSceneDrawer().render(light, RenderableDrawer::RS_MATERIAL,
-			1, *(*it).node, (*it).subSpatialIndices, 
+			DEPTH_PASS, *(*it).node, (*it).subSpatialIndices, 
 			(*it).subSpatialIndicesCount);
 	}
 

+ 1 - 1
src/resource/Image.cpp

@@ -470,7 +470,7 @@ static PtrSize calcSizeOfSegment(const AnkiTextureHeader& header,
 	U width = header.width;
 	U height = header.height;
 	U mips = header.mipLevels;
-	U layers;
+	U layers = 0;
 
 	switch(header.type)
 	{

+ 15 - 2
src/resource/Material.cpp

@@ -18,6 +18,11 @@ namespace anki {
 // Misc                                                                        =
 //==============================================================================
 
+//==============================================================================
+static Array<const char*, PASS_COUNT> passNames = {{
+	"COLOR", "DEPTH"
+}};
+
 //==============================================================================
 struct SetMaterialVariableValuesVisitor
 {
@@ -228,6 +233,7 @@ void Material::parseMaterialTag(const XmlElement& materialEl)
 	XmlElement blendFunctionsEl =
 		materialEl.getChildElementOptional("blendFunctions");
 
+	Bool disableDepthPass = false;
 	if(blendFunctionsEl)
 	{
 		// sFactor
@@ -237,6 +243,8 @@ void Material::parseMaterialTag(const XmlElement& materialEl)
 		// dFactor
 		blendingDfactor = blendToEnum(
 			blendFunctionsEl.getChildElement("dFactor").getText());
+
+		disableDepthPass = true;
 	}
 
 	// depthTesting
@@ -265,12 +273,17 @@ void Material::parseMaterialTag(const XmlElement& materialEl)
 
 	for(U32 level = 0; level < levelsOfDetail; ++level)
 	{
-		for(U32 pid = 0; pid < passes.size(); ++pid)
+		for(U32 pid = 0; pid < PASS_COUNT; ++pid)
 		{
+			if(disableDepthPass && pid == DEPTH_PASS)
+			{
+				continue;
+			}
+
 			std::stringstream src;
 
 			src << "#define LOD " << level << std::endl;
-			src << "#define PASS_" << passes[pid] << std::endl;
+			src << "#define PASS_" << passNames[pid] << std::endl;
 			src << mspc.getShaderProgramSource() << std::endl;
 
 			std::string filename =

+ 3 - 2
testapp/Main.cpp

@@ -474,7 +474,7 @@ void mainLoop()
 
 		// Sleep
 		//
-#if 1
+#if 0
 		timer.stop();
 		if(timer.getElapsedTime() < AppSingleton::get().getTimerTick())
 		{
@@ -537,7 +537,8 @@ void initSubsystems(int argc, char* argv[])
 
 	// Main renderer
 	RendererInitializer initializer;
-	initializer.ms.ez.enabled = true;
+	initializer.ms.ez.enabled = false;
+	initializer.ms.ez.maxObjectsToDraw = 100;
 	initializer.dbg.enabled = false;
 	initializer.is.sm.bilinearEnabled = true;
 	initializer.is.groundLightEnabled = true;