|
|
@@ -54,23 +54,23 @@ struct Plane
|
|
|
|
|
|
struct Tilegrid
|
|
|
{
|
|
|
- Plane planesX[Is::TILES_X_COUNT - 1];
|
|
|
- Plane planesY[Is::TILES_Y_COUNT - 1];
|
|
|
- Plane planesNear[Is::TILES_Y_COUNT][Is::TILES_X_COUNT];
|
|
|
- Plane planesFar[Is::TILES_Y_COUNT][Is::TILES_X_COUNT];
|
|
|
+ Plane planesX[TILES_X_COUNT - 1];
|
|
|
+ Plane planesY[TILES_Y_COUNT - 1];
|
|
|
+ Plane planesNear[TILES_Y_COUNT][TILES_X_COUNT];
|
|
|
+ Plane planesFar[TILES_Y_COUNT][TILES_X_COUNT];
|
|
|
};
|
|
|
|
|
|
struct Tile
|
|
|
{
|
|
|
- U32 lightsCount[4];
|
|
|
- U32 pointLightIndices[Is::MAX_POINT_LIGHTS_PER_TILE];
|
|
|
- U32 spotLightIndices[Is::MAX_SPOT_LIGHTS_PER_TILE];
|
|
|
- U32 spotTexLightndices[Is::MAX_SPOT_TEX_LIGHTS_PER_TILE];
|
|
|
+ Array<U32, 4> lightsCount;
|
|
|
+ Array<U32, MAX_POINT_LIGHTS_PER_TILE> pointLightIndices;
|
|
|
+ Array<U32, MAX_SPOT_LIGHTS_PER_TILE> spotLightIndices;
|
|
|
+ Array<U32, MAX_SPOT_TEX_LIGHTS_PER_TILE> spotTexLightIndices;
|
|
|
};
|
|
|
|
|
|
struct Tiles
|
|
|
{
|
|
|
- Tile tiles[Is::TILES_Y_COUNT][Is::TILES_X_COUNT];
|
|
|
+ Tile tiles[TILES_Y_COUNT][TILES_X_COUNT];
|
|
|
};
|
|
|
|
|
|
struct Light
|
|
|
@@ -87,7 +87,7 @@ struct SpotLight: Light
|
|
|
{
|
|
|
Vec4 lightDir;
|
|
|
Vec4 outerCosInnerCos;
|
|
|
- Vec4 extendPoints[4];
|
|
|
+ Array<Vec4, 4> extendPoints;
|
|
|
};
|
|
|
|
|
|
struct SpotTexLight: SpotLight
|
|
|
@@ -105,9 +105,9 @@ struct CommonUniforms
|
|
|
} // end namespace shader
|
|
|
|
|
|
static const PtrSize LIGHTS_UBO_SIZE =
|
|
|
- MAX_POINT_LIGHTS * sizeof(shader::PointLight)
|
|
|
- + MAX_SPOT_LIGHTS * sizeof(shader::SpotLight)
|
|
|
- + MAX_SPOT_TEX_LIGHTS * sizeof(shader::SpotTexLight);
|
|
|
+ MAX_POINT_LIGHTS * sizeof(shader::PointLight)
|
|
|
+ + MAX_SPOT_LIGHTS * sizeof(shader::SpotLight)
|
|
|
+ + MAX_SPOT_TEX_LIGHTS * sizeof(shader::SpotTexLight);
|
|
|
|
|
|
//==============================================================================
|
|
|
|
|
|
@@ -119,21 +119,22 @@ struct WriteLightsJob: ThreadJob
|
|
|
shader::PointLight* pointLights = nullptr;
|
|
|
shader::SpotLight* spotLights = nullptr;
|
|
|
shader::SpotTexLight* spotTexLights = nullptr;
|
|
|
+
|
|
|
shader::Tiles* tiles = nullptr;
|
|
|
|
|
|
- SceneVector<Light*>::iterator lightsBegin; // XXX Make them const and ShaderNode
|
|
|
- SceneVector<Light*>::iterator lightsEnd;
|
|
|
+ VisibilityTestResults::Container::const_iterator lightsBegin;
|
|
|
+ VisibilityTestResults::Container::const_iterator lightsEnd;
|
|
|
|
|
|
std::atomic<U32>* pointLightsCount = nullptr;
|
|
|
std::atomic<U32>* spotLightsCount = nullptr;
|
|
|
std::atomic<U32>* spotTexLightsCount = nullptr;
|
|
|
|
|
|
std::atomic<U32>
|
|
|
- (*tilePointLightsCount)[TILES_Y_COUNT][TILES_X_COUNT];
|
|
|
+ (*tilePointLightsCount)[TILES_Y_COUNT][TILES_X_COUNT] = nullptr;
|
|
|
std::atomic<U32>
|
|
|
- (*tileSpotLightsCount)[TILES_Y_COUNT][TILES_X_COUNT];
|
|
|
+ (*tileSpotLightsCount)[TILES_Y_COUNT][TILES_X_COUNT] = nullptr;
|
|
|
std::atomic<U32>
|
|
|
- (*tileSpotTexLightsCount)[TILES_Y_COUNT][TILES_X_COUNT];
|
|
|
+ (*tileSpotTexLightsCount)[TILES_Y_COUNT][TILES_X_COUNT] = nullptr;
|
|
|
|
|
|
Tiler* tiler = nullptr;
|
|
|
Is* is = nullptr;
|
|
|
@@ -149,28 +150,52 @@ struct WriteLightsJob: ThreadJob
|
|
|
// Run all lights
|
|
|
for(U64 i = start; i < end; i++)
|
|
|
{
|
|
|
- Light* light = lightsBegin + i;
|
|
|
+ const SceneNode* snode = *(lightsBegin + i);
|
|
|
+ const Light* light = snode->getLight();
|
|
|
+ ANKI_ASSERT(light);
|
|
|
|
|
|
switch(light->getLightType())
|
|
|
{
|
|
|
case Light::LT_POINT:
|
|
|
- doLight(*static_cast<PointLight*>(light));
|
|
|
+ {
|
|
|
+ const PointLight& l =
|
|
|
+ *static_cast<const PointLight*>(light);
|
|
|
+ I pos = doLight(l);
|
|
|
+ if(pos != -1)
|
|
|
+ {
|
|
|
+ binLight(l, pos);
|
|
|
+ }
|
|
|
+ }
|
|
|
break;
|
|
|
case Light::LT_SPOT:
|
|
|
- doLight(*static_cast<SpotLight*>(light));
|
|
|
+ {
|
|
|
+ const SpotLight& l =
|
|
|
+ *static_cast<const SpotLight*>(light);
|
|
|
+ I pos = doLight(l);
|
|
|
+ if(pos != -1)
|
|
|
+ {
|
|
|
+ binLight(l, pos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ ANKI_ASSERT(0);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// Copy CPU light to GPU buffer
|
|
|
- U doLight(PointLight& light)
|
|
|
+ I doLight(const PointLight& light)
|
|
|
{
|
|
|
// Get GPU light
|
|
|
- U32 pos = pointLightsCount->fetch_add(1);
|
|
|
- ANKI_ASSERT(pos < MAX_POINT_LIGHTS);
|
|
|
+ I i = pointLightsCount->fetch_add(1);
|
|
|
+ if(i >= (I)MAX_POINT_LIGHTS)
|
|
|
+ {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
|
|
|
- shader::PointLight& slight = pointLights[pos];
|
|
|
+ shader::PointLight& slight = pointLights[i];
|
|
|
|
|
|
const Camera* cam = is->cam;
|
|
|
ANKI_ASSERT(cam);
|
|
|
@@ -182,24 +207,28 @@ struct WriteLightsJob: ThreadJob
|
|
|
slight.diffuseColorShadowmapId = light.getDiffuseColor();
|
|
|
slight.specularColorTexId = light.getSpecularColor();
|
|
|
|
|
|
- return pos;
|
|
|
+ return i;
|
|
|
}
|
|
|
|
|
|
/// Copy CPU spot light to GPU buffer
|
|
|
- U doLight(SpotLight& light)
|
|
|
+ I doLight(const SpotLight& light)
|
|
|
{
|
|
|
+ const Camera* cam = is->cam;
|
|
|
Bool isTexLight = light.getShadowEnabled();
|
|
|
-
|
|
|
- U32 pos;
|
|
|
+ I i;
|
|
|
shader::SpotLight* baseslight = nullptr;
|
|
|
+
|
|
|
if(isTexLight)
|
|
|
{
|
|
|
// Spot tex light
|
|
|
|
|
|
- pos = spotTexLightsCount->fetch_add(1);
|
|
|
- ANKI_ASSERT(pos < MAX_SPOT_TEX_LIGHTS);
|
|
|
+ i = spotTexLightsCount->fetch_add(1);
|
|
|
+ if(i >= (I)MAX_SPOT_TEX_LIGHTS)
|
|
|
+ {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
|
|
|
- shader::SpotTexLight& slight = spotTexLights[pos];
|
|
|
+ shader::SpotTexLight& slight = spotTexLights[i];
|
|
|
baseslight = &slight;
|
|
|
|
|
|
// Write matrix
|
|
|
@@ -215,18 +244,18 @@ struct WriteLightsJob: ThreadJob
|
|
|
|
|
|
// Transpose because of driver bug
|
|
|
slight.texProjectionMat.transpose();
|
|
|
-
|
|
|
- // Write tex IDs
|
|
|
- slight.diffuseColorShadowmapId.w() = pos;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// Spot light without texture
|
|
|
|
|
|
- pos = spotLightsCount->fetch_add(1);
|
|
|
- ANKI_ASSERT(pos < MAX_SPOT_LIGHTS);
|
|
|
+ i = spotLightsCount->fetch_add(1);
|
|
|
+ if(i >= (I)MAX_SPOT_LIGHTS)
|
|
|
+ {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
|
|
|
- shader::SpotLight& slight = spotLights[pos];
|
|
|
+ shader::SpotLight& slight = spotLights[i];
|
|
|
baseslight = &slight;
|
|
|
}
|
|
|
|
|
|
@@ -238,13 +267,11 @@ struct WriteLightsJob: ThreadJob
|
|
|
cam->getViewMatrix());
|
|
|
baseslight->posRadius = Vec4(pos, light.getDistance());
|
|
|
|
|
|
- // Diff color
|
|
|
- baseslight->diffuseColorShadowmapId = Vec4(
|
|
|
- light.getDiffuseColor().xyz(),
|
|
|
- slight.diffuseColorShadowmapId.w());
|
|
|
+ // Diff color. don't set the shadowmap ID now
|
|
|
+ baseslight->diffuseColorShadowmapId = light.getDiffuseColor();
|
|
|
|
|
|
// Spec color
|
|
|
- slight.specularColorTexId = light.getSpecularColor();
|
|
|
+ baseslight->specularColorTexId = light.getSpecularColor();
|
|
|
|
|
|
// Light dir
|
|
|
Vec3 lightDir = -light.getWorldTransform().getRotation().getZAxis();
|
|
|
@@ -252,21 +279,25 @@ struct WriteLightsJob: ThreadJob
|
|
|
baseslight->lightDir = Vec4(lightDir, 0.0);
|
|
|
|
|
|
// Angles
|
|
|
- slight.outerCosInnerCos = Vec4(light.getOuterAngleCos(),
|
|
|
- light.getInnerAngleCos(), 1.0, 1.0);
|
|
|
+ baseslight->outerCosInnerCos = Vec4(
|
|
|
+ light.getOuterAngleCos(),
|
|
|
+ light.getInnerAngleCos(),
|
|
|
+ 1.0,
|
|
|
+ 1.0);
|
|
|
|
|
|
// extend points
|
|
|
const PerspectiveFrustum& frustum = light.getFrustum();
|
|
|
|
|
|
for(U i = 0; i < 4; i++)
|
|
|
{
|
|
|
- Vec3 dir = light.getWorldTransform().getOrigin()
|
|
|
+ Vec3 extendPoint = light.getWorldTransform().getOrigin()
|
|
|
+ frustum.getDirections()[i];
|
|
|
- dir.transform(cam->getViewMatrix());
|
|
|
- baseslight->extendPoints[i] = Vec4(dir, 1.0);
|
|
|
+
|
|
|
+ extendPoint.transform(cam->getViewMatrix());
|
|
|
+ baseslight->extendPoints[i] = Vec4(extendPoint, 1.0);
|
|
|
}
|
|
|
|
|
|
- return pos;
|
|
|
+ return i;
|
|
|
}
|
|
|
|
|
|
// Bin point light
|
|
|
@@ -274,7 +305,7 @@ struct WriteLightsJob: ThreadJob
|
|
|
{
|
|
|
// Do the tests
|
|
|
Tiler::Bitset bitset;
|
|
|
- tiler->test(light->getSpatialCollisonShape(), true, &bitset);
|
|
|
+ tiler->test(light.getSpatialCollisionShape(), true, &bitset);
|
|
|
|
|
|
// Bin to the correct tiles
|
|
|
for(U t = 0; t < TILES_COUNT; t++)
|
|
|
@@ -302,7 +333,7 @@ struct WriteLightsJob: ThreadJob
|
|
|
{
|
|
|
// Do the tests
|
|
|
Tiler::Bitset bitset;
|
|
|
- tiler->test(light->getSpatialCollisonShape(), true, &bitset);
|
|
|
+ tiler->test(light.getSpatialCollisionShape(), true, &bitset);
|
|
|
|
|
|
// Bin to the correct tiles
|
|
|
for(U t = 0; t < TILES_COUNT; t++)
|
|
|
@@ -319,12 +350,20 @@ struct WriteLightsJob: ThreadJob
|
|
|
if(light.getShadowEnabled())
|
|
|
{
|
|
|
U tilePos = (*tileSpotTexLightsCount)[y][x].fetch_add(1);
|
|
|
- tiles->tiles[y][x].spotTexLightIndices[tilePos] = pos;
|
|
|
+
|
|
|
+ if(tilePos < MAX_SPOT_TEX_LIGHTS_PER_TILE)
|
|
|
+ {
|
|
|
+ tiles->tiles[y][x].spotTexLightIndices[tilePos] = pos;
|
|
|
+ }
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
U tilePos = (*tileSpotLightsCount)[y][x].fetch_add(1);
|
|
|
- tiles->tiles[y][x].spotLightIndices[tilePos] = pos;
|
|
|
+
|
|
|
+ if(tilePos < MAX_SPOT_LIGHTS_PER_TILE)
|
|
|
+ {
|
|
|
+ tiles->tiles[y][x].spotLightIndices[tilePos] = pos;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -366,14 +405,21 @@ void Is::initInternal(const RendererInitializer& initializer)
|
|
|
// Load the programs
|
|
|
//
|
|
|
std::string pps =
|
|
|
- "#define TILES_X_COUNT " + std::to_string(Tiler::TILES_X_COUNT) + "\n"
|
|
|
- "#define TILES_Y_COUNT " + std::to_string(Tiler::TILES_Y_COUNT) + "\n"
|
|
|
+ "#define TILES_X_COUNT " + std::to_string(TILES_X_COUNT) + "\n"
|
|
|
+ "#define TILES_Y_COUNT " + std::to_string(TILES_Y_COUNT) + "\n"
|
|
|
+ "#define TILES_COUNT " + std::to_string(TILES_COUNT) + "\n"
|
|
|
"#define RENDERER_WIDTH " + std::to_string(r->getWidth()) + "\n"
|
|
|
"#define RENDERER_HEIGHT " + std::to_string(r->getHeight()) + "\n"
|
|
|
- "#define MAX_LIGHTS_PER_TILE " + std::to_string(MAX_LIGHTS_PER_TILE)
|
|
|
- + "\n"
|
|
|
+ "#define MAX_POINT_LIGHTS_PER_TILE "
|
|
|
+ + std::to_string(MAX_POINT_LIGHTS_PER_TILE) + "\n"
|
|
|
+ "#define MAX_SPOT_LIGHTS_PER_TILE "
|
|
|
+ + std::to_string(MAX_SPOT_LIGHTS_PER_TILE) + "\n"
|
|
|
+ "#define MAX_SPOT_TEX_LIGHTS_PER_TILE "
|
|
|
+ + std::to_string(MAX_SPOT_TEX_LIGHTS_PER_TILE) + "\n"
|
|
|
"#define MAX_POINT_LIGHTS " + std::to_string(MAX_POINT_LIGHTS) + "\n"
|
|
|
"#define MAX_SPOT_LIGHTS " + std::to_string(MAX_SPOT_LIGHTS) + "\n"
|
|
|
+ "#define MAX_SPOT_TEX_LIGHTS "
|
|
|
+ + std::to_string(MAX_SPOT_TEX_LIGHTS) + "\n"
|
|
|
"#define GROUND_LIGHT " + std::to_string(groundLightEnabled) + "\n";
|
|
|
|
|
|
if(sm.getPcfEnabled())
|
|
|
@@ -389,9 +435,6 @@ void Is::initInternal(const RendererInitializer& initializer)
|
|
|
lightPassProg.load(ShaderProgramResource::createSrcCodeToCache(
|
|
|
"shaders/IsLp.glsl", pps.c_str()).c_str());
|
|
|
|
|
|
- tilerProg.load(ShaderProgramResource::createSrcCodeToCache(
|
|
|
- "shaders/IsUpdateTiles.glsl", pps.c_str()).c_str());
|
|
|
-
|
|
|
//
|
|
|
// Create FBOs
|
|
|
//
|
|
|
@@ -434,17 +477,18 @@ void Is::initInternal(const RendererInitializer& initializer)
|
|
|
commonUbo.create(sizeof(shader::CommonUniforms), nullptr);
|
|
|
|
|
|
// lights UBO
|
|
|
- lightsUbo.create()
|
|
|
-
|
|
|
- pointLightsUbo.create(LIGHTS_UBO_SIZE, nullptr);
|
|
|
+ lightsUbo.create(LIGHTS_UBO_SIZE, nullptr);
|
|
|
|
|
|
// tiles UBO
|
|
|
tilesUbo.create(sizeof(shader::Tiles), nullptr);
|
|
|
|
|
|
// tilegrid
|
|
|
- tilegridBuffer.create(sizeof(shader::Tilegrid), GL_SHADER_STORAGE_BUFFER,
|
|
|
+ tilegridBuffer.create(GL_SHADER_STORAGE_BUFFER, sizeof(shader::Tilegrid),
|
|
|
nullptr, GL_STATIC_DRAW);
|
|
|
|
|
|
+ ANKI_LOGI("Creating BOs: lights: " << LIGHTS_UBO_SIZE << "B tiles: "
|
|
|
+ << sizeof(shader::Tiles) << "B");
|
|
|
+
|
|
|
// Sanity checks
|
|
|
const ShaderProgramUniformBlock* ublock;
|
|
|
|
|
|
@@ -507,6 +551,7 @@ void Is::lightPass()
|
|
|
for(auto it = vi.getLightsBegin(); it != vi.getLightsEnd(); ++it)
|
|
|
{
|
|
|
Light* light = (*it)->getLight();
|
|
|
+ ANKI_ASSERT(light);
|
|
|
switch(light->getLightType())
|
|
|
{
|
|
|
case Light::LT_POINT:
|
|
|
@@ -534,32 +579,23 @@ void Is::lightPass()
|
|
|
}
|
|
|
|
|
|
// Sanitize the counts
|
|
|
- visiblePointLightsCount = MAX_POINT_LIGHTS % visiblePointLightsCount;
|
|
|
- visibleSpotLightsCount = MAX_SPOT_LIGHTS % visibleSpotLightsCount;
|
|
|
- visibleSpotTexLightsCount = MAX_SPOT_TEX_LIGHTS % visibleSpotTexLightsCount;
|
|
|
+ visiblePointLightsCount = (visiblePointLightsCount > 0)
|
|
|
+ ? visiblePointLightsCount % MAX_POINT_LIGHTS : visiblePointLightsCount;
|
|
|
+ visibleSpotLightsCount = (visibleSpotLightsCount > 0)
|
|
|
+ ? visibleSpotLightsCount % MAX_SPOT_LIGHTS : visibleSpotLightsCount;
|
|
|
+ visibleSpotTexLightsCount = (visibleSpotTexLightsCount > 0)
|
|
|
+ ? visibleSpotTexLightsCount % MAX_SPOT_TEX_LIGHTS
|
|
|
+ : visibleSpotTexLightsCount;
|
|
|
|
|
|
//
|
|
|
// Do shadows pass
|
|
|
//
|
|
|
Array<U32, Sm::MAX_SHADOW_CASTERS> shadowmapLayers;
|
|
|
- sm.run(&shadowCasters[0], spotsShadowCount, shadowmapLayers);
|
|
|
+ sm.run(&shadowCasters[0], visibleSpotTexLightsCount, shadowmapLayers);
|
|
|
|
|
|
//
|
|
|
- // Prepare state
|
|
|
+ // Write the ligths and tiles UBOs
|
|
|
//
|
|
|
- fbo.bind();
|
|
|
- r->clearAfterBindingFbo(
|
|
|
- GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
|
|
- GlStateSingleton::get().setViewport(
|
|
|
- 0, 0, r->getWidth(), r->getHeight());
|
|
|
- GlStateSingleton::get().disable(GL_DEPTH_TEST);
|
|
|
- GlStateSingleton::get().disable(GL_BLEND);
|
|
|
-
|
|
|
- //
|
|
|
- // Write the lights UBO
|
|
|
- //
|
|
|
-
|
|
|
- U8 clientBuffer[LIGHTS_UBO_SIZE];
|
|
|
|
|
|
// Get the offsets and sizes of each uniform block
|
|
|
PtrSize pointLightsOffset = 0;
|
|
|
@@ -579,7 +615,8 @@ void Is::lightPass()
|
|
|
// Fire the super jobs
|
|
|
WriteLightsJob jobs[ThreadPool::MAX_THREADS];
|
|
|
|
|
|
- shader::Tiles tilesClient;
|
|
|
+ U8 clientBuffer[LIGHTS_UBO_SIZE];
|
|
|
+ shader::Tiles clientTiles;
|
|
|
|
|
|
std::atomic<U32> pointLightsAtomicCount;
|
|
|
std::atomic<U32> spotLightsAtomicCount;
|
|
|
@@ -596,16 +633,17 @@ void Is::lightPass()
|
|
|
{
|
|
|
WriteLightsJob& job = jobs[i];
|
|
|
|
|
|
- job.pointLigths =
|
|
|
+ job.pointLights =
|
|
|
(shader::PointLight*)(&clientBuffer[0] + pointLightsOffset);
|
|
|
- job.spotLigths =
|
|
|
+ job.spotLights =
|
|
|
(shader::SpotLight*)(&clientBuffer[0] + spotLightsOffset);
|
|
|
- job.spotTexLigths =
|
|
|
+ job.spotTexLights =
|
|
|
(shader::SpotTexLight*)(&clientBuffer[0] + spotTexLightsOffset);
|
|
|
|
|
|
- job.tiles = &tilesClient;
|
|
|
+ job.tiles = &clientTiles;
|
|
|
|
|
|
- // XXX add more
|
|
|
+ job.lightsBegin = vi.getLightsBegin();
|
|
|
+ job.lightsEnd = vi.getLightsEnd();
|
|
|
|
|
|
job.pointLightsCount = &pointLightsAtomicCount;
|
|
|
job.spotLightsCount = &spotLightsAtomicCount;
|
|
|
@@ -615,57 +653,50 @@ void Is::lightPass()
|
|
|
job.tileSpotLightsCount = &tileSpotLightsCount;
|
|
|
job.tileSpotTexLightsCount = &tileSpotTexLightsCount;
|
|
|
|
|
|
- job.tiler = r->getTiler();
|
|
|
+ job.tiler = &r->getTiler();
|
|
|
job.is = this;
|
|
|
+
|
|
|
+ threadPool.assignNewJob(i, &job);
|
|
|
}
|
|
|
|
|
|
+ // In the meantime set the state
|
|
|
+ setState();
|
|
|
+
|
|
|
// Sync
|
|
|
threadPool.waitForAllJobsToFinish();
|
|
|
|
|
|
- // Write BO
|
|
|
- lightsUbo.write(&clientBuffer[0], spotTexLightsOffset + spotTexLightsSize);
|
|
|
-
|
|
|
- //
|
|
|
- // Update the tiles UBO
|
|
|
- //
|
|
|
-
|
|
|
- shader::Tiles clientBuffer;
|
|
|
-
|
|
|
- WriteTilesUboJob tjobs[ThreadPool::MAX_THREADS];
|
|
|
- for(U i = 0; i < threadPool.getThreadsCount(); i++)
|
|
|
+ // Write the shadomap IDs
|
|
|
+ for(U i = 0; i < visibleSpotTexLightsCount; i++)
|
|
|
{
|
|
|
- tjobs[i].visiblePointLights = &visiblePointLights[0];
|
|
|
- tjobs[i].visiblePointLightsCount = visiblePointLightsCount;
|
|
|
-
|
|
|
- tjobs[i].visibleSpotLights = &visibleSpotLights[0];
|
|
|
- tjobs[i].visibleSpotLightsCount = visibleSpotLightsCount;
|
|
|
-
|
|
|
- tjobs[i].shaderTiles = &clientBuffer.tiles[0];
|
|
|
- tjobs[i].is = this;
|
|
|
-
|
|
|
- threadPool.assignNewJob(i, &tjobs[i]);
|
|
|
+ jobs[0].spotTexLights[i].diffuseColorShadowmapId.w() =
|
|
|
+ (F32)shadowmapLayers[i];
|
|
|
}
|
|
|
|
|
|
- threadPool.waitForAllJobsToFinish();
|
|
|
-
|
|
|
- tilesUbo.write(&clientBuffer);
|
|
|
-
|
|
|
- // XXX
|
|
|
- /*{
|
|
|
- tilesUbo.bind(GL_SHADER_STORAGE_BUFFER);
|
|
|
- tilesUbo.setBinding(0);
|
|
|
+ // Write the light count for each tile
|
|
|
+ for(U y = 0; y < TILES_Y_COUNT; y++)
|
|
|
+ {
|
|
|
+ for(U x = 0; x < TILES_X_COUNT; x++)
|
|
|
+ {
|
|
|
+ clientTiles.tiles[y][x].lightsCount[0] =
|
|
|
+ tilePointLightsCount[y][x].load();
|
|
|
|
|
|
- tilerProg->bind();
|
|
|
+ clientTiles.tiles[y][x].lightsCount[2] =
|
|
|
+ tileSpotLightsCount[y][x].load();
|
|
|
|
|
|
- glDispatchCompute(Tiler::TILES_X_COUNT, Tiler::TILES_Y_COUNT, 1);
|
|
|
+ clientTiles.tiles[y][x].lightsCount[3] =
|
|
|
+ tileSpotTexLightsCount[y][x].load();
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- tilesUbo.bind(GL_UNIFORM_BUFFER);
|
|
|
- }*/
|
|
|
+ // Write BOs
|
|
|
+ lightsUbo.write(
|
|
|
+ &clientBuffer[0], 0, spotTexLightsOffset + spotTexLightsSize);
|
|
|
+ tilesUbo.write(&clientTiles);
|
|
|
|
|
|
//
|
|
|
// Setup shader and draw
|
|
|
//
|
|
|
-
|
|
|
+
|
|
|
// shader prog
|
|
|
lightPassProg->bind();
|
|
|
|
|
|
@@ -673,8 +704,22 @@ void Is::lightPass()
|
|
|
Vec4(r->getLimitsOfNearPlane(), r->getLimitsOfNearPlane2()));
|
|
|
|
|
|
commonUbo.setBinding(COMMON_UNIFORMS_BLOCK_BINDING);
|
|
|
- pointLightsUbo.setBinding(POINT_LIGHTS_BLOCK_BINDING);
|
|
|
- spotLightsUbo.setBinding(SPOT_LIGHTS_BLOCK_BINDING);
|
|
|
+
|
|
|
+ if(pointLightsSize > 0)
|
|
|
+ {
|
|
|
+ lightsUbo.setBindingRange(POINT_LIGHTS_BLOCK_BINDING, pointLightsOffset,
|
|
|
+ pointLightsSize);
|
|
|
+ }
|
|
|
+ if(spotLightsSize > 0)
|
|
|
+ {
|
|
|
+ lightsUbo.setBindingRange(SPOT_LIGHTS_BLOCK_BINDING, spotLightsOffset,
|
|
|
+ spotLightsSize);
|
|
|
+ }
|
|
|
+ if(spotTexLightsSize > 0)
|
|
|
+ {
|
|
|
+ lightsUbo.setBindingRange(SPOT_TEX_LIGHTS_BLOCK_BINDING,
|
|
|
+ spotTexLightsOffset, spotTexLightsSize);
|
|
|
+ }
|
|
|
tilesUbo.setBinding(TILES_BLOCK_BINDING);
|
|
|
|
|
|
lightPassProg->findUniformVariable("msFai0").set(r->getMs().getFai0());
|
|
|
@@ -684,7 +729,19 @@ void Is::lightPass()
|
|
|
|
|
|
quadVao.bind();
|
|
|
glDrawElementsInstanced(GL_TRIANGLES, 2 * 3, GL_UNSIGNED_SHORT, 0,
|
|
|
- Tiler::TILES_Y_COUNT * Tiler::TILES_X_COUNT);
|
|
|
+ TILES_COUNT);
|
|
|
+}
|
|
|
+
|
|
|
+//==============================================================================
|
|
|
+void Is::setState()
|
|
|
+{
|
|
|
+ fbo.bind();
|
|
|
+ r->clearAfterBindingFbo(
|
|
|
+ GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
|
|
+ GlStateSingleton::get().setViewport(
|
|
|
+ 0, 0, r->getWidth(), r->getHeight());
|
|
|
+ GlStateSingleton::get().disable(GL_DEPTH_TEST);
|
|
|
+ GlStateSingleton::get().disable(GL_BLEND);
|
|
|
}
|
|
|
|
|
|
//==============================================================================
|