WMO glass transparency for instances, disable interior shadows

- Add case-insensitive "glass" detection for WMO window materials
- Make instance (WMO-only) glass highly transparent (12-35% alpha)
  so underwater scenes are visible through Deeprun Tram windows
- Keep normal world windows at existing opacity (40-95% alpha)
- Disable shadow mapping for interior WMO groups to fix dark
  indoor areas like Ironforge
This commit is contained in:
Kelsi 2026-03-06 23:48:35 -08:00
parent f4c115ade9
commit 2c5b7cd368
4 changed files with 23 additions and 7 deletions

View file

@ -152,9 +152,9 @@ void main() {
vec3 result;
// Sample shadow map for all non-window WMO surfaces
// Sample shadow map — skip for interior WMO groups (no sun indoors)
float shadow = 1.0;
if (shadowParams.x > 0.5) {
if (shadowParams.x > 0.5 && isInterior == 0) {
vec3 ldir = normalize(-lightDir.xyz);
float normalOffset = SHADOW_TEXEL * 2.0 * (1.0 - abs(dot(norm, ldir)));
vec3 biasedPos = FragPos + norm * normalOffset;
@ -219,7 +219,12 @@ void main() {
glass += specBroad * lightColor.rgb * 0.12;
result = glass;
alpha = mix(0.4, 0.95, NdotV);
if (isWindow == 2) {
// Instance/dungeon glass: mostly transparent to see through
alpha = mix(0.12, 0.35, fresnel);
} else {
alpha = mix(0.4, 0.95, NdotV);
}
}
outColor = vec4(result, alpha);

View file

@ -196,6 +196,7 @@ public:
void setNormalMapStrength(float s) { normalMapStrength_ = s; materialSettingsDirty_ = true; }
void setPOMEnabled(bool enabled) { pomEnabled_ = enabled; materialSettingsDirty_ = true; }
void setPOMQuality(int q) { pomQuality_ = q; materialSettingsDirty_ = true; }
void setWMOOnlyMap(bool v) { wmoOnlyMap_ = v; materialSettingsDirty_ = true; }
bool isNormalMappingEnabled() const { return normalMappingEnabled_; }
float getNormalMapStrength() const { return normalMapStrength_; }
bool isPOMEnabled() const { return pomEnabled_; }
@ -670,6 +671,7 @@ private:
bool pomEnabled_ = true; // on by default
int pomQuality_ = 1; // 0=Low(16), 1=Medium(32), 2=High(64)
bool materialSettingsDirty_ = false; // rebuild UBOs when settings change
bool wmoOnlyMap_ = false; // true for dungeon/instance WMO-only maps
// Rendering state
bool wireframeMode = false;

View file

@ -3525,9 +3525,10 @@ void Application::loadOnlineWorldTerrain(uint32_t mapId, float x, float y, float
renderer->getCameraController()->reset();
}
// Set map name for WMO renderer
// Set map name for WMO renderer and reset instance mode
if (renderer->getWMORenderer()) {
renderer->getWMORenderer()->setMapName(mapName);
renderer->getWMORenderer()->setWMOOnlyMap(false);
}
// Set map name for terrain manager
@ -3634,6 +3635,7 @@ void Application::loadOnlineWorldTerrain(uint32_t mapId, float x, float y, float
// Set map name on WMO renderer and disable terrain streaming (no ADT tiles for instances)
if (renderer->getWMORenderer()) {
renderer->getWMORenderer()->setMapName(mapName);
renderer->getWMORenderer()->setWMOOnlyMap(true);
}
if (renderer->getTerrainManager()) {
renderer->getTerrainManager()->setStreamingEnabled(false);

View file

@ -593,16 +593,23 @@ bool WMORenderer::loadModel(const pipeline::WMOModel& model, uint32_t id) {
// Detect window/glass materials by texture name.
// Flag 0x10 (F_SIDN) marks night-glow materials (windows AND lamps),
// so we additionally check for "window" in the texture path to
// so we additionally check for "window" or "glass" in the texture path to
// distinguish actual glass from lamp post geometry.
bool isWindow = false;
if (batch.materialId < modelData.materialTextureIndices.size()) {
uint32_t ti = modelData.materialTextureIndices[batch.materialId];
if (ti < modelData.textureNames.size()) {
isWindow = (modelData.textureNames[ti].find("window") != std::string::npos);
const auto& texName = modelData.textureNames[ti];
// Case-insensitive search for "window" or "glass"
std::string texNameLower = texName;
std::transform(texNameLower.begin(), texNameLower.end(), texNameLower.begin(), ::tolower);
isWindow = (texNameLower.find("window") != std::string::npos ||
texNameLower.find("glass") != std::string::npos);
}
}
BatchKey key{ reinterpret_cast<uintptr_t>(tex), alphaTest, unlit, isWindow };
auto& mb = batchMap[key];
if (mb.draws.empty()) {
@ -651,7 +658,7 @@ bool WMORenderer::loadModel(const pipeline::WMOModel& model, uint32_t id) {
matData.unlit = mb.unlit ? 1 : 0;
matData.isInterior = isInterior ? 1 : 0;
matData.specularIntensity = 0.5f;
matData.isWindow = mb.isWindow ? 1 : 0;
matData.isWindow = mb.isWindow ? (wmoOnlyMap_ ? 2 : 1) : 0;
matData.enableNormalMap = normalMappingEnabled_ ? 1 : 0;
matData.enablePOM = pomEnabled_ ? 1 : 0;
matData.pomScale = 0.012f;