erebus
changeset 28:4a0a288ffb27
phong/lafortune BRDF
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 06 Jun 2014 14:39:40 +0300 |
parents | 0ced900e15a7 |
children | fb20e3855740 |
files | liberebus/src/brdf.cc liberebus/src/brdf.h liberebus/src/rt.cc liberebus/src/scene.cc test/scene |
diffstat | 5 files changed, 87 insertions(+), 7 deletions(-) [+] |
line diff
1.1 --- a/liberebus/src/brdf.cc Mon Jun 02 00:53:01 2014 +0300 1.2 +++ b/liberebus/src/brdf.cc Fri Jun 06 14:39:40 2014 +0300 1.3 @@ -130,3 +130,45 @@ 1.4 { 1.5 return 1.0f; 1.6 } 1.7 + 1.8 +// --- class PhongRefl --- 1.9 +PhongRefl::PhongRefl() 1.10 +{ 1.11 + shininess = 42.0; 1.12 +} 1.13 + 1.14 +Vector3 PhongRefl::sample_dir(const Vector3 &norm, const Vector3 &outdir) const 1.15 +{ 1.16 + // construct orthonormal basis with k being the reflection dir 1.17 + Vector3 refl = outdir.reflection(norm).normalized(); 1.18 + Vector3 up = Vector3(0, 0, 1); 1.19 + if(fabs(dot_product(refl, up)) - 1.0 < 0.001) { 1.20 + up = Vector3(0, 1, 0); 1.21 + } 1.22 + Vector3 right = cross_product(up, refl); 1.23 + up = cross_product(refl, right); 1.24 + 1.25 + // construct the matrix transposed to move the sample from reflection 1.26 + // space to world space 1.27 + Matrix3x3 xform; 1.28 + xform.set_column_vector(right, 0); 1.29 + xform.set_column_vector(up, 1); 1.30 + xform.set_column_vector(refl, 2); 1.31 + 1.32 + float phi = acos(pow(randf(), 1.0 / (shininess + 1))); 1.33 + float theta = 2.0 * M_PI * randf(); 1.34 + 1.35 + Vector3 v; 1.36 + v.x = cos(theta) * sin(phi); 1.37 + v.y = sin(theta) * sin(phi); 1.38 + v.z = cos(phi); 1.39 + v.transform(xform); 1.40 + return v; 1.41 +} 1.42 + 1.43 +float PhongRefl::eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const 1.44 +{ 1.45 + Vector3 refl = outdir.reflection(norm); 1.46 + float dot = std::max<float>(dot_product(indir, refl), 0.0f); 1.47 + return pow(dot, shininess); 1.48 +}
2.1 --- a/liberebus/src/brdf.h Mon Jun 02 00:53:01 2014 +0300 2.2 +++ b/liberebus/src/brdf.h Fri Jun 06 14:39:40 2014 +0300 2.3 @@ -53,4 +53,14 @@ 2.4 float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const override; 2.5 }; 2.6 2.7 +class PhongRefl : public Reflectance { 2.8 +public: 2.9 + float shininess; 2.10 + 2.11 + PhongRefl(); 2.12 + 2.13 + Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const override; 2.14 + float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const override; 2.15 +}; 2.16 + 2.17 #endif // BRDF_H_
3.1 --- a/liberebus/src/rt.cc Mon Jun 02 00:53:01 2014 +0300 3.2 +++ b/liberebus/src/rt.cc Fri Jun 06 14:39:40 2014 +0300 3.3 @@ -2,7 +2,7 @@ 3.4 #include "rt.h" 3.5 #include "erebus_impl.h" 3.6 3.7 -#define MAX_ITER 8 3.8 +#define MAX_ITER 6 3.9 3.10 Color ray_trace(struct erebus *ctx, const Ray &ray, int iter) 3.11 { 3.12 @@ -40,14 +40,18 @@ 3.13 Vector2 texcoords = hit.calc_texcoords(); 3.14 3.15 Color color = mtl->get_attrib_color("diffuse", texcoords.x, texcoords.y); 3.16 - Color res = mtl->get_attrib_color("emissive") + color * scn->get_env().ambient; 3.17 + Color specular = mtl->get_attrib_color("specular", texcoords.x, texcoords.y); 3.18 + Color res = mtl->get_attrib_color("emissive", texcoords.x, texcoords.y) + 3.19 + color * scn->get_env().ambient; 3.20 + float shininess = mtl->get_attrib_value("shininess"); 3.21 3.22 Vector3 sample_dir; 3.23 float prob = brdf->sample(norm, -hit.world_ray.dir, &sample_dir); 3.24 - if(iter < max_iter && randf() <= prob) { 3.25 + if(iter < max_iter && randf() <= prob && ray.energy * prob > 0.001) { 3.26 Ray sample_ray; 3.27 sample_ray.origin = ray.origin + ray.dir * hit.dist; 3.28 sample_ray.dir = sample_dir; 3.29 + sample_ray.energy = ray.energy * prob; 3.30 3.31 res += ray_trace(ctx, sample_ray, iter + 1) * color; 3.32 }
4.1 --- a/liberebus/src/scene.cc Mon Jun 02 00:53:01 2014 +0300 4.2 +++ b/liberebus/src/scene.cc Fri Jun 06 14:39:40 2014 +0300 4.3 @@ -140,9 +140,22 @@ 4.4 4.5 bool Scene::load(FILE *fp) 4.6 { 4.7 - static char buf[256]; 4.8 + static char buf[4096]; 4.9 + int offset = 0; 4.10 4.11 - while(fgets(buf, sizeof buf, fp)) { 4.12 + while(fgets(buf + offset, sizeof buf - offset, fp)) { 4.13 + // handle line continuations 4.14 + int len = strlen(buf); 4.15 + if(strcmp(buf + len - 2, "\\\n") == 0 || strcmp(buf + len - 2, "\\\r") == 0) { 4.16 + offset = len - 2; 4.17 + continue; 4.18 + } 4.19 + if(strcmp(buf + len - 3, "\\\r\n") == 0) { 4.20 + offset = len - 3; 4.21 + continue; 4.22 + } 4.23 + offset = 0; 4.24 + 4.25 char *line = strip_wspace(buf); 4.26 if(!line || !*line || *line == '#') { 4.27 continue; 4.28 @@ -198,6 +211,13 @@ 4.29 brdf = new LambertRefl; 4.30 if(!composite) break; 4.31 4.32 + } else if(strcmp(argv[i], "phong") == 0) { 4.33 + if(composite && brdf) { 4.34 + composite->add_brdf(brdf, weight); 4.35 + } 4.36 + brdf = new PhongRefl; 4.37 + if(!composite) break; 4.38 + 4.39 } else if(strcmp(argv[i], "mirror") == 0) { 4.40 if(composite && brdf) { 4.41 composite->add_brdf(brdf, weight);
5.1 --- a/test/scene Mon Jun 02 00:53:01 2014 +0300 5.2 +++ b/test/scene Fri Jun 06 14:39:40 2014 +0300 5.3 @@ -1,8 +1,12 @@ 5.4 # test scene 5.5 5.6 -sphere -position 0 0 0 -scaling 1 1 1 -diffuse 1 0.6 0.5 5.7 +sphere -position 0 0 0 -scaling 1 1 1 -diffuse 1 0.6 0.5 -brdf composite \ 5.8 + -brdf lambert -brdf-weight 0.5 \ 5.9 + -brdf phong -brdf-weight 0.5 5.10 5.11 -box -position 0 -1.25 0 -scaling 4 0.5 4 -diffuse 0.3 0.4 1.0 -brdf composite -brdf lambert -brdf-weight 0.3 -brdf mirror -brdf-weight 0.7 5.12 +box -position 0 -1.25 0 -scaling 4 0.5 4 -diffuse 0.3 0.4 1.0 -brdf composite \ 5.13 + -brdf lambert -brdf-weight 0.3 \ 5.14 + -brdf mirror -brdf-weight 0.7 5.15 box -position 0 3.75 0 -scaling 20 10 20 -diffuse 1.0 1.0 1.0 -brdf lambert 5.16 5.17 box -position 0 4 0 -scaling 3 0.1 3 -emissive 6 6 6