erebus

diff liberebus/src/brdf.cc @ 28:4a0a288ffb27

phong/lafortune BRDF
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 06 Jun 2014 14:39:40 +0300
parents e49f4d7ad04c
children e78f68d03ae9
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 +}