00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #if defined(_MSC_VER)
00025 #pragma once
00026 #endif
00027
00028 #ifndef PBRT_CORE_SH_H
00029 #define PBRT_CORE_SH_H
00030
00031
00032 #include "pbrt.h"
00033 #include "geometry.h"
00034 #include "spectrum.h"
00035
00036
00037 inline int SHTerms(int lmax) {
00038 return (lmax + 1) * (lmax + 1);
00039 }
00040
00041
00042 inline int SHIndex(int l, int m) {
00043 return l*l + l + m;
00044 }
00045
00046
00047 void SHEvaluate(const Vector &v, int lmax, float *out);
00048 void SHWriteImage(const char *filename, const Spectrum *c, int lmax, int yres);
00049 template <typename Func>
00050 void SHProjectCube(Func func, const Point &p, int res, int lmax,
00051 Spectrum *coeffs) {
00052 float *Ylm = ALLOCA(float, SHTerms(lmax));
00053 for (int u = 0; u < res; ++u) {
00054 float fu = -1.f + 2.f * (float(u) + 0.5f) / float(res);
00055 for (int v = 0; v < res; ++v) {
00056 float fv = -1.f + 2.f * (float(v) + 0.5f) / float(res);
00057
00058 Vector w(fu, fv, 1);
00059 SHEvaluate(Normalize(w), lmax, Ylm);
00060 Spectrum f = func(u, v, p, w);
00061 float dA = 1.f / powf(Dot(w, w), 3.f/2.f);
00062 for (int k = 0; k < SHTerms(lmax); ++k)
00063 coeffs[k] += f * Ylm[k] * dA * (4.f / (res * res));
00064
00065
00066 w = Vector(fu, fv, -1);
00067 SHEvaluate(Normalize(w), lmax, Ylm);
00068 f = func(u, v, p, w);
00069 for (int k = 0; k < SHTerms(lmax); ++k)
00070 coeffs[k] += f * Ylm[k] * dA * (4.f / (res * res));
00071 w = Vector(fu, 1, fv);
00072 SHEvaluate(Normalize(w), lmax, Ylm);
00073 f = func(u, v, p, w);
00074 for (int k = 0; k < SHTerms(lmax); ++k)
00075 coeffs[k] += f * Ylm[k] * dA * (4.f / (res * res));
00076 w = Vector(fu, -1, fv);
00077 SHEvaluate(Normalize(w), lmax, Ylm);
00078 f = func(u, v, p, w);
00079 for (int k = 0; k < SHTerms(lmax); ++k)
00080 coeffs[k] += f * Ylm[k] * dA * (4.f / (res * res));
00081 w = Vector(1, fu, fv);
00082 SHEvaluate(Normalize(w), lmax, Ylm);
00083 f = func(u, v, p, w);
00084 for (int k = 0; k < SHTerms(lmax); ++k)
00085 coeffs[k] += f * Ylm[k] * dA * (4.f / (res * res));
00086 w = Vector(-1, fu, fv);
00087 SHEvaluate(Normalize(w), lmax, Ylm);
00088 f = func(u, v, p, w);
00089 for (int k = 0; k < SHTerms(lmax); ++k)
00090 coeffs[k] += f * Ylm[k] * dA * (4.f / (res * res));
00091 }
00092 }
00093 }
00094
00095
00096 void SHProjectIncidentDirectRadiance(const Point &p, float pEpsilon, float time,
00097 MemoryArena &arena, const Scene *scene, bool computeLightVisibility,
00098 int lmax, RNG &rng, Spectrum *c_d);
00099 void SHProjectIncidentIndirectRadiance(const Point &p, float pEpsilon,
00100 float time, const Renderer *renderer, Sample *origSample,
00101 const Scene *scene, int lmax, RNG &rng, int nSamples, Spectrum *c_i);
00102 void SHReduceRinging(Spectrum *c, int lmax, float lambda = .005f);
00103 void SHRotate(const Spectrum *c_in, Spectrum *c_out, const Matrix4x4 &m,
00104 int lmax, MemoryArena &arena);
00105 void SHRotateZ(const Spectrum *c_in, Spectrum *c_out, float alpha, int lmax);
00106 void SHRotateXMinus(const Spectrum *c_in, Spectrum *c_out, int lmax);
00107 void SHRotateXPlus(const Spectrum *c_in, Spectrum *c_out, int lmax);
00108
00109 void SHConvolveCosTheta(int lmax, const Spectrum *c_in, Spectrum *c_out);
00110 void SHConvolvePhong(int lmax, float n, const Spectrum *c_in, Spectrum *c_out);
00111 void SHComputeDiffuseTransfer(const Point &p, const Normal &n, float rayEpsilon,
00112 const Scene *scene, RNG &rng, int nSamples, int lmax, Spectrum *c_transfer);
00113 void SHComputeTransferMatrix(const Point &p, float rayEpsilon,
00114 const Scene *scene, RNG &rng, int nSamples, int lmax, Spectrum *T);
00115 void SHComputeBSDFMatrix(const Spectrum &Kd, const Spectrum &Ks,
00116 float roughness, RNG &rng, int nSamples, int lmax, Spectrum *B);
00117 void SHMatrixVectorMultiply(const Spectrum *M, const Spectrum *v,
00118 Spectrum *vout, int lmax);
00119
00120 #endif // PBRT_CORE_SH_H