Skip to content

Commit ad0a08c

Browse files
committed
Improve rasterizer depth buffer
1 parent bee63f4 commit ad0a08c

File tree

3 files changed

+51
-33
lines changed

3 files changed

+51
-33
lines changed

pipeline/Rasterizer.cpp

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ namespace osgVerse
148148
rd->data->setModelViewProjection(m.ptr());
149149
}
150150

151-
void UserRasterizer::render(const osg::Vec3& cameraPos, std::vector<float>& depthData)
151+
void UserRasterizer::render(const osg::Vec3& cameraPos, std::vector<float>* depthData,
152+
std::vector<unsigned short>* hizData)
152153
{
153154
std::vector<BatchOccluder*> globalOccluders;
154155
for (std::set<osg::ref_ptr<UserOccluder>>::iterator it = _occluders.begin();
@@ -165,8 +166,8 @@ namespace osgVerse
165166
__m128 camPos = convertFromVec3(cameraPos);
166167
std::sort(globalOccluders.begin(), globalOccluders.end(), [&](const BatchOccluder* o1, const BatchOccluder* o2)
167168
{
168-
__m128 dist1 = _mm_sub_ps(convertFromVec3(o1->getCenter()), camPos);
169-
__m128 dist2 = _mm_sub_ps(convertFromVec3(o2->getCenter()), camPos);
169+
__m128 dist1 = _mm_sub_ps(((BatchOccluderData*)o1->getOccluder())->data->m_center, camPos);
170+
__m128 dist2 = _mm_sub_ps(((BatchOccluderData*)o2->getOccluder())->data->m_center, camPos);
170171
return _mm_comilt_ss(_mm_dp_ps(dist1, dist1, 0x7f), _mm_dp_ps(dist2, dist2, 0x7f));
171172
});
172173

@@ -186,49 +187,60 @@ namespace osgVerse
186187
it != _occluders.end(); ++it)
187188
{
188189
std::set<osg::ref_ptr<BatchOccluder>>& batches = (*it)->getBatches();
189-
size_t count = 0, maxCount = batches.size();
190+
size_t count = 0, count2 = 0, maxCount = batches.size();
190191

191192
for (std::set<osg::ref_ptr<BatchOccluder>>::iterator it2 = batches.begin();
192193
it2 != batches.end(); ++it2)
193194
{
194195
BatchOccluder* bo = (*it2).get(); bool needsClipping = false;
195196
BatchOccluderData* od = (BatchOccluderData*)bo->getOccluder();
196197
if (rd->data->queryVisibility(od->data->m_boundsMin, od->data->m_boundsMax, needsClipping))
197-
count++;
198+
{ count++; if (needsClipping) count2++; }
198199
}
199-
std::cout << (*it)->getName() << "; " << count << " / " << maxCount << "\n";
200+
std::cout << (*it)->getName() << "; " << count << " (" << count2 << ") / " << maxCount << "\n";
200201
}
201202

202203
// Get result depth image
203204
std::vector<__m128i>& depthBuffer = rd->data->getDepthBuffer();
204205
std::vector<uint16_t>& hizBuffer = rd->data->getHiZ();
205-
depthData.resize(_blockNumX * _blockNumY * 64, 1.0f);
206-
207-
const float bias = 3.9623753e+28f; // 1.0f / floatCompressionBias
208-
for (uint32_t y = 0; y < _blockNumY; ++y)
206+
if (depthData)
209207
{
210-
for (uint32_t x = 0; x < _blockNumX; ++x)
208+
const float bias = 3.9623753e+28f; // 1.0f / floatCompressionBias
209+
depthData->resize(_blockNumX * _blockNumY * 64);
210+
for (uint32_t y = 0; y < _blockNumY; ++y)
211211
{
212-
uint32_t index = y * _blockNumX + x;
213-
if (hizBuffer[index] == 1) continue;
214-
215-
const __m128i* source = &depthBuffer[8 * index];
216-
for (uint32_t subY = 0; subY < 8; ++subY)
212+
for (uint32_t x = 0; x < _blockNumX; ++x)
217213
{
218-
__m128i depthI = _mm_load_si128(source++);
219-
__m256i depthI256 = _mm256_slli_epi32(_mm256_cvtepu16_epi32(depthI), 12);
220-
__m256 depth = _mm256_mul_ps(_mm256_castsi256_ps(depthI256), _mm256_set1_ps(bias));
221-
__m256 linDepth = _mm256_div_ps(_mm256_set1_ps(2 * 0.25f),
222-
_mm256_sub_ps(_mm256_set1_ps(0.25f + 1000.0f),
223-
_mm256_mul_ps(_mm256_sub_ps(_mm256_set1_ps(1.0f), depth),
224-
_mm256_set1_ps(1000.0f - 0.25f))));
225-
float linDepthA[16]; _mm256_storeu_ps(linDepthA, linDepth);
226-
227-
std::vector<float>::iterator it = depthData.begin() + ((8 * _blockNumX) * (8 * y + subY) + 8 * x);
228-
for (uint32_t subX = 0; subX < 8; ++subX, ++it) *it = linDepthA[subX];
214+
uint32_t index = y * _blockNumX + x;
215+
if (hizBuffer[index] == 1)
216+
{
217+
for (uint32_t subY = 0; subY < 8; ++subY)
218+
{
219+
std::vector<float>::iterator it = depthData->begin() + ((8 * _blockNumX) * (8 * y + subY) + 8 * x);
220+
for (uint32_t subX = 0; subX < 8; ++subX, ++it) *it = -1.0f;
221+
}
222+
continue;
223+
}
224+
225+
const __m128i* source = &depthBuffer[8 * index];
226+
for (uint32_t subY = 0; subY < 8; ++subY)
227+
{
228+
__m128i depthI = _mm_load_si128(source++);
229+
__m256i depthI256 = _mm256_slli_epi32(_mm256_cvtepu16_epi32(depthI), 12);
230+
__m256 depth = _mm256_mul_ps(_mm256_castsi256_ps(depthI256), _mm256_set1_ps(bias));
231+
__m256 linDepth = _mm256_div_ps(_mm256_set1_ps(2 * 0.25f),
232+
_mm256_sub_ps(_mm256_set1_ps(0.25f + 1000.0f),
233+
_mm256_mul_ps(_mm256_sub_ps(_mm256_set1_ps(1.0f), depth),
234+
_mm256_set1_ps(1000.0f - 0.25f))));
235+
float linDepthA[16]; _mm256_storeu_ps(linDepthA, linDepth);
236+
237+
std::vector<float>::iterator it = depthData->begin() + ((8 * _blockNumX) * (8 * y + subY) + 8 * x);
238+
for (uint32_t subX = 0; subX < 8; ++subX, ++it) *it = linDepthA[subX];
239+
}
229240
}
230241
}
231242
}
243+
if (hizData) hizData->assign(hizBuffer.begin(), hizBuffer.end());
232244

233245
# if false
234246
std::vector<char> rawData(_blockNumX * _blockNumY * 256);

pipeline/Rasterizer.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace osgVerse
1515
BatchOccluder(UserOccluder* u, const std::vector<osg::Vec3> vertices,
1616
const osg::BoundingBoxf& refBound);
1717
BatchOccluder(UserOccluder* u, void* verticesInternal, const osg::BoundingBoxf& refBound);
18-
void* getOccluder() { return _privateData; }
18+
void* getOccluder() const { return _privateData; }
1919
UserOccluder* getOwner() { return _owner; }
2020

2121
osg::BoundingBoxf getBound() const;
@@ -51,7 +51,8 @@ namespace osgVerse
5151
public:
5252
UserRasterizer(unsigned int width, unsigned int height);
5353
void setModelViewProjection(const osg::Matrixf& matrix);
54-
void render(const osg::Vec3& cameraPos, std::vector<float>& depthData);
54+
void render(const osg::Vec3& cameraPos, std::vector<float>* depthData,
55+
std::vector<unsigned short>* hizData);
5556

5657
void addOccluder(UserOccluder* o) { _occluders.insert(o); }
5758
void removeOccluder(UserOccluder* o);

tests/occlusion_cull_test.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,14 @@ int main(int argc, char** argv)
4646
osg::ref_ptr<osgVerse::UserRasterizer> rasterizer = new osgVerse::UserRasterizer(1280, 720);
4747
rasterizer->addOccluder(occ1.get()); rasterizer->addOccluder(occ2.get());
4848

49-
std::vector<float> depthData;
49+
std::vector<float> depthData; std::vector<unsigned short> hizData;
5050
while (!viewer.done())
5151
{
5252
osg::Matrix mvp = viewer.getCamera()->getViewMatrix()
5353
* viewer.getCamera()->getProjectionMatrix();
5454
osg::Vec3 cameraPos = osg::Vec3() * viewer.getCamera()->getInverseViewMatrix();
5555
rasterizer->setModelViewProjection(mvp);
56-
rasterizer->render(cameraPos, depthData);
56+
rasterizer->render(cameraPos, &depthData, &hizData);
5757

5858
viewer.frame();
5959
}
@@ -65,8 +65,13 @@ int main(int argc, char** argv)
6565
for (int y = 0; y < image->t(); ++y)
6666
for (int x = 0; x < image->s(); ++x)
6767
{
68-
unsigned char value = (unsigned char)(255.0f * depthData[y * image->s() + x]);
69-
*(ptr + y * image->s() + x) = osg::Vec4ub(value, value, value, 255);
68+
unsigned char mid = 0, value = 0, alpha = 255;
69+
float depth = depthData[y * image->s() + x] * 100.0f;
70+
if (depth > 1.0f) { mid = (unsigned char)(floor(depth) * 2.55f); depth *= 0.01f; }
71+
else if (depth < 0.0f) { alpha = 0; depth = 0.0f; }
72+
73+
value = (unsigned char)(255.0f * depth);
74+
*(ptr + y * image->s() + x) = osg::Vec4ub(value, mid, 0, alpha);
7075
}
7176
}
7277
osgDB::writeImageFile(*image, "test_occlusion.png");

0 commit comments

Comments
 (0)