1 #pragma once
2 
3 #ifndef Y_LIGHT_H
4 #define Y_LIGHT_H
5 
6 #include <yafray_constants.h>
7 #include "color.h"
8 
9 __BEGIN_YAFRAY
10 
11 class surfacePoint_t;
12 class background_t;
13 class ray_t;
14 class scene_t;
15 class vector3d_t;
16 class point3d_t;
17 
18 enum { LIGHT_NONE = 0, LIGHT_DIRACDIR = 1, LIGHT_SINGULAR = 1<<1 }; // "LIGHT_DIRACDIR" *must* be same as "BSDF_SPECULAR" (material.h)!
19 typedef unsigned int LIGHTF_t;
20 
21 struct lSample_t
22 {
splSample_t23 	lSample_t(surfacePoint_t *s_p=nullptr): sp(s_p) {}
24 	float s1, s2; //<! 2d sample value for choosing a surface point on the light.
25 	float s3, s4; //<! 2d sample value for choosing an outgoing direction on the light (emitSample)
26 	float pdf; //<! "standard" directional pdf from illuminated surface point for MC integration of direct lighting (illumSample)
27 	float dirPdf; //<! probability density for generating this sample direction (emitSample)
28 	float areaPdf; //<! probability density for generating this sample point on light surface (emitSample)
29 	color_t col; //<! color of the generated sample
30 	LIGHTF_t flags; //<! flags of the sampled light source
31 	surfacePoint_t *sp; //!< surface point on the light source, may only be complete enough to call other light methods with it!
32 };
33 
34 class light_t
35 {
36 	public:
37 		//! allow for preprocessing when scene loading has finished
init(scene_t & scene)38 		virtual void init(scene_t &scene) {}
39 		//! total energy emmitted during whole frame
40 		virtual color_t totalEnergy() const = 0;
41 		//! emit a photon
42 		virtual color_t emitPhoton(float s1, float s2, float s3, float s4, ray_t &ray, float &ipdf) const = 0;
43 		//! create a sample of light emission, similar to emitPhoton, just more suited for bidirectional methods
44 		/*! fill in s.dirPdf, s.areaPdf, s.col and s.flags, and s.sp if not nullptr */
emitSample(vector3d_t & wo,lSample_t & s)45 		virtual color_t emitSample(vector3d_t &wo, lSample_t &s) const{return color_t(0.f);};
46 		//! indicate whether the light has a dirac delta distribution or not
47 		virtual bool diracLight() const = 0;
48 		//! illuminate a given surface point, generating sample s, fill in s.sp if not nullptr; Set ray to test visibility by integrator
49 		/*! fill in s.pdf, s.col and s.flags */
50 		virtual bool illumSample(const surfacePoint_t &sp, lSample_t &s, ray_t &wi) const = 0;
51 		//! illuminate a given surfance point; Set ray to test visibility by integrator. Only for dirac lights.
52 		/*!	return false only if no light is emitted towards sp, e.g. outside cone angle of spot light	*/
53 		virtual bool illuminate(const surfacePoint_t &sp, color_t &col, ray_t &wi) const = 0;
54 		//! indicate whether the light can intersect with a ray (by the intersect function)
canIntersect()55 		virtual bool canIntersect() const { return false; }
56 		//! intersect the light source with a ray, giving back distance, energy and 1/PDF
intersect(const ray_t & ray,float & t,color_t & col,float & ipdf)57 		virtual bool intersect(const ray_t &ray, float &t, color_t &col, float &ipdf) const { return false; }
58 		//! get the pdf for sampling the incoming direction wi at surface point sp (illumSample!)
59 		/*! this method requires an intersection point with the light (sp_light). Otherwise, use intersect() */
illumPdf(const surfacePoint_t & sp,const surfacePoint_t & sp_light)60 		virtual float illumPdf(const surfacePoint_t &sp, const surfacePoint_t &sp_light) const { return 0.f; }
61 		//! get the pdf values for sampling point sp on the light and outgoing direction wo when emitting energy (emitSample, NOT illumSample)
62 		/*! sp should've been generated from illumSample or emitSample, and may only be complete enough to call light functions! */
emitPdf(const surfacePoint_t & sp,const vector3d_t & wo,float & areaPdf,float & dirPdf,float & cos_wo)63 		virtual void emitPdf(const surfacePoint_t &sp, const vector3d_t &wo, float &areaPdf, float &dirPdf, float &cos_wo) const { areaPdf=0.f; dirPdf=0.f; }
64 		//! (preferred) number of samples for direct lighting
nSamples()65 		virtual int nSamples() const { return 8; }
~light_t()66 		virtual ~light_t() {}
67 		//! This method must be called right after the factory is called on a background light or the light will fail
setBackground(background_t * bg)68 		virtual void setBackground(background_t *bg) { background = bg; }
69 		//! Enable/disable entire light source
lightEnabled()70 		bool lightEnabled() const { return lLightEnabled;}
castShadows()71 		bool castShadows() const { return lCastShadows; }
72 		//! checks if the light can shoot caustic photons (photonmap integrator)
shootsCausticP()73 		bool shootsCausticP() const { return lShootCaustic; }
74 		//! checks if the light can shoot diffuse photons (photonmap integrator)
shootsDiffuseP()75 		bool shootsDiffuseP() const { return lShootDiffuse; }
76 		//! checks if the light is a photon-only light (only shoots photons, not illuminating)
photonOnly()77 		bool photonOnly() const { return lPhotonOnly; }
78 		//! sets clampIntersect value to reduce noise at the expense of realism and inexact overall lighting
setClampIntersect(float clamp)79 		void setClampIntersect(float clamp) { lClampIntersect = clamp; }
80 
light_t()81 		light_t(): flags(LIGHT_NONE),lLightEnabled(true),lCastShadows(true),lShootCaustic(true),lShootDiffuse(true),lPhotonOnly(false) {}
light_t(LIGHTF_t _flags)82 		light_t(LIGHTF_t _flags): flags(_flags) {}
getFlags()83 		LIGHTF_t getFlags() const { return flags; }
84 
85 	protected:
86 		LIGHTF_t flags;
87 		background_t* background;
88 	    bool lLightEnabled; //!< enable/disable light
89 		bool lCastShadows; //!< enable/disable if the light should cast direct shadows
90 		bool lShootCaustic; //!<enable/disable if the light can shoot caustic photons (photonmap integrator)
91 		bool lShootDiffuse; //!<enable/disable if the light can shoot diffuse photons (photonmap integrator)
92 		bool lPhotonOnly; //!<enable/disable if the light is a photon-only light (only shoots photons, not illuminating)
93 		float lClampIntersect = 0.f;	//!<trick to reduce light sampling noise at the expense of realism and inexact overall light. 0.f disables clamping
94 
95 };
96 
97 __END_YAFRAY
98 
99 #endif // Y_LIGHT_H
100