Skip to content
Snippets Groups Projects
Commit bd676fcc authored by Adrian Herath's avatar Adrian Herath
Browse files

Implement checker texture

parent 82ab0791
No related branches found
No related tags found
1 merge request!2Combined
......@@ -2,15 +2,50 @@
#define MATERIAL_H
#include "Hittable.h"
#include "math.h"
/**
* Clamps the input color to [0,1] range.
* @param clr - input color
*/
RGB clamp(const RGB& clr) {
inline RGB clamp(const RGB& clr) {
return clr.cwiseMax(0).cwiseMin(1);
}
/**
* Linearly interpolates between a and b at time t
*/
template<class T>
T lerp(const double t, const T& a, const T& b) {
return (a+t*(b-a));
}
Vec floor(const Vec& v) {
double x, y, z;
int ix, iy, iz;
x = v.x();
ix = floor(x);
y = v.y();
iy = floor(y);
z = v.z();
iz = floor(z);
return {ix,iy,iz};
}
Vec fract(const Vec& v) {
return v - floor(v);
}
double fract(const double x) {
return x - floor(x);
}
class Material {
public:
virtual RGB emitted() const {
......@@ -147,6 +182,68 @@ public:
}
};
/**
* Same as Lambertian but 2 colors and a checker_size is given to generate checkers.
*/
class CheckeredLambertian : public Material {
public:
const double W_LIGHT = 0.5;
RGB clr1, clr2;
double chkr_size;
CheckeredLambertian(const RGB& color1, const RGB& color2, const float& checker_size) {
clr1 = color1;
clr2 = color2;
chkr_size = checker_size;
}
bool scatter(
const Ray& in, const HitRecord& rec, const Hittable& lights,
RGB& attenuation, Ray& scattered) const {
if (Eigen::Array<double,1,1>::Random()[0] < W_LIGHT*2-1) {
//Happens with probability W_LIGHT
//Sample lights
scattered = lights.sample(rec.pos);
} else {
// Random sample on surface of unit sphere
Vec t;
while (true) {
t = Vec::Random();
double r2 = t.squaredNorm();
if (EPSILON < r2 && r2 < 1) break;
}
Vec dir = rec.normal+t.normalized();
dir = dir.squaredNorm()<EPSILON? rec.normal : dir.normalized();
scattered = {rec.pos, dir};
}
//Weight attenuation
double c = rec.normal.dot(scattered.dir.normalized());
double pdfScattered = (c <= 0) ? 0 : c/M_PI;
double pdfMixed = lights.sample_pdf(scattered)*W_LIGHT +
pdfScattered*(1-W_LIGHT);
RGB color = checker_color(rec);
attenuation = color * pdfScattered / pdfMixed;
return true;
}
private:
RGB checker_color(const HitRecord& rec) const {
Vec pos = rec.pos;
float x = pos.x() + EPSILON;
float y = pos.y() + EPSILON;
float z = pos.z() + EPSILON;
if (((int)floor(x/chkr_size)+(int)floor(y/chkr_size) + (int)floor(z/chkr_size)) % 2) {
return clr1;
} else {
return clr2;
}
}
};
const shared_ptr<Material> MAT_DEFAULT = make_shared<Lambertian>(Vec(0,1,0));
#endif
......@@ -69,7 +69,8 @@ Scene complexScene() {
scene.background = {0.2,0.2,0.2};
auto ground = make_shared<Plane>(Vec(0,-600,0), Vec(0,1,0));
ground->matPtr = make_shared<Lambertian>(Vec(0.1,0.1,0.8));
//ground->matPtr = make_shared<CheckeredLambertian>(Vec(0.1,0.1,0.8), Vec(1.0, 1.0, 1.0), 100.0);
ground->matPtr = make_shared<CheckeredLambertian>(Vec(0.1,0.1,0.8), Vec(0.0, 0.0, 0.0), 100.0);
world->list.push_back(ground);
auto mirror = make_shared<Mirror>(Vec(1,1,1));
......@@ -88,6 +89,8 @@ Scene complexScene() {
world->list.push_back(tri0b);
auto sph1 = make_shared<Sphere>(Vec(600,0,-6000), 600);
sph1->matPtr = make_shared<CheckeredLambertian>(Vec(0.1,0.8,0.1), Vec(0.0, 0.0, 0.0), 100.0);
world->list.push_back(sph1);
auto sph2 = make_shared<Sphere>(Vec(900,300,-4000), 300);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment