-
Notifications
You must be signed in to change notification settings - Fork 336
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
15 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,9 +12,9 @@ struct Light { | |
}; | ||
|
||
struct Material { | ||
Material(const Vec2f &a, const Vec3f &color, const float &spec) : albedo(a), diffuse_color(color), specular_exponent(spec) {} | ||
Material() : albedo(1,0), diffuse_color(), specular_exponent() {} | ||
Vec2f albedo; | ||
Material(const Vec3f &a, const Vec3f &color, const float &spec) : albedo(a), diffuse_color(color), specular_exponent(spec) {} | ||
Material() : albedo(1,0,0), diffuse_color(), specular_exponent() {} | ||
Vec3f albedo; | ||
Vec3f diffuse_color; | ||
float specular_exponent; | ||
}; | ||
|
@@ -58,14 +58,18 @@ bool scene_intersect(const Vec3f &orig, const Vec3f &dir, const std::vector<Sphe | |
return spheres_dist<1000; | ||
} | ||
|
||
Vec3f cast_ray(const Vec3f &orig, const Vec3f &dir, const std::vector<Sphere> &spheres, const std::vector<Light> &lights) { | ||
Vec3f cast_ray(const Vec3f &orig, const Vec3f &dir, const std::vector<Sphere> &spheres, const std::vector<Light> &lights, size_t depth=0) { | ||
Vec3f point, N; | ||
Material material; | ||
|
||
if (!scene_intersect(orig, dir, spheres, point, N, material)) { | ||
if (depth>4 || !scene_intersect(orig, dir, spheres, point, N, material)) { | ||
return Vec3f(0.2, 0.7, 0.8); // background color | ||
} | ||
|
||
Vec3f reflect_dir = reflect(dir, N).normalize(); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
ssloy
Author
Owner
|
||
Vec3f reflect_orig = reflect_dir*N < 0 ? point - N*1e-3 : point + N*1e-3; // offset the original point to avoid occlusion by the object itself | ||
Vec3f reflect_color = cast_ray(reflect_orig, reflect_dir, spheres, lights, depth + 1); | ||
|
||
float diffuse_light_intensity = 0, specular_light_intensity = 0; | ||
for (size_t i=0; i<lights.size(); i++) { | ||
Vec3f light_dir = (lights[i].position - point).normalize(); | ||
|
@@ -80,7 +84,7 @@ Vec3f cast_ray(const Vec3f &orig, const Vec3f &dir, const std::vector<Sphere> &s | |
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 * material.albedo[0] + Vec3f(1., 1., 1.)*specular_light_intensity * material.albedo[1]; | ||
return material.diffuse_color * diffuse_light_intensity * material.albedo[0] + Vec3f(1., 1., 1.)*specular_light_intensity * material.albedo[1] + reflect_color*material.albedo[2]; | ||
} | ||
|
||
void render(const std::vector<Sphere> &spheres, const std::vector<Light> &lights) { | ||
|
@@ -114,14 +118,15 @@ void render(const std::vector<Sphere> &spheres, const std::vector<Light> &lights | |
} | ||
|
||
int main() { | ||
Material ivory(Vec2f(0.6, 0.3), Vec3f(0.4, 0.4, 0.3), 50.); | ||
Material red_rubber(Vec2f(0.9, 0.1), Vec3f(0.3, 0.1, 0.1), 10.); | ||
Material ivory(Vec3f(0.6, 0.3, 0.1), Vec3f(0.4, 0.4, 0.3), 50.); | ||
Material red_rubber(Vec3f(0.9, 0.1, 0.0), Vec3f(0.3, 0.1, 0.1), 10.); | ||
Material mirror(Vec3f(0.0, 10.0, 0.8), Vec3f(1.0, 1.0, 1.0), 1425.); | ||
|
||
std::vector<Sphere> spheres; | ||
spheres.push_back(Sphere(Vec3f(-3, 0, -16), 2, ivory)); | ||
spheres.push_back(Sphere(Vec3f(-1.0, -1.5, -12), 2, red_rubber)); | ||
spheres.push_back(Sphere(Vec3f(-1.0, -1.5, -12), 2, mirror)); | ||
spheres.push_back(Sphere(Vec3f( 1.5, -0.5, -18), 3, red_rubber)); | ||
spheres.push_back(Sphere(Vec3f( 7, 5, -18), 4, ivory)); | ||
spheres.push_back(Sphere(Vec3f( 7, 5, -18), 4, mirror)); | ||
|
||
std::vector<Light> lights; | ||
lights.push_back(Light(Vec3f(-20, 20, 20), 1.5)); | ||
|
I suppose we don't need
normalize
here becausedir
andN
are already unit vectors and reflection doesn't change vector norm or I'm wrong?