Quick Thing, прежде чем мы начнем. Поскольку я совершенно новичок в «поле» трассировки лучей, особенно материальных систем, помните, что моя теоретическая основа может быть или не быть структурно звучащей ... так сказать

Диаграмма системы можно увидеть ниже. Примечание, я не реализовал Box Mix ... пока! /1gnwze3l.png " /> < /p>
Я застрял на нескольких деталях и нуждается в помощи: < /p>
- В спецификации используются векторы L и v , которые обычно относятся к вектору из точки пересечения в направлении источника света и вектор из пересечение точки к камере соответственно. Полем Единственный «источник света» - это цвет фона, который можно рассматривать как «окружающее освещение». Таким образом, я решил интерпретировать l как wi в моей реализации, где wi является избранным отбросом. Моя мотивация для этого заключается в том, что я подпрыгиваю в этом направлении, чтобы выяснить, каков вклад света с этого угла. Таким образом, в некотором смысле l и wi - одно и то же (ISH). Я не знаю, правильно ли это сделать. Скорее, я предпочитаю интерпретировать v как wo , где wo является направлением входящего луча. Опять же, я не знаю, правильно ли это сделать. >, а также то, что такое PDF. Оценка BRDF достаточно простой; Тем не менее, не тривиально выяснить, как попробовать новое направление, а также то, что такое PDF. По крайней мере, не для меня. < /P>
Выяснить, как попробовать новое направление отскока в Dielectric :: sample < /code>, а также как то, что PDF. Материал Dielectric имеет specularbrdf и diffusebrdf . Я понятия не имею, как я должен учитывать их обоих, когда хочу попробовать новое направление, а также определять PDF. < /P>
< li> Как представить концепцию «эмиссивных материалов» в эту материальную систему.
#pragma once
#include
#include
#include
#include "../Util.hpp"
struct Sample {
glm::dvec3 wi;
double pdf;
};
struct BxDF {
BxDF() = default;
virtual ~BxDF() = default;
[[nodiscard]] virtual glm::dvec3 f(const glm::dvec3& wi, const glm::dvec3& wo, const glm::dvec3& normal) const = 0;
[[nodiscard]] virtual Sample sample(const glm::dvec3& wo, const glm::dvec3& normal) const = 0;
};
struct SpecularBRDF : BxDF {
double alpha{0.25};
double alpha2{0.0625};
SpecularBRDF() = default;
SpecularBRDF(const double roughness)
: alpha(roughness * roughness), alpha2(alpha * alpha) {}
[[nodiscard]] glm::dvec3 f(const glm::dvec3& wi, const glm::dvec3& wo, const glm::dvec3& normal) const override {
const auto H = glm::normalize(wi + wo);
const auto brdf = glm::dvec3(V(wi, wo, normal) * D(normal, H));
return brdf;
}
[[nodiscard]] Sample sample(const glm::dvec3& wo, const glm::dvec3& normal) const override {
const Sample sample {
.wi = ..............................TODO
.pdf = ..............................TODO
};
return sample;
}
private:
double Chi(const double x) const {
if (std::fabs(x) f(wi, wo, N);
const glm::dvec3 layer = specular->f(wi, wo, N);
return glm::mix(base, layer, fr);
}
[[nodiscard]] Sample sample(const glm::dvec3& wo, const glm::dvec3& N) const {
const Sample sample {
.wi = ..............................TODO
.pdf = ..............................TODO
};
return sample;
}
};
struct Metal : NewMaterial {
std::shared_ptr specular{nullptr};
glm::dvec3 f0{1.0};
Metal() = default;
Metal(const std::shared_ptr& specular, const glm::dvec3& f0)
: specular(specular), f0(f0) {}
[[nodiscard]] glm::dvec3 f(const glm::dvec3& wi, const glm::dvec3& wo, const glm::dvec3& N) const {
const glm::dvec3 H = glm::normalize(wi + wo);
const double WOdotH = glm::dot(wo, H);
return specular->f(wi, wo, N) * (f0 + (1.0 - f0) * glm::pow(1 - glm::abs(WOdotH), 5));
}
[[nodiscard]] Sample sample(const glm::dvec3& wo, const glm::dvec3& N) const {
return specular->sample(wo, N);
}
};
Возможно, Traceray (...) Код ниже может представлять интерес, я не уверен. Я помесчу это здесь на случай, если нам это нужно.glm::dvec3 TraceRay(Ray& ray) {
glm::dvec3 Lo{0.0f};
glm::dvec3 throughput{1.0};
for (uint32_t i = 0; i emission;
const glm::dvec3 wo = glm::normalize(-ray.direction);
const Sample sample = material->sample(wo, hp.normal);
// PDF near zero => extremely unlikely path
if (sample.pdf < Util::EPSILON)
break;
const double cosine = glm::dot(sample.wi, hp.normal);
const glm::dvec3 brdf = material->f(sample.wi, wo, hp.normal);
throughput *= (brdf * cosine) / sample.pdf;
// throughput has decreased so much => not much point in continuing
if (throughput.x < Util::EPSILON && throughput.y < Util::EPSILON && throughput.z < Util::EPSILON)
break;
// Russian roulette
static uint32_t ITERS_BEFORE_RR = 5;
if (i >= ITERS_BEFORE_RR) {
const double p = glm::max(glm::max(throughput.x, throughput.y), throughput.z);
if (Util::RandomDouble() > p) {
break;
}
throughput *= (1.0f / p);
}
// Bounce ray
ray.origin = hp.position + Util::EPSILON * sample.wi;
ray.direction = sample.wi;
}
return Lo;
}
Подробнее здесь: https://stackoverflow.com/questions/794 ... r-gltf-2-0