Stencil Shadow Test (Blitz3D)

Miscellaneous Forums/Blitz Showcase/Stencil Shadow Test (Blitz3D)

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

rifraf: Maybe your driver needs an update? Everybody else with ATI cards seem to be doing fine.

lenn: Yes, I saw that thread. Feel free to make your own version, why would I be upset about that? The more the merrier.

sswift: Argh, really? I thought I had it from Terabit, from when I was doing a lightwave importer for gile[s], but I'm sorry if I stepped on your toes. I can replace the model if that would make you comfortable.

rob: Because it wouldn't work :) It's better to do multi sampled stencil shadows to get soft shadows, but that's pretty slow... A better way is: http://download.nvidia.com/developer/presentations/2005/SIGGRAPH/PCSS.pdf but that obviously requires shaders, so it's not possible in blitz3d.

And here's the shadow renderworld function, it's pretty simple:
Function Shadow_RenderWorld(tween#=1.0)

	;
	; Update shadow volumes	
	Shadow_Update()

	;
	; Clear All
	DeviceClear(ShadowClear,$FFFFFFFF,$00000000,1.0,0)

	;
	; Render Scene with ambient light only
	HideEntity ShadowLight
	For s.shadowcaster = Each shadowcaster
		HideEntity s\volume
	Next 
	ShowEntity ShadowScene

	RenderWorld tween
	CameraClsMode ShadowCam,False,False

	;
	; Mask out shadow areas
	For s.shadowcaster = Each shadowcaster
		ShowEntity s\volume
	Next 
	HideEntity ShadowScene
	
	SetRenderState( D3DRS_ZWRITEENABLE,False)
	SetRenderState( D3DRS_STENCILENABLE,True)
	SetRenderState( D3DRS_ALPHABLENDENABLE,True)
	
	SetRenderState( D3DRS_STENCILFUNC, D3DCMP_ALWAYS)
	SetRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP)
	SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP)

	SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO)
	SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE)

	;
	; Render shadow volume front
	; (Increase stencil value)
	SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW)
	SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR)
	RenderWorld tween

	;
	; Render shadow volume back
	; (Decrease stencil value)
	SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR)	
	SetRenderState( D3DRS_CULLMODE, D3DCULL_CW)
	RenderWorld tween
	
	;
	; Draw Lit area
	SetRenderState( D3DRS_ZWRITEENABLE,  True )
	SetRenderState( D3DRS_STENCILENABLE, True )
	SetRenderState( D3DRS_ALPHABLENDENABLE, True )
	
	SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA )
	SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA )

	SetRenderState( D3DRS_STENCILREF,  0 )
	SetRenderState( D3DRS_STENCILFUNC, D3DCMP_EQUAL )
	
	SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP)
	
	SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW)

	ShowEntity ShadowScene
	ShowEntity ShadowLight
	RenderWorld tween

	;
	; Restore states
	SetRenderState( D3DRS_STENCILENABLE,    False )
	CameraClsMode ShadowCam,True,True
	
End Function

You will need the latest version of tom's directx dll to make it work. I'm not sure where he keeps it though :)

It's based on 'Paper Storm' from here: http://www.pvrdev.com/pub/PC/eg/index.htm
And this explanation of Stencil Shadows: http://www.gamasutra.com/features/20021011/lengyel_05.htm

You'll also have to construct your own shadow volumes :)