3D模型体素化(Voxelization)过程实现与分析(二)
生活随笔
收集整理的這篇文章主要介紹了
3D模型体素化(Voxelization)过程实现与分析(二)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
文章目錄
- 體素化方法
- 原理展示
- 實(shí)現(xiàn)過程
- 使用Buffer
- 著色器
- 讀取體素坐標(biāo)
- 實(shí)現(xiàn)代碼
- 頂點(diǎn)著色器
- 片元著色器
- CPU讀取
- 效果圖
體素化方法
體素化能夠?qū)δP瓦M(jìn)行簡化,得到均勻的網(wǎng)格,在求模型的測地線,求交等過程中有較好的應(yīng)用。個人理解,把體素化分為基于CPU的方法和基于GPU渲染的方法。輸入是三角面片,輸出體素化格子。
直接使用三角形求交的方法見
3D模型體素化(Voxelization)過程實(shí)現(xiàn)與分析(一)
使用三角形求交的方法,體素化計算量與三角形的數(shù)量,體素分辨率直接相關(guān)。當(dāng)三角形數(shù)量增多,分辨率增大時,計算量將急劇增加,計算十分緩慢。
本文介紹使用OpenGL快速計算體素化的方法,使用渲染管線中的片段著色器,將三角形與體素的求交轉(zhuǎn)化為采樣點(diǎn)與體素的求交。運(yùn)用片元的并行性,快速得到體素化結(jié)果。
原理展示
實(shí)現(xiàn)過程
使用Buffer
這里需要從著色器回傳會體素占用信息,使用一個一維的數(shù)組來展開三維的體素位置。uniform對于著色器是只讀的。因此使用Buffer,著色器是可讀寫的,同時Buffer也允許使用較大的空間。
著色器
讀取體素坐標(biāo)
在CPU中讀取Buffer數(shù)組,解析出體素化結(jié)果。
實(shí)現(xiàn)代碼
頂點(diǎn)著色器
#version 430 core layout (location=0) in vec3 aPos; layout (location=1) in vec3 aNormal; layout (location=2) in vec2 aTexture;out vec3 FragPos; uniform mat4 model; uniform mat4 view; uniform mat4 projection;void main() { FragPos = aPos; // 局部坐標(biāo)gl_Position = projection *view *model *vec4(aPos,1.0); }片元著色器
#version 430 coreout vec4 FragColor;in vec3 FragPos;layout (std430, binding =0) buffer CountBuffer{int cnts[]; };uniform vec3 box_min; uniform float interval; // 步長 uniform vec3 xyz; // 分辨率 uniform int pass;void main() {if(pass ==0){ int x = int((FragPos.x-box_min.x)/interval);int y = int((FragPos.y-box_min.y)/interval);int z = int((FragPos.z-box_min.z)/interval);int idx = int(y *(xyz.z *xyz.x) + z *xyz.x + x); atomicAdd(cnts[idx], 1);}FragColor = vec4(1, 0, 0, 1); }CPU讀取
glBindBuffer(GL_SHADER_STORAGE_BUFFER, cntBO); // 獲取buffer指針 int * ptr = (int *)(glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY)); // cout << "error node: " << glGetError() << endl; vector<glm::vec3> pos; // 體素位置 vector<glm::ivec3> idx; // 體素索引 if (ptr != NULL) {for (int i = 0; i < cnts.size(); ++i){if (*(ptr + i)){int y1 = i / (x*z);int z1 = (i - y1 *x*z) / x;int x1 = (i - y1*x*z - z1*x);pos.push_back(box_min + glm::vec3(x1*width, y1*width, z1*width));idx.push_back(glm::ivec3(x1, y1, z1));}} } else {Error("read buffer data error"); } glUnmapBuffer(cntBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);效果圖
如有錯誤,歡迎指出~
總結(jié)
以上是生活随笔為你收集整理的3D模型体素化(Voxelization)过程实现与分析(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 生成动态库_Python
- 下一篇: QColor的使用