Panagiotis Christopoulos Charitos 13 years ago
parent
commit
1a47c1cfa4

+ 6 - 3
include/anki/renderer/Is.h

@@ -35,7 +35,7 @@ public:
 	static const U TILES_X_COUNT = 16;
 	static const U TILES_Y_COUNT = 16;
 
-	static const U MAX_LIGHTS_PER_TILE = 32;
+	static const U MAX_LIGHTS_PER_TILE = 40;
 
 	static const U MAX_POINT_LIGHTS = 512;
 	static const U MAX_SPOT_LIGHTS = 8;
@@ -59,7 +59,7 @@ public:
 	}
 	/// @}
 
-private
+private:
 	/// A screen tile
 	struct Tile
 	{
@@ -120,6 +120,9 @@ private
 	/// Shadow mapping
 	Sm sm;
 
+	/// Opt because many ask for it
+	Camera* cam;
+
 	/// Called by init
 	void initInternal(const RendererInitializer& initializer);
 
@@ -136,7 +139,7 @@ private
 
 	/// Update the 4 planes of the tile for a perspective camera
 	void updateTiles4PlanesInternal(const PerspectiveCamera& cam,
-		U32 start, U32 stop)
+		U32 start, U32 stop);
 
 	/// See if the light is inside the tile
 	static Bool cullLight(const PointLight& light, const Tile& tile);

+ 7 - 8
include/anki/util/Functions.h

@@ -4,8 +4,7 @@
 #ifndef ANKI_UTIL_FUNCTIONS_H
 #define ANKI_UTIL_FUNCTIONS_H
 
