/* * Ray++ - Object-oriented ray tracing library * Copyright (C) 1998-2001 Martin Reinecke and others. * See the AUTHORS file for more information. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * See the README file for more information. */ #include "surfaces/phong.h" #include "surfaces/pigments/pure_colour.h" #include "utils/utils.h" namespace RAYPP { PHONG::PHONG () : Ka (float4(0.2)), Kd (float4(0.5)), Ks (float4(0.8)), Kr (float4(0.0)), Kt (float4(0.0)), Specpow (float4(200.0)) {} PHONG::PHONG (float4 a, float4 d, float4 s, float4 r, float4 t, float4 p, const HANDLE &pig) : Ka (a), Kd (d), Ks (s), Kr (r), Kt (t), Specpow (p), Pigment (pig) {} PHONG::PHONG (float4 a, float4 d, float4 s, float4 r, float4 t, float4 p, const COLOUR &Col) : Ka (a), Kd (d), Ks (s), Kr (r), Kt (t), Specpow (p), Pigment (Cnew PURE_COLOUR(Col)) {} //virtual void PHONG::Init () { if (initialized) return; if (!Pigment) error ("PHONG: no pigment given"); initialized = true; } //virtual void PHONG::Transform (const TRANSFORM &trans) { cni(); if (Pigment) Pigment->Transform (trans); } //virtual void PHONG::Get_Full_Shading_Info (const SHADING_INFO &In, FULL_SHADING_INFO &Out) const { SHADING_INFO &tmp = Out; tmp = In; Out.MC_diffuse = false; Out.MC_reflect = false; Out.MC_refract = false; Out.Bumped_Normal = In.Normal; float8 cosine = -Dot (In.Incident_Dir, In.Normal); if (Ks > Small_float4) { Out.reflect = true; Calc_Reflected_Dir (In.Incident_Dir, In.Normal, cosine, Out.Reflected); Out.Reflected_Imp = Ks*In.Importance; } else { Out.reflect = false; } if (Kt > Small_float4) { float8 n1, n2; if (In.Ins1.Vol) n1 = In.Ins1.Vol->Refractive_Index(In); else n1 = 1.0; if (In.Ins2.Vol) n2 = In.Ins2.Vol->Refractive_Index(In); else n2 = 1.0; Out.refract = Calc_Refracted_Dir (In.Incident_Dir, In.Normal, cosine, n1/n2, Out.Refracted); } else { Out.refract = false; } if (Out.refract) Out.Refracted_Imp = Kt*In.Importance; } //virtual COLOUR PHONG::Get_Total_Importance (const FULL_SHADING_INFO &Info, const VECTOR &Dir) const { ci(); float8 dotprod = Dot (Dir, Info.Normal); if (dotprod<0) return COLOUR(0,0,0); VECTOR half = (Dir - Info.Incident_Dir).Norm(); float8 dot2 = Dot(Info.Normal, half); return Pigment->Get_Colour (Info)*Info.Importance* (Kd*dotprod + Ks*pow(dot2, float8(Specpow))); } //virtual VECTOR PHONG::Get_MC_Reflected_Dir (const FULL_SHADING_INFO &) const { ci(); return VECTOR (0,0,0); } //virtual VECTOR PHONG::Get_MC_Refracted_Dir (const FULL_SHADING_INFO &) const { ci(); return VECTOR (0,0,0); } //virtual VECTOR PHONG::Get_MC_Diffuse_Dir (const FULL_SHADING_INFO &) const { ci(); return VECTOR (0,0,0); } //virtual COLOUR PHONG::Get_Emitted_Light (const FULL_SHADING_INFO &Info, const INCIDENT_ARRAY &Arr, const COLOUR &Refl, const COLOUR &Refr, const INCIDENT_ARRAY &, const INCIDENT_ARRAY &, const INCIDENT_ARRAY &) const { ci(); float8 dotprod, dot2; COLOUR newcol = Pigment->Get_Colour (Info); COLOUR Col = Ka*newcol*Arr.Ambient; for (INCIDENT_ARRAY::const_iterator i=Arr.begin(); iDirection), Info.Normal); if (dotprod >= 0.0) { VECTOR half = (i->Direction + Info.Incident_Dir).Norm(); dot2 = -Dot(Info.Normal, half); // MR: moved factor newcol into the diffuse contribution; // this is the traditional formula Col += (i->Intensity)* (newcol*Kd*dotprod +COLOUR(1,1,1)*Ks*pow(dot2, float8(Specpow))); } } if (Info.reflect) Col += Kr * Refl; if (Info.refract) Col += Kt * Refr; return Col; } //virtual COLOUR PHONG::Get_Transmitted_Light (const SHADING_INFO &, const COLOUR &) const { ci(); return COLOUR(0,0,0); } void PHONG::Set_Ka (float4 new_Ka) { cni(); Ka = new_Ka; } void PHONG::Set_Kd (float4 new_Kd) { cni(); Kd = new_Kd; } void PHONG::Set_Ks (float4 new_Ks) { cni(); Ks = new_Ks; } void PHONG::Set_Kr (float4 new_Kr) { cni(); Kr = new_Kr; } void PHONG::Set_Kt (float4 new_Kt) { cni(); Kt = new_Kt; } void PHONG::Set_Specpow (float4 new_Specpow) { cni(); Specpow = new_Specpow; } void PHONG::Set_Pigment (const HANDLE &ThePig) { cni(); Pigment = ThePig; } } // namespace RAYPP