Files
EVEngine/test/ParallaxMap.cpp
T
西风逍遥游andCursor Agent 59b2ebabf1 feat(graphics): parallax occlusion mapping (POM) for mesh3d (#35)
Add height-map driven POM on the default mesh3d / mesh3d_clustered PBR
path so brick/stone materials get fake depth without tessellation.

- GLSL: parallax_map.glsl (adaptive steep march + linear refinement)
- API: Renderable3D::setHeightTexture / setParallax; scale=0 keeps old UVs
- Descriptor binding for height sampler; UBO parallax vec4 appended
- Docs + CPU math tests + GPU pixel-diff coverage

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-08-12 18:33:03 +08:00

47 lines
1.3 KiB
C++

#include "zeroerr/assert.h"
#include "zeroerr/unittest.h"
#include <cmath>
#include "graphics/ParallaxMap.h"
using eve::graphics::ParallaxParams;
using eve::graphics::clampParallaxParams;
using eve::graphics::parallaxOffsetUV;
TEST_CASE("ParallaxMap.scaleZeroIsIdentity") {
float ou = -1.f, ov = -1.f;
parallaxOffsetUV(0.4f, 0.6f, 0.2f, 0.5f, -0.3f, 0.8f, 0.f, ou, ov);
CHECK(std::fabs(ou - 0.4f) < 1e-6f);
CHECK(std::fabs(ov - 0.6f) < 1e-6f);
}
TEST_CASE("ParallaxMap.heightDisplacesTowardViewXY") {
// Low height → deep → larger displacement along -viewXY.
float ouLo = 0.f, ovLo = 0.f;
float ouHi = 0.f, ovHi = 0.f;
parallaxOffsetUV(0.5f, 0.5f, 0.0f, 0.4f, 0.0f, 0.9f, 0.1f, ouLo, ovLo);
parallaxOffsetUV(0.5f, 0.5f, 1.0f, 0.4f, 0.0f, 0.9f, 0.1f, ouHi, ovHi);
CHECK(ouLo < ouHi); // deeper surface shifts UV more opposite +viewX
CHECK(std::fabs(ovLo - 0.5f) < 1e-5f);
CHECK(std::fabs(ovHi - 0.5f) < 1e-5f);
}
TEST_CASE("ParallaxMap.clampParams") {
ParallaxParams p;
p.scale = 1.f;
p.minLayers = 0.f;
p.maxLayers = 100.f;
clampParallaxParams(p);
CHECK(p.scale == 0.25f);
CHECK(p.minLayers == 1.f);
CHECK(p.maxLayers == 64.f);
p.scale = -1.f;
p.minLayers = 16.f;
p.maxLayers = 8.f;
clampParallaxParams(p);
CHECK(p.scale == 0.f);
CHECK(p.maxLayers == 16.f);
}