cube mapping for water

Blitz3D Forums/Blitz3D Programming/cube mapping for water

aCiD2(Posted 2004) [#1]
hows it done? i'd never heard of cube mapping until blitz had the update with it in and saw robs demo. i noticed he was making water refelection using a cube map and i tryed to work out what he was doing and came up with this code....

Function GenerateReflections(water, camera, WaterMapTexture)

	CameraProjMode camera,0
	CameraProjMode FXCamera,1

	PositionEntity FXCamera,EntityX(camera),EntityY(water)-2,EntityZ(camera)
	HideEntity water
	;do left view	
	SetCubeFace WaterMapTexture,0
	RotateEntity FXCamera,0,90,0
	RenderWorld
	CopyRect 0,0,WaterMapSize,WaterMapSize,0,0,BackBuffer(),TextureBuffer(WaterMapTexture)
	;do forward view
	SetCubeFace WaterMapTexture,1
	RotateEntity FXCamera,0,0,0
	RenderWorld
	CopyRect 0,0,WaterMapSize,WaterMapSize,0,0,BackBuffer(),TextureBuffer(WaterMapTexture)
	;do right view	
	SetCubeFace WaterMapTexture,2
	RotateEntity FXCamera,0,-90,0
	RenderWorld
	CopyRect 0,0,WaterMapSize,WaterMapSize,0,0,BackBuffer(),TextureBuffer(WaterMapTexture)
	;do backward view
	SetCubeFace WaterMapTexture,3
	RotateEntity FXCamera,0,180,0
	RenderWorld
	CopyRect 0,0,WaterMapSize,WaterMapSize,0,0,BackBuffer(),TextureBuffer(WaterMapTexture)
	;do up view
	SetCubeFace WaterMapTexture,4
	RotateEntity FXCamera,-90,0,0
	RenderWorld
	CopyRect 0,0,WaterMapSize,WaterMapSize,0,0,BackBuffer(),TextureBuffer(WaterMapTexture)
	CameraProjMode camera,1
	CameraProjMode FXCamera,0
	ShowEntity water
	Return WaterMapTexture
End Function


but it really desnt work. I jsut get strange blotches of colour that arent even in the code :\


Mustang(Posted 2004) [#2]
What 3D-card do you have?


aCiD2(Posted 2004) [#3]
geforce2, it works fine with robs demo :\


fredborg(Posted 2004) [#4]
It might be because your cubemap texture is too big. If you have the screen resolution set to 640x480, the max cubemap resolution is 256x256. Using a larger cubemap size than this will produce errors, because you are trying to copy something outside the screen onto the cubemap.

You can also try this one: http://www.frecle.net/giles/download/gile[s]-b3d-parser.zip


jfk EO-11110(Posted 2004) [#5]
If you want the water to reflect things correctly, try to position the cubemap camera at the screen cameras x and z position, and use

water_Y - (screen_camera_Y - water_Y)

for the Y-position of the cubemap camera.


JoshK(Posted 2004) [#6]
I prefer to just create a cubemap at startup, and leave it alone, rather than killing my framerate with a lot of CopyRects().

Function CreateCubeMap(size,x#,y#,z#,flags=128+256)
If Not (128 And flags) flags=flags+128
Local cam=CreateCamera()
Local tex=CreateTexture(size,size,flags)
If skybox
RotateEntity skybox,0,0,0,1
PositionEntity skybox,x,y,z,1
EndIf
CameraRange cam,1,100000
CameraViewport cam,0,0,size,size
PositionEntity cam,x,y,z
TurnEntity cam,0,90,0
RenderWorld
SetCubeFace tex,0
CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex)
TurnEntity cam,0,-90,0
RenderWorld
SetCubeFace tex,1
CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex)
TurnEntity cam,0,-90,0
If skybox RotateEntity skybox,0,0,0,1
RenderWorld
SetCubeFace tex,2
CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex)
TurnEntity cam,0,-90,0
If skybox RotateEntity skybox,0,0,0,1
RenderWorld
SetCubeFace tex,3
CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex)
TurnEntity cam,0,-90,0
TurnEntity cam,90,0,0
If skybox RotateEntity skybox,0,0,0,1
RenderWorld
SetCubeFace tex,4
CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex)
TurnEntity cam,180,0,0
If skybox RotateEntity skybox,0,0,0,1
RenderWorld
SetCubeFace tex,5
CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex)
FreeEntity cam
If skybox PositionEntity skybox,0,0,0
Return tex
End Function

Function UpdateCubeMap(tex,x#,y#,z#)
Local cam=CreateCamera()
CameraRange cam,1,100000
CameraViewport cam,0,0,TextureWidth(tex),TextureHeight(tex)
PositionEntity cam,x,y,z
TurnEntity cam,0,90,0
RenderWorld
SetCubeFace tex,0
CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex)
TurnEntity cam,0,-90,0
RenderWorld
SetCubeFace tex,1
CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex)
TurnEntity cam,0,-90,0
RenderWorld
SetCubeFace tex,2
CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex)
TurnEntity cam,0,-90,0
RenderWorld
SetCubeFace tex,3
CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex)
TurnEntity cam,0,-90,0
TurnEntity cam,90,0,0
RenderWorld
SetCubeFace tex,4
CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex)
TurnEntity cam,180,0,0
RenderWorld
SetCubeFace tex,5
CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex)
FreeEntity cam
Return tex
End Function


