00001 #include "WoodTexture.h"
00002
00003 namespace rcrt
00004 {
00005
00006 WoodTexture::WoodTexture(float ringDist, float distortion, float weight, Point3D org, Vec3D dir, const RGBColor& light, const RGBColor& dark) : Texture3D(),
00007 ringDist(ringDist), distortion(distortion), weight(weight), org(org), dir(dir.normalized()),
00008 light(light.r(),light.g(),light.b(),1), dark(dark.r(),dark.g(),dark.b(),1)
00009 {
00010 }
00011
00012 WoodTexture::~WoodTexture()
00013 {
00014 }
00015
00016 RGBAColor WoodTexture::getColor(const Point3D& p) const
00017 {
00018
00019 bool down;
00020 Vec3D radiusVec;
00021
00022 float scale = getScale(p,PerlinNoise::turbulence(p,0.01f,2),0.03f, down, radiusVec);
00023
00024
00025
00026 return calcColor(scale);
00027 }
00028
00029 RGBAColor WoodTexture::calcColor(const float& x) const
00030 {
00031 return (light - dark) * x + dark;
00032 }
00033
00034 float WoodTexture::getScale(const Point3D& hit, float disturbation, float widthFactor, bool& down, Vec3D& radiusVec) const
00035 {
00036
00037 float factor;
00038
00039 radiusVec = org - hit;
00040 radiusVec = radiusVec - dir * (radiusVec * dir);
00041
00042
00043
00044 float radius = radiusVec.norm() / ringDist + distortion * (disturbation - 0.5);
00045
00046
00047 radius -= floor(radius);
00048
00049 if (radius <= 0.7) {
00050 down = false;
00051 factor = radius * 10.0f / 7.0f;
00052 }
00053 else {
00054 down = true;
00055 factor = (1 - radius) * 10.0f / 3.0f;
00056 }
00057
00058 radiusVec.normalize();
00059
00060
00061
00062 return std::max(std::min(widthFactor * (disturbation - 0.5f) + factor, 1.0f), 0.0f);
00063 }
00064
00065 Vec3D WoodTexture::getBump(const Point3D& p, const Vec3D& normal) const
00066 {
00067 bool down;
00068 Vec3D radiusVec;
00069
00070 float scale = getScale(p,PerlinNoise::turbulence(p,0.01f,2),0.03f, down, radiusVec);
00071
00072 float perturbation = (-down) * weight * sin(M_PI * scale);
00073
00074 return (radiusVec * perturbation + normal).normalized();
00075 }
00076
00077 }