mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-23 07:40:14 +00:00
Add normal mapping and parallax occlusion mapping for WMO surfaces
Generate normal+height maps from diffuse textures at load time using luminance-to-height and Sobel 3x3 filtering. Compute per-vertex tangents via Lengyel's method for TBN basis construction. Fragment shader uses screen-space UV derivatives (dFdx/dFdy) for smooth LOD crossfade and angle-adaptive POM sample counts. Flat textures naturally produce low height variance, causing POM to self-select off. Settings: Normal Mapping on by default, POM off by default with Low/Medium/High quality presets. Persisted across sessions.
This commit is contained in:
parent
1b16bcf71f
commit
eaceb58e77
8 changed files with 424 additions and 33 deletions
|
|
@ -6,6 +6,7 @@
|
|||
#include "core/spawn_presets.hpp"
|
||||
#include "core/input.hpp"
|
||||
#include "rendering/renderer.hpp"
|
||||
#include "rendering/wmo_renderer.hpp"
|
||||
#include "rendering/terrain_manager.hpp"
|
||||
#include "rendering/minimap.hpp"
|
||||
#include "rendering/world_map.hpp"
|
||||
|
|
@ -277,6 +278,19 @@ void GameScreen::render(game::GameHandler& gameHandler) {
|
|||
msaaSettingsApplied_ = true;
|
||||
}
|
||||
|
||||
// Apply saved normal mapping / POM settings once when WMO renderer is available
|
||||
if (!normalMapSettingsApplied_) {
|
||||
auto* renderer = core::Application::getInstance().getRenderer();
|
||||
if (renderer) {
|
||||
if (auto* wr = renderer->getWMORenderer()) {
|
||||
wr->setNormalMappingEnabled(pendingNormalMapping);
|
||||
wr->setPOMEnabled(pendingPOM);
|
||||
wr->setPOMQuality(pendingPOMQuality);
|
||||
normalMapSettingsApplied_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply auto-loot setting to GameHandler every frame (cheap bool sync)
|
||||
gameHandler.setAutoLoot(pendingAutoLoot);
|
||||
|
||||
|
|
@ -5894,6 +5908,33 @@ void GameScreen::renderSettingsWindow() {
|
|||
}
|
||||
saveSettings();
|
||||
}
|
||||
if (ImGui::Checkbox("Normal Mapping", &pendingNormalMapping)) {
|
||||
if (renderer) {
|
||||
if (auto* wr = renderer->getWMORenderer()) {
|
||||
wr->setNormalMappingEnabled(pendingNormalMapping);
|
||||
}
|
||||
}
|
||||
saveSettings();
|
||||
}
|
||||
if (ImGui::Checkbox("Parallax Mapping", &pendingPOM)) {
|
||||
if (renderer) {
|
||||
if (auto* wr = renderer->getWMORenderer()) {
|
||||
wr->setPOMEnabled(pendingPOM);
|
||||
}
|
||||
}
|
||||
saveSettings();
|
||||
}
|
||||
if (pendingPOM) {
|
||||
const char* pomLabels[] = { "Low", "Medium", "High" };
|
||||
if (ImGui::Combo("Parallax Quality", &pendingPOMQuality, pomLabels, 3)) {
|
||||
if (renderer) {
|
||||
if (auto* wr = renderer->getWMORenderer()) {
|
||||
wr->setPOMQuality(pendingPOMQuality);
|
||||
}
|
||||
}
|
||||
saveSettings();
|
||||
}
|
||||
}
|
||||
|
||||
const char* resLabel = "Resolution";
|
||||
const char* resItems[kResCount];
|
||||
|
|
@ -5917,6 +5958,9 @@ void GameScreen::renderSettingsWindow() {
|
|||
pendingShadows = kDefaultShadows;
|
||||
pendingGroundClutterDensity = kDefaultGroundClutterDensity;
|
||||
pendingAntiAliasing = 0;
|
||||
pendingNormalMapping = true;
|
||||
pendingPOM = false;
|
||||
pendingPOMQuality = 1;
|
||||
pendingResIndex = defaultResIndex;
|
||||
window->setFullscreen(pendingFullscreen);
|
||||
window->setVsync(pendingVsync);
|
||||
|
|
@ -5928,6 +5972,13 @@ void GameScreen::renderSettingsWindow() {
|
|||
tm->setGroundClutterDensityScale(static_cast<float>(pendingGroundClutterDensity) / 100.0f);
|
||||
}
|
||||
}
|
||||
if (renderer) {
|
||||
if (auto* wr = renderer->getWMORenderer()) {
|
||||
wr->setNormalMappingEnabled(pendingNormalMapping);
|
||||
wr->setPOMEnabled(pendingPOM);
|
||||
wr->setPOMQuality(pendingPOMQuality);
|
||||
}
|
||||
}
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
|
|
@ -6854,6 +6905,9 @@ void GameScreen::saveSettings() {
|
|||
out << "auto_loot=" << (pendingAutoLoot ? 1 : 0) << "\n";
|
||||
out << "ground_clutter_density=" << pendingGroundClutterDensity << "\n";
|
||||
out << "antialiasing=" << pendingAntiAliasing << "\n";
|
||||
out << "normal_mapping=" << (pendingNormalMapping ? 1 : 0) << "\n";
|
||||
out << "pom=" << (pendingPOM ? 1 : 0) << "\n";
|
||||
out << "pom_quality=" << pendingPOMQuality << "\n";
|
||||
|
||||
// Controls
|
||||
out << "mouse_sensitivity=" << pendingMouseSensitivity << "\n";
|
||||
|
|
@ -6932,6 +6986,9 @@ void GameScreen::loadSettings() {
|
|||
else if (key == "auto_loot") pendingAutoLoot = (std::stoi(val) != 0);
|
||||
else if (key == "ground_clutter_density") pendingGroundClutterDensity = std::clamp(std::stoi(val), 0, 150);
|
||||
else if (key == "antialiasing") pendingAntiAliasing = std::clamp(std::stoi(val), 0, 3);
|
||||
else if (key == "normal_mapping") pendingNormalMapping = (std::stoi(val) != 0);
|
||||
else if (key == "pom") pendingPOM = (std::stoi(val) != 0);
|
||||
else if (key == "pom_quality") pendingPOMQuality = std::clamp(std::stoi(val), 0, 2);
|
||||
// Controls
|
||||
else if (key == "mouse_sensitivity") pendingMouseSensitivity = std::clamp(std::stof(val), 0.05f, 1.0f);
|
||||
else if (key == "invert_mouse") pendingInvertMouse = (std::stoi(val) != 0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue