00001 /*************************************************************************** 00002 * Copyright (C) 1998-2008 by authors (see AUTHORS.txt ) * 00003 * * 00004 * This file is part of LuxRender. * 00005 * * 00006 * Lux Renderer is free software; you can redistribute it and/or modify * 00007 * it under the terms of the GNU General Public License as published by * 00008 * the Free Software Foundation; either version 3 of the License, or * 00009 * (at your option) any later version. * 00010 * * 00011 * Lux Renderer is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU General Public License * 00017 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 00018 * * 00019 * This project is based on PBRT ; see http://www.pbrt.org * 00020 * Lux Renderer website : http://www.luxrender.net * 00021 ***************************************************************************/ 00022 00023 // material.cpp* 00024 #include "material.h" 00025 #include "shape.h" 00026 #include "texture.h" 00027 #include "geometry.h" 00028 00029 using namespace lux; 00030 00031 // Material Method Definitions 00032 Material::~Material() { 00033 } 00034 00035 void Material::Bump(boost::shared_ptr<Texture<float> > d, 00036 const DifferentialGeometry &dgGeom, 00037 const DifferentialGeometry &dgs, 00038 DifferentialGeometry *dgBump) { 00039 // Compute offset positions and evaluate displacement texture 00040 DifferentialGeometry dgEval = dgs; 00041 00042 // Dade - in order to fix bug #180 00043 Normal ndndu; 00044 if((dgs.dndu.x == 0.0f) && (dgs.dndu.y == 0.0f) && (dgs.dndu.z == 0.0f)) 00045 ndndu = 0.0f; 00046 else 00047 ndndu = Normalize(dgs.dndu); 00048 Normal ndndv; 00049 if((dgs.dndv.x == 0.0f) && (dgs.dndv.y == 0.0f) && (dgs.dndv.z == 0.0f)) 00050 ndndv = 0.0f; 00051 else 00052 ndndv = Normalize(dgs.dndv); 00053 00054 // Shift _dgEval_ _du_ in the $u$ direction 00055 float du = .5f * (fabsf(dgs.dudx) + fabsf(dgs.dudy)); 00056 if (du == 0.f) du = .01f; 00057 dgEval.p = dgs.p + du * dgs.dpdu; 00058 dgEval.u = dgs.u + du; 00059 dgEval.nn = 00060 Normalize((Normal)Cross(dgs.dpdu, dgs.dpdv) + 00061 du * ndndu); 00062 float uDisplace = d->Evaluate(dgEval); 00063 00064 // Shift _dgEval_ _dv_ in the $v$ direction 00065 float dv = .5f * (fabsf(dgs.dvdx) + fabsf(dgs.dvdy)); 00066 if (dv == 0.f) dv = .01f; 00067 dgEval.p = dgs.p + dv * dgs.dpdv; 00068 dgEval.u = dgs.u; 00069 dgEval.v = dgs.v + dv; 00070 dgEval.nn = 00071 Normalize((Normal)Cross(dgs.dpdu, dgs.dpdv) + 00072 dv * ndndv); 00073 float vDisplace = d->Evaluate(dgEval); 00074 float displace = d->Evaluate(dgs); 00075 00076 // Compute bump-mapped differential geometry 00077 *dgBump = dgs; 00078 dgBump->dpdu = dgs.dpdu + 00079 (uDisplace - displace) / du * Vector(dgs.nn) + 00080 displace * Vector(ndndu); 00081 dgBump->dpdv = dgs.dpdv + 00082 (vDisplace - displace) / dv * Vector(dgs.nn) + 00083 displace * Vector(ndndv); 00084 00085 dgBump->nn = 00086 Normal(Normalize(Cross(dgBump->dpdu, dgBump->dpdv))); 00087 if (dgs.shape->reverseOrientation ^ 00088 dgs.shape->transformSwapsHandedness) 00089 dgBump->nn *= -1.f; 00090 00091 // Orient shading normal to match geometric normal 00092 if (Dot(dgGeom.nn, dgBump->nn) < 0.f) 00093 dgBump->nn *= -1.f; 00094 }