mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-23 15:50:20 +00:00
Improve shadow stability and reduce foliage pop-in
This commit is contained in:
parent
979c0b5592
commit
ab4cb878ea
6 changed files with 48 additions and 16 deletions
|
|
@ -310,6 +310,8 @@ bool M2Renderer::initialize(pipeline::AssetManager* assets) {
|
|||
vec4 lsPos = uLightSpaceMatrix * vec4(FragPos, 1.0);
|
||||
vec3 proj = lsPos.xyz / lsPos.w * 0.5 + 0.5;
|
||||
if (proj.z <= 1.0 && proj.x >= 0.0 && proj.x <= 1.0 && proj.y >= 0.0 && proj.y <= 1.0) {
|
||||
float edgeDist = max(abs(proj.x - 0.5), abs(proj.y - 0.5));
|
||||
float coverageFade = 1.0 - smoothstep(0.40, 0.49, edgeDist);
|
||||
float bias = max(0.005 * (1.0 - abs(dot(normal, lightDir))), 0.001);
|
||||
shadow = 0.0;
|
||||
vec2 texelSize = vec2(1.0 / 2048.0);
|
||||
|
|
@ -319,6 +321,7 @@ bool M2Renderer::initialize(pipeline::AssetManager* assets) {
|
|||
}
|
||||
}
|
||||
shadow /= 9.0;
|
||||
shadow = mix(1.0, shadow, coverageFade);
|
||||
}
|
||||
}
|
||||
shadow = mix(1.0, shadow, clamp(uShadowStrength, 0.0, 1.0));
|
||||
|
|
@ -497,6 +500,7 @@ bool M2Renderer::loadModel(const pipeline::M2Model& model, uint32_t modelId) {
|
|||
tightMin = glm::min(tightMin, v.position);
|
||||
tightMax = glm::max(tightMax, v.position);
|
||||
}
|
||||
bool foliageOrTreeLike = false;
|
||||
{
|
||||
std::string lowerName = model.name;
|
||||
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(),
|
||||
|
|
@ -545,6 +549,7 @@ bool M2Renderer::loadModel(const pipeline::M2Model& model, uint32_t modelId) {
|
|||
(lowerName.find("lily") != std::string::npos) ||
|
||||
(lowerName.find("weed") != std::string::npos);
|
||||
bool treeLike = (lowerName.find("tree") != std::string::npos);
|
||||
foliageOrTreeLike = (foliageName || treeLike);
|
||||
bool hardTreePart =
|
||||
(lowerName.find("trunk") != std::string::npos) ||
|
||||
(lowerName.find("stump") != std::string::npos) ||
|
||||
|
|
@ -609,6 +614,7 @@ bool M2Renderer::loadModel(const pipeline::M2Model& model, uint32_t modelId) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
gpuModel.disableAnimation = foliageOrTreeLike;
|
||||
|
||||
// Flag smoke models for UV scroll animation (particle emitters not implemented)
|
||||
{
|
||||
|
|
@ -773,7 +779,7 @@ uint32_t M2Renderer::createInstance(uint32_t modelId, const glm::vec3& position,
|
|||
|
||||
// Initialize animation: play first sequence (usually Stand/Idle)
|
||||
const auto& mdl = models[modelId];
|
||||
if (mdl.hasAnimation && !mdl.sequences.empty()) {
|
||||
if (mdl.hasAnimation && !mdl.disableAnimation && !mdl.sequences.empty()) {
|
||||
instance.currentSequenceIndex = 0;
|
||||
instance.idleSequenceIndex = 0;
|
||||
instance.animDuration = static_cast<float>(mdl.sequences[0].duration);
|
||||
|
|
@ -827,7 +833,7 @@ uint32_t M2Renderer::createInstanceWithMatrix(uint32_t modelId, const glm::mat4&
|
|||
transformAABB(instance.modelMatrix, localMin, localMax, instance.worldBoundsMin, instance.worldBoundsMax);
|
||||
// Initialize animation
|
||||
const auto& mdl2 = models[modelId];
|
||||
if (mdl2.hasAnimation && !mdl2.sequences.empty()) {
|
||||
if (mdl2.hasAnimation && !mdl2.disableAnimation && !mdl2.sequences.empty()) {
|
||||
instance.currentSequenceIndex = 0;
|
||||
instance.idleSequenceIndex = 0;
|
||||
instance.animDuration = static_cast<float>(mdl2.sequences[0].duration);
|
||||
|
|
@ -1040,7 +1046,7 @@ void M2Renderer::update(float deltaTime) {
|
|||
if (it == models.end()) continue;
|
||||
const M2ModelGPU& model = it->second;
|
||||
|
||||
if (!model.hasAnimation) {
|
||||
if (!model.hasAnimation || model.disableAnimation) {
|
||||
instance.animTime += dtMs;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1139,8 +1145,8 @@ void M2Renderer::render(const Camera& camera, const glm::mat4& view, const glm::
|
|||
|
||||
lastDrawCallCount = 0;
|
||||
|
||||
// Adaptive render distance: shorter in dense areas (cities), longer in open terrain
|
||||
const float maxRenderDistance = (instances.size() > 600) ? 180.0f : 2000.0f;
|
||||
// Adaptive render distance: keep longer tree/foliage visibility to reduce pop-in.
|
||||
const float maxRenderDistance = (instances.size() > 600) ? 320.0f : 2800.0f;
|
||||
const float maxRenderDistanceSq = maxRenderDistance * maxRenderDistance;
|
||||
const float fadeStartFraction = 0.75f;
|
||||
const glm::vec3 camPos = camera.getPosition();
|
||||
|
|
@ -1161,10 +1167,14 @@ void M2Renderer::render(const Camera& camera, const glm::mat4& view, const glm::
|
|||
float worldRadius = model.boundRadius * instance.scale;
|
||||
// Cull small objects (radius < 20) at distance, keep larger objects visible longer
|
||||
float effectiveMaxDistSq = maxRenderDistanceSq * std::max(1.0f, worldRadius / 12.0f);
|
||||
if (model.disableAnimation) {
|
||||
// Trees/foliage keep a larger horizon before culling.
|
||||
effectiveMaxDistSq *= 1.8f;
|
||||
}
|
||||
if (worldRadius < 0.8f) {
|
||||
effectiveMaxDistSq = std::min(effectiveMaxDistSq, 65.0f * 65.0f);
|
||||
} else if (worldRadius < 1.5f) {
|
||||
effectiveMaxDistSq = std::min(effectiveMaxDistSq, 95.0f * 95.0f);
|
||||
} else if (worldRadius < 1.5f) {
|
||||
effectiveMaxDistSq = std::min(effectiveMaxDistSq, 140.0f * 140.0f);
|
||||
}
|
||||
if (distSq > effectiveMaxDistSq) {
|
||||
continue;
|
||||
|
|
@ -1189,7 +1199,7 @@ void M2Renderer::render(const Camera& camera, const glm::mat4& view, const glm::
|
|||
shader->setUniform("uFadeAlpha", fadeAlpha);
|
||||
|
||||
// Upload bone matrices if model has skeletal animation
|
||||
bool useBones = model.hasAnimation && !instance.boneMatrices.empty();
|
||||
bool useBones = model.hasAnimation && !model.disableAnimation && !instance.boneMatrices.empty();
|
||||
shader->setUniform("uUseBones", useBones);
|
||||
if (useBones) {
|
||||
int numBones = std::min(static_cast<int>(instance.boneMatrices.size()), 128);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue