7.10. Algorithms   

7.10.1. Hemicube form factor algorithm [Hall,89]   

The environment contains 'N patches' patches. A hemicube of resolution 'Hemi_res' is used. The delta factors for the top face of the cube are precomputed and loaded in the array 'Delta_top', and for a side face of ray 'Visible' is filled with the indices of the visible patches by the routine 'Vis_surf'. The subroutine use the patch information to transform the frustum for correct orientation relative to the patch and then performs the visible surface determination. The array of structures 'Frustums' contains the frustums and resolutions associated with each of the faces of the hemi-cube. Element 0 in the 'Frustums' array is the top face of the hem-cube.

   GLOBAL INTEGER  Hemi_res

GLOBAL REAL Delta_top[Hemi_res*Hemi_res]
GLOBAL REAL Delta_side[Hemi_res*Hemi_res/2]
GLOBAL STRUCTURE Frustums[5]
GLOBAL INTEGER Form_factor[N_patches][N_patches]
GLOBAL REAL form_factor()
SUBROUTINE Computer_form_factor()
Initialize the form factor matrix by setting all elements equal to zero.

FOR (each P in N_patches ) DO
FOR (each
Q in N_patches ) DO
Form_factor[P][Q] = 0.0
END DO
END DO

Loop through the patches and compute the form factors for each patch ( row 'P' of the from factor matrix contains the form factors for patch 'P'):
FOR (each P in N_patches ) DO
Loop through the sides of the hemi_cube for the current patch.
Compute the visibility buffer, 'Visible', for each face the sum the delta form factors for the face.

    FOR (each F in Frustums) DO

REAL
Deltas[]
INTEGER Samples
INTEGER Visible[Hemi_res*Hemi_res]
Call Vis_surf (P,Frustums[F]; Visible)
IF (F=0) THEN
Deltas=Deltas_top
Samples=Hemi_res*Hemi_res
ELSE
Deltas=Delta_side
Samples=Hemi_res*Hemi_res/2
END IF
FOR (each
S in Samples) DO
Form_factor[P][Visible[S]] =
Form_factor[P][Visible[S]] + Deltas[S]
END DO
END DO
RETURN
END SUB

7.10.2. A Rapid Hierarchical Algorithm   

     Refine (Patch *p,Patch *q,float Feps,float Aeps)

{
float Fpq,Fqp ;
Fpq = FormFactorEstimate( p,q ) ;
Fqp = FormFactorEstimate( q,p ) ;
if ( Fpq < Fqp )
{
if ( Subdiv(q,Aeps) )
{
Refine( p,q->ne,Feps,Aeps ) ;
Refine( p,q->nw,Feps,Aeps ) ;
Refine( p,q->se,Feps,Aeps ) ;
Refine( p,q->sw,Feps,Aeps ) ;
}
else {
if ( Subdiv( p,Aeps) ) {
Refine( q,p->ne,Feps,Aeps ) ;
Refine( q,p->nw,Feps,Aeps ) ;
Refine( q,p->se,Feps,Aeps ) ;
Refine( q,p->sw,Feps,Aeps ) ;
}
else
Link( p,q ) ;
}
}
}

Procedure definition

 Procedure Refine estimate form factor between each patches, either to

subdivide the patches or refine further.
Procedure Sudiv sudive the patch into four subpatch, ne,nw,se,sw
Procedure Line record the interaction between the patches.
Procedure FormfacrorEstimate returns an upper bound on the form factor
from the first patch to the second patch.

7.10.3. Hybrid form factor algorithm   

The environment contains 'N_patches' patches. A hemicube of resolution 'Hemi_res' is used. The delta factors for the top face of the cube are precomputed and loaded in the array 'Delta_top', and for a side face of the cube are loaded in the array 'Delta_side'. The array 'Vis' is filled with the indices of the visible patches by the routine 'Vis_surf'. The subroutine uses the patch information to transform the frustum for coorect orientation relative to the patch and then performs the visible surface determination. The structure 'Frustums' contains the frustums and resolutions associated with each of the faces of the hemi-cube. The form factor matrix, 'FF', is a matrix of structures consisting of a real 'Form_factor' field and an integer 'Reflect_flag' field describing whether the form factor element results from reflection or refraction. Element 0 in the 'Frustums' array is the top face of the hemi-cube. The structure for patches includes 'Ks' and of the patch. 'Termination' is the level of contribution at which specular contribution is terminated.

   GLOBAL INTEGER  Hemi_res

GLOBAL REAL Delta_top[Hemi_res*Hemi_res]
GLOBAL REAL Delta_side[Hemi_res*Hemi_res/2]
GLOBAL STRUCTURE Frustums[5]
GLOBAL INTEGER N_patches
GLOBAL STRUCTURE Patches[N_patches]
GLOBAL STRUCTURE Form_factor[N_patches][N_patches]
SUBROUTINE Computer_form_factor()
Initialize the form factor matrix by setting all elements equal to zero.
FOR ( each P in N_patches ) DO
FOR
( each Q in N_patches ) DO
FF[P][Q].Form_factor = 0.0
FF[P][Q].Reflect_flag = true
END DO
END DO

