From 55cbff1186f5628765a262a5c3d040a4bcf97d67 Mon Sep 17 00:00:00 2001 From: David Williams Date: Sat, 16 Apr 2011 14:10:34 +0100 Subject: [PATCH] Added control over the number of samples taken in the ambient occlusion calculator. --- .../include/AmbientOcclusionCalculator.h | 4 +++- .../include/AmbientOcclusionCalculator.inl | 23 +++++++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/library/PolyVoxCore/include/AmbientOcclusionCalculator.h b/library/PolyVoxCore/include/AmbientOcclusionCalculator.h index 7b453cb4..f6fec428 100644 --- a/library/PolyVoxCore/include/AmbientOcclusionCalculator.h +++ b/library/PolyVoxCore/include/AmbientOcclusionCalculator.h @@ -32,7 +32,7 @@ namespace PolyVox class AmbientOcclusionCalculator { public: - AmbientOcclusionCalculator(Volume* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength); + AmbientOcclusionCalculator(Volume* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement); ~AmbientOcclusionCalculator(); void execute(void); @@ -44,6 +44,8 @@ namespace PolyVox Array<3, uint8_t>* m_arrayResult; float m_fRayLength; + uint8_t m_uNoOfSamplesPerOutputElement; + uint16_t mRandomUnitVectorIndex; uint16_t mRandomVectorIndex; uint16_t mIndexIncreament; diff --git a/library/PolyVoxCore/include/AmbientOcclusionCalculator.inl b/library/PolyVoxCore/include/AmbientOcclusionCalculator.inl index 2fffd7e1..a579cf4d 100644 --- a/library/PolyVoxCore/include/AmbientOcclusionCalculator.inl +++ b/library/PolyVoxCore/include/AmbientOcclusionCalculator.inl @@ -32,12 +32,13 @@ freely, subject to the following restrictions: namespace PolyVox { template - AmbientOcclusionCalculator::AmbientOcclusionCalculator(Volume* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength) + AmbientOcclusionCalculator::AmbientOcclusionCalculator(Volume* volInput, Array<3, uint8_t>* arrayResult, Region region, float fRayLength, uint8_t uNoOfSamplesPerOutputElement) :m_region(region) ,m_sampVolume(volInput) ,m_volInput(volInput) ,m_arrayResult(arrayResult) ,m_fRayLength(fRayLength) + ,m_uNoOfSamplesPerOutputElement(uNoOfSamplesPerOutputElement) { //Make sure that the size of the volume is an exact multiple of the size of the array. assert(m_volInput->getWidth() % arrayResult->getDimension(0) == 0); @@ -100,9 +101,9 @@ namespace PolyVox //Keep track of how many rays did not hit anything uint8_t uVisibleDirections = 0; - for(int ct = 0; ct < 255; ct++) + for(int ct = 0; ct < m_uNoOfSamplesPerOutputElement; ct++) { - //We take a random vector with components going from -1 to 1 and scale it to go from -haflRatio to +halfRatio. + //We take a random vector with components going from -1 to 1 and scale it to go from -halfRatio to +halfRatio. //This jitter value moves our sample point from the center of the array cell to somewhere else in the array cell Vector3DFloat v3dJitter = randomVectors[(mRandomVectorIndex += (++mIndexIncreament)) % 1019]; //Prime number helps avoid repetition on sucessive loops. v3dJitter *= v3dHalfRatio; @@ -120,7 +121,21 @@ namespace PolyVox ++uVisibleDirections; } } - (*m_arrayResult)[z / iRatioZ][y / iRatioY][x / iRatioX] = uVisibleDirections; + + float fVisibility; + if(m_uNoOfSamplesPerOutputElement == 0) + { + //The user might request zero samples (I've done this in the past while debugging - I don't want to + //wait for ambient occlusion but I do want as valid result for rendering). Avoid the divide by zero. + fVisibility = 1.0f; + } + else + { + fVisibility = static_cast(uVisibleDirections) / static_cast(m_uNoOfSamplesPerOutputElement); + assert((fVisibility >= 0.0f) && (fVisibility <= 1.0f)); + } + + (*m_arrayResult)[z / iRatioZ][y / iRatioY][x / iRatioX] = static_cast(255.0f * fVisibility); } } }