4.4. Postavljanje matrica

 

Kako izračunati matricu projekcije svjetla?

 

Matrica projekcije svjetla koristi se da projicira polovicu vrhova mreže volumena sjene u smjeru svjetla. Postupak njenog određivanja različit je za direkcijsko i točkasto svjetlo. U slučaju direkcijskog svjetla vrhovi su jednostavno translatirani u smjeru koje pokazuje svjetlo. Postupak je malo zamršeniji u slučaju točkastog svjetla. Vrhovi se prvo moraju translatirati u prostor svjetla, zatim se moraju uvećati (pomnožiti sa nekom velikom konstantom) i na kraju vratiti nazad u normalni prostor. To je demonstrirano slijedećom originalnom funkcijom u C++ kodu koju koristimo u aplikaciji.

 

D3DXMATRIX GetLightMatrix(int lightID)

{

  D3DLIGHT8  mineL;

  D3DXMATRIX mineM;

  D3DXMatrixIdentity(&mineM);

  D3DDevice->GetLight(lightID, &mineL);

  if(mineL.Type==D3DLIGHT_DIRECTIONAL)

  {

    mineM._41=mineL.Direction.x * 1000;

    mineM._42=mineL.Direction.y * 1000;

    mineM._43=mineL.Direction.z * 1000;

  }

  else             // SPOT or POINT light

  {

    mineM._11=1000;

    mineM._22=1000;

    mineM._33=1000;

    mineM._41=mineL.Position.x*(-999.0f);

    mineM._42=mineL.Position.y*(-999.0f);

    mineM._43=mineL.Position.z*(-999.0f);

  }

  return mineM;

}

 

Projekcijska matrica točkastog svjetla opisana je formulom 4.1.

 

                                       (4.1.)

X, Y, Z                      - pozicija svjetla

D                               - velika konstanta (1000)

 

Projekcijska matrica usmjerenog svjetla opisana je formulom 4.2.

 

                                                           (4.2.)

X, Y, Z                      - pozicija svjetla

dX, dY, dZ                - usmjerenost svjetla

D                               - velika konstanta (1000)

 

 

Pošto su matrice originalne mreže postavljene, moramo ih proširiti dodatnim matricama zaduženim za projicirane mreže volumena sjene. Kao što smo prije spomenuli, ove matrice se dobivaju množenjem originalnih matrica s matricom projekcije svjetla. Slijedeći C++ kod demonstrira tu operaciju:

 

void Append(int matrixNumber, int lightID)

{

  D3DXMATRIX tempMatrix1, tempMatrix2;

  D3DXMATRIX lightMatrix;

  lightMatrix = GetLightMatrix(lightID);

  for(int r = 0; r<matrixNumber; r++)

  {

    D3DDevice->GetTransform(D3DTS_WORLDMATRIX(r), &tempMatrix1);

    tempMatrix2 = tempMatrix1 * lightMatrix;

    D3DDevice->SetTransform(D3DTS_WORLDMATRIX(matrixNumber + r), &tempMatrix2);

  }

}