1
0
forked from 0ad/0ad
0ad/source/renderer/SHCoeffs.cpp
Ykkrosh 2790981eae CVSROOT: doesn't seem particularly useful now
ObjectBase: removed support for old actor format
Various: reduced sometimes-unnecessary header inclusions
Atlas: slightly nicer tool and message systems

This was SVN commit r2816.
2005-09-30 00:59:42 +00:00

86 lines
2.1 KiB
C++
Executable File

//----------------------------------------------------------------
//
// Name: SHCoeffs.h
// Last Update: 25/11/03
// Author: Rich Cross
// Contact: rich@0ad.wildfiregames.com
//
// Description: implementation of 9 component spherical harmonic
// lighting
//----------------------------------------------------------------
#include "precompiled.h"
#include "SHCoeffs.h"
#include "MathUtil.h"
CSHCoeffs::CSHCoeffs()
{
Clear();
}
void CSHCoeffs::Clear()
{
for (int i=0;i<9;i++) {
_data[i].Clear();
}
}
void CSHCoeffs::AddAmbientLight(const RGBColor& color)
{
_data[0]+=color;
}
void CSHCoeffs::AddDirectionalLight(const CVector3D& lightDir,const RGBColor& lightColor)
{
CVector3D dirToLight(-lightDir.X,-lightDir.Y,-lightDir.Z);
const float normalisation = PI*16/17;
const float c1 = SQR(0.282095f) * normalisation * 1.0f;
const float c2 = SQR(0.488603f) * normalisation * (2.0f/3.0f);
const float c3 = SQR(1.092548f) * normalisation * (1.0f/4.0f);
const float c4 = SQR(0.315392f) * normalisation * (1.0f/4.0f);
const float c5 = SQR(0.546274f) * normalisation * (1.0f/4.0f);
_data[0]+=lightColor*c1;
_data[1]+=lightColor*c2*dirToLight.X;
_data[2]+=lightColor*c2*dirToLight.Y;
_data[3]+=lightColor*c2*dirToLight.Z;
_data[4]+=lightColor*c3*dirToLight.X*dirToLight.Z;
_data[5]+=lightColor*c3*dirToLight.Z*dirToLight.Y;
_data[6]+=lightColor*c3*dirToLight.Y*dirToLight.X;
_data[7]+=lightColor*c4*(3.0f*SQR(dirToLight.Z)-1.0f);
_data[8]+=lightColor*c5*(SQR(dirToLight.X)-SQR(dirToLight.Y));
}
void CSHCoeffs::Evaluate(const CVector3D& normal,RGBColor& color,RGBColor mod) const
{
#if 1
float c4=normal.X*normal.Z;
float c5=normal.Z*normal.Y;
float c6=normal.Y*normal.X;
float c7=(3*SQR(normal.Z)-1.0f);
float c8=(SQR(normal.X)-SQR(normal.Y));
#define DO(C) \
color.C = mod.C * (\
_data[0].C \
+ _data[1].C*normal.X \
+ _data[2].C*normal.Y \
+ _data[3].C*normal.Z \
+ _data[4].C*c4 \
+ _data[5].C*c5 \
+ _data[6].C*c6 \
+ _data[7].C*c7 \
+ _data[8].C*c8)
DO(X);
DO(Y);
DO(Z);
#undef DO
#else
// debug aid: output quantised normal
color=RGBColor((normal.X+1)*0.5,(normal.Y+1)*0.5,(normal.Z+1)*0.5);
#endif
}