00001 #include <yafray_config.h>
00002
00003 #include <core_api/ray.h>
00004 #include <core_api/color.h>
00005 #include <core_api/volume.h>
00006 #include <core_api/bound.h>
00007 #include <core_api/surface.h>
00008 #include <core_api/texture.h>
00009 #include <core_api/environment.h>
00010
00011
00012 #include <utilities/mcqmc.h>
00013
00014
00015 #include <cmath>
00016
00017 __BEGIN_YAFRAY
00018
00019 class renderState_t;
00020 class pSample_t;
00021
00022 class SkyVolume : public VolumeRegion {
00023 public:
00024
00025 SkyVolume(color_t sa, color_t ss, color_t le, point3d_t pmin, point3d_t pmax) {
00026 bBox = bound_t(pmin, pmax);
00027 s_a = color_t(0.f);
00028 s_ray = sa;
00029 s_ray.B /= 3.f;
00030 s_mie = ss;
00031 s_s = color_t(0.f);
00032 l_e = le;
00033 g = 0.f;
00034 std::cout << "SkyVolume vol: " << s_ray << " " << s_mie << " " << l_e << std::endl;
00035 }
00036
00037 virtual float p(const vector3d_t &w_l, const vector3d_t &w_s);
00038
00039 float phaseRayleigh(const vector3d_t &w_l, const vector3d_t &w_s);
00040 float phaseMie(const vector3d_t &w_l, const vector3d_t &w_s);
00041
00042 virtual color_t sigma_a(const point3d_t &p, const vector3d_t &v);
00043 virtual color_t sigma_s(const point3d_t &p, const vector3d_t &v);
00044 virtual color_t emission(const point3d_t &p, const vector3d_t &v);
00045 virtual color_t tau(const ray_t &ray, float step, float offset);
00046
00047 static VolumeRegion* factory(paraMap_t ¶ms, renderEnvironment_t &render);
00048
00049 protected:
00050 color_t s_ray;
00051 color_t s_mie;
00052
00053
00054 };
00055
00056 color_t SkyVolume::sigma_a(const point3d_t &p, const vector3d_t &v) {
00057 return color_t(0.f);
00058 }
00059
00060 color_t SkyVolume::sigma_s(const point3d_t &p, const vector3d_t &v) {
00061
00062 return s_ray + s_mie;
00063
00064
00065
00066 }
00067
00068 color_t SkyVolume::tau(const ray_t &ray, float step, float offset) {
00069 float t0 = -1, t1 = -1;
00070
00071
00072 if (!intersect(ray, t0, t1)) {
00073
00074 return color_t(0.f);
00075 }
00076
00077
00078
00079 if (ray.tmax < t0 && ! (ray.tmax < 0)) return color_t(0.f);
00080
00081 if (ray.tmax < t1 && ! (ray.tmax < 0)) t1 = ray.tmax;
00082
00083
00084 if (t0 < 0.f) t0 = 0.f;
00085
00086
00087 float dist = t1 - t0;
00088
00089
00090
00091 return (s_ray + s_mie) * dist;
00092 }
00093
00094 color_t SkyVolume::emission(const point3d_t &p, const vector3d_t &v) {
00095 if (bBox.includes(p)) {
00096 return l_e;
00097 }
00098 else
00099 return color_t(0.f);
00100 }
00101
00102 float SkyVolume::p(const vector3d_t &w_l, const vector3d_t &w_s) {
00103 return phaseRayleigh(w_l, w_s) + phaseMie(w_l, w_s);
00104 }
00105
00106 float SkyVolume::phaseRayleigh(const vector3d_t &w_l, const vector3d_t &w_s) {
00107 float costheta = (w_l * w_s);
00108 return 3.f / (16.f * M_PI) * (1.f + costheta * costheta) * s_ray.energy();
00109 }
00110
00111 float SkyVolume::phaseMie(const vector3d_t &w_l, const vector3d_t &w_s) {
00112 float k = 1.55f * g - .55f * g * g * g;
00113 float kcostheta = k * (w_l * w_s);
00114 return 1.f / (4.f * M_PI) * (1.f - k * k) / ((1.f - kcostheta) * (1.f - kcostheta)) * s_mie.energy();
00115 }
00116
00117
00118 VolumeRegion* SkyVolume::factory(paraMap_t ¶ms,renderEnvironment_t &render) {
00119 float ss = .1f;
00120 float sa = .1f;
00121 float le = .0f;
00122 float g = .0f;
00123 float min[] = {0, 0, 0};
00124 float max[] = {0, 0, 0};
00125 params.getParam("sigma_s", ss);
00126 params.getParam("sigma_a", sa);
00127 params.getParam("l_e", le);
00128 params.getParam("g", g);
00129 params.getParam("minX", min[0]);
00130 params.getParam("minY", min[1]);
00131 params.getParam("minZ", min[2]);
00132 params.getParam("maxX", max[0]);
00133 params.getParam("maxY", max[1]);
00134 params.getParam("maxZ", max[2]);
00135
00136 SkyVolume *vol = new SkyVolume(color_t(sa), color_t(ss), color_t(le),
00137 point3d_t(min[0], min[1], min[2]), point3d_t(max[0], max[1], max[2]));
00138 return vol;
00139 }
00140
00141 extern "C"
00142 {
00143 YAFRAYPLUGIN_EXPORT void registerPlugin(renderEnvironment_t &render)
00144 {
00145 render.registerFactory("SkyVolume", SkyVolume::factory);
00146 }
00147 }
00148
00149 __END_YAFRAY