-#include <cstdint>
-#include <cstdlib> // For size_t
+#include "anki/util/StdTypes.h"
 
 namespace anki {
 
@@ -15,22 +14,22 @@ namespace anki {
 /// @{
 
 /// Pick a random number from min to max
-extern int randRange(int min, int max);
+extern I32 randRange(I32 min, I32 max);
 
 /// Pick a random number from min to max
-extern uint32_t randRange(uint32_t min, uint32_t max);
+extern U32 randRange(U32 min, U32 max);
 
 /// Pick a random number from min to max
-extern float randRange(float min, float max);
+extern F32 randRange(F32 min, F32 max);
 
 /// Pick a random number from min to max
-extern double randRange(double min, double max);
+extern F64 randRange(F64 min, F64 max);
 
-extern float randFloat(float max);
+extern F32 randFloat(F32 max);
 
 /// Get the size in bytes of a vector
 template<typename Vec>
-extern size_t getVectorSizeInBytes(const Vec& v)
+extern PtrSize getVectorSizeInBytes(const Vec& v)
 {
 	return v.size() * sizeof(typename Vec::value_type);
 }

+ 26 - 35
shaders/IsLpGeneric.glsl

@@ -11,8 +11,6 @@
 #pragma anki include "shaders/Pack.glsl"
 #pragma anki include "shaders/LinearDepth.glsl"
 
-#define DISCARD 0
-
 #if !MAX_LIGHTS_PER_TILE || !TILES_X_COUNT || !TILES_Y_COUNT
 #	error "See file"
 #endif
@@ -21,6 +19,8 @@
 #	error "See file"
 #endif
 
+#define ATTENUATION_FINE 0
+
 /// @name Uniforms
 /// @{
 
@@ -55,6 +55,7 @@ struct Light
 struct SpotLight
 {
 	Light light;
+	vec4 lightDirection;
 	mat4 texProjectionMat;
 };
 
@@ -103,13 +104,6 @@ vec3 getFragPosVSpace()
 {
 	float depth = texture(msDepthFai, vTexCoords).r;
 
-#if DISCARD
-	if(depth == 1.0)
-	{
-		discard;
-	}
-#endif
-
 	vec3 fragPosVspace;
 	fragPosVspace.z = -planes.y / (planes.x + depth);
 
@@ -133,25 +127,20 @@ vec3 doPhong(in vec3 fragPosVspace, in vec3 normal, in vec3 diffuse,
 
 	// Instead of using normalize(frag2LightVec) we brake the operation 
 	// because we want fragLightDist for the calc of the attenuation
-	float fragLightDistSqrt = sqrt(dot(frag2LightVec, frag2LightVec));
-	vec3 lightDir = frag2LightVec / fragLightDistSqrt;
+	float fragLightDistSquared = dot(frag2LightVec, frag2LightVec);
+	float fragLightDist = sqrt(fragLightDistSquared);
+	vec3 lightDir = frag2LightVec / fragLightDist;
 
 	// Lambert term
-	float lambertTerm = dot(normal, lightDir);
+	float lambertTerm = max(0.0, dot(normal, lightDir));
 
-#if DISCARD
-	if(lambertTerm < 0.0)
-	{
-		discard;
-	}
+	// Attenuation
+#if ATTENUATION_FINE
+	float att = max(1.0 - fragLightDistSquared / light.posAndRadius.w, 0.0);
 #else
-	lambertTerm = max(0.0, lambertTerm);
+	float att = max(1.0 - fragLightDist / light.posAndRadius.w, 0.0);
 #endif
 
-	// Attenuation
-	float attenuation = 
-		max(1.0 - fragLightDistSqrt / light.posAndRadius.w, 0.0);
-
 	// Diffuse
 	vec3 difCol = diffuse * light.diffuseColor.rgb;
 
@@ -162,7 +151,7 @@ vec3 doPhong(in vec3 fragPosVspace, in vec3 normal, in vec3 diffuse,
 	vec3 specCol = light.specularColor.rgb * (specIntensity * specularAll.r);
 	
 	// end
-	return (difCol + specCol) * (attenuation * lambertTerm);
+	return (difCol + specCol) * (att * lambertTerm);
 }
 
 //==============================================================================
@@ -172,7 +161,7 @@ void main()
 	uvec2 msAll = texture(msFai0, vTexCoords).rg;
 
 	// get frag pos in view space
-	vec3 fragPosVspace = getFragPosVSpace();
+	const vec3 fragPosVspace = getFragPosVSpace();
 
 	// Decode MS
 	vec3 normal = unpackNormal(unpackHalf2x16(msAll[1]));
@@ -199,17 +188,19 @@ void main()
 	{
 		uint lightId = tiles[vInstanceId].lightIndices[i / 4][i % 4];
 
-		vec4 texCoords2 = slights[lightId].texProjectionMat 
-			* vec4(fragPosVspace, 1.0);
-		vec3 texCoords3 = texCoords2.xyz / texCoords2.w;
-		
-		vec2 pureColor = doPhong(fragPosVspace, normal, diffuseAndSpec.rgb, 
-			specularAll, plights[lightId].light);
+		vec3 pureColor = doPhong(fragPosVspace, normal, diffuseAndSpec.rgb, 
+			specularAll, slights[lightId].light);
+
+		vec4 lightDirAndAng = slights[lightId].lightDirection;
+
+		vec3 l = 
+			normalize(fragPosVspace - slights[lightId].light.posAndRadius.xyz);
 
-		vec3 lightTexColor = 
-			textureProj(lightTextures[lightId], texCoords2.xyz).rgb;
+		float costheta = dot(l, lightDirAndAng.xyz);
+		float spotFactor = smoothstep(lightDirAndAng.w,
+			cos(0.75 / 10), costheta);
 
-		fColor += pureColor * lightTexColor;
+		fColor += pureColor * spotFactor;
 	}
 
 #if 0
@@ -227,9 +218,9 @@ void main()
 #endif
 
 #if 0
-	if(lightsCount > 0)
+	if(tiles[vInstanceId].lightsCount[1] > 0)
 	{
-		fColor += vec3(0.0, float(lightsCount) / 7.0, 0.0);
+		fColor += vec3(0.0, 1.0, 0.0);
 	}
 #endif
 }

+ 9 - 4
src/collision/Frustum.cpp

@@ -1,6 +1,7 @@
 #include "anki/collision/Frustum.h"
 #include "anki/collision/LineSegment.h"
 #include "anki/collision/Aabb.h"
+#include <limits>
 
 namespace anki {
 
@@ -51,14 +52,18 @@ PerspectiveFrustum& PerspectiveFrustum::operator=(const PerspectiveFrustum& b)
 //==============================================================================
 F32 PerspectiveFrustum::testPlane(const Plane& p) const
 {
-	F32 o = 0.0;
+	// At this point all are in the front side of the plane, all the are 
+	// intersecting or all on the negative side
 
-	for(const Vec3& dir : dirs)
+	LineSegment ls(eye, dirs[0]);
+	F32 o = ls.testPlane(p);
+
+	for(U i = 1; i < dirs.size(); i++)
 	{
-		LineSegment ls(eye, dir);
+		LineSegment ls(eye, dirs[i]);
 		F32 t = ls.testPlane(p);
 
-		if(t == 0)
+		if(t == 0.0)
 		{
 			return 0.0;
 		}

+ 15 - 11
src/renderer/Dbg.cpp

@@ -69,17 +69,6 @@ void Dbg::run()
 		}
 
 		sceneDrawer->draw(*node);
-
-		// XXX
-		if(node->getLight())
-		{
-			CollisionDebugDrawer cdd(drawer.get());
-			Light& l = *node->getLight();
-			l.getLightType();
-			PointLight& pl = static_cast<PointLight&>(l);
-			deleteme = &pl;
-			pl.getSphere().accept(cdd);
-		}
 	}
 
 	for(const Sector* sector : scene.sectors)
@@ -87,6 +76,21 @@ void Dbg::run()
 		sceneDrawer->draw(sector->getOctree());
 	}
 
+#if 0
+	drawer->setViewProjectionMatrix(r->getViewProjectionMatrix());
+	drawer->setModelMatrix(Mat4::getIdentity());
+
+	SceneNode* node = scene.findSceneNode("spot0");
+	Light* light = static_cast<Light*>(node);
+	SpotLight* slight = static_cast<SpotLight*>(light);
+
+	const Transform& trf = light->getWorldTransform();
+
+	drawer->drawLine(trf.getOrigin(),
+		trf.getOrigin() + (-trf.getRotation().getZAxis()), 
+		Vec4(1.0));
+#endif
+
 #if 0
 	// XXX
 	drawer->setViewProjectionMatrix(r->getViewProjectionMatrix());

+ 26 - 25
src/renderer/Is.cpp

@@ -5,8 +5,6 @@
 #include "anki/scene/Light.h"
 #include "anki/core/ThreadPool.h"
 
-#define BLEND_ENABLE 1
-
 namespace anki {
 
 //==============================================================================
@@ -25,6 +23,7 @@ struct ShaderPointLight: ShaderLight
 
 struct ShaderSpotLight: ShaderLight
 {
+	Vec4 lightDirection;
 	Mat4 texProjectionMat;
 };
 
@@ -125,7 +124,7 @@ struct WriteTilesUboJob: ThreadJob
 /// Job that updates the tile planes
 struct UpdateTilesJob: ThreadJob
 {
-	F32 (*pixels)[TILES_Y_COUNT][TILES_X_COUNT][2];
+	F32 (*pixels)[Is::TILES_Y_COUNT][Is::TILES_X_COUNT][2];
 	Is* is;
 
 	void operator()(U threadId, U threadsCount)
@@ -321,12 +320,12 @@ void Is::updateTiles()
 	// 
 
 	ThreadPool& threadPool = ThreadPoolSingleton::get();
-	UpdateTilesJob jobs[ThreadPool::MAX_THREADS]
+	UpdateTilesJob jobs[ThreadPool::MAX_THREADS];
 	
 	for(U i = 0; i < threadPool.getThreadsCount(); i++)
 	{
-		job[i].pixels = &pixels;
-		job[i].is = this;
+		jobs[i].pixels = &pixels;
+		jobs[i].is = this;
 
 		threadPool.assignNewJob(i, &jobs[i]);
 	}
@@ -336,7 +335,7 @@ void Is::updateTiles()
 
 //==============================================================================
 void Is::updateTilePlanes(F32 (*pixels)[TILES_Y_COUNT][TILES_X_COUNT][2],
-	U32 start, U32 finish)
+	U32 start, U32 stop)
 {
 	// Update only the 4 planes
 	updateTiles4Planes(start, stop);
@@ -345,6 +344,8 @@ void Is::updateTilePlanes(F32 (*pixels)[TILES_Y_COUNT][TILES_X_COUNT][2],
 	// - transform the planes
 	for(U32 k = start; k < stop; k++)
 	{
+		U i = k % TILES_X_COUNT;
+		U j = k / TILES_X_COUNT;
 		Tile& tile = tiles[j][i];
 
 		/// Calculate as you do in the vertex position inside the shaders
@@ -360,7 +361,7 @@ void Is::updateTilePlanes(F32 (*pixels)[TILES_Y_COUNT][TILES_X_COUNT][2],
 		for(U k = 0; k < 6; k++)
 		{
 			tile.planesWSpace[k] = tile.planes[k].getTransformed(
-				Transform(cam.getViewMatrix()));
+				Transform(cam->getWorldTransform()));
 		}
 	}
 }
@@ -368,19 +369,18 @@ void Is::updateTilePlanes(F32 (*pixels)[TILES_Y_COUNT][TILES_X_COUNT][2],
 //==============================================================================
 void Is::updateTiles4Planes(U32 start, U32 stop)
 {
-	Camera& cam = r->getScene().getActiveCamera();
-	U32 camTimestamp = cam.getFrustumable()->getFrustumableTimestamp();
-
+	U32 camTimestamp = cam->getFrustumable()->getFrustumableTimestamp();
 	if(camTimestamp < planesUpdateTimestamp)
 	{
+		// Early exit if the frustum have not changed
 		return;
 	}
 
-	switch(cam.getCameraType())
+	switch(cam->getCameraType())
 	{
 	case Camera::CT_PERSPECTIVE:
 		updateTiles4PlanesInternal(
-			static_cast<const PerspectiveCamera&>(cam), start, stop);
+			static_cast<const PerspectiveCamera&>(*cam), start, stop);
 		break;
 	default:
 		ANKI_ASSERT(0 && "Unimplemented");
@@ -451,8 +451,6 @@ void Is::updateTiles4PlanesInternal(const PerspectiveCamera& cam,
 void Is::writeLightUbo(ShaderPointLights& shaderLights, U32 maxShaderLights,
 	PointLight* visibleLights[], U32 visibleLightsCount, U start, U end)
 {
-	const Camera& cam = r->getScene().getActiveCamera();
-
 	for(U64 i = start; i < end; i++)
 	{
 		ANKI_ASSERT(i < maxShaderLights);
@@ -460,7 +458,7 @@ void Is::writeLightUbo(ShaderPointLights& shaderLights, U32 maxShaderLights,
 		const PointLight& light = *visibleLights[i];
 
 		Vec3 pos = light.getWorldTransform().getOrigin().getTransformed(
-			cam.getViewMatrix());
+			cam->getViewMatrix());
 
 		pl.posAndRadius = Vec4(pos, light.getRadius());
 		pl.diffuseColor = light.getDiffuseColor();
@@ -472,8 +470,6 @@ void Is::writeLightUbo(ShaderPointLights& shaderLights, U32 maxShaderLights,
 void Is::writeLightUbo(ShaderSpotLights& shaderLights, U32 maxShaderLights,
 	SpotLight* visibleLights[], U32 visibleLightsCount, U start, U end)
 {
-	const Camera& cam = r->getScene().getActiveCamera();
-
 	for(U64 i = start; i < end; i++)
 	{
 		ANKI_ASSERT(i < maxShaderLights);
@@ -481,17 +477,21 @@ void Is::writeLightUbo(ShaderSpotLights& shaderLights, U32 maxShaderLights,
 		const SpotLight& light = *visibleLights[i];
 
 		Vec3 pos = light.getWorldTransform().getOrigin().getTransformed(
-			cam.getViewMatrix());
+			cam->getViewMatrix());
 
 		slight.posAndRadius = Vec4(pos, light.getDistance());
 		slight.diffuseColor = light.getDiffuseColor();
 		slight.specularColor = light.getSpecularColor();
+
+		Vec3 lightDir = -light.getWorldTransform().getRotation().getZAxis();
+		lightDir = cam->getViewMatrix().getRotationPart() * lightDir;
+		slight.lightDirection = Vec4(lightDir, cos(light.getFov() / 2.0));
 		
 		static const Mat4 biasMat4(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 
 			0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0);
 		slight.texProjectionMat = biasMat4 * light.getProjectionMatrix() *
 			Mat4::combineTransformations(light.getViewMatrix(),
-			Mat4(cam.getWorldTransform()));
+			Mat4(cam->getWorldTransform()));
 	}
 }
 
@@ -502,7 +502,6 @@ void Is::writeTilesUbo(
 	ShaderTiles& shaderTiles, U32 maxLightsPerTile,
 	U32 start, U32 end)
 {
-	const Camera& cam = r->getScene().getActiveCamera();
 	ANKI_ASSERT(maxLightsPerTile <= MAX_LIGHTS_PER_TILE);
 
 	for(U32 i = start; i < end; i++)
@@ -570,8 +569,7 @@ void Is::writeTilesUbo(
 void Is::lightPass()
 {
 	ThreadPool& threadPool = ThreadPoolSingleton::get();
-	Camera& cam = r->getScene().getActiveCamera();
-	VisibilityInfo& vi = cam.getFrustumable()->getVisibilityInfo();
+	VisibilityInfo& vi = cam->getFrustumable()->getVisibilityInfo();
 
 	Array<PointLight*, MAX_POINT_LIGHTS> visiblePointLights;
 	U visiblePointLightsCount = 0;
@@ -703,8 +701,10 @@ void Is::run()
 	GlStateSingleton::get().disable(GL_DEPTH_TEST);
 	GlStateSingleton::get().disable(GL_BLEND);
 
-	// Write common block
 	Scene& scene = r->getScene();
+	cam = &scene.getActiveCamera();
+
+	// Write common block
 	if(commonUboUpdateTimestamp < r->getPlanesUpdateTimestamp()
 		|| commonUboUpdateTimestamp < scene.getAmbientColorUpdateTimestamp()
 		|| commonUboUpdateTimestamp == 1)
@@ -715,7 +715,7 @@ void Is::run()
 			r->getPlanes().y());
 		blk.limitsOfNearPlane = Vec4(r->getLimitsOfNearPlane(),
 			r->getLimitsOfNearPlane2());
-		blk.sceneAmbientColor = Vec4(r->getScene().getAmbientColor(), 0.0);
+		blk.sceneAmbientColor = Vec4(scene.getAmbientColor(), 0.0);
 
 		commonUbo.write(&blk);
 
@@ -724,6 +724,7 @@ void Is::run()
 
 	commonUbo.setBinding(COMMON_UNIFORMS_BLOCK_BINDING);
 	pointLightsUbo.setBinding(POINT_LIGHTS_BLOCK_BINDING);
+	spotLightsUbo.setBinding(SPOT_LIGHTS_BLOCK_BINDING);
 	tilesUbo.setBinding(TILES_BLOCK_BINDING);
 
 	// Update tiles

+ 8 - 8
src/util/Functions.cpp

@@ -6,35 +6,35 @@
 namespace anki {
 
 //==============================================================================
-int randRange(int min, int max)
+I32 randRange(I32 min, I32 max)
 {
 	return (rand() % (max - min + 1)) + min;
 }
 
 //==============================================================================
-uint32_t randRange(uint32_t min, uint32_t max)
+U32 randRange(U32 min, U32 max)
 {
 	return (rand() % (max - min + 1)) + min;
 }
 
 //==============================================================================
-float randRange(float min, float max)
+F32 randRange(F32 min, F32 max)
 {
-	float r = (float)rand() / (float)RAND_MAX;
+	F32 r = (F32)rand() / (F32)RAND_MAX;
 	return min + r * (max - min);
 }
 
 //==============================================================================
-double randRange(double min, double max)
+F64 randRange(F64 min, F64 max)
 {
-	double r = (double)rand() / (double)RAND_MAX;
+	F64 r = (F64)rand() / (F64)RAND_MAX;
 	return min + r * (max - min);
 }
 
 //==============================================================================
-float randFloat(float max)
+F32 randFloat(F32 max)
 {
-	float r = float(rand()) / float(RAND_MAX);
+	F32 r = F32(rand()) / F32(RAND_MAX);
 	return r * max;
 }
 

+ 16 - 13
testapp/Main.cpp

@@ -38,6 +38,7 @@
 #include "anki/resource/Material.h"
 #include "anki/core/ThreadPool.h"
 #include "anki/core/Timestamp.h"
+#include "anki/util/Functions.h"
 
 using namespace anki;
 
@@ -79,7 +80,7 @@ void init()
 		1.0));
 
 	// lights
-	Vec3 lpos(-100.0, 0.0, -20.0);
+	Vec3 lpos(-100.0, 0.0, -50.0);
 	for(int i = 0; i < 50; i++)
 	{
 		for(int j = 0; j < 10; j++)
@@ -89,29 +90,31 @@ void init()
 			PointLight* point = new PointLight(name.c_str(), &scene,
 				Movable::MF_NONE, nullptr);
 			point->setRadius(2.0);
-			point->setDiffuseColor(Vec4(1.0, 0.0, 0.0, 0.0));
-			point->setSpecularColor(Vec4(0.0, 0.0, 1.0, 0.0));
+			point->setDiffuseColor(Vec4(randFloat(3.0), randFloat(3.0), randFloat(3.0), 0.0));
+			point->setSpecularColor(Vec4(randFloat(3.0), randFloat(3.0), randFloat(3.0), 0.0));
 			point->setLocalTranslation(lpos);
 
-			lpos.z() += 4.0;
+			lpos.z() += 10.0;
 		}
 
 		lpos.x() += 4.0;
-		lpos.z() = -20;
+		lpos.z() = -50;
 	}
 
 
-	/*SpotLight* spot = new SpotLight("spot0", &scene, Movable::MF_NONE, nullptr);
+#if 0
+	SpotLight* spot = new SpotLight("spot0", &scene, Movable::MF_NONE, nullptr);
 	spot->setFov(Math::toRad(45.0));
 	spot->setLocalTransform(Transform(Vec3(1.3, 4.3, 3.0),
-		Mat3(Euler(Math::toRad(-20), Math::toRad(20), 0.0)), 1.0));
-	spot->setDiffuseColor(Vec4(4.0));
+		Mat3::getIdentity(), 1.0));
+	spot->setDiffuseColor(Vec4(1.0));
 	spot->setSpecularColor(Vec4(1.0));
 	spot->loadTexture("gfx/lights/flashlight.tga");
 	spot->setDistance(20.0);
 	spot->setShadowEnabled(true);
+#endif
 
-	PointLight* point = new PointLight("point0", &scene, Movable::MF_NONE,
+	/*PointLight* point = new PointLight("point0", &scene, Movable::MF_NONE,
 		nullptr);
 	point->setRadius(3.0);
 	point->setDiffuseColor(Vec4(1.0, 0.0, 0.0, 0.0));
@@ -187,11 +190,11 @@ void mainLoopExtra()
 	{
 		mover = SceneSingleton::get().findSceneNode("horse")->getMovable();
 	}
-	/*if(in.getKey(SDL_SCANCODE_3))
+	if(in.getKey(SDL_SCANCODE_3))
 	{
 		mover = SceneSingleton::get().findSceneNode("spot0")->getMovable();
 	}
-	if(in.getKey(SDL_SCANCODE_4))
+	/*if(in.getKey(SDL_SCANCODE_4))
 	{
 		mover = SceneSingleton::get().findSceneNode("point0")->getMovable();
 	}
@@ -275,7 +278,7 @@ void mainLoop()
 
 		// Sleep
 		//
-#if 1
+#if 0
 		timer.stop();
 		if(timer.getElapsedTime() < AppSingleton::get().getTimerTick())
 		{
@@ -283,7 +286,7 @@ void mainLoop()
 				- timer.getElapsedTime()) * 1000.0);
 		}
 #else
-		if(MainRendererSingleton::get().getFramesCount() == 100)
+		if(MainRendererSingleton::get().getFramesCount() == 1000)
 		{
 			break;
 		}