Permalink
Browse files

Add light support: single point light

  • Loading branch information...
Ninputer committed Apr 12, 2012
1 parent ca08b6d commit 24b7b7c38f381e83b7b4ad0c41d1e89ae17c6852
@@ -91,6 +91,8 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="ampmathhelper.h" />
<ClInclude Include="light.h" />
<ClInclude Include="material.h" />
<ClInclude Include="raycommon.h" />
<ClInclude Include="render.h" />
<ClInclude Include="RayTracingApplication.h" />
@@ -1,7 +1,5 @@
#pragma once
#include "amp.h"
#include "amp_math.h"
#include "ampmathhelper.h"
template<typename fp_t>
@@ -1,7 +1,5 @@
#pragma once
#include <amp.h>
#include <amp_math.h>
#include "raycommon.h"
class geometry
@@ -105,4 +103,50 @@ class plane : public geometry
{
position = normal * d;
}
};
template<typename fp_t>
class scene_storage
{
public:
enum
{
geometry_max_size = 16,
geometry_count = 3
};
scene_storage() restrict(cpu)
{
new(geometries + 0) plane<fp_t>(vector3<fp_t>(0.0f, 1.0f, 0.0f), 0.0f, 2);
new(geometries + 1) sphere<fp_t>(vector3<fp_t>(-15.0f, 15.0f, -10.0f), 15.0f, 0);
new(geometries + 2) sphere<fp_t>(vector3<fp_t>(12.0f, 10.0f, -10.0f), 10.0f, 1);
}
intersect_result<fp_t> intersect(const ray<fp_t>& ray) const restrict(cpu, amp)
{
fp_t z = 0.0f;
fp_t min_dist = 1.0f / z;
intersect_result<fp_t> min_result;
for (int i = 0; i < geometry_count; i++)
{
const geometry_object* o = &geometries[i];
const geometry* g = reinterpret_cast<const geometry*>(o);
intersect_result<fp_t> result(g->intersect(ray));
if (result.is_hit && result.distance < min_dist)
{
min_dist = result.distance;
min_result = result;
}
}
return min_result;
}
private:
struct geometry_object
{
fp_t values[geometry_max_size];
} geometries[geometry_count];
};
View
@@ -0,0 +1,44 @@
#pragma once
#include "geometry.h"
template<typename fp_t>
class light_sample
{
public:
vector3<fp_t> light_vec;
color<fp_t> energy;
light_sample() restrict(cpu, amp) {}
explicit light_sample(const vector3<fp_t>& l, const color<fp_t>& el) restrict(cpu, amp) : light_vec(l), energy(el) {}
light_sample(const light_sample& other) restrict(cpu, amp) : light_vec(other.light_vec), energy(other.energy) {}
};
template<typename fp_t>
class point_light
{
public:
color<fp_t> intensity;
vector3<fp_t> position;
explicit point_light(const color<fp_t>& intensity, const vector3<fp_t>& position) restrict(cpu, amp) : intensity(intensity), position(position) {}
light_sample<fp_t> sample(const scene_storage<fp_t>& scene, const vector3<fp_t>& pos) const restrict(cpu, amp)
{
vector3<fp_t> delta(position - pos);
fp_t rr = delta.sqr_length();
fp_t r = gpu::sqrt(rr);
vector3<fp_t> l = delta / r;
ray<fp_t> shadow_ray(pos, l);
intersect_result<fp_t> shadow_result(scene.intersect(shadow_ray));
if (shadow_result.is_hit && shadow_result.distance <= r)
return light_sample<fp_t>();
fp_t attenuation = 1.0f / rr;
return light_sample<fp_t>(l, intensity * attenuation);
}
};
@@ -0,0 +1,127 @@
#pragma once
#include "light.h"
template <typename fp_t>
class material
{
public:
enum material_type
{
material_checker,
material_phong
};
fp_t reflectiveness;
template<typename fp_t>
color<fp_t> sample(const ray<fp_t>& ray, const vector3<fp_t>& position, const vector3<fp_t>& normal, light_sample<fp_t> ls) const restrict(cpu, amp)
{
switch (type)
{
case material_checker:
return static_cast<const checker<fp_t>*>(this)->sample_impl(ray, position, normal, ls);
case material_phong:
return static_cast<const phong<fp_t>*>(this)->sample_impl(ray, position, normal, ls);
default:
return color<fp_t>::black();
}
}
protected:
explicit material(int type, fp_t reflectiveness) restrict(cpu, amp) : type(type), reflectiveness(reflectiveness) {}
private:
int type;
};
template <typename fp_t>
class checker : public material<fp_t>
{
public:
checker(fp_t scale, fp_t reflectiveness) restrict(cpu, amp) : material(material_checker, reflectiveness), scale(scale) {}
color<fp_t> sample_impl(const ray<fp_t>& ray, const vector3<fp_t>& position, const vector3<fp_t>& normal, light_sample<fp_t> ls)const restrict(cpu, amp)
{
fp_t r = gpu::fabs(gpu::floor(position.x * scale) + gpu::floor(position.z * scale));
color<fp_t> checker_color((static_cast<int>(r) % 2) < 1 ? color<fp_t>::black() : ls.energy);
color<fp_t> basic_color;
fp_t n_dot_l = normal.dot(ls.light_vec);
if (n_dot_l >= 0)
basic_color = basic_color + (checker_color * n_dot_l);
return basic_color;
}
private:
fp_t scale;
};
template <typename fp_t>
class phong : public material<fp_t>
{
public:
phong(color<fp_t> diffuse, color<fp_t> specular, fp_t shininess, fp_t reflectiveness)
: material(material_phong, reflectiveness), diffuse(diffuse), specular(specular), shininess(shininess) {}
color<fp_t> sample_impl(const ray<fp_t>& ray, const vector3<fp_t>& position, const vector3<fp_t>& normal, light_sample<fp_t> ls) const restrict(cpu, amp)
{
/*vector3<fp_t> light_dir(0.5773503f, 0.5773503f, 0.5773503f);
color<fp_t> light_color(color<fp_t>::white());*/
fp_t n_dot_l = normal.dot(ls.light_vec);
vector3<fp_t> h((ls.light_vec - ray.direction).normalize());
fp_t n_dot_h = normal.dot(h);
color<fp_t> diffuse_term = diffuse * gpu::fmax(n_dot_l, 0.0f);
color<fp_t> specular_term = specular * gpu::pow(gpu::fmax(n_dot_h, 0.0f), shininess);
return ls.energy * (diffuse_term + specular_term);
}
private:
color<fp_t> diffuse;
color<fp_t> specular;
fp_t shininess;
};
template<typename fp_t>
class material_storage
{
public:
enum
{
material_max_size = 16,
material_count = 3
};
material_storage() restrict(cpu)
{
new(materials + 0) phong<fp_t>(color<fp_t>::red(), color<fp_t>::white(), 16.0f, 0.25f);
new(materials + 1) phong<fp_t>(color<fp_t>::blue(), color<fp_t>::white(), 16.0f, 0.25f);
new(materials + 2) checker<fp_t>(0.1f, 0.5f);
}
color<fp_t> sample(int material_id, const ray<fp_t>& ray, const vector3<fp_t>& position, const vector3<fp_t>& normal, light_sample<fp_t> ls) const restrict(cpu, amp)
{
const material_value* m = &materials[material_id];
const material<fp_t>* p = reinterpret_cast<const material<fp_t>*>(m);
return p->sample(ray, position, normal, ls);
}
fp_t get_reflectiveness(int material_id) const restrict(cpu, amp)
{
const material_value* m = &materials[material_id];
const material<fp_t>* p = reinterpret_cast<const material<fp_t>*>(m);
return p->reflectiveness;
}
private:
struct material_value
{
fp_t values[material_max_size];
} materials[material_count];
};
@@ -1,7 +1,5 @@
#pragma once
#include <amp.h>
#include <amp_math.h>
#include "ampvectors.h"
template <typename fp_t>
@@ -73,6 +71,7 @@ class color
fp_t g;
fp_t b;
color() restrict(cpu, amp) : r(0.0f), g(0.0f), b(0.0f) {}
explicit color(fp_t r, fp_t g, fp_t b) restrict(cpu, amp) : r(r), g(g), b(b) {}
color(const color& other) restrict(cpu, amp) : r(other.r), g(other.g), b(other.b) {}
@@ -98,78 +97,3 @@ class color
static color blue() restrict(cpu, amp) { return color(0.0f, 0.0f, 1.0f); }
};
template <typename fp_t>
class material
{
public:
enum material_type
{
material_checker,
material_phong
};
fp_t reflectiveness;
template<typename fp_t>
color<fp_t> sample(const ray<fp_t>& ray, const vector3<fp_t>& position, const vector3<fp_t>& normal) const restrict(cpu, amp)
{
switch (type)
{
case material_checker:
return static_cast<const checker<fp_t>*>(this)->sample_impl(ray, position, normal);
case material_phong:
return static_cast<const phong<fp_t>*>(this)->sample_impl(ray, position, normal);
default:
return color<fp_t>::black();
}
}
protected:
explicit material(int type, fp_t reflectiveness) restrict(cpu, amp) : type(type), reflectiveness(reflectiveness) {}
private:
int type;
};
template <typename fp_t>
class checker : public material<fp_t>
{
public:
checker(fp_t scale, fp_t reflectiveness) restrict(cpu, amp) : material(material_checker, reflectiveness), scale(scale) {}
color<fp_t> sample_impl(const ray<fp_t>& ray, const vector3<fp_t>& position, const vector3<fp_t>& normal)const restrict(cpu, amp)
{
fp_t r = gpu::fabs(gpu::floor(position.x * scale) + gpu::floor(position.z * scale));
return (static_cast<int>(r) % 2) < 1 ? color<fp_t>::black() : color<fp_t>::white();
}
private:
fp_t scale;
};
template <typename fp_t>
class phong : public material<fp_t>
{
public:
phong(color<fp_t> diffuse, color<fp_t> specular, fp_t shininess, fp_t reflectiveness)
: material(material_phong, reflectiveness), diffuse(diffuse), specular(specular), shininess(shininess) {}
color<fp_t> sample_impl(const ray<fp_t>& ray, const vector3<fp_t>& position, const vector3<fp_t>& normal)const restrict(cpu, amp)
{
vector3<fp_t> light_dir(0.5773503f, 0.5773503f, 0.5773503f);
color<fp_t> light_color(color<fp_t>::white());
fp_t n_dot_l = normal.dot(light_dir);
vector3<fp_t> h((light_dir - ray.direction).normalize());
fp_t n_dot_h = normal.dot(h);
color<fp_t> diffuse_term = diffuse * gpu::fmax(n_dot_l, 0.0f);
color<fp_t> specular_term = specular * gpu::pow(gpu::fmax(n_dot_h, 0.0f), shininess);
return light_color * (diffuse_term + specular_term);
}
private:
color<fp_t> diffuse;
color<fp_t> specular;
fp_t shininess;
};
Oops, something went wrong.

0 comments on commit 24b7b7c

Please sign in to comment.