aCiD2(Posted 2004) [#7]
ah thanks for all of that everyone :) halo - the reason im generating the cube map every loop is so its more realistic, and it doesnt seem to kill my fps at all really :)


Jeroen(Posted 2004) [#8]
Hi Halo,

I'm trying to make a simple demo of your code:

Graphics3D 800,600,32,2
SetBuffer BackBuffer()

water=CreatePlane()
cam=CreateCamera()
PositionEntity cam,0,10,-20
RotateEntity cam,40,0,0

cube=CreateCube()
PositionEntity cube,1,5,1

tex = CreateCubeMap(128,EntityX(cam),cubeMapCameraY( EntityY(cam),EntityY(water) ),EntityZ(cam)) 
EntityTexture water,tex

While Not KeyHit(1)
	UpdateWorld
	TurnEntity cube,1,1,1
	tex = UpdateCubeMap(tex,EntityX(cam),cubeMapCameraY( EntityY(cam),EntityY(water) ),EntityZ(cam))
	EntityTexture water,tex
	RenderWorld
	Flip
Wend
End

Function cubeMapCameraY(screenCameraY#,waterY#)
	; tip from jfk
	; returns Y coordinate for cubemap camera
	y# = waterY# - (screenCameraY# - waterY#) 
	RuntimeError y#

End Function

Function CreateCubeMap(size,x#,y#,z#,flags=128+256) 
	If Not (128 And flags) flags=flags+128 
	Local cam=CreateCamera() 
	Local tex=CreateTexture(size,size,flags) 
	If skybox 
		RotateEntity skybox,0,0,0,1 
		PositionEntity skybox,x,y,z,1 
	EndIf 
	CameraRange cam,1,100000 
	CameraViewport cam,0,0,size,size 
	PositionEntity cam,x,y,z 
	TurnEntity cam,0,90,0 
	RenderWorld 
	SetCubeFace tex,0 
	CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex) 
	TurnEntity cam,0,-90,0 
	RenderWorld 
	SetCubeFace tex,1 
	CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex) 
	TurnEntity cam,0,-90,0 
	If skybox RotateEntity skybox,0,0,0,1 
	RenderWorld 
	SetCubeFace tex,2 
	CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex) 
	TurnEntity cam,0,-90,0 
	If skybox RotateEntity skybox,0,0,0,1 
	RenderWorld 
	SetCubeFace tex,3 
	CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex) 
	TurnEntity cam,0,-90,0 
	TurnEntity cam,90,0,0 
	If skybox RotateEntity skybox,0,0,0,1 
	RenderWorld 
	SetCubeFace tex,4 
	CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex) 
	TurnEntity cam,180,0,0 
	If skybox RotateEntity skybox,0,0,0,1 
	RenderWorld 
	SetCubeFace tex,5 
	CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex) 
	FreeEntity cam 
	If skybox PositionEntity skybox,0,0,0 
	Return tex 
End Function 

Function UpdateCubeMap(tex,x#,y#,z#) 
	Local cam=CreateCamera() 
	CameraRange cam,1,100000 
	CameraViewport cam,0,0,TextureWidth(tex),TextureHeight(tex) 
	PositionEntity cam,x,y,z 
	TurnEntity cam,0,90,0 
	RenderWorld 
	SetCubeFace tex,0 
	CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex) 
	TurnEntity cam,0,-90,0 
	RenderWorld 
	SetCubeFace tex,1 
	CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex) 
	TurnEntity cam,0,-90,0 
	RenderWorld 
	SetCubeFace tex,2 
	CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex) 
	TurnEntity cam,0,-90,0 
	RenderWorld 
	SetCubeFace tex,3 
	CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex) 
	TurnEntity cam,0,-90,0 
	TurnEntity cam,90,0,0 
	RenderWorld 
	SetCubeFace tex,4 
	CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex) 
	TurnEntity cam,180,0,0 
	RenderWorld 
	SetCubeFace tex,5 
	CopyRect 0,0,size,size,0,0,BackBuffer(),TextureBuffer(tex) 
	FreeEntity cam 
	Return tex 
End Function 



...But I think I'm not understanding this at all :)


IPete2(Posted 2004) [#9]
Jeroen,

If you have Gile[s], check out the Roman Bath download - the water code is small and reflects nicely.

IPete2.


fredborg(Posted 2004) [#10]
You don't even need gile[s] for it :) Full source and media is included! http://www.frecle.net/giles/download/gile[s]-b3d-parser.zip


Jeroen(Posted 2004) [#11]
i used Freborgs' code at first - but when I copied to my own example, reflections where all wrong.
I'll try again!


aCiD2(Posted 2004) [#12]
i use freds code and it works a treat, what code are you using?