PDA

View Full Version : If any ideas -> just add 2 code, thx

Tenson
08-02-2003, 01:16 AM
The question follows:
how to interpolate n1, n2, n3, n4 in order 2 get phong shaded object (bilinear interpolation)?
(didn't find anything on Google, Altavista, MSN, ...)

GLfloat Color[3];

GLfloat ambientLight[] = {0.3f, 0.3f, 0.3f, 1.0f};
GLfloat diffuseLight[] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat lightPos[] = {50.0f, -100.0f, 0.0f};

float sinus[365];
float cosinus[365];

void CalcTable(void)
{
int i;

for(i=0; i<365; i++)
{
sinus[i] = sinf((float)i*PI2/365.0f);
cosinus[i] = cosf((float)i*PI2/365.0f);
}
}

void Rotation(int ax, int ay, int az, float v[3], float rot_v[3])
{
const int x = 0;
const int y = 1;
const int z = 2;

rot_v[y] = v[y]*cosinus[ax] - v[z]*sinus[ax]; //x
rot_v[z] = v[z]*cosinus[ax] + v[y]*sinus[ax];

// rot_v[z] = rot_v[z]*cosinus[ay] - v[x]*sinus[ay]; //y
// rot_v[x] = v[x]*cosinus[ay] + rot_v[x]*sinus[ay];

// rot_v[x] = rot_v[x]*cosinus[az] - rot_v[y]*sinus[az]; //z
// rot_v[y] = rot_v[y]*cosinus[az] - rot_v[x]*sinus[az];
}

void ReduceToUnit(float vector[3])
{
float length;

length = (float)sqrt((vector[0]*vector[0]) +
(vector[1]*vector[1]) +
(vector[2]*vector[2]));
if(length == 0.0f)
length = 1.0f;

vector[0] /= length;
vector[1] /= length;
vector[2] /= length;
}

void CalcCross(float v1[3], float v2[3], float n[3])
{
const int x = 0;
const int y = 1;
const int z = 2;

n[x] = v1[y]*v2[z] - v1[z]*v2[y];
n[y] = v1[z]*v2[x] - v1[x]*v2[z];
n[z] = v1[x]*v2[y] - v1[y]*v2[x];

ReduceToUnit(n);
}

void CalcLight(float normal[3])
{
static int R = 0;
static int G = 1;
static int B = 2;
static int A = 3;

GLfloat Iambient[4], Idiffuse[4], Ispecular[4];
float ka[3], kd[3], ks[3];
float l[3];
float l_cross_n;
float b = 10.0f;

ka[R] = 1.0f;
ka[G] = 0.0f;
ka[B] = 1.0f;

kd[R] = 1.0f;
kd[G] = 0.0f;
kd[B] = 1.0f;

ks[R] = 0.8f;
ks[G] = 0.8f;
ks[B] = 0.8f;

l[0] = lightPos[0];
l[1] = lightPos[1];
l[2] = lightPos[2];

Rotation(angle, 0, 0, normal, normal);

ReduceToUnit(l);

l_cross_n = (normal[0]*l[0] + normal[1]*l[1] + normal[2]*l[2]);

Iambient[R] = ambientLight[R]*ka[R];
Iambient[G] = ambientLight[G]*ka[G];
Iambient[B] = ambientLight[B]*ka[B];
Iambient[A] = ambientLight[A];

Idiffuse[R] = diffuseLight[R]*kd[R]*l_cross_n;
Idiffuse[G] = diffuseLight[G]*kd[G]*l_cross_n;
Idiffuse[B] = diffuseLight[B]*kd[B]*l_cross_n;
Idiffuse[A] = diffuseLight[A];

Ispecular[R] = specular[R]*ks[R]*(float)pow(l_cross_n, b);
Ispecular[G] = specular[G]*ks[G]*(float)pow(l_cross_n, b);
Ispecular[B] = specular[B]*ks[B]*(float)pow(l_cross_n, b);
Ispecular[A] = specular[A];

Color[R] = Iambient[R] + Idiffuse[R] + Ispecular[R];
Color[G] = Iambient[G] + Idiffuse[G] + Ispecular[G];
Color[B] = Iambient[B] + Idiffuse[B] + Ispecular[B];
Color[A] = Iambient[A] + Idiffuse[A] + Ispecular[A];

glColor4f(Color[R], Color[G], Color[B], Color[A]);
}

void QuadNormal(float A[3], float B[3], float C[3], float D[3])
{
const int x = 0;
const int y = 1;
const int z = 2;

float vbc[3], vba[3], n2[3];
float vcb[3], vcd[3], n3[3];
float vdc[3], vda[3], n4[3];

vab[x] = B[x] - A[x];
vab[y] = B[y] - A[y];
vab[z] = B[z] - A[z];

CalcCross(vad, vab, n1); // right up
CalcLight(n1);

vbc[x] = C[x] - B[x];
vbc[y] = C[y] - B[y];
vbc[z] = C[z] - B[z];

vba[x] = -vab[x];
vba[y] = -vab[y];
vba[z] = -vab[z];

CalcCross(vbc, vba, n2); // right down
CalcLight(n2);

vcb[x] = -vbc[x];
vcb[y] = -vbc[y];
vcb[z] = -vbc[z];

vcd[x] = D[x] - C[x];
vcd[y] = D[y] - C[y];
vcd[z] = D[z] - C[z];

CalcCross(vcb, vcd, n3); // left down
CalcLight(n3);

vdc[x] = -vcd[x];
vdc[y] = -vcd[y];
vdc[z] = -vcd[z];

CalcCross(vdc, vda, n4); // left up
CalcLight(n4);
}

Phong crazy Tenson :P

pleopard
08-02-2003, 07:34 AM
Not sure what u are asking for ... if you need a 3D bilinear interp functions here is a snip ...

/** Interpolate the dependent axis value of a point.
@param xSw X coordinate of south-western point.
@param ySw Y coordinate of south-western point.
@param zSw Z coordinate of south-western point.
@param xSe X coordinate of south-eastern point.
@param ySe Y coordinate of south-eastern point.
@param zSe Z coordinate of south-eastern point.
@param xNw X coordinate of north-western point.
@param yNw Y coordinate of north-western point.
@param zNw Z coordinate of north-western point.
@param xNe X coordinate of north-eastern point.
@param yNe Y coordinate of north-eastern point.
@param zNe Z coordinate of north-eastern point.
@param x X coordinate of point in question.
@param y Y coordinate of point in question.
receptor.
*/
double BilinearInterpolate(
double xSw, double ySw, double zSw,
double xSe, double ySe, double zSe,
double xNw, double yNw, double zNw,
double xNe, double yNe, double zNe,
double x, double y
) const
{
double delX = (x - xSw) / (xSe - xSw);
double delY = (y - ySw) / (ySe - ySw);

double delX1 = 1.0 - delX;
double delY1 = 1.0 - delY;
return
delY1*delX1*zSw + delY*delX1*zSe +
delY* delX *zNe + delY1* delX*zNw;
}

jwatte
08-02-2003, 10:30 PM
The original Phong paper talks about this, too. Nothing like going back to the source of a technique if you're un-sure :-)