Volumes Of Fun http://www.volumesoffun.com/phpBB3/ |
|
Using Ambient Occlusion http://www.volumesoffun.com/phpBB3/viewtopic.php?f=2&t=156 |
Page 1 of 1 |
Author: | Jmgr [ Wed Mar 02, 2011 9:00 pm ] |
Post subject: | Using Ambient Occlusion |
Hi people, Now that I have achieved texturing my cubes I would like to add ambient occlusion using the AmbientOcclusionCalculator. I looked at the Thermite project but couldn't really find out what are the steps required to send the resulting volume to the GPU. For now I'm computing my AmbientOcclusionVolume each time a chunk is updated and then storing it into a 3D texture. (the same thing that Thermite does) To create the 3D texture : Code: mAmbientOcclusionVolumeTexture = Ogre::TextureManager::getSingleton().createManual( "AmbientOcclusionVolumeTexture" + Ogre::StringConverter::toString(x) + "_" + Ogre::StringConverter::toString(y), // Name of texture "General", // Name of resource group in which the texture should be created Ogre::TEX_TYPE_3D, // Texture type ChunkSizeX, // Width ChunkSizeY, // Height ChunkSizeZ, // Depth (Must be 1 for two dimensional textures) 0, // Number of mipmaps Ogre::PF_L8, // Pixel format Ogre::TU_STATIC_WRITE_ONLY // usage ); x and y are the coordinates of the chunk. Copying the computed volume into this texture : Code: Ogre::HardwarePixelBuffer* pixelBuffer = mAmbientOcclusionVolumeTexture.getPointer()->getBuffer().getPointer(); Ogre::PixelBox pixelBox(mAmbientOcclusionVolumeTexture->getWidth(),mAmbientOcclusionVolumeTexture->getHeight(),mAmbientOcclusionVolumeTexture->getDepth(), mAmbientOcclusionVolumeTexture->getFormat(), ambientOcclusionVolume->getRawData()); pixelBuffer->blitFromMemory(pixelBox); I'm certainly missing something because the computation seems to take place (it's using one CPU core for some time) but nothing can be seen. |
Author: | David Williams [ Wed Mar 02, 2011 9:20 pm ] | ||
Post subject: | Re: Using Ambient Occlusion | ||
Unfortunatly Thermite doesn't show everything you need to know - there is some shader code to go with it which is part of the game rather than being part of Thermite. Basically you need the following steps: 1) Create the 3D array comtaining the data, using the PolyVox AmbientOcclusionCalculator. You can also try just filling the array with a 3D checkerboard pattern or something, for debugging. 2) Copy the 3D array into a Ogre volume texture. 3) Declare the texture to your material. Be aware, you might need to be careful to make sure the texture has been created in code before the material actually tries to use it. Code: texture_unit { texture AmbientOcclusionVolumeTexture 3d tex_address_mode clamp } 4) Pass the texture as a parameter to your pixel shader and sample it to apply the lighting. Note that you need to know the volume size to do this: Code: float ambientVal = tex3D(ambientMap, (inWorldPosition.xyz + float3(0.499f, 0.499f, 0.499f)) / float3(256.0f, 64.0f, 256.0f)); I've attached some code you might find useful.
|
Author: | Jmgr [ Wed Mar 02, 2011 9:30 pm ] |
Post subject: | Re: Using Ambient Occlusion |
Thanks, I will check this. It seems that the zip file is corrupted? |
Author: | milliams [ Wed Mar 02, 2011 9:53 pm ] |
Post subject: | Re: Using Ambient Occlusion |
Jmgr wrote: It seems that the zip file is corrupted? It extracts fine for me.
|
Author: | Jmgr [ Wed Mar 02, 2011 10:01 pm ] |
Post subject: | Re: Using Ambient Occlusion |
Oh yes I see It's working with Chrome... No idea why Firefox didn't want it. |
Author: | Jmgr [ Thu Mar 03, 2011 7:28 pm ] |
Post subject: | Re: Using Ambient Occlusion |
I'm using 16x128x16 chunks for now. Do you think that it would be possible to generate one ambient occlusion texture per chunk rather than for the whole volume ? Also ambient occlusion computation time seems to be very high. I don't know the optimal value of fRayLength, but with 32 it takes a very long time for 16*128*16 chunks. I heard somewhere that it is possible to do this on the GPU, but my GPU skills are too low to implement that anyway ![]() |
Author: | David Williams [ Thu Mar 03, 2011 11:36 pm ] |
Post subject: | Re: Using Ambient Occlusion |
Jmgr wrote: I'm using 16x128x16 chunks for now. Do you think that it would be possible to generate one ambient occlusion texture per chunk rather than for the whole volume ? Probably not... I expect you would see visual artefacts because one chunk should actually cause occlusion in the next. Besides, you would then have to upload multiple volume textures to the GPU. It should be possible to update only part of the volume texture at a time though - I don't think I did this yet in Thermite (I think I still upload the whole thing). Jmgr wrote: Also ambient occlusion computation time seems to be very high. I don't know the optimal value of fRayLength, but with 32 it takes a very long time for 16*128*16 chunks. I heard somewhere that it is possible to do this on the GPU, but my GPU skills are too low to implement that anyway ![]() Yes, it is currently slow. That said, you shouldn't need to make the volume texture as large as the chuck - ambient occlusion changes slowly so in Thermite I'm using a volume texture 1/4 the size of the volume in each dimension. In your case that would be 32x4x4. I should also point out that it's all very experimental... I like the result I've got in Thermite but there's plenty of research to be done. You might decide that you don't want to store the ambient occlusion in a volume texture for example, but you would prefer to store it in the vertices. This will be much better for large volumes. You would have to implement this yourself using the Raycast class aand looking at the AmbientOcclusionCalculator as an example. |
Author: | AndiNo [ Thu Apr 05, 2012 1:37 am ] |
Post subject: | Re: Using Ambient Occlusion |
I hope it's okay to revive this old thread ![]() It seems AO is nearly working for me. However I could not find any information about how I should feed the generated AO data into the Ogre 3D texture. The way I do it now is most probably wrong. Code: // fill Ogre texture with data Ogre::HardwarePixelBufferSharedPtr pixelBuffer = AOtexture->getBuffer(); pixelBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL); const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock(); Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data); for (int z=0; z<AO_VOL_SIZE; z++) { for (int y=0; y<AO_VOL_SIZE; y++) { for (int x=0; x<AO_VOL_SIZE; x++) { *pDest++ = ambientOcclusionResult[x][y][z]; } } } The important line is in the for-loops. In which order do I have to write the data into the texture? Are there better methods to copy the data? |
Author: | David Williams [ Thu Apr 05, 2012 8:12 am ] |
Post subject: | Re: Using Ambient Occlusion |
The ambient occlusion code in Thermite3D has been removed as updating AO was too slow for Voxeliens (we'll come back to that in the future) but you can still find some stuff through Git. In particular have a look at these few lines: http://www.gitorious.org/thermite3d/the ... pp#line288 You might also find it useful to create dummy textures (e.g. going from dark to light as you move along a known axis) in order to make sure the orientation is correct. |
Author: | David Williams [ Sun Apr 08, 2012 3:29 pm ] |
Post subject: | Re: Using Ambient Occlusion |
Bug report split off to here: viewtopic.php?f=15&t=360 |
Page 1 of 1 | All times are UTC |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |