载入中...
搜索中...
未找到
FogProfile.cpp
浏览该文件的文档.
2
3#include "common/Diagnostic.h"
4
5#include <algorithm>
6#include <cmath>
7
8namespace eve::graphics::fog {
9namespace {
10
11[[nodiscard]] bool finiteVec3(const glm::vec3& v) noexcept {
12 return std::isfinite(v.x) && std::isfinite(v.y) && std::isfinite(v.z);
13}
14
15[[nodiscard]] float henyeyGreenstein(float g, float cosTheta) noexcept {
16 const float g2 = g * g;
17 const float denom = 1.f + g2 - 2.f * g * cosTheta;
18 const float denom32 = denom * std::sqrt(std::max(denom, 1e-8f));
19 return (1.f - g2) / (4.f * 3.14159265f * std::max(denom32, 1e-8f));
20}
21
22} // namespace
23
24Result<void> FogProfile::configure(float extinctionPerDensity, const glm::vec3& albedo,
25 float ambientOcclusion, float ambientUp, float ambientDown,
26 float anisotropy) {
27 if (!std::isfinite(extinctionPerDensity) || extinctionPerDensity < 0.f) {
29 DiagnosticCode::InvalidArgument, "extinctionPerDensity must be finite and >= 0",
30 "extinctionPerDensity", {}, "graphics.fog"));
31 }
32 if (!finiteVec3(albedo) || albedo.x < 0.f || albedo.y < 0.f || albedo.z < 0.f || albedo.x > 1.f ||
33 albedo.y > 1.f || albedo.z > 1.f) {
35 DiagnosticCode::InvalidArgument, "albedo components must be finite and in [0,1]", "albedo",
36 {}, "graphics.fog"));
37 }
38 auto in01 = [](float v) { return std::isfinite(v) && v >= 0.f && v <= 1.f; };
39 if (!in01(ambientOcclusion) || !in01(ambientUp) || !in01(ambientDown)) {
41 DiagnosticCode::InvalidArgument, "ambient terms must be finite and in [0,1]", "ambient", {},
42 "graphics.fog"));
43 }
44 if (!std::isfinite(anisotropy) || anisotropy < -0.99f || anisotropy > 0.99f) {
46 DiagnosticCode::InvalidArgument, "anisotropy must be finite and in [-0.99,0.99]",
47 "anisotropy", {}, "graphics.fog"));
48 }
49
50 extinctionPerDensity_ = extinctionPerDensity;
51 albedo_ = albedo;
52 ambientOcclusion_ = ambientOcclusion;
53 ambientUp_ = ambientUp;
54 ambientDown_ = ambientDown;
55 anisotropy_ = anisotropy;
56 return Result<void>::success();
57}
58
59float FogProfile::extinctionAt(float density) const noexcept {
60 return extinctionPerDensity_ * std::max(density, 0.f);
61}
62
63glm::vec3 FogProfile::scatteringAt(float density) const noexcept {
64 return albedo_ * extinctionAt(density);
65}
66
67float FogProfile::phase(float cosTheta) const noexcept {
68 const float c = std::clamp(cosTheta, -1.f, 1.f);
69 const float g = anisotropy_;
70 // Dual-lobe: forward HG + mild isotropic back lobe for ambient fill.
71 return 0.85f * henyeyGreenstein(g, c) + 0.15f * henyeyGreenstein(-0.25f * g, c);
72}
73
74glm::vec3 FogProfile::ambientRadiance(const glm::vec3& skyUp, const glm::vec3& groundDown,
75 float density) const noexcept {
76 const float ao = 1.f - ambientOcclusion_ * std::clamp(density, 0.f, 1.f);
77 return ao * (ambientUp_ * skyUp + ambientDown_ * groundDown);
78}
79
80} // namespace eve::graphics::fog
graphics::Texture * albedo
Stable, structured diagnostics shared by engine modules.
tensor::Graph g
Definition GpuGraph.cpp:7
float v
std::int32_t c
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
float ambientOcclusion() const noexcept
Ambient occlusion strength in [0,1].
Definition FogProfile.h:23
float extinctionAt(float density) const noexcept
Extinction for a sampled density value.
float extinctionPerDensity() const noexcept
Extinction coefficient per unit density (σ_t), non-negative.
Definition FogProfile.h:19
float anisotropy() const noexcept
Henyey–Greenstein anisotropy in [-0.99, 0.99].
Definition FogProfile.h:29
Result< void > configure(float extinctionPerDensity, const glm::vec3 &albedo, float ambientOcclusion, float ambientUp, float ambientDown, float anisotropy)
Atomically replace the optical profile.
glm::vec3 ambientRadiance(const glm::vec3 &skyUp, const glm::vec3 &groundDown, float density) const noexcept
Ambient term using up/down visibility and AO.
float phase(float cosTheta) const noexcept
Dual-lobe Henyey–Greenstein phase evaluated for cosθ.
float ambientDown() const noexcept
Downward ambient visibility scale in [0,1].
Definition FogProfile.h:27
glm::vec3 scatteringAt(float density) const noexcept
Scattering coefficient σ_s = albedo * σ_t.
float ambientUp() const noexcept
Upward ambient visibility scale in [0,1].
Definition FogProfile.h:25
const glm::vec3 & albedo() const noexcept
Single-scattering albedo in [0,1].
Definition FogProfile.h:21