00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "lux.h"
00025 #include "texture.h"
00026 #include "paramset.h"
00027 #include "error.h"
00028 #include "blender_texlib.h"
00029
00030 namespace lux {
00031 template <class T>
00032
00033 class BlenderMusgraveTexture3D : public Texture<T> {
00034 public:
00035
00036
00037 ~BlenderMusgraveTexture3D() {
00038 delete mapping;
00039 }
00040
00041 BlenderMusgraveTexture3D(
00042 boost::shared_ptr<Texture<T> > c1,
00043 boost::shared_ptr<Texture<T> > c2,
00044 float mg_H,
00045 float mg_lacunarity,
00046 float mg_octaves,
00047 float mg_gain,
00048 float mg_offset,
00049 float noiseSize,
00050 float ns_outscale,
00051 short sType,
00052 short noiseBasis,
00053 float bright,
00054 float contrast,
00055 TextureMapping3D *map) : mapping(map) {
00056 tex.type = TEX_MUSGRAVE;
00057
00058 tex.mg_H = mg_H;
00059 tex.mg_lacunarity = mg_lacunarity;
00060 tex.mg_octaves = mg_octaves;
00061 tex.mg_gain = mg_gain;
00062 tex.mg_offset = mg_offset;
00063
00064 tex.noisesize = noiseSize;
00065 tex.ns_outscale = ns_outscale;
00066 tex.stype = sType;
00067 tex.noisebasis = noiseBasis;
00068
00069 tex.bright = bright;
00070 tex.contrast = contrast;
00071 tex1 = c1;
00072 tex2 = c2;
00073 }
00074
00075 T Evaluate(const DifferentialGeometry &dg) const {
00076 Vector dpdx, dpdy;
00077 Point P = mapping->Map(dg, &dpdx, &dpdy);
00078
00079 blender::TexResult texres;
00080 int resultType = multitex(&tex, &P.x, &texres);
00081
00082 if(resultType & TEX_RGB)
00083 texres.tin = (0.35 * texres.tr + 0.45 * texres.tg
00084 + 0.2 * texres.tb);
00085 else
00086 texres.tr = texres.tg = texres.tb = texres.tin;
00087
00088 T t1 = tex1->Evaluate(dg), t2 = tex2->Evaluate(dg);
00089 return (1.f - texres.tin) * t1 + texres.tin * t2;
00090 }
00091
00092 static Texture<float> *CreateFloatTexture(const Transform &tex2world, const TextureParams &tp);
00093 static Texture<Spectrum> *CreateSpectrumTexture(const Transform &tex2world, const TextureParams &tp);
00094
00095 private:
00096
00097
00098 TextureMapping3D *mapping;
00099 boost::shared_ptr<Texture<T> > tex1, tex2;
00100 blender::Tex tex;
00101 };
00102
00103 template <class T> Texture<float> *BlenderMusgraveTexture3D<T>::CreateFloatTexture(
00104 const Transform &tex2world,
00105 const TextureParams &tp) {
00106
00107 TextureMapping3D *map = new IdentityMapping3D(tex2world);
00108
00109 IdentityMapping3D *imap = (IdentityMapping3D*) map;
00110 imap->Apply3DTextureMappingOptions(tp);
00111
00112 boost::shared_ptr<Texture<float> > tex1 = tp.GetFloatTexture("tex1", 1.f);
00113 boost::shared_ptr<Texture<float> > tex2 = tp.GetFloatTexture("tex2", 0.f);
00114
00115
00116 short type = TEX_MFRACTAL;
00117 string noiseType = tp.FindString("type");
00118 if ((noiseType == "multifractal") || (noiseType == ""))
00119 type = TEX_MFRACTAL;
00120 else if (noiseType == "ridged_multifractal")
00121 type = TEX_RIDGEDMF;
00122 else if (noiseType == "hybrid_multifractal")
00123 type = TEX_HYBRIDMF;
00124 else if (noiseType == "hetero_terrain")
00125 type = TEX_HTERRAIN;
00126 else if (noiseType == "fbm")
00127 type = TEX_FBM;
00128 else {
00129 std::stringstream ss;
00130 ss << "Unknown noise type '" << noiseType << "'";
00131 luxError(LUX_BADTOKEN, LUX_ERROR, ss.str().c_str());
00132 }
00133
00134
00135 short basis = TEX_BLENDER;
00136 string noiseBasis = tp.FindString("noisebasis");
00137 if ((noiseBasis == "blender_original") || (noiseBasis == ""))
00138 basis = TEX_BLENDER;
00139 else if (noiseBasis == "original_perlin")
00140 basis = TEX_STDPERLIN;
00141 else if (noiseBasis == "improved_perlin")
00142 basis = TEX_NEWPERLIN;
00143 else if (noiseBasis == "voronoi_f1")
00144 basis = TEX_VORONOI_F1;
00145 else if (noiseBasis == "voronoi_f2")
00146 basis = TEX_VORONOI_F2;
00147 else if (noiseBasis == "voronoi_f3")
00148 basis = TEX_VORONOI_F3;
00149 else if (noiseBasis == "voronoi_f4")
00150 basis = TEX_VORONOI_F4;
00151 else if (noiseBasis == "voronoi_f2f1")
00152 basis = TEX_VORONOI_F2F1;
00153 else if (noiseBasis == "voronoi_crackle")
00154 basis = TEX_VORONOI_CRACKLE;
00155 else if (noiseBasis == "cell_noise")
00156 basis = TEX_CELLNOISE;
00157 else {
00158 std::stringstream ss;
00159 ss << "Unknown noise basis '" << noiseBasis << "'";
00160 luxError(LUX_BADTOKEN, LUX_ERROR, ss.str().c_str());
00161 }
00162
00163 return new BlenderMusgraveTexture3D<float>(
00164 tex1,
00165 tex2,
00166 tp.FindFloat("h", 1.0f),
00167 tp.FindFloat("lacu", 2.0f),
00168 tp.FindFloat("octs", 2.0f),
00169 tp.FindFloat("gain", 1.0f),
00170 tp.FindFloat("offset", 1.0f),
00171 tp.FindFloat("noisesize", 0.250f),
00172 tp.FindFloat("outscale", 1.0f),
00173 type,
00174 basis,
00175 tp.FindFloat("bright", 1.0f),
00176 tp.FindFloat("contrast", 1.0f),
00177 map);
00178 }
00179
00180 template <class T> Texture<Spectrum> *BlenderMusgraveTexture3D<T>::CreateSpectrumTexture(
00181 const Transform &tex2world,
00182 const TextureParams &tp) {
00183
00184 TextureMapping3D *map = new IdentityMapping3D(tex2world);
00185
00186 IdentityMapping3D *imap = (IdentityMapping3D*) map;
00187 imap->Apply3DTextureMappingOptions(tp);
00188
00189 boost::shared_ptr<Texture<Spectrum> > tex1 = tp.GetSpectrumTexture("tex1", 1.f);
00190 boost::shared_ptr<Texture<Spectrum> > tex2 = tp.GetSpectrumTexture("tex2", 0.f);
00191
00192
00193 short type = TEX_MFRACTAL;
00194 string noiseType = tp.FindString("type");
00195 if ((noiseType == "multifractal") || (noiseType == ""))
00196 type = TEX_MFRACTAL;
00197 else if (noiseType == "ridged_multifractal")
00198 type = TEX_RIDGEDMF;
00199 else if (noiseType == "hybrid_multifractal")
00200 type = TEX_HYBRIDMF;
00201 else if (noiseType == "hetero_terrain")
00202 type = TEX_HTERRAIN;
00203 else if (noiseType == "fbm")
00204 type = TEX_FBM;
00205 else {
00206 std::stringstream ss;
00207 ss << "Unknown noise type '" << noiseType << "'";
00208 luxError(LUX_BADTOKEN, LUX_ERROR, ss.str().c_str());
00209 }
00210
00211
00212 short basis = TEX_BLENDER;
00213 string noiseBasis = tp.FindString("noisebasis");
00214 if ((noiseBasis == "blender_original") || (noiseBasis == ""))
00215 basis = TEX_BLENDER;
00216 else if (noiseBasis == "original_perlin")
00217 basis = TEX_STDPERLIN;
00218 else if (noiseBasis == "improved_perlin")
00219 basis = TEX_NEWPERLIN;
00220 else if (noiseBasis == "voronoi_f1")
00221 basis = TEX_VORONOI_F1;
00222 else if (noiseBasis == "voronoi_f2")
00223 basis = TEX_VORONOI_F2;
00224 else if (noiseBasis == "voronoi_f3")
00225 basis = TEX_VORONOI_F3;
00226 else if (noiseBasis == "voronoi_f4")
00227 basis = TEX_VORONOI_F4;
00228 else if (noiseBasis == "voronoi_f2f1")
00229 basis = TEX_VORONOI_F2F1;
00230 else if (noiseBasis == "voronoi_crackle")
00231 basis = TEX_VORONOI_CRACKLE;
00232 else if (noiseBasis == "cell_noise")
00233 basis = TEX_CELLNOISE;
00234 else {
00235 std::stringstream ss;
00236 ss << "Unknown noise basis '" << noiseBasis << "'";
00237 luxError(LUX_BADTOKEN, LUX_ERROR, ss.str().c_str());
00238 }
00239
00240 return new BlenderMusgraveTexture3D<Spectrum>(
00241 tex1,
00242 tex2,
00243 tp.FindFloat("h", 1.0f),
00244 tp.FindFloat("lacu", 2.0f),
00245 tp.FindFloat("octs", 2.0f),
00246 tp.FindFloat("gain", 1.0f),
00247 tp.FindFloat("offset", 1.0f),
00248 tp.FindFloat("noisesize", 0.250f),
00249 tp.FindFloat("outscale", 1.0f),
00250 type,
00251 basis,
00252 tp.FindFloat("bright", 1.0f),
00253 tp.FindFloat("contrast", 1.0f),
00254 map);
00255 }
00256
00257 }