Loop through the patches and compute the form factors for each patch ( row
'P' of the form factor matrix contains the form factors for patch 'P').

FOR ( each P in N_patches ) DO
loop through hte sides of the hemi-cube for the reflection side of the
current patch. Compute the visibility buffer, 'Vis', for each face of the
sum the delta form factors for the face.

REAL Delatas[]
INTEGER Samples
INTEGER Vis[Hemi_res*Hemi_res]
VECTOR V
FOR ( each F in Frustum ) DO
CALL Vis_surf ( P,Frustums[F]; Vis )
IF ( F=0 ) THEN
Delatas = Delta_top
Sampels= Hemi_res*Hemi_res
ELSE
Delatas = Delta_side
Sampels= Hemi_res*Hemi_res/2
END IF
FOR
( EACH S in Samples) DO
Sum in the delta form factor for the visible patch. This acconts for
diffuse illumination from the visible patch. The routine illum_dir gets
the direction of illumination for the hemi-cube sample. The routine
Sum_spec sums the specular illumination contribution from the currently
visible patch.

FF[P][Vis[S]].Form_factor =
FF[P][Vis[S]].Form_factor + Delatas[S]
CALL illum_dir(P,F,S;V)
CALL Sum_spec(P,Vis[S],V,Delatas[S],true; )
END DO
END DO
IF
( Patch[P].Kt >0.0 ) THEN
The current patch is transparent. Build a hemi-cube on the back surface
ofthe patch and sum the form factors that contribute to transparent
diffuse illumination of the current patch. Repeat the stpes in building
the hemi-cube on the reflection side of the patch.

FOR ( each F in Frustums ) DO
CALL
Vis_surf( -P,Frustum[F] ; Vis )
IF ( F=0 ) THEN
Deltas = Delta_top
Sampels = Hemi_res*Hemi_res
ELSE
Deltas =Delta_side
Sampels = Hemi_res*Hemi_res/2
END IF
FOR
( each S in Samples ) DO
FF[P][Vis[S]].Form_factor = FF[P][Vis[S]].Form_factor + Delatas[S]
FF[P][Vis[S]].Reflect_flag = false
CALL ILlum_dir( P,F,S; V )
CALL Sum_spec( P,Vis[S],V,Deltas[S],false ; )
END DO
END DO
END IF
END DO
RETURN
END SUB

This is the procedure to sum in the specular illumination contribution to the form factor for the current patch. The patch that is the vehicle for the specular reflection or transmission is 'Last_P'. The current patch is passed in as 'P' . The view vector is passed in as 'Last_V'. The current contribution is passed in as 'Last_FF'. 'R_flag' describes whether the illumination is contributing to reflceted or transmitted diffuse illuminiation of the current patch. This routine is recursively called until the contribution falls below the specified threshold 'Terminator'.

   SUBROUTINE Sum_spec(P,Last_P,Last_V,Last_FF,R_flag; )

VECTOR Next_V
INTEGER Next_P
REAL Next_FF
IF (Patch[Last_P].Ks > 0.0 )THEN
The patch is reflective. The routine 'Rfl_vect' returns the refleced
vector. The routine 'Get_visible' returns the visible patch. The last
form factor is factored by the specular reflectandce of the last patch to
determine the contribution of the visible patch. This is summed into the
form factor matrix.

CALL Rfl_vect[Last_P,Last_V ;Next_V )
CALL Get_visible( Next_V ; Next_P )
NEXT_FF = Last_FF*Patch[Last_P].Ks
FF[P][Next_p].Form_factor= FF[P][Next_p].Form_factor + NEXT_FF
FF[P][Next_p].Reflect_flag = R_flag
IF ( Next_FF > Termination ) THEN
CALL Sum_spec(P,Next_P, Next_V, Next_FF,R_Flag; );
END IF
END IF
IF
( Patch[Last_P].Kt > 0.0 ) THEN
The patch is transperent. The routine 'Trans_vect' returns the
transmitted vector. Refer to notes describing reflection for the remaining
details

CALL Trans_vect(Last_P, Last_V ; Next_V )
CALL Get_visible( Next_V; Next_P )
Next_FF = Last_FF*Patch[Last_P].Kt
FF[P][Next_p].Form_factor= FF[P][Next_p].Form_factor + NEXT_FF
FF[P][Next_p].Reflect_flag = R_flag
IF ( Next_FF > Termination ) THEN
CALL Sum_spec(P,Next_P, Next_V, Next_FF,R_Flag; );
END IF
END IF
END SUB