mirror of
https://github.com/ssloy/tinyraytracer.git
synced 2025-08-11 00:43:58 +02:00
specular lighting
This commit is contained in:
BIN
out.jpg
BIN
out.jpg
Binary file not shown.
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 49 KiB |
@@ -12,9 +12,11 @@ struct Light {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Material {
|
struct Material {
|
||||||
Material(const Vec3f &color) : diffuse_color(color) {}
|
Material(const Vec2f &a, const Vec3f &color, const float &spec) : albedo(a), diffuse_color(color), specular_exponent(spec) {}
|
||||||
Material() : diffuse_color() {}
|
Material() : albedo(1,0), diffuse_color(), specular_exponent() {}
|
||||||
|
Vec2f albedo;
|
||||||
Vec3f diffuse_color;
|
Vec3f diffuse_color;
|
||||||
|
float specular_exponent;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Sphere {
|
struct Sphere {
|
||||||
@@ -38,6 +40,10 @@ struct Sphere {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Vec3f reflect(const Vec3f &I, const Vec3f &N) {
|
||||||
|
return I - N*2.f*(I*N);
|
||||||
|
}
|
||||||
|
|
||||||
bool scene_intersect(const Vec3f &orig, const Vec3f &dir, const std::vector<Sphere> &spheres, Vec3f &hit, Vec3f &N, Material &material) {
|
bool scene_intersect(const Vec3f &orig, const Vec3f &dir, const std::vector<Sphere> &spheres, Vec3f &hit, Vec3f &N, Material &material) {
|
||||||
float spheres_dist = std::numeric_limits<float>::max();
|
float spheres_dist = std::numeric_limits<float>::max();
|
||||||
for (size_t i=0; i < spheres.size(); i++) {
|
for (size_t i=0; i < spheres.size(); i++) {
|
||||||
@@ -60,12 +66,14 @@ Vec3f cast_ray(const Vec3f &orig, const Vec3f &dir, const std::vector<Sphere> &s
|
|||||||
return Vec3f(0.2, 0.7, 0.8); // background color
|
return Vec3f(0.2, 0.7, 0.8); // background color
|
||||||
}
|
}
|
||||||
|
|
||||||
float diffuse_light_intensity = 0;
|
float diffuse_light_intensity = 0, specular_light_intensity = 0;
|
||||||
for (size_t i=0; i<lights.size(); i++) {
|
for (size_t i=0; i<lights.size(); i++) {
|
||||||
Vec3f light_dir = (lights[i].position - point).normalize();
|
Vec3f light_dir = (lights[i].position - point).normalize();
|
||||||
|
|
||||||
diffuse_light_intensity += lights[i].intensity * std::max(0.f, light_dir*N);
|
diffuse_light_intensity += lights[i].intensity * std::max(0.f, light_dir*N);
|
||||||
|
specular_light_intensity += powf(std::max(0.f, -reflect(-light_dir, N)*dir), material.specular_exponent)*lights[i].intensity;
|
||||||
}
|
}
|
||||||
return material.diffuse_color * diffuse_light_intensity;
|
return material.diffuse_color * diffuse_light_intensity * material.albedo[0] + Vec3f(1., 1., 1.)*specular_light_intensity * material.albedo[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void render(const std::vector<Sphere> &spheres, const std::vector<Light> &lights) {
|
void render(const std::vector<Sphere> &spheres, const std::vector<Light> &lights) {
|
||||||
@@ -88,6 +96,9 @@ void render(const std::vector<Sphere> &spheres, const std::vector<Light> &lights
|
|||||||
ofs.open("./out.ppm");
|
ofs.open("./out.ppm");
|
||||||
ofs << "P6\n" << width << " " << height << "\n255\n";
|
ofs << "P6\n" << width << " " << height << "\n255\n";
|
||||||
for (size_t i = 0; i < height*width; ++i) {
|
for (size_t i = 0; i < height*width; ++i) {
|
||||||
|
Vec3f &c = framebuffer[i];
|
||||||
|
float max = std::max(c[0], std::max(c[1], c[2]));
|
||||||
|
if (max>1) c = c*(1./max);
|
||||||
for (size_t j = 0; j<3; j++) {
|
for (size_t j = 0; j<3; j++) {
|
||||||
ofs << (char)(255 * std::max(0.f, std::min(1.f, framebuffer[i][j])));
|
ofs << (char)(255 * std::max(0.f, std::min(1.f, framebuffer[i][j])));
|
||||||
}
|
}
|
||||||
@@ -96,8 +107,8 @@ void render(const std::vector<Sphere> &spheres, const std::vector<Light> &lights
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
Material ivory(Vec3f(0.4, 0.4, 0.3));
|
Material ivory(Vec2f(0.6, 0.3), Vec3f(0.4, 0.4, 0.3), 50.);
|
||||||
Material red_rubber(Vec3f(0.3, 0.1, 0.1));
|
Material red_rubber(Vec2f(0.9, 0.1), Vec3f(0.3, 0.1, 0.1), 10.);
|
||||||
|
|
||||||
std::vector<Sphere> spheres;
|
std::vector<Sphere> spheres;
|
||||||
spheres.push_back(Sphere(Vec3f(-3, 0, -16), 2, ivory));
|
spheres.push_back(Sphere(Vec3f(-3, 0, -16), 2, ivory));
|
||||||
@@ -107,6 +118,8 @@ int main() {
|
|||||||
|
|
||||||
std::vector<Light> lights;
|
std::vector<Light> lights;
|
||||||
lights.push_back(Light(Vec3f(-20, 20, 20), 1.5));
|
lights.push_back(Light(Vec3f(-20, 20, 20), 1.5));
|
||||||
|
lights.push_back(Light(Vec3f( 30, 50, -25), 1.8));
|
||||||
|
lights.push_back(Light(Vec3f( 30, 20, 30), 1.7));
|
||||||
|
|
||||||
render(spheres, lights);
|
render(spheres, lights);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user