Woo Scene updates...

This commit is contained in:
Eryn Wells 2014-08-09 12:25:59 -07:00
parent c49457a817
commit 47ae52ed05
4 changed files with 258 additions and 224 deletions

View file

@ -51,7 +51,6 @@ struct Camera
virtual basics::Ray PrimaryRay(const int x, const int width,
const int y, const int height) const = 0;
protected:
virtual std::string GetTypeString() const;
private:

View file

@ -5,84 +5,123 @@
* Eryn Wells <eryn@erynwells.me>
*/
#include <chrono>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <chrono>
#include "scene.hh"
#include "basics.h"
#include "light.h"
#include "log.hh"
#include "object.h"
#include "scene.h"
#include "object.hh"
#include "writer.h"
#include "basics/basics.hh"
#define LOG_NAME "scene"
#include "logModule.hh"
using namespace charles;
using charles::basics::Ray;
using charles::basics::Vector4;
namespace charles {
/*
* charles::Scene::Scene --
*/
Scene::Scene()
: width(640), height(480),
: mWidth(640),
mHeight(480),
mCamera(new PerspectiveCamera()),
max_depth(5),
min_weight(1e-4),
ambient(new AmbientLight()),
shapes(),
lights(),
mMaxDepth(5),
mMinWeight(1e-6),
mAmbient(),
mObjects(),
mLights(),
mStats(),
pixels(NULL)
mPixels(NULL)
{ }
/*
* charles::Scene::~Scene --
*/
Scene::~Scene()
{
mCamera.reset();
if (ambient != NULL) {
delete ambient;
}
mObjects.clear();
shapes.clear();
for (PointLight *l : lights) {
for (PointLight *l : mLights) {
delete l;
}
lights.clear();
mLights.clear();
if (pixels != NULL) {
delete[] pixels;
_is_rendered = false;
if (mPixels != NULL) {
delete[] mPixels;
mIsRendered = false;
}
}
bool
Scene::is_rendered()
const
{
return _is_rendered;
}
int
Scene::get_width()
const
{
return width;
}
int
Scene::get_height()
const
{
return height;
}
/*
* Scene::GetCamera --
* charles::Scene::IsRendered --
*/
bool
Scene::IsRendered()
const
{
return mIsRendered;
}
/*
* charles::Scene::GetWidth --
*/
UInt
Scene::GetWidth()
const
{
return mWidth;
}
/*
* charles::Scene::SetWidth --
*/
void
Scene::SetWidth(UInt w)
{
mWidth = w;
}
/*
* charles::Scene::GetHeight --
*/
UInt
Scene::GetHeight()
const
{
return mHeight;
}
/*
* charles::Scene::SetHeight --
*/
void
Scene::SetHeight(UInt h)
{
mHeight = h;
}
/*
* charles::Scene::GetCamera --
*/
Camera::Ptr
Scene::GetCamera()
@ -93,63 +132,55 @@ Scene::GetCamera()
/*
* Scene::SetCamera --
* charles::Scene::SetCamera --
*/
void
Scene::SetCamera(Camera* camera)
Scene::SetCamera(Camera::Ptr camera)
{
mCamera.reset(camera);
}
AmbientLight &
Scene::get_ambient()
const
{
return *ambient;
}
const Color *
Scene::get_pixels()
const
{
return pixels;
mCamera = camera;
}
/*
* scene_load --
*
* Load scene objects into this Scene from the given file.
* charles::Scene::GetAmbient --
*/
void
Scene::read(const std::string &filename)
{ }
AmbientLight&
Scene::GetAmbient()
{
return mAmbient;
}
/*
* scene_save --
*
* Write a rendered scene to the given file.
* charles::Scene::GetPixels --
*/
const Color*
Scene::GetPixels()
const
{
return mPixels;
}
/*
* charles::Scene::Write --
*/
void
Scene::write(Writer &writer, const std::string &filename)
Scene::Write(Writer& writer,
const std::string& filename)
{
writer.write_scene(*this, filename);
}
/*
* Scene::render --
*
* Render the given Scene.
* charles::Scene::Render --
*/
void
Scene::render()
Scene::Render()
{
LOG_INFO << "Rendering scene with " << shapes.size() << " objects.";
printf("Rendering scene with %lu objects.\n", shapes.size());
LOG_INFO << "Rendering scene with " << mObjects.size() << " objects.";
printf("Rendering scene with %lu objects.\n", mObjects.size());
LogCamera();
LogObjects();
@ -157,23 +188,23 @@ Scene::render()
std::chrono::time_point<std::chrono::system_clock> start, end;
start = std::chrono::system_clock::now();
pixels = new Color[width * height];
mPixels = new Color[mWidth * mHeight];
Ray primary_ray;
Vector3 o, d;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
primary_ray = mCamera->compute_primary_ray(x, width, y, height);
Ray primaryRay;
Vector4 o, d;
for (UInt y = 0; y < mHeight; y++) {
for (UInt x = 0; x < mWidth; x++) {
primaryRay = mCamera->PrimaryRay(x, mWidth, y, mHeight);
mStats.primaryRays++;
Color c = trace_ray(primary_ray);
pixels[y * width + x] = c;
Color c = TraceRay(primaryRay);
mPixels[y * mWidth + x] = c;
}
}
end = std::chrono::system_clock::now();
std::chrono::duration<float> seconds = end - start;
std::chrono::duration<Double> seconds = end - start;
_is_rendered = true;
mIsRendered = true;
printf("Rendering completed in %f seconds.\n\n", seconds.count());
LOG_INFO << "Rendering completed in " << seconds.count() << " seconds.";
@ -184,83 +215,77 @@ Scene::render()
/*
* Scene::add_shape --
*
* Add a shape to the scene.
* charles::Scene::AddObject --
*/
void
Scene::add_shape(Object::Ptr shape)
Scene::AddObject(Object::Ptr obj)
{
shapes.push_back(shape);
mObjects.push_back(obj);
}
/*
* Scene::add_light --
*
* Add a light to the scene.
* charles::Scene::AddLight --
*/
void
Scene::add_light(PointLight *light)
Scene::AddLight(PointLight* light)
{
lights.push_back(light);
mLights.push_back(light);
}
/*
* Scene::trace_ray --
*
* Trace the given ray through the scene, recursing until depth has been reached.
* charles::Scene::TraceRay --
*/
Color
Scene::trace_ray(const Ray &ray,
const int depth,
const float weight)
Scene::TraceRay(const Ray &ray,
const int depth,
const Double weight)
{
if (depth >= max_depth || weight <= min_weight) {
if (depth >= mMaxDepth || weight <= mMinWeight) {
return Color::Black;
}
Color out_color = Color::Black;
Object::Ptr intersected_shape;
Color outColor = Color::Black;
Object::Ptr intersectedObj;
TVector ts;
Double nearest_t = INFINITY;
Double nearestT = INFINITY;
ts.reserve(2);
// Find intersections of this ray with objects in the scene.
for (Object::Ptr s : shapes) {
for (Object::Ptr obj : mObjects) {
ts.clear();
if (s->DoesIntersect(ray, ts, mStats)) {
if (ts[0] < nearest_t) {
intersected_shape = s;
nearest_t = ts[0];
if (obj->Intersect(ray, ts, mStats)) {
if (ts[0] < nearestT) {
intersectedObj = obj;
nearestT = ts[0];
}
}
}
// If there was no intersection, return black.
if (!intersected_shape) {
return out_color;
if (!intersectedObj) {
return outColor;
}
Material& shape_material = intersected_shape->GetMaterial();
const Color& shape_color = shape_material.GetDiffuseColor();
Material& material = intersectedObj->GetMaterial();
const Color& shapeColor = material.GetDiffuseColor();
Vector3 intersection = ray.parameterize(nearest_t);
Vector3 normal = intersected_shape->compute_normal(intersection);
Vector4 intersection = ray.Parameterize(nearestT);
Vector4 normal = intersectedObj->Normal(intersection);
/*
* Diffuse lighting. (Shading, etc.)
*/
Vector3 light_direction;
Double ldotn, diffuse_level, ambient_level;
Vector4 lightDirection;
Double ldotn, diffuseLevel, ambientLevel;
Ray shadowRay;
for (PointLight *l : lights) {
light_direction = (l->GetOrigin() - intersection).normalize();
ldotn = light_direction.dot(normal);
for (PointLight *l : mLights) {
lightDirection = (l->GetOrigin() - intersection).normalize();
ldotn = lightDirection.Dot(normal);
/*
* TODO: What is this even for? Removing it makes the darker showers
@ -270,12 +295,12 @@ Scene::trace_ray(const Ray &ray,
ldotn = 0.0;
}
diffuse_level = shape_material.GetDiffuseIntensity();
ambient_level = 1.0 - diffuse_level;
diffuseLevel = material.GetDiffuseIntensity();
ambientLevel = 1.0 - diffuseLevel;
shadowRay = Ray(intersection, light_direction);
for (Object::Ptr s : shapes) {
if (s == intersected_shape) {
shadowRay = Ray(intersection, lightDirection);
for (Object::Ptr obj : mObjects) {
if (obj == intersectedObj) {
/* Skip the intersected shape. */
continue;
}
@ -284,8 +309,8 @@ Scene::trace_ray(const Ray &ray,
/* Figure out if we're in shadow. */
ts.clear();
if (s->DoesIntersect(shadowRay, ts, mStats)) {
diffuse_level = 0.0;
if (obj->Intersect(shadowRay, ts, mStats)) {
diffuseLevel = 0.0;
break;
}
}
@ -293,8 +318,8 @@ Scene::trace_ray(const Ray &ray,
/*
* Compute basic Lambert diffuse shading for this object.
*/
out_color += shape_color * ( ambient_level * ambient->compute_color_contribution()
+ diffuse_level * ldotn);
outColor += shapeColor * ( ambientLevel * mAmbient.compute_color_contribution()
+ diffuseLevel * ldotn);
}
/*
@ -328,10 +353,13 @@ Scene::trace_ray(const Ray &ray,
out_color += specular_level * specular_color * reflection_color;
#endif
return out_color;
return outColor;
}
/*
* charles::Scene::LogCamera --
*/
void
Scene::LogCamera()
const
@ -341,7 +369,7 @@ Scene::LogCamera()
LOG_DEBUG << "BEGIN CAMERA";
LOG_DEBUG << " type = " << c.GetTypeString();
LOG_DEBUG << " origin = " << c.GetOrigin();
LOG_DEBUG << " direction = " << c.get_direction();
LOG_DEBUG << " direction = " << c.GetDirection();
LOG_DEBUG << " right = " << c.GetRight();
LOG_DEBUG << " up = " << c.GetUp();
LOG_DEBUG << " coordinate system is "
@ -350,15 +378,20 @@ Scene::LogCamera()
}
/*
* charles::Scene::LogObjects --
*/
void
Scene::LogObjects()
const
{
LOG_DEBUG << "BEGIN SCENE OBJECTS";
for (Object::Ptr obj : shapes) {
for (Object::Ptr obj : mObjects) {
LOG_DEBUG << " " << *obj;
}
LOG_DEBUG << "END SCENE OBJECTS";
}
} /* namespace charles */

View file

@ -1,84 +0,0 @@
/* scene.h
*
* Definition of the Scene class.
*
* Scenes are the top level object in charles. Scenes contain objects, lights, a camera,
* etc. and can be rendered to pixel data and written to a file.
*
* Eryn Wells <eryn@erynwells.me>
*/
#ifndef __SCENE_H__
#define __SCENE_H__
#include <list>
#include <string>
#include "basics.h"
#include "camera.h"
#include "object.h"
#include "stats.hh"
class AmbientLight;
class PointLight;
class Writer;
class Scene
{
public:
Scene();
~Scene();
bool is_rendered() const;
int get_width() const;
void set_width(int w) { width = w; }
int get_height() const;
void set_height(int h) { height = h; }
Camera::Ptr GetCamera() const;
void SetCamera(Camera* camera);
AmbientLight &get_ambient() const;
const Color *get_pixels() const;
void read(const std::string &filename);
void write(Writer &writer, const std::string &filename);
void render();
void add_shape(charles::Object::Ptr obj);
void add_light(PointLight *light);
private:
Color trace_ray(const Ray &ray, const int depth = 0, const float weight = 1.0);
void LogCamera() const;
void LogObjects() const;
// Pixel dimensions of the image.
int width, height;
Camera::Ptr mCamera;
/*
* Ray tracing parameters. max_depth indicates the maximum depth of the ray tree. min_weight indicates the minimum
* specular weight to apply before giving up.
*/
int max_depth;
float min_weight;
// Scene objects.
AmbientLight *ambient;
std::list<charles::Object::Ptr> shapes;
std::list<PointLight *> lights;
// Rendering stats
charles::Stats mStats;
// Rendering output.
bool _is_rendered;
Color *pixels;
};
#endif

86
src/scene.hh Normal file
View file

@ -0,0 +1,86 @@
/* scene.h
* vim: tw=80:
* Eryn Wells <eryn@erynwells.me>
*/
#ifndef __SCENE_H__
#define __SCENE_H__
#include <list>
#include <string>
#include "camera.hh"
#include "light.h"
#include "object.hh"
#include "stats.hh"
#include "basics/basics.hh"
class Writer;
namespace charles {
/**
* Scenes are the top level object in charles. Scenes contain objects, lights, a
* camera, etc. and can be rendered to pixel data and written to a file.
*/
struct Scene
{
Scene();
~Scene();
UInt GetWidth() const;
void SetWidth(UInt w);
UInt GetHeight() const;
void SetHeight(UInt h);
Camera::Ptr GetCamera() const;
void SetCamera(Camera::Ptr camera);
void Write(Writer& writer, const std::string& filename);
void Render();
bool IsRendered() const;
const Color* GetPixels() const;
AmbientLight& GetAmbient();
void AddObject(Object::Ptr obj);
void AddLight(PointLight* light);
private:
Color TraceRay(const basics::Ray &ray,
const int depth = 0,
const Double weight = 1.0);
void LogCamera() const;
void LogObjects() const;
/** Pixel width */
UInt mWidth;
/** Pixel height */
UInt mHeight;
Camera::Ptr mCamera;
/** Maximum depth of the ray tree */
int mMaxDepth;
/** Minimum specular weight to apply before giving up */
float mMinWeight;
// Scene objects.
AmbientLight mAmbient;
std::list<charles::Object::Ptr> mObjects;
std::list<PointLight *> mLights;
// Rendering stats
charles::Stats mStats;
// Rendering output.
bool mIsRendered;
Color *mPixels;
};
} /* namespace charles */
#endif