Монте -Карло пути трассера, казалось бы, слишком яркийC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Монте -Карло пути трассера, казалось бы, слишком яркий

Сообщение Anonymous »

Я пишу трассором пути Монте-Карло (MCPT). Я считаю, что есть проблема, касающаяся яркости отображаемых изображений. Внизу вы найдете несколько изображений, демонстрирующих то, о чем я говорю. Обратите внимание на разницу в цветах на первых двух изображениях ниже. Там нет прямого освещения. Единственный источник света - это «фоновый» свет в соответствии с функцией среды (...) . Это функционирует, что и из книги Ширли. Таким образом, я могу только думать о том, что две вещи являются проблемой: (1) способ, которым я накапливаю пропускную способность и/или цвет в функции Traceray (...) , и или (2) как я сохраняю изображение. Сохранение изображения такое же, как в книге, поэтому моя гипотеза заключается в том, что моя функция Traceray (...) проблематична. Мой код часами пытаюсь понять, где я ошибаюсь; Однако, насколько я знаю, все выглядит нормально. Я не понимаю, почему это происходит, и ищу советы о том, как отладить это. br /> функция литья Ray < /strong> < /p>

Код: Выделить всё

void Render(const Camera& camera, std::vector& color_buffer) {
constexpr float fSAMPLES_PER_PIXEL = static_cast(SAMPLES_PER_PIXEL);

#pragma omp parallel for
for (uint32_t y = 0; y < IMG_HEIGHT; y++) {
for (uint32_t x = 0; x < IMG_WIDTH; x++) {
glm::vec3 color{0.0f};

for (uint32_t i = 0; i < SAMPLES_PER_PIXEL; i++) {
// TODO: Perform better AA
Ray ray = camera.RayThrough(x + Util::RandomFloat() - 0.5f, y + Util::RandomFloat() - 0.5f);
color += TraceRay(ray);
}

color_buffer[y * IMG_WIDTH + x] = color / fSAMPLES_PER_PIXEL;
}
}
}
функция трассировки лучей [/b]

Код: Выделить всё

glm::vec3 TraceRay(Ray& ray) {

glm::vec3 Lo{0.0f};
glm::vec3 throughput{1.0f};

for (uint32_t i = 0; i emission;

const glm::vec3 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 float cosine = glm::dot(sample.wi, hp.normal);
const glm::vec3 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;
const float p = glm::max(glm::max(throughput.x, throughput.y), throughput.z);
if (i >= ITERS_BEFORE_RR && Util::RandomFloat() > p) {
break;
}
throughput *= (1.0f / p);

// Bounce ray
ray.origin = hp.position + Util::EPSILON * sample.wi;
ray.direction = sample.wi;

}

return Lo;
}

glm::vec3 Environment(const Ray& ray) {
static const glm::vec3 SKY_COLOR{ 0.5f, 0.7f, 1.0f };

const float alpha = 0.5f * (glm::normalize(ray.direction).y + 1.0f);
const glm::vec3 skyColor = alpha * SKY_COLOR + (1.0f - alpha) * glm::vec3{1.0f};
return skyColor;
}
lambertian material

Код: Выделить всё

#pragma once

#include "Material.hpp"

#include "../Util.hpp"

#include 
#include 
#include 

struct Lambertian : Material {
Lambertian(const glm::vec3 color, const glm::vec3 emission = glm::vec3(0.0f))
: Material(color, emission) {}

[[nodiscard]] glm::vec3 f(const glm::vec3& wi, const glm::vec3& wo, const glm::vec3& normal) const {
const glm::vec3 brdf = color / glm::pi();
return brdf;
}

[[nodiscard]] Sample sample(const glm::vec3& wo, const glm::vec3& normal) const {
const Sample sample{
.wi = Util::CosineSampleHemisphere(normal),
.pdf = glm::max(glm::dot(sample.wi, normal), 0.0f) / glm::pi()
};
return sample;
}
};
зеркальный материал

Код: Выделить всё

#pragma once

#include "Material.hpp"

#include "../Util.hpp"

#include 
#include 
#include 

struct Mirror : Material {
Mirror(const glm::vec3 color, const glm::vec3 emission = glm::vec3(0.0f))
: Material(color, emission) {}

[[nodiscard]] glm::vec3 f(const glm::vec3& wi, const glm::vec3& wo, const glm::vec3&  normal) const {
const glm::vec3 brdf = color;
return brdf;
}

[[nodiscard]] Sample sample(const glm::vec3& wo, const glm::vec3& normal) const {
const Sample sample{
.wi = glm::reflect(-wo, normal),//-wo - 2 * glm::dot(-wo, normal) * normal,
.pdf = 1.0f
};
return sample;
}
};
функции утилиты

Код: Выделить всё

#include "Util.hpp"

#include 
#include 

static thread_local std::random_device rd;
static thread_local std::mt19937 generator(rd());

float Util::RandomFloat()
{
std::uniform_real_distribution dist(0, 1);
return dist(generator);
}

float Util::RandomFloat(const float &a, const float &b)
{
return a + (b - a) * RandomFloat();
}

int Util::RandomInt(const int& a, const int& b)
{
return int(RandomFloat(a, b + 1));
}

glm::vec3 Util::CosineSampleHemisphere(const glm::vec3 &normal)
{
float r1 = RandomFloat();
float r2 = RandomFloat();

float phi = 2.0f * Util::PI * r1;

float x = std::cos(phi) * std::sqrt(r2);
float y = std::sin(phi) * std::sqrt(r2);
float z = std::sqrt(1.0f - r2);

return Util::ToNormalCoordSystem({x, y, z}, normal);
}

glm::vec3 Util::ToNormalCoordSystem(const glm::vec3 &local, const glm::vec3 &normal)
{
const glm::vec3 up = std::abs(normal.z) < 0.999f ? glm::vec3(0, 0, 1) : glm::vec3(1, 0, 0);
const glm::vec3 tangent = glm::normalize(glm::cross(up, normal));
const glm::vec3 bitangent = glm::cross(normal, tangent);

return glm::normalize(tangent * local.x + bitangent * local.y + normal * local.z);
}
Сохранение изображения. процесс такой же, как в книге Ширли. переопределить ">uint32_t Save(std::vector& color_buffer) {
std::cout

Подробнее здесь: https://stackoverflow.com/questions/794 ... too-bright
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»