297 lines
7.0 KiB
C++
297 lines
7.0 KiB
C++
/* -----------------------------------------------------------------------------
|
|
GSFramework
|
|
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
|
----------------------------------------------------------------------------- */
|
|
|
|
|
|
#ifndef __TRACER_CORE__
|
|
#define __TRACER_CORE__
|
|
|
|
|
|
#include "raytracer/raytracer_scene.h"
|
|
#include "raytracer/raytracer_spread.h"
|
|
#include "core/shader_tree.h"
|
|
#include "core/material.h"
|
|
#include "picture/pict.h"
|
|
|
|
|
|
namespace GS {
|
|
struct Color;
|
|
|
|
namespace Core {
|
|
struct ShaderBlock;
|
|
struct ShaderBlockValue;
|
|
}
|
|
namespace S3D { class Scene; }
|
|
namespace Raytrace {
|
|
|
|
//
|
|
struct Bounce
|
|
{
|
|
uint indirect,
|
|
reflection,
|
|
refraction;
|
|
};
|
|
|
|
/// Ray grid (ray density estimation).
|
|
struct RayGrid
|
|
{
|
|
Vector4 p[4], d[4];
|
|
|
|
RayGrid(const Vector4 &_p, const Vector4 &_d)
|
|
{ p[0] = _p; d[0] = _d; }
|
|
};
|
|
|
|
//
|
|
struct Statistics
|
|
{
|
|
uint ray_count,
|
|
tri_test;
|
|
|
|
void Reset()
|
|
{
|
|
ray_count = 0;
|
|
tri_test = 0;
|
|
}
|
|
|
|
Statistics()
|
|
{ Reset(); }
|
|
};
|
|
|
|
//
|
|
struct Configuration
|
|
{
|
|
uint trace_shadow_transparency_max_recursion,
|
|
trace_reflection_max_recursion,
|
|
trace_refraction_max_recursion,
|
|
indirect_gi_bounce,
|
|
gi_sample,
|
|
aa_sample;
|
|
|
|
bool trace_shadow,
|
|
trace_gi,
|
|
trace_aa,
|
|
trace_transparency,
|
|
trace_reflection,
|
|
trace_refraction,
|
|
gi_use_ambient,
|
|
aa_jitter,
|
|
ao_activate,
|
|
fresnel_activate;
|
|
|
|
float ao_length,
|
|
ao_angle;
|
|
|
|
bool interlaced, ///< Interlaced render.
|
|
interlace_even, ///< Start with even ordered scanline.
|
|
interlaced_trace_half_frame; ///< When rendering interlaced, compute half-frames instead of full ones (at a very small cost in quality).
|
|
|
|
float aa_threshold;
|
|
|
|
uint job_affinity;
|
|
|
|
Configuration()
|
|
{
|
|
trace_shadow_transparency_max_recursion = 32;
|
|
trace_reflection_max_recursion = 2;
|
|
trace_refraction_max_recursion = 6;
|
|
indirect_gi_bounce = 1;
|
|
|
|
trace_shadow = true;
|
|
trace_reflection = true;
|
|
trace_refraction = true;
|
|
trace_gi = false;
|
|
trace_aa = true;
|
|
trace_transparency = true;
|
|
|
|
ao_length = 1.0f;
|
|
ao_angle = 90.0f;
|
|
ao_activate = false;
|
|
|
|
fresnel_activate = false;
|
|
|
|
gi_use_ambient = false;
|
|
gi_sample = 8;
|
|
aa_sample = 4;
|
|
aa_threshold = 0.0075f;
|
|
aa_jitter = false;
|
|
|
|
interlaced = false;
|
|
interlace_even = true;
|
|
interlaced_trace_half_frame = true;
|
|
|
|
job_affinity = uint(~0);
|
|
}
|
|
};
|
|
|
|
class Raytracer;
|
|
|
|
//
|
|
struct Progress
|
|
{
|
|
const Raytracer *instance;
|
|
|
|
String description;
|
|
uint start_clock; ///< System clock when rendering started.
|
|
|
|
float progress;
|
|
int w, h;
|
|
Color *buffer;
|
|
|
|
bool aborted; ///< Rendering aborted.
|
|
bool done; ///< Rendering done.
|
|
};
|
|
|
|
/// Progress hook.
|
|
struct ProgressHook
|
|
{ virtual bool RaytracerProgress(const Progress &) = 0; };
|
|
|
|
/*!
|
|
@short Raytracer.
|
|
|
|
This class can be used as a generic raytracer to render raytraced pictures
|
|
of a scene or as a baking tool for the nGeometry class.
|
|
Supports, forward raytracing, Monte-Carlo raytracing, photon mapping along
|
|
more common material properties, diffuse, specular, reflection, refraction,
|
|
etc...
|
|
|
|
@author Emmanuel Julien (ejulien@nworks.fr)
|
|
*/
|
|
class Raytracer
|
|
{
|
|
public:
|
|
|
|
/// Geometry attributes.
|
|
enum GeometryAttribute
|
|
{
|
|
GeometryNormal = 0,
|
|
GeometryVertexColor
|
|
};
|
|
|
|
protected:
|
|
|
|
bool abort;
|
|
|
|
Core::ResourceFactory *gf;
|
|
|
|
const S3D::Scene *scene;
|
|
|
|
SceneBIH scene_tree, ///< Scene tree.
|
|
scene_shadow_tree; ///< Shadow scene tree.
|
|
|
|
Array <Light> lgt; ///< Light array.
|
|
|
|
Statistics statistics;
|
|
Configuration configuration;
|
|
Spread monte_carlo[32]; ///< Monte-Carlo vector spread.
|
|
|
|
Vector2 viewport; ///< Output resolution of the current rendering.
|
|
|
|
float render_clock; ///< Reference clock frozen at frame start.
|
|
|
|
/// Compute the Fresnel factor
|
|
float Fresnel(const Vector4 &v, const Vector4 &np, float eta);
|
|
|
|
/// Compute trace result radiance.
|
|
void ComputeRadiance(Trace &trace, Color &o, Bounce &bounce);
|
|
/// Raytrace.
|
|
void Raytrace(const RayGrid &ray, Color &o, Bounce &bounce, Trace *previous_trace = 0);
|
|
|
|
/// Evaluate shader block on the CPU.
|
|
bool EvaluateShaderBlock(const Trace &trace, const Core::ShaderBlock *block, Core::ShaderBlockValue &out);
|
|
|
|
/// Sample material opacity.
|
|
float SampleMaterialOpacity(const Trace &trace);
|
|
/// Sample material sink.
|
|
virtual Vector4 SampleMaterialSink(const Trace &trace, Core::ShaderTree::ShaderSinkType sink);
|
|
/// Sample material attribute.
|
|
Vector4 SampleMaterialAttribute(const Trace &trace, Core::MaterialChannel channel);
|
|
/// Sample geometry attribute.
|
|
Vector4 SampleGeometryAttribute(const Trace &trace, GeometryAttribute attr);
|
|
|
|
/// Shadow feel.
|
|
float ShadowFeel(const Vector4 &s, const Vector4 &d, float l, int r);
|
|
|
|
/*!
|
|
@name Interlace support.
|
|
@{
|
|
*/
|
|
bool interlace_even; ///< Internal interlace parity.
|
|
Picture interlace_half_frame; ///< The previous interlace frame.
|
|
/// @}
|
|
|
|
public:
|
|
|
|
ProgressHook *hook;
|
|
|
|
/// Get system configuration.
|
|
Configuration &GetConfiguration()
|
|
{ return configuration; }
|
|
/// Set system configuration.
|
|
void SetConfiguration(const Configuration &config);
|
|
|
|
/// Return system statistics object.
|
|
const Statistics &GetStatistics() const { return statistics; }
|
|
|
|
/// Abort current rendering.
|
|
void Abort();
|
|
/// Last render abort flag.
|
|
bool Aborted() const { return abort; }
|
|
|
|
/*!
|
|
@short Start a rendering sequence.
|
|
|
|
@note This call is only necessary when rendering an interlaced
|
|
sequence.
|
|
*/
|
|
void StartInterlacedSequence();
|
|
|
|
/// Trace a primary ray across the scene tree, returns resulting HDR color.
|
|
void PrimaryRay(const RayGrid &ray, Color &o);
|
|
/*!
|
|
@short Raytrace scene to a raw raytracing structure.
|
|
|
|
Use this function if you need the intersected scene object and its
|
|
geometric properties rather than a fully computed evaluation.
|
|
*/
|
|
void RawPrimaryRay(const Vector4 &s, const Vector4 &d, Trace &t, float l = -1.f) { scene_tree.RaytraceScene(t, s, d, l); }
|
|
/*!
|
|
@short Perform a full scene raytracing.
|
|
|
|
@note The raytracer internally only works with real colors.
|
|
The frame is converted by the end of the render to rgb24.
|
|
@note The provided picture object will be reallocated to the
|
|
render output dimensions and all previous content will be
|
|
lost.
|
|
*/
|
|
bool Render(Picture &, uint width = 640, uint height = 480);
|
|
|
|
/// Return the internal scene BIH tree.
|
|
SceneBIH &GetBIH() { return scene_tree; }
|
|
/// Return the internal scene shadow BIH tree.
|
|
SceneBIH &GetShadowBIH() { return scene_shadow_tree; }
|
|
|
|
/*!
|
|
@short Setup a scene for use by the raytracer.
|
|
|
|
@note The raytracer does not mirror any data from the scene
|
|
so it will rely on the object remaining valid as long
|
|
as it is registered as the current raytracer scene.
|
|
@warning Before deleting the referred scene object do not forget
|
|
to call SetScene(NULL) in order to release all
|
|
references.
|
|
*/
|
|
bool SetScene(const S3D::Scene *);
|
|
|
|
void Free();
|
|
|
|
Raytracer(Core::ResourceFactory * = 0);
|
|
virtual ~Raytracer() {}
|
|
};
|
|
|
|
} // Raytrace
|
|
} // GS
|
|
|
|
|
|
#endif // __TRACER_CORE__
|