00001 00002 /* 00003 pbrt source code Copyright(c) 1998-2007 Matt Pharr and Greg Humphreys. 00004 00005 This file is part of pbrt. 00006 00007 pbrt is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 2 of the License, or 00010 (at your option) any later version. Note that the text contents of 00011 the book "Physically Based Rendering" are *not* licensed under the 00012 GNU GPL. 00013 00014 pbrt is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program. If not, see <http://www.gnu.org/licenses/>. 00021 00022 */ 00023 00024 // material.cpp* 00025 #include "material.h" 00026 // Material Method Definitions 00027 Material::~Material() { 00028 } 00029 void Material::Bump(Reference<Texture<float> > d, 00030 const DifferentialGeometry &dgGeom, 00031 const DifferentialGeometry &dgs, 00032 DifferentialGeometry *dgBump) { 00033 // Compute offset positions and evaluate displacement texture 00034 DifferentialGeometry dgEval = dgs; 00035 // Shift _dgEval_ _du_ in the $u$ direction 00036 float du = .5f * (fabsf(dgs.dudx) + fabsf(dgs.dudy)); 00037 if (du == 0.f) du = .01f; 00038 dgEval.p = dgs.p + du * dgs.dpdu; 00039 dgEval.u = dgs.u + du; 00040 dgEval.nn = 00041 Normalize((Normal)Cross(dgs.dpdu, dgs.dpdv) + 00042 du * dgs.dndu); 00043 float uDisplace = d->Evaluate(dgEval); 00044 // Shift _dgEval_ _dv_ in the $v$ direction 00045 float dv = .5f * (fabsf(dgs.dvdx) + fabsf(dgs.dvdy)); 00046 if (dv == 0.f) dv = .01f; 00047 dgEval.p = dgs.p + dv * dgs.dpdv; 00048 dgEval.u = dgs.u; 00049 dgEval.v = dgs.v + dv; 00050 dgEval.nn = 00051 Normalize((Normal)Cross(dgs.dpdu, dgs.dpdv) + 00052 dv * dgs.dndv); 00053 float vDisplace = d->Evaluate(dgEval); 00054 float displace = d->Evaluate(dgs); 00055 // Compute bump-mapped differential geometry 00056 *dgBump = dgs; 00057 dgBump->dpdu = dgs.dpdu + 00058 (uDisplace - displace) / du * Vector(dgs.nn) + 00059 displace * Vector(dgs.dndu); 00060 dgBump->dpdv = dgs.dpdv + 00061 (vDisplace - displace) / dv * Vector(dgs.nn) + 00062 displace * Vector(dgs.dndv); 00063 dgBump->nn = 00064 Normal(Normalize(Cross(dgBump->dpdu, dgBump->dpdv))); 00065 if (dgs.shape->reverseOrientation ^ 00066 dgs.shape->transformSwapsHandedness) 00067 dgBump->nn *= -1.f; 00068 // Orient shading normal to match geometric normal 00069 if (Dot(dgGeom.nn, dgBump->nn) < 0.f) 00070 dgBump->nn *= -1.f; 00071 }