Skip to content

Commit

Permalink
-Use raw material pointers for speed in hit_record
Browse files Browse the repository at this point in the history
-Change CSG threshold and ray marching algorithm
-Fix elongate bounding box
-Remove offseting hit point for dielectrics
  • Loading branch information
tylermorganwall committed Dec 17, 2020
1 parent 6c91e6a commit 7358edf
Show file tree
Hide file tree
Showing 16 changed files with 133 additions and 153 deletions.
10 changes: 0 additions & 10 deletions src/bvh_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,6 @@ bool bvh_node::hit(const ray& r, Float t_min, Float t_max, hit_record& rec, rand
#endif
}

// bool bvh_node::hit(const ray& r, Float t_min, Float t_max, hit_record& rec, random_gen& rng) {
// if (!box.hit(r, t_min, t_max, rng))
// return false;
//
// bool hit_left = left->hit(r, t_min, t_max, rec, rng);
// bool hit_right = right->hit(r, t_min, hit_left ? rec.t : t_max, rec, rng);
//
// return hit_left || hit_right;
// }

inline bool box_compare(const std::shared_ptr<hitable> a, const std::shared_ptr<hitable> b, int axis) {
aabb box_a;
aabb box_b;
Expand Down
6 changes: 3 additions & 3 deletions src/cone.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ bool cone::hit(const ray& r, Float t_min, Float t_max, hit_record& rec, random_g
// rec.bump_normal = -rec.bump_normal;
// }

rec.mat_ptr = mat_ptr;
rec.mat_ptr = mat_ptr.get();
return(true);
}
// if((t_cyl < temp2 || !second_is_hit) && t_cyl > t_min && t_cyl < t_max && radHit2 <= radius * radius && base_is_hit) {
Expand All @@ -143,7 +143,7 @@ bool cone::hit(const ray& r, Float t_min, Float t_max, hit_record& rec, random_g
rec.p = p;
rec.normal = vec3(0,-1,0);
rec.t = t_cyl;
rec.mat_ptr = mat_ptr;
rec.mat_ptr = mat_ptr.get();
rec.u = u;
rec.v = v;
rec.dpdu = vec3(1, 0, 0);
Expand Down Expand Up @@ -187,7 +187,7 @@ bool cone::hit(const ray& r, Float t_min, Float t_max, hit_record& rec, random_g
// rec.normal = -rec.normal;
// rec.bump_normal = -rec.bump_normal;
// }
rec.mat_ptr = mat_ptr;
rec.mat_ptr = mat_ptr.get();
return(true);
}
return(false);
Expand Down
2 changes: 1 addition & 1 deletion src/constant.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ bool constant_medium::hit(const ray& r, Float t_min, Float t_max, hit_record& re
rec.t = rec1.t + hit_distance / r.direction().length();
rec.p = r.point_at_parameter(rec.t);
rec.normal = vec3(1,0,0);
rec.mat_ptr = phase_function;
rec.mat_ptr = phase_function.get();
return(true);
}
}
Expand Down
13 changes: 8 additions & 5 deletions src/csg.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#include "csg.h"

bool csg::hit(const ray& r, Float t_min, Float t_max, hit_record& rec, random_gen& rng) {
Float threshold = 10e-6;
Float threshold = 0.001;

Float delta = 10e-5 * max_dist/100;
Float t = 0;
bool first = true;
vec3 dir = unit_vector(r.direction());
Float max_t = t_max * r.direction().length();


while (t < max_t) {
Float minDistance = INFINITY;
Expand All @@ -16,16 +18,17 @@ bool csg::hit(const ray& r, Float t_min, Float t_max, hit_record& rec, random_ge
float d = std::fabs(shapes->getDistance(from));

//Need to deal with refraction, often initial distance is too close to surface, so we offset
if(first && t < threshold) {
t += 100 * threshold; //Hard coded threshold, not great
if(first && d < threshold) {
t += 0.01; //Hard coded offset, not great
first = false;
continue;
}

if (d < minDistance) {
minDistance = d;
}
if (minDistance <= threshold * t) {
first = false;
if (minDistance <= threshold) {
Float tval = t / r.direction().length();
if(tval > t_min && tval < t_max) {
rec.normal = vec3(
Expand All @@ -44,7 +47,7 @@ bool csg::hit(const ray& r, Float t_min, Float t_max, hit_record& rec, random_ge
rec.v = 0.5;
rec.dpdu = 0.5;
rec.dpdv = 0.5;
rec.mat_ptr = mat_ptr;
rec.mat_ptr = mat_ptr.get();
rec.has_bump = false;
rec.bump_normal = rec.normal;
return(true);
Expand Down
4 changes: 0 additions & 4 deletions src/csg.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,8 +354,6 @@ class csg_elongate : public ImplicitShape {
}
virtual bool bbox(Float t0, Float t1, aabb& box) const {
shape->bbox(t0,t1,box);
box.bounds[0] += center;
box.bounds[1] += center;
box = Expand(box, elongate);
return(true);
}
Expand All @@ -377,8 +375,6 @@ class csg_elongate_robust : public ImplicitShape {
}
virtual bool bbox(Float t0, Float t1, aabb& box) const {
shape->bbox(t0,t1,box);
box.bounds[0] += center;
box.bounds[1] += center;
box = Expand(box, elongate);
return(true);
}
Expand Down
2 changes: 1 addition & 1 deletion src/curve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ bool curve::recursiveIntersect(const ray& r, Float tmin, Float tmax, hit_record&

rec.u = u;
rec.v = v;
rec.mat_ptr = mat_ptr;
rec.mat_ptr = mat_ptr.get();
rec.has_bump = false;
rec.p = r.point_at_parameter(rec.t) + rec.normal * hitWidth * 0.5 * offset_scale;
return(true);
Expand Down
8 changes: 4 additions & 4 deletions src/cylinder.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ bool cylinder::hit(const ray& r, Float t_min, Float t_max, hit_record& rec, rand
rec.bump_normal *= dot(temppoint, dir) > 0 ? -1 : 1;

}
rec.mat_ptr = mat_ptr;
rec.mat_ptr = mat_ptr.get();
return(true);
}
Float t_cyl = -(r.origin().y()-length/2) / r.direction().y();
Expand All @@ -139,7 +139,7 @@ bool cylinder::hit(const ray& r, Float t_min, Float t_max, hit_record& rec, rand
rec.p = p;
rec.normal = vec3(0,1,0);
rec.t = t_cyl;
rec.mat_ptr = mat_ptr;
rec.mat_ptr = mat_ptr.get();
rec.u = u;
rec.v = v;
rec.dpdu = vec3(1, 0, 0);
Expand Down Expand Up @@ -174,7 +174,7 @@ bool cylinder::hit(const ray& r, Float t_min, Float t_max, hit_record& rec, rand
rec.p = p;
rec.normal = vec3(0,-1,0);
rec.t = t_cyl2;
rec.mat_ptr = mat_ptr;
rec.mat_ptr = mat_ptr.get();
rec.u = u;
rec.v = v;
rec.dpdu = vec3(1, 0, 0);
Expand Down Expand Up @@ -214,7 +214,7 @@ bool cylinder::hit(const ray& r, Float t_min, Float t_max, hit_record& rec, rand
rec.bump_normal.make_unit_vector();
}

rec.mat_ptr = mat_ptr;
rec.mat_ptr = mat_ptr.get();
return(true);
}
return(false);
Expand Down
2 changes: 1 addition & 1 deletion src/disk.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ bool disk::hit(const ray& r, Float t_min, Float t_max, hit_record& rec, random_g
rec.p = p;
rec.normal = n;
rec.t = t;
rec.mat_ptr = mat_ptr;
rec.mat_ptr = mat_ptr.get();
rec.u = u;
rec.v = v;

Expand Down
12 changes: 4 additions & 8 deletions src/ellipsoid.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ class ellipsoid: public hitable {
inv_axes = vec3(1.0f/axes.x(), 1.0f/axes.y(), 1.0f/axes.z());
largest_proj_axis = axes.x() * axes.y() * axes.z() / ffmin(axes.x(), ffmin(axes.y(), axes.z()));
};
~ellipsoid() {
// delete mat_ptr;
// delete alpha_mask;
}
virtual bool hit(const ray& r, Float tmin, Float tmax, hit_record& rec, random_gen& rng);
virtual bool bounding_box(Float t0, Float t1, aabb& box) const;
virtual Float pdf_value(const vec3& o, const vec3& v, random_gen& rng);
Expand Down Expand Up @@ -51,7 +47,7 @@ bool ellipsoid::hit(const ray& r, Float t_min, Float t_max, hit_record& rec, ran
Float v;
if(temp1 < t_max && temp1 > t_min) {
vec3 p1 = scaled_ray.point_at_parameter(temp1) ;
p1 *= 1/p1.length() * axes;;
p1 *= 1/p1.length() * axes;
vec3 normal = (p1 - center) * inv_axes;
normal.make_unit_vector();
get_sphere_uv(normal, u, v);
Expand All @@ -61,7 +57,7 @@ bool ellipsoid::hit(const ray& r, Float t_min, Float t_max, hit_record& rec, ran
}
if(temp2 < t_max && temp2 > t_min) {
vec3 p2 = scaled_ray.point_at_parameter(temp2) ;
p2 *= 1/p2.length() * axes;;
p2 *= 1/p2.length() * axes;
vec3 normal = (p2 - center) * inv_axes;
normal.make_unit_vector();
get_sphere_uv(normal, u, v);
Expand All @@ -77,7 +73,7 @@ bool ellipsoid::hit(const ray& r, Float t_min, Float t_max, hit_record& rec, ran
rec.t = temp1;
rec.p = scaled_ray.point_at_parameter(rec.t) ;
rec.normal = (rec.p - center);
rec.mat_ptr = mat_ptr;
rec.mat_ptr = mat_ptr.get();
vec3 trans_normal = rec.normal * inv_axes;
trans_normal.make_unit_vector();

Expand Down Expand Up @@ -109,7 +105,7 @@ bool ellipsoid::hit(const ray& r, Float t_min, Float t_max, hit_record& rec, ran
rec.t = temp2;
rec.p = scaled_ray.point_at_parameter(rec.t) ;
rec.normal = (rec.p - center);
rec.mat_ptr = mat_ptr;
rec.mat_ptr = mat_ptr.get();
vec3 trans_normal = rec.normal * inv_axes;
trans_normal.make_unit_vector();

Expand Down
2 changes: 1 addition & 1 deletion src/hitable.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct hit_record {
vec3 dpdu, dpdv;
vec3 bump_normal;
bool has_bump;
std::shared_ptr<material> mat_ptr;
material* mat_ptr;
};

class hitable {
Expand Down
4 changes: 2 additions & 2 deletions src/infinite_area_light.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ bool InfiniteAreaLight::hit(const ray& r, Float t_min, Float t_max, hit_record&
vec3 v2(-r.direction().z(),r.direction().y(),r.direction().x());
get_sphere_uv(unit_vector(v2), rec.u, rec.v);
rec.u = 1 - rec.u;
rec.mat_ptr = mat_ptr;
rec.mat_ptr = mat_ptr.get();
return(true);
}
if(temp2 < t_max && temp2 > t_min) {
Expand All @@ -85,7 +85,7 @@ bool InfiniteAreaLight::hit(const ray& r, Float t_min, Float t_max, hit_record&
vec3 v2(-r.direction().z(),r.direction().y(),r.direction().x());
get_sphere_uv(unit_vector(v2), rec.u, rec.v);
rec.u = 1 - rec.u;
rec.mat_ptr = mat_ptr;
rec.mat_ptr = mat_ptr.get();
return(true);
}
return(false);
Expand Down
99 changes: 99 additions & 0 deletions src/material.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,105 @@
#include "material.h"
#include "mathinline.h"

bool dielectric::scatter(const ray& r_in, const hit_record& hrec, scatter_record& srec, random_gen& rng) {
srec.is_specular = true;
vec3 outward_normal;
vec3 normal = !hrec.has_bump ? hrec.normal : hrec.bump_normal;

vec3 reflected = reflect(r_in.direction(), normal);
Float ni_over_nt;
srec.attenuation = albedo;
Float current_ref_idx = 1.0;

size_t active_priority_value = priority;
size_t next_down_priority = 100000;
int current_layer = -1; //keeping track of index of current material
int prev_active = -1; //keeping track of index of active material (higher priority)

bool entering = dot(hrec.normal, r_in.direction()) < 0;
bool skip = false;
vec3 offset_p = hrec.p;

for(size_t i = 0; i < r_in.pri_stack->size(); i++) {
if(r_in.pri_stack->at(i) == this) {
current_layer = i;
continue;
}
if(r_in.pri_stack->at(i)->priority < active_priority_value) {
active_priority_value = r_in.pri_stack->at(i)->priority;
skip = true;
}
if(r_in.pri_stack->at(i)->priority < next_down_priority && r_in.pri_stack->at(i) != this) {
prev_active = i;
next_down_priority = r_in.pri_stack->at(i)->priority;
}
}
if(entering) {
r_in.pri_stack->push_back(this);
}
current_ref_idx = prev_active != -1 ? r_in.pri_stack->at(prev_active)->ref_idx : 1;
if(skip) {
srec.specular_ray = ray(offset_p, r_in.direction(), r_in.pri_stack, r_in.time());
Float distance = (offset_p-r_in.point_at_parameter(0)).length();
vec3 prev_atten = r_in.pri_stack->at(prev_active)->attenuation;
srec.attenuation = vec3(std::exp(-distance * prev_atten.x()),
std::exp(-distance * prev_atten.y()),
std::exp(-distance * prev_atten.z()));
if(!entering && current_layer != -1) {
r_in.pri_stack->erase(r_in.pri_stack->begin() + static_cast<size_t>(current_layer));
}
return(true);
}

Float reflect_prob;
if(!entering) {
outward_normal = -normal;
ni_over_nt = ref_idx / current_ref_idx ;
} else {
outward_normal = normal;
ni_over_nt = current_ref_idx / ref_idx;
}
vec3 unit_direction = unit_vector(r_in.direction());
Float cos_theta = ffmin(dot(-unit_direction, outward_normal), (Float)1.0);
Float sin_theta = sqrt(1.0 - cos_theta*cos_theta);
if(ni_over_nt * sin_theta <= 1.0 ) {
reflect_prob = schlick(cos_theta, ref_idx, current_ref_idx);
reflect_prob = ni_over_nt == 1 ? 0 : reflect_prob;
} else {
reflect_prob = 1.0;
}
if(!entering) {
Float distance = (offset_p-r_in.point_at_parameter(0)).length();
srec.attenuation = vec3(std::exp(-distance * attenuation.x()),
std::exp(-distance * attenuation.y()),
std::exp(-distance * attenuation.z()));
} else {
if(prev_active != -1) {
Float distance = (offset_p-r_in.point_at_parameter(0)).length();
vec3 prev_atten = r_in.pri_stack->at(prev_active)->attenuation;

srec.attenuation = albedo * vec3(std::exp(-distance * prev_atten.x()),
std::exp(-distance * prev_atten.y()),
std::exp(-distance * prev_atten.z()));
} else {
srec.attenuation = albedo;
}
}
if(rng.unif_rand() < reflect_prob) {
if(entering) {
r_in.pri_stack->pop_back();
}
srec.specular_ray = ray(offset_p, reflected, r_in.pri_stack, r_in.time());
} else {
if(!entering && current_layer != -1) {
r_in.pri_stack->erase(r_in.pri_stack->begin() + current_layer);
}
vec3 refracted = refract(unit_direction, outward_normal, ni_over_nt);
srec.specular_ray = ray(offset_p, refracted, r_in.pri_stack, r_in.time());
}
return(true);
}

std::array<Float, pMax + 1> hair::ComputeApPdf(Float cosThetaO, Float h) const {
// Compute array of $A_p$ values for _cosThetaO_
Float sinThetaO = SafeSqrt(1 - cosThetaO * cosThetaO);
Expand Down
Loading

0 comments on commit 7358edf

Please sign in to comment.