# HG changeset patch # User John Tsiombikas # Date 1401249989 -10800 # Node ID e49f4d7ad04c3f38ec4a96aee13e8f67f785545b # Parent ea95b62dbc87499e606409689364f75ee6bf7b7c started adding BRDFs diff -r ea95b62dbc87 -r e49f4d7ad04c liberebus/src/brdf.cc --- a/liberebus/src/brdf.cc Tue May 27 07:49:09 2014 +0300 +++ b/liberebus/src/brdf.cc Wed May 28 07:06:29 2014 +0300 @@ -12,6 +12,102 @@ return eval(norm, outdir, *indir); } +// --- class CompositeRefl ---- +CompositeRefl::CompositeRefl() +{ + valid_checked = false; +} + +int CompositeRefl::pick_brdf(const Vector3 &norm, const Vector3 &outdir) const +{ + if(sub_brdf.empty()) { + return -1; + } + + int brdf_count = (int)sub_brdf.size(); + if(brdf_count == 1) { + return 0; + } + + // construct CDF from sub-brdf probabilities + float *cdf = (float*)alloca(brdf_count * sizeof *cdf); + for(int i=0; i 0 ? cdf[i - 1] + w : w; + } + + float rval = randf(0.0, cdf[brdf_count - 1]); + for(int i=0; isample_dir(norm, outdir); +} + +float CompositeRefl::sample(const Vector3 &norm, const Vector3 &outdir, Vector3 *indir) const +{ + int bidx = pick_brdf(norm, outdir); + return sub_brdf[bidx].brdf->sample(norm, outdir, indir); +} + +float CompositeRefl::eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const +{ + if(!warned_composite_usage) { + fputs(composite_usage_warnstr, stderr); + warned_composite_usage = true; + } + int bidx = pick_brdf(norm, outdir); + return sub_brdf[bidx].brdf->eval(norm, outdir, indir); +} + // --- class LambertRefl --- Vector3 LambertRefl::sample_dir(const Vector3 &norm, const Vector3 &outdir) const { @@ -23,3 +119,14 @@ { return dot_product(norm, outdir); } + +// --- class MirrorRefl --- +Vector3 MirrorRefl::sample_dir(const Vector3 &norm, const Vector3 &outdir) const +{ + return outdir.reflection(norm); +} + +float MirrorRefl::eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const +{ + return 1.0f; +} diff -r ea95b62dbc87 -r e49f4d7ad04c liberebus/src/brdf.h --- a/liberebus/src/brdf.h Tue May 27 07:49:09 2014 +0300 +++ b/liberebus/src/brdf.h Wed May 28 07:06:29 2014 +0300 @@ -1,6 +1,7 @@ #ifndef BRDF_H_ #define BRDF_H_ +#include #include "texture.h" class Reflectance { @@ -13,10 +14,43 @@ virtual float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const = 0; }; +typedef float (*CompReflWeightFunc)(const Vector3 &norm, const Vector3 &outdir); + +class CompositeRefl : public Reflectance { +private: + struct SubRefl { + Reflectance *brdf; + float weight; + CompReflWeightFunc weight_func; // if null, use static weight above + }; + std::vector sub_brdf; + mutable bool valid_checked; + + int pick_brdf(const Vector3 &norm, const Vector3 &outdir) const; + +public: + CompositeRefl(); + + virtual void add_brdf(Reflectance *brdf, float weight); + virtual void add_brdf(Reflectance *brdf, CompReflWeightFunc weight_func); + + bool check_valid() const; + + Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const override; + float sample(const Vector3 &norm, const Vector3 &outdir, Vector3 *indir) const override; + float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const override; +}; + class LambertRefl : public Reflectance { public: Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const override; float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const override; }; +class MirrorRefl : public Reflectance { +public: + Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const override; + float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const override; +}; + #endif // BRDF_H_ diff -r ea95b62dbc87 -r e49f4d7ad04c src/main.cc --- a/src/main.cc Tue May 27 07:49:09 2014 +0300 +++ b/src/main.cc Wed May 28 07:06:29 2014 +0300 @@ -75,10 +75,12 @@ } } - printf("begin rendering\n"); - render_pending = true; - glutIdleFunc(idle); - erb_begin_frame(erb, 0); + if(!sfiles.empty()) { + printf("begin rendering\n"); + render_pending = true; + glutIdleFunc(idle); + erb_begin_frame(erb, 0); + } glEnable(GL_TEXTURE_2D); return true;