frustrum culling (camera inside shadow volume) ?

Blitz3D Forums/Blitz3D Programming/frustrum culling (camera inside shadow volume) ?

hello!

in order to optimize our shadow system to about 1.5x speed i have to do it as follows:



the object is a shpere which represents the bounding sphere of an entity (or box or what ever the algorithm supports)...

i need to know whether the camera is inside the red area below the shadow caster.

thank you :)

I'm not sure if this works, I don't know how to test it.
;-------------------------------------------------------------------------------------------------------
;											TestForArea()
;-------------------------------------------------------------------------------------------------------
;combine IsInRedArea and IsBelowCaster
Function TestForArea(camera, light, entity, radius)

	test1 = IsInRedArea(camera, light, entity, radius)
	test2 = IsBelowCaster(camera, light, entity, radius)
	
	Return (test1 And test2)
	
End Function

;-------------------------------------------------------------------------------------------------------
;											 IsInRedArea()
;-------------------------------------------------------------------------------------------------------
;if camera is within red area
Function IsInRedArea(camera, light, entity, radius )

	;distance light-entity
	dist1# = EntityDistance(light, entity)
	;distance light-camera
	dist2# = EntityDistance(light, camera)
	
	;light x,y,z	
	x1# = EntityX(light)
	y1# = EntityY(light)
	z1# = EntityZ(light)
	
	;entity x,y,z
	x2# = EntityX(entity)
	y2# = EntityY(entity)
	z2# = EntityZ(entity)
	
	;extrapolate entity position to the same distance as the distance from camera to light
	x# = ((x2 - x1) * dist2 / dist1) + x1
	y# = ((y2 - y1) * dist2 / dist1) + y1
	z# = ((z2 - z1) * dist2 / dist1) + z1
	
	;position a pivot at that location	
	temppivot = CreatePivot()
	PositionEntity temppivot, x, y, z
	
	;distance camera-new location
	dist# = EntityDistance(camera, temppivot)
	FreeEntity temppivot	
	
	;check if this distance is within the radius	
	Return (dist < radius)
	
End Function

;-------------------------------------------------------------------------------------------------------
;										   IsBelowCaster()
;-------------------------------------------------------------------------------------------------------
;if camera is outside entity radius and farther away from the light than the entity
Function IsBelowCaster(camera, light, entity, radius)
	
	;if the camera is closer to the light than the entity, return 0
	If EntityDistance(camera, light) < EntityDistance(camera, entity) Then Return 0
	;return if the distance camera-entity is outside the radius
	Return (EntityDistance(camera, entity) > radius)
	
End Function


hey bram
thx it works seamless! thank you. you helped me alot.

i will release an update as soon as i finished this.

cya!!

one issue:
this code is made for parrallel light, right?
what if my lightsource is a pointlight? then it is making strange thigs...

Yes, you are right, sorry. I forgot to include scale the radius# in IsInRedArea(). This might be better:
;-------------------------------------------------------------------------------------------------------
;											TestForArea()
;-------------------------------------------------------------------------------------------------------
;combine IsInRedArea and IsBelowCaster
Function TestForArea(camera, light, entity, radius#)

	test1 = IsInRedArea(camera, light, entity, radius)
	test2 = IsBelowCaster(camera, light, entity, radius)
	
	Return (test1 And test2)
	
End Function

;-------------------------------------------------------------------------------------------------------
;											 IsInRedArea()
;-------------------------------------------------------------------------------------------------------
;if camera is within red area
Function IsInRedArea(camera, light, entity, radius#)

	;distance light-entity
	dist1# = EntityDistance(light, entity)
	;distance light-camera
	dist2# = EntityDistance(light, camera)
	
	;light x,y,z	
	x1# = EntityX(light)
	y1# = EntityY(light)
	z1# = EntityZ(light)
	r1# = 0
	
	;entity x,y,z
	x2# = EntityX(entity)
	y2# = EntityY(entity)
	z2# = EntityZ(entity)
	r2# = radius
	
	;extrapolate entity position to the same distance as the distance from camera to light
	x# = ((x2 - x1) * dist2 / dist1) + x1
	y# = ((y2 - y1) * dist2 / dist1) + y1
	z# = ((z2 - z1) * dist2 / dist1) + z1
	r# = ((r2 - r1) * dist2 / dist1) + r1
	
	;position a pivot at that location	
	temppivot = CreatePivot()
	PositionEntity temppivot, x, y, z
	
	;distance camera-new location
	dist# = EntityDistance(camera, temppivot)
	FreeEntity temppivot	
	
	;check if this distance is within the radius	
	Return (dist < r#)
	
End Function

;-------------------------------------------------------------------------------------------------------
;										   IsBelowCaster()
;-------------------------------------------------------------------------------------------------------
;if camera is outside entity radius and farther away from the light than the entity
Function IsBelowCaster(camera, light, entity, radius#)
	
	;if the camera is closer to the light than the entity, return 0
	If EntityDistance(camera, light) < EntityDistance(camera, entity) Then Return 0
	;return if the distance camera-entity is outside the radius
	Return (EntityDistance(camera, entity) > radius)
	
End Function

Note that instead of using EntityDistance() you could also calculate the distance between two points yourself. It will save creating/destroying a pivot for each calculation.

thank you :)

no problem, Teufel!