- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
namespace raytracing
{
struct Scene::Implementation
{
std::vector<std::unique_ptr<RenderObject>> renderObjects;
std::vector<Light> lights;
Camera camera;
};
}
Scene::Scene() :
implementation{std::make_unique<Implementation>()}
{
}
void Scene::insertObject(RenderObject* renderObject) noexcept
{
implementation->renderObjects.push_back(std::unique_ptr<RenderObject>{renderObject});
}
const RenderObject* Scene::getIntersectedObject(Ray ray, vec3f* intersectionPoint) const noexcept
{
const auto& renderObjects = implementation->renderObjects;
if (renderObjects.empty())
return nullptr;
struct IntersectionData
{
const RenderObject* renderObject;
float t;
bool isIntersect;
vec3f intersectionPoint;
} temp{};
for (decltype(implementation->renderObjects)::const_iterator iter = renderObjects.cbegin();
iter != renderObjects.cend(); ++iter)
{
IntersectionData intersectionData;
intersectionData.renderObject = (*iter).get();
intersectionData.isIntersect = (*iter)->isIntersect(ray, intersectionData.t,
&intersectionData.intersectionPoint);
if (intersectionData.isIntersect)
{
if (temp.isIntersect)
{
if (temp.t > intersectionData.t)
temp = intersectionData;
}
else
temp = intersectionData;
}
}
if (intersectionPoint)
*intersectionPoint = temp.intersectionPoint;
return temp.renderObject;
}
namespace raytracing
{
struct Renderer::Implementation
{
vec3f trace(const Scene& scene, Ray ray) const noexcept
{
vec3f intersectionPoint;
const RenderObject* const renderObject = scene.getIntersectedObject(ray, &intersectionPoint);
vec3f color{};
if (!renderObject)
return color;
for (Light l : scene.getLights())
{
const Ray lightRay{intersectionPoint, (l.position - intersectionPoint).normalize()};
float brightness = renderObject->getNormal(intersectionPoint).dot(lightRay.direction);
if (brightness < 0.0F)
brightness = 0.0F;
color += renderObject->getColor(intersectionPoint) * 255.0F * brightness;
}
return color;
}
}
}