Сцена содержит 3 сферы, два красных шара и один зеленый. В верхнем правом углу должен быть красный шарик, но по какой-то причине он не появляется, а фон черный, когда должен быть серым. Также освещение работает только для красного шара, а не для зеленого. pi c:
https://imgur.com/a/AHP5tsi
Я думаю, что ошибка заключается в большей части цвета
vec color(const ray& r)
{
vector <Light> lighting;
vector <sphere> objects;
lighting.push_back(Light(vec(0, 0, 50), vec(0, -1, 0)));
lighting.push_back(Light(vec(10, 20, -2), vec(0, -1, 0)));
//ighting.push_back(Light(vec(-10, 30, -4), vec(0, -1, 0)));
objects.push_back(sphere(vec(0,-100.5,-3), 100, vec(0, 1, 0)));
objects.push_back(sphere(vec(0, 0, -1), 0.5, vec(1, 0, 0)));
objects.push_back(sphere(vec(5, 5,-2), 3, vec(1, 0, 0)));
float t_near = 2000.0;
float t = 0.0;
int pos = 0;
vec frame_buffer = vec(0.502, 0.502, 0.498);//grey background color
vec totalLight{0, 0, 0};
float depth = 0.0;
for(int j = 0; j < objects.size(); j++)
{
t = objects[j].intersect(r);
if(t > 0.0)
depth = t;
else
depth = t_near;
if(depth < t_near)
{
t_near = depth;
frame_buffer = objects[j].col();
pos = j;
}
else
{
t = t_near;
frame_buffer = frame_buffer;
pos = pos;
}
}
if(depth > 0.0)
{
for(int i = 0; i < lighting.size(); i++)
{
vec hit = unit_vector(r.p_at_par(depth) - objects[pos].centre);
vec L = unit_vector(lighting[i].position() - r.p_at_par(depth));
vec R = L - 2.0*dot(L, hit)*hit;
vec S = vec(1, 1, 1)*pow(max(0.f, dot(R, vec(0, 0, -1))), 50);//Specular component
vec D = (frame_buffer * max(0.f, dot(L, hit)) * 1.0);//Diffuse component
totalLight += S + D;
}
return totalLight; //+= A;
}
else
return vec(0.502, 0.502, 0.498);
}
это остальная часть основного. cpp
#include <iostream>
#include <cstdio>
#include "vec.h"
#include "ray.h"
#include "Light.h"
#include "sphere.h"
#include "object.h"
#include <vector>
#include <functional>
#include <random>
#include <math.h>
using namespace std;
inline double random_double() {
static std::uniform_real_distribution<double> distribution(0.0, 1.0);
static std::mt19937 generator;
static std::function<double()> rand_generator =
std::bind(distribution, generator);
return rand_generator();
}
vec color(const ray& r)
{
vector <Light> lighting;
vector <sphere> objects;
lighting.push_back(Light(vec(0, 0, 50), vec(0, -1, 0)));
lighting.push_back(Light(vec(10, 20, -2), vec(0, -1, 0)));
//ighting.push_back(Light(vec(-10, 30, -4), vec(0, -1, 0)));
objects.push_back(sphere(vec(0,-100.5,-3), 100, vec(0, 1, 0)));
objects.push_back(sphere(vec(0, 0, -1), 0.5, vec(1, 0, 0)));
objects.push_back(sphere(vec(5, 5,-2), 3, vec(1, 0, 0)));
float t_near = 2000.0;
float t = 0.0;
int pos = 0;
vec frame_buffer = vec(0.502, 0.502, 0.498);//grey background color
vec totalLight{0, 0, 0};
float depth = 0.0;
for(int j = 0; j < objects.size(); j++)
{
t = objects[j].intersect(r);
if(t > 0.0)
depth = t;
else
depth = t_near;
if(depth < t_near)
{
t_near = depth;
frame_buffer = objects[j].col();
pos = j;
}
else
{
t = t_near;
frame_buffer = frame_buffer;
pos = pos;
}
}
if(depth > 0.0)
{
for(int i = 0; i < lighting.size(); i++)
{
vec hit = unit_vector(r.p_at_par(depth) - objects[pos].centre);
vec L = unit_vector(lighting[i].position() - r.p_at_par(depth));
vec R = L - 2.0*dot(L, hit)*hit;
vec S = vec(1, 1, 1)*pow(max(0.f, dot(R, vec(0, 0, -1))), 50);//Specular component
vec D = (frame_buffer * max(0.f, dot(L, hit)) * 1.0);//Diffuse component
totalLight += S + D;
}
return totalLight; //+= A;
}
else
return vec(0.502, 0.502, 0.498);
}
float clamp(float a)
{
return (a > 255)? 255: (a < 0)? 0: a;
}
int main()
{
const int w = 200, h = 100;
FILE *fp;
fp = fopen("img.ppm", "wb");
fprintf(fp, "P6\n%d %d\n255\n", w, h);
vec lower_corner(-2.0, -1.0, -1.0);
vec horizontal(4.0, 0.0, 0.0);
vec vertical(0.0, 2.0, 0.0);
vec origin(0.0, 0.0, 0.0);
for(int j = h - 1; j >= 0; j--)
{
for(int i = 0; i < w; i++)
{
vec col(0, 0, 0);
static unsigned char pixel[3];
for(int s = 0; s < 200; s++){
float u = float(i + random_double())/float(w);
float v = float(j + random_double())/float(h);
ray r(origin, lower_corner + u*horizontal + v*vertical);
col += color(r);
}
col /= float(200);
pixel[0] = int(clamp(col.r() * 255));
pixel[1] = int(clamp(col.g() * 255));
pixel[2] = int(clamp(col.b() * 255));
fwrite(pixel, 3, 1, fp);
}
}
fclose(fp);
return 0;
}
Спасибо