107 std::make_unique<RayTracer::AmbientLight>(
108 static_cast<float>(cfg.
ambient)
115 std::make_unique<RayTracer::DirectionalLight>(
117 static_cast<float>(cfg.
diffuse)
123 for (
const auto &p : cfg.
points) {
125 std::make_unique<RayTracer::PointLight>(
127 static_cast<float>(cfg.
diffuse)
132 for (
const auto &s : cfg.
spheres) {
134 std::make_shared<RayTracer::Sphere>(
137 std::make_shared<RayTracer::FlatColor>(s.color)
142 for (
const auto &p : cfg.
planes) {
144 if (p.axis ==
'X') normal.
x = 1.0f;
145 else if (p.axis ==
'Y') normal.y = 1.0f;
146 else normal.z = 1.0f;
149 if (p.axis ==
'X') pt.
x = p.position;
150 else if (p.axis ==
'Y') pt.y = p.position;
151 else pt.z = p.position;
154 std::make_shared<RayTracer::Plane>(
157 std::make_shared<RayTracer::FlatColor>(p.color)
166 for (
int y = 0; y < h; ++y) {
167 for (
int x = 0; x < w; ++x) {
168 double u = (x + 0.5) / w;
169 double v = (y + 0.5) / h;
172 Color finalColor(0, 0, 0);
173 double closest_t = std::numeric_limits<double>::max();
174 std::shared_ptr<RayTracer::IPrimitive> closestObject =
nullptr;
182 if (obj->intersect(ray, t, pt, n) && t < closest_t) {
193 finalColor = scene.
getAmbient()->illuminate(ray, *closestObject, hitPoint);
196 for (
const auto &light : scene.
getLights()) {
199 lightDir = lightDir / lightDir.
length();
202 const double bias = 1e-4;
205 bool shadowed =
false;
208 if (obj != closestObject) {
212 if (obj->intersect(shadowRay, tTmp, tmpPt, tmpN)) {
219 double diff = std::max(0.0, normal.
dot(lightDir));
220 Color lightColor = light->illuminate(ray, *closestObject, hitPoint);
221 finalColor.
r = std::min(finalColor.
r +
static_cast<int>(lightColor.
r * diff), 255);
222 finalColor.
g = std::min(finalColor.
g +
static_cast<int>(lightColor.
g * diff), 255);
223 finalColor.
b = std::min(finalColor.
b +
static_cast<int>(lightColor.
b * diff), 255);
228 double dist = lightDir.
length();
229 lightDir = lightDir / dist;
231 const double bias = 1e-4;
234 bool inShadow =
false;
236 if (obj != closestObject) {
240 if (obj->intersect(shadowRay, tTmp, tmpPt, tmpN) && tTmp < dist) {
247 double diff = std::max(0.0, normal.
dot(lightDir));
248 Color c = light->illuminate(ray, *closestObject, hitPoint);
249 finalColor.
r = std::min(finalColor.
r +
static_cast<int>(c.
r * diff), 255);
250 finalColor.
g = std::min(finalColor.
g +
static_cast<int>(c.
g * diff), 255);
251 finalColor.
b = std::min(finalColor.
b +
static_cast<int>(c.
b * diff), 255);
269 bool isDebug =
false;
270 main.parseArguments(argc, argv, file, isDebug);
275 main.debug_config(cfg);
279 Display display(cfg.camera.width, cfg.camera.height);
283 if (worker.joinable())
287 std::cerr << e.what() << std::endl;
void parseArguments(int argc, char **argv, std::string &file, bool &isDebug)
void debug_config(const Config::Scene &cfg)
void calculPPM(const Config::Scene &cfg, Display &display)
int main(int argc, char **argv)