00001 00002 /* 00003 pbrt source code Copyright(c) 1998-2010 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 00025 // core/material.cpp* 00026 #include "stdafx.h" 00027 #include "material.h" 00028 #include "primitive.h" 00029 #include "texture.h" 00030 #include "spectrum.h" 00031 #include "reflection.h" 00032 00033 // Material Method Definitions 00034 Material::~Material() { 00035 } 00036 00037 00038 void Material::Bump(const Reference<Texture<float> > &d, 00039 const DifferentialGeometry &dgGeom, 00040 const DifferentialGeometry &dgs, 00041 DifferentialGeometry *dgBump) { 00042 // Compute offset positions and evaluate displacement texture 00043 DifferentialGeometry dgEval = dgs; 00044 00045 // Shift _dgEval_ _du_ in the $u$ direction 00046 float du = .5f * (fabsf(dgs.dudx) + fabsf(dgs.dudy)); 00047 if (du == 0.f) du = .01f; 00048 dgEval.p = dgs.p + du * dgs.dpdu; 00049 dgEval.u = dgs.u + du; 00050 dgEval.nn = Normalize((Normal)Cross(dgs.dpdu, dgs.dpdv) + 00051 du * dgs.dndu); 00052 float uDisplace = d->Evaluate(dgEval); 00053 00054 // Shift _dgEval_ _dv_ in the $v$ direction 00055 float dv = .5f * (fabsf(dgs.dvdx) + fabsf(dgs.dvdy)); 00056 if (dv == 0.f) dv = .01f; 00057 dgEval.p = dgs.p + dv * dgs.dpdv; 00058 dgEval.u = dgs.u; 00059 dgEval.v = dgs.v + dv; 00060 dgEval.nn = Normalize((Normal)Cross(dgs.dpdu, dgs.dpdv) + 00061 dv * dgs.dndv); 00062 float vDisplace = d->Evaluate(dgEval); 00063 float displace = d->Evaluate(dgs); 00064 00065 // Compute bump-mapped differential geometry 00066 *dgBump = dgs; 00067 dgBump->dpdu = dgs.dpdu + (uDisplace - displace) / du * Vector(dgs.nn) + 00068 displace * Vector(dgs.dndu); 00069 dgBump->dpdv = dgs.dpdv + (vDisplace - displace) / dv * Vector(dgs.nn) + 00070 displace * Vector(dgs.dndv); 00071 dgBump->nn = Normal(Normalize(Cross(dgBump->dpdu, dgBump->dpdv))); 00072 if (dgs.shape->ReverseOrientation ^ dgs.shape->TransformSwapsHandedness) 00073 dgBump->nn *= -1.f; 00074 00075 // Orient shading normal to match geometric normal 00076 dgBump->nn = Faceforward(dgBump->nn, dgGeom.nn); 00077 } 00078 00079