Archive for November, 2011

Dynamic Reflections with Stage3D

Thursday, November 24th, 2011

First up the video:

This was actually pretty easy to achieve, it basically involves rendering the scene 6 times with a wide angle lens each time rendering to a side of a cube map.
This cube map can then be used as a basis for a reflection shader.

Noteworthy observations:

this will be slow for complex scenes as there could potentially be 7 times more draw calls!!
forgetting to convert degrees to radians can be a pain in the but (doh)
frustum cull with each face render to reduce the number of draw calls
to get it to reflect another reflective object will really start to complicate things..so avoid like hell
could probably get away with rendering to really small textures, as perfect reflections can look less realistic anyway.
there is something wrong with my reflection math as those of you with keen eyes will have noticed the reflected cubes are moving backwards – will fix this soon I hope.

All this was achieved in a very short space of time, about 30 mins of coding and about 2 hours to realise I forgot to convert degrees to radians.

example code:

public function rendertoCubeMap(cubeTexture:CubeTexture, exclude:Object3D = null):void
{
	this.exclude = exclude;
	var cameraPositionCache:Vector3D = camera.position.clone();
	var cameraTargetCache:Vector3D = camera.target.clone();
	var fovCache:Number = camera.fov;		
	var aspectCache:Number = _aspect;		
	camera.fov = cubeFov;
	_aspect = 1;
 
	camera.position.setTo(0,0,0);
 
	context3D.setRenderToTexture(cubeTexture, true, 0, 0);
	camera.target.setTo(camera.position.x - 1, camera.position.y, camera.position.z);
	update();
	renderAll();
 
	context3D.setRenderToTexture(cubeTexture, true, 0, 1);
	camera.target.setTo(camera.position.x + 1, camera.position.y, camera.position.z);
	update();
	renderAll();
 
	context3D.setRenderToTexture(cubeTexture, true, 0, 2);
	camera.target.setTo(camera.position.x, camera.position.y + 1, camera.position.z+0.001);	//get some NaNs if z = 0 here
	update();
	renderAll();
 
	context3D.setRenderToTexture(cubeTexture, true, 0, 3);
	camera.target.setTo(camera.position.x, camera.position.y - 1, camera.position.z-0.001);		//get some NaNs if z = 0 here
	update();
	renderAll();
 
	context3D.setRenderToTexture(cubeTexture, true, 0, 4);
	camera.target.setTo(camera.position.x, camera.position.y, camera.position.z + 1);
	update();
	renderAll();
 
	context3D.setRenderToTexture(cubeTexture, true, 0, 5);
	camera.target.setTo(camera.position.x, camera.position.y, camera.position.z - 1);
	update();
	renderAll();
 
	context3D.setRenderToBackBuffer();
 
	_aspect = aspectCache;
	camera.fov = fovCache;
	camera.target.setTo(cameraTargetCache.x, cameraTargetCache.y, cameraTargetCache.z);
	camera.position.setTo(cameraPositionCache.x, cameraPositionCache.y, cameraPositionCache.z);
 
	this.exclude = null;
}

and that’s it!

:)

A few screen captures of some stage3d experiments

Monday, November 21st, 2011