Fixing lights and shadows
This commit is contained in:
1 parent
9f4d60036d
commit
bba493ee7c
18 files changed
+308
-126
No files matched your search
+38
-9
@@ -318,6 +318,10 @@ namespace ZL
|
||||
pl.id = item.value("id", "");
|
||||
pl.autoLight = item.value("autoLight", false);
|
||||
pl.autoLightDistance = item.value("autoLightDistance", -1.0f);
|
||||
pl.limitX = item.value("limitX", 99999.f);
|
||||
pl.limitY = item.value("limitY", 99999.f);
|
||||
pl.autoLightLimitX = item.value("autoLightLimitX", -1.0f);
|
||||
pl.autoLightLimitY = item.value("autoLightLimitY", -1.0f);
|
||||
pl.position = Eigen::Vector3f(
|
||||
item.value("positionX", 0.0f),
|
||||
item.value("positionY", 0.0f),
|
||||
@@ -1005,10 +1009,18 @@ namespace ZL
|
||||
for (int i = 0; i < static_cast<int>(pointLights.size()); ++i) {
|
||||
const PointLight& pl = pointLights[i];
|
||||
bool active = !pl.autoLight;
|
||||
if (!active && i == nearestLightIdx) {
|
||||
// autoLight: also check distance threshold if set
|
||||
const float dist = player ? (pl.position - player->position).norm() : 0.0f;
|
||||
active = (pl.autoLightDistance <= 0.0f || dist <= pl.autoLightDistance);
|
||||
if (!active && player) {
|
||||
if (pl.autoLightLimitX > 0.0f && pl.autoLightLimitY > 0.0f) {
|
||||
// Rectangular activation zone — independent of nearest-light heuristic
|
||||
const float dx = std::abs(player->position.x() - pl.position.x());
|
||||
const float dz = std::abs(player->position.z() - pl.position.z());
|
||||
active = (dx <= pl.autoLightLimitX && dz <= pl.autoLightLimitY);
|
||||
} else {
|
||||
// Legacy: only the nearest autoLight activates, with optional distance cap
|
||||
const float dist = (pl.position - player->position).norm();
|
||||
active = (i == nearestLightIdx) &&
|
||||
(pl.autoLightDistance <= 0.0f || dist <= pl.autoLightDistance);
|
||||
}
|
||||
}
|
||||
if (active) {
|
||||
activeLightIndices.push_back(i);
|
||||
@@ -1079,6 +1091,8 @@ namespace ZL
|
||||
float plPosEye[MAX_POINT_LIGHTS * 3] = {};
|
||||
float plDirEye[MAX_POINT_LIGHTS * 3] = {};
|
||||
float plColors[MAX_POINT_LIGHTS * 3] = {};
|
||||
float plWorldXZ[MAX_POINT_LIGHTS * 2] = {};
|
||||
float plLimitXZ[MAX_POINT_LIGHTS * 2] = {};
|
||||
const Eigen::Matrix3f camRot = cameraViewMatrix.block<3, 3>(0, 0);
|
||||
const int lightCount = static_cast<int>(activeLightIndices.size());
|
||||
for (int j = 0; j < lightCount; ++j) {
|
||||
@@ -1095,12 +1109,19 @@ namespace ZL
|
||||
plColors[j * 3 + 0] = pl.color.x();
|
||||
plColors[j * 3 + 1] = pl.color.y();
|
||||
plColors[j * 3 + 2] = pl.color.z();
|
||||
plWorldXZ[j * 2 + 0] = pl.position.x();
|
||||
plWorldXZ[j * 2 + 1] = pl.position.z();
|
||||
plLimitXZ[j * 2 + 0] = pl.limitX;
|
||||
plLimitXZ[j * 2 + 1] = pl.limitY;
|
||||
}
|
||||
|
||||
// Compute camera view inverse (needed for shadow lookup and skinning world-pos recovery)
|
||||
const Eigen::Matrix4f cameraViewInverse = cameraViewMatrix.inverse();
|
||||
|
||||
// Compute light-from-camera matrix for shadow lookup
|
||||
Eigen::Matrix4f lightFromCamera = Eigen::Matrix4f::Identity();
|
||||
if (hasShadows) {
|
||||
lightFromCamera = shadowMap->getLightSpaceMatrix() * cameraViewMatrix.inverse();
|
||||
lightFromCamera = shadowMap->getLightSpaceMatrix() * cameraViewInverse;
|
||||
renderer.RenderUniformMatrix4fv("uLightFromCamera", false, lightFromCamera.data());
|
||||
// Pass first active light's eye-space direction as uLightDir for shadow bias
|
||||
renderer.RenderUniform3fv("uLightDir", plDirEye);
|
||||
@@ -1111,6 +1132,8 @@ namespace ZL
|
||||
renderer.RenderUniform3fvArray("uPointLightPos[0]", lightCount, plPosEye);
|
||||
renderer.RenderUniform3fvArray("uPointLightDir[0]", lightCount, plDirEye);
|
||||
renderer.RenderUniform3fvArray("uPointLightColor[0]", lightCount, plColors);
|
||||
renderer.RenderUniform2fvArray("uPointLightWorldXZ[0]", lightCount, plWorldXZ);
|
||||
renderer.RenderUniform2fvArray("uPointLightLimitXZ[0]", lightCount, plLimitXZ);
|
||||
}
|
||||
|
||||
renderer.RenderUniform1f("uAlpha", 1.0f);
|
||||
@@ -1132,11 +1155,17 @@ namespace ZL
|
||||
for (auto& tz : teleportZones) tz.prepareForDraw(cameraViewMatrix);
|
||||
|
||||
if (hasShadows) {
|
||||
if (player) player->drawNightWithShadow(renderer, plPosEye, plDirEye, plColors, lightCount, lightFromCamera, shadowMap->getDepthTexture(), ambientColor, fogColor);
|
||||
for (auto& npc : npcs) npc->drawNightWithShadow(renderer, plPosEye, plDirEye, plColors, lightCount, lightFromCamera, shadowMap->getDepthTexture(), ambientColor, fogColor);
|
||||
if (player) player->drawNightWithShadow(renderer, plPosEye, plDirEye, plColors, lightCount,
|
||||
plWorldXZ, plLimitXZ, cameraViewInverse,
|
||||
lightFromCamera, shadowMap->getDepthTexture(), ambientColor, fogColor);
|
||||
for (auto& npc : npcs) npc->drawNightWithShadow(renderer, plPosEye, plDirEye, plColors, lightCount,
|
||||
plWorldXZ, plLimitXZ, cameraViewInverse,
|
||||
lightFromCamera, shadowMap->getDepthTexture(), ambientColor, fogColor);
|
||||
} else {
|
||||
if (player) player->drawNight(renderer, plPosEye, plDirEye, plColors, lightCount, ambientColor, fogColor);
|
||||
for (auto& npc : npcs) npc->drawNight(renderer, plPosEye, plDirEye, plColors, lightCount, ambientColor, fogColor);
|
||||
if (player) player->drawNight(renderer, plPosEye, plDirEye, plColors, lightCount,
|
||||
plWorldXZ, plLimitXZ, cameraViewInverse, ambientColor, fogColor);
|
||||
for (auto& npc : npcs) npc->drawNight(renderer, plPosEye, plDirEye, plColors, lightCount,
|
||||
plWorldXZ, plLimitXZ, cameraViewInverse, ambientColor, fogColor);
|
||||
}
|
||||
|
||||
for (auto& tz : teleportZones) tz.draw(renderer, Environment::zoom, Environment::width, Environment::height);
|
||||
|
||||
Reference in new issue
Block a user