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