基本确定BVH结构

dev-VirtualTexture
wuyize 2022-07-31 22:02:13 +08:00
parent b95586db2b
commit 5fd42b6636
6 changed files with 173 additions and 118 deletions

View File

@ -5,9 +5,11 @@
#include <QTextCodec> #include <QTextCodec>
#include <iostream> #include <iostream>
#include "PaintingMesh.h" #include "PaintingMesh.h"
#include <QtMath>
Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram) Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram)
: context(context) : context(context)
, glFunc(context->versionFunctions<QOpenGLFunctions_4_5_Compatibility>())
, shaderProgram(shaderProgram) , shaderProgram(shaderProgram)
, directory(path) , directory(path)
{ {
@ -28,6 +30,7 @@ Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shader
Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram) Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram)
: context(context) : context(context)
, glFunc(context->versionFunctions<QOpenGLFunctions_4_5_Compatibility>())
, shaderProgram(shaderProgram) , shaderProgram(shaderProgram)
, paintingProgram(paintingProgram) , paintingProgram(paintingProgram)
, directory(path) , directory(path)
@ -104,7 +107,7 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
{ {
qDebug() << str.C_Str(); qDebug() << str.C_Str();
// 初始化网格 // 初始化网格
PaintingMesh* m_mesh = new PaintingMesh(QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Compatibility>(), paintingProgram, model); PaintingMesh* m_mesh = new PaintingMesh(glFunc, paintingProgram, model);
// 遍历网格的每个顶点 // 遍历网格的每个顶点
for (unsigned int i = 0; i < mesh->mNumVertices; i++) for (unsigned int i = 0; i < mesh->mNumVertices; i++)
{ {
@ -136,13 +139,39 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
} }
} }
GLuint bvhChildren[] = {7/*Êý×鳤¶È*/,0/*ÓëÏÔ´æ¶ÔÆë*/,
1,2,
3,4, 5,6,
7,0, 7,45./360* 4294967296 , 7,0, 7,0};
QVector4D bvhBound[] = { QVector4D(-1,-1,1,1) ,
QVector4D(0.1,0.1,0.4,0.9), QVector4D(0.6,0.1,0.9,0.9),
QVector4D(0.2,0.2,0.3,0.4), QVector4D(0.2,0.5,0.3,0.8), QVector4D(0.7,0.2,0.8,0.4), QVector4D(0.7,0.3,0.8,0.8) };
glFunc->glGenBuffers(1, &m_mesh->bvhSSBO);
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_mesh->bvhSSBO);
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER,sizeof(bvhChildren), bvhChildren, GL_DYNAMIC_DRAW);
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
glFunc->glGenBuffers(1, &m_mesh->bvhBoundSSBO);
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_mesh->bvhBoundSSBO);
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(bvhBound), bvhBound, GL_DYNAMIC_DRAW);
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLfloat elementData[] = { 1,2,3,4,5 };
glFunc->glGenBuffers(1, &m_mesh->elementSSBO);
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_mesh->elementSSBO);
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(elementData), elementData, GL_DYNAMIC_DRAW);
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
m_mesh->setupMesh(); m_mesh->setupMesh();
return m_mesh; return m_mesh;
} }
else else
{ {
// 初始化网格 // 初始化网格
Mesh* m_mesh = new Mesh(QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Compatibility>(), shaderProgram, model); Mesh* m_mesh = new Mesh(glFunc, shaderProgram, model);
// 遍历网格的每个顶点 // 遍历网格的每个顶点
for (unsigned int i = 0; i < mesh->mNumVertices; i++) for (unsigned int i = 0; i < mesh->mNumVertices; i++)
{ {

View File

@ -16,6 +16,7 @@ private:
~Model(); ~Model();
QOpenGLContext* context; //opengl函数入口 QOpenGLContext* context; //opengl函数入口
QOpenGLFunctions_4_5_Compatibility* glFunc;
QOpenGLShaderProgram* shaderProgram = nullptr; QOpenGLShaderProgram* shaderProgram = nullptr;
QOpenGLShaderProgram* paintingProgram = nullptr; //彩绘着色器程序 QOpenGLShaderProgram* paintingProgram = nullptr; //彩绘着色器程序
/* 模型数据 */ /* 模型数据 */

View File

@ -14,7 +14,13 @@ void PaintingMesh::draw()
shaderProgram->bind(); shaderProgram->bind();
QOpenGLVertexArrayObject::Binder bind(&VAO); QOpenGLVertexArrayObject::Binder bind(&VAO);
shaderProgram->setUniformValue("model", model); shaderProgram->setUniformValue("model", model);
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, bvhSSBO);
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, bvhBoundSSBO);
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, elementSSBO);
glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
shaderProgram->release(); shaderProgram->release();
} }
void PaintingMesh::setupMesh() void PaintingMesh::setupMesh()

View File

@ -24,6 +24,14 @@ struct PaintingVertex
QVector3D Bitangent; QVector3D Bitangent;
}; };
struct BvhNode {
GLuint leftChild;
GLuint rightChild;
GLuint padding[2];//与显存对齐
QVector4D bound;
BvhNode(GLuint leftChild, GLuint rightChild, QVector4D bound) :leftChild(leftChild), rightChild(rightChild), bound(bound) {}
};
class PaintingMesh : public Drawable class PaintingMesh : public Drawable
{ {
public: public:
@ -34,6 +42,8 @@ public:
QOpenGLFunctions_4_5_Compatibility* glFunc; //opengl函数入口 QOpenGLFunctions_4_5_Compatibility* glFunc; //opengl函数入口
QOpenGLShaderProgram* shaderProgram; //着色器程序 QOpenGLShaderProgram* shaderProgram; //着色器程序
GLuint bvhSSBO, bvhBoundSSBO, elementSSBO;
/* 函数 */ /* 函数 */
PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model); PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model);
void draw() override; void draw() override;

View File

@ -9,7 +9,26 @@ in vec2 TexCoords;
in vec3 WorldPos; in vec3 WorldPos;
in vec3 Normal; in vec3 Normal;
layout(std430, binding = 1) buffer bvhBuffer
{
uint bvhLength;
uvec2 bvhChildren[];
};
layout(std430, binding = 2) buffer bvhBoundBuffer
{
vec4 bvhBound[];
};
layout(std430, binding = 3) buffer elementIndexBuffer
{
int elementCount;
int elementIndex[];
};
layout(std430, binding = 4) buffer elementBuffer
{
float elementData[];
};
const float PI = 3.14159265359;
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@ -139,6 +158,9 @@ float bezier_sd(vec2 uv, vec2 p0, vec2 p1, vec2 p2){
} }
float render_serif(vec2 uv){ float render_serif(vec2 uv){
uv.y-=.5; uv.y-=.5;
@ -153,100 +175,7 @@ float render_serif(vec2 uv){
float d1 = 1e38; float d1 = 1e38;
vec2 p0,p1,p2; vec2 p0,p1,p2;
/*
if(all(lessThan(abs(uv-vec2(-1.29705090246,0.49556210191)),vec2(0.203622751405,0.194877434267)+vec2(border)))){
d1=1e38;
d1=abs_min(d1,line_dist(uv,vec2(-1.50067365386,0.690439536177),vec2(-1.50067365386,0.662506649919)));
d1=abs_min(d1,line_dist(uv,vec2(-1.34847869375,0.690439536177),vec2(-1.50067365386,0.690439536177)));
d1=abs_min(d1,line_dist(uv,vec2(-1.34847869375,0.662506649919),vec2(-1.34847869375,0.690439536177)));
d1=abs_min(d1,line_dist(uv,vec2(-1.50067365386,0.662506649919),vec2(-1.34847869375,0.662506649919)));
if(d1<=0.){
return d1;
}
else{
poly_d=min(d1,poly_d);
}
d1=1e38;
d1=abs_min(d1,line_dist(uv,vec2(-1.50067365386,0.328356479174),vec2(-1.50067365386,0.300684667642)));
d1=abs_min(d1,line_dist(uv,vec2(-1.50067365386,0.300684667642),vec2(-1.34847869375,0.300684667642)));
d1=abs_min(d1,line_dist(uv,vec2(-1.34847869375,0.300684667642),vec2(-1.34847869375,0.328356479174)));
d1=abs_min(d1,line_dist(uv,vec2(-1.34847869375,0.328356479174),vec2(-1.50067365386,0.328356479174)));
if(d1<=0.){
return d1;
}
else{
poly_d=min(d1,poly_d);
}
d1=1e38;
d1=abs_min(d1,line_dist(uv,vec2(-1.24562309793,0.328356479174),vec2(-1.24562309793,0.300684667642)));
d1=abs_min(d1,line_dist(uv,vec2(-1.09342815105,0.328356479174),vec2(-1.24562309793,0.328356479174)));
d1=abs_min(d1,line_dist(uv,vec2(-1.09342815105,0.300684667642),vec2(-1.09342815105,0.328356479174)));
d1=abs_min(d1,line_dist(uv,vec2(-1.24562309793,0.300684667642),vec2(-1.09342815105,0.300684667642)));
if(d1<=0.){
return d1;
}
else{
poly_d=min(d1,poly_d);
}
d1=1e38;
d1=abs_min(d1,line_dist(uv,vec2(-1.24562309793,0.690439536177),vec2(-1.24562309793,0.662506649919)));
d1=abs_min(d1,line_dist(uv,vec2(-1.09342815105,0.690439536177),vec2(-1.24562309793,0.690439536177)));
d1=abs_min(d1,line_dist(uv,vec2(-1.09342815105,0.662506649919),vec2(-1.09342815105,0.690439536177)));
d1=abs_min(d1,line_dist(uv,vec2(-1.24562309793,0.662506649919),vec2(-1.09342815105,0.662506649919)));
if(d1<=0.){
return d1;
}
else{
poly_d=min(d1,poly_d);
}
d1=1e38;
d1=abs_min(d1,line_dist(uv,vec2(-1.45107323965,0.300684667642),vec2(-1.39807911127,0.300684667642)));
d1=abs_min(d1,line_dist(uv,vec2(-1.39807911127,0.300684667642),vec2(-1.39807911127,0.690439536177)));
d1=abs_min(d1,line_dist(uv,vec2(-1.39807911127,0.690439536177),vec2(-1.45107323965,0.690439536177)));
d1=abs_min(d1,line_dist(uv,vec2(-1.45107323965,0.690439536177),vec2(-1.45107323965,0.300684667642)));
if(d1<=0.){
return d1;
}
else{
poly_d=min(d1,poly_d);
}
d1=1e38;
d1=abs_min(d1,line_dist(uv,vec2(-1.45107323965,0.527802348895),vec2(-1.45107323965,0.495953672637)));
d1=abs_min(d1,line_dist(uv,vec2(-1.45107323965,0.495953672637),vec2(-1.14302855203,0.495953672637)));
d1=abs_min(d1,line_dist(uv,vec2(-1.14302855203,0.495953672637),vec2(-1.14302855203,0.527802348895)));
d1=abs_min(d1,line_dist(uv,vec2(-1.14302855203,0.527802348895),vec2(-1.45107323965,0.527802348895)));
if(d1<=0.){
return d1;
}
else{
poly_d=min(d1,poly_d);
}
d1=1e38;
d1=abs_min(d1,line_dist(uv,vec2(-1.19602268041,0.300684667642),vec2(-1.14302855203,0.300684667642)));
d1=abs_min(d1,line_dist(uv,vec2(-1.14302855203,0.300684667642),vec2(-1.14302855203,0.690439536177)));
d1=abs_min(d1,line_dist(uv,vec2(-1.14302855203,0.690439536177),vec2(-1.19602268041,0.690439536177)));
d1=abs_min(d1,line_dist(uv,vec2(-1.19602268041,0.690439536177),vec2(-1.19602268041,0.300684667642)));
if(d1<=0.){
return d1;
}
else{
poly_d=min(d1,poly_d);
}
}
*/
if(all(lessThan(abs(uv-vec2(-0.905207605282,0.43943531671)),vec2(0.131571631799,0.146321237064)+vec2(border)))){ if(all(lessThan(abs(uv-vec2(-0.905207605282,0.43943531671)),vec2(0.131571631799,0.146321237064)+vec2(border)))){
p0=vec2(-0.980652472562,0.432256320122);p1=vec2(-0.980652472562,0.376129514241);p2=vec2(-0.959444621888,0.347459653556); p0=vec2(-0.980652472562,0.432256320122);p1=vec2(-0.980652472562,0.376129514241);p2=vec2(-0.959444621888,0.347459653556);
if(tri_test(uv, p0, p1, p2, true)){ if(tri_test(uv, p0, p1, p2, true)){
@ -466,7 +395,7 @@ float render_serif(vec2 uv){
void mainImage( out vec4 fragColor, in vec2 fragCoord ){ void mainImage( out vec4 fragColor, in vec2 fragCoord ){
border = 0.0; border = 0.01;
vec2 uv = fragCoord.xy; vec2 uv = fragCoord.xy;
@ -478,14 +407,90 @@ void mainImage( out vec4 fragColor, in vec2 fragCoord ){
d=min(d,render_serif(uv)); d=min(d,render_serif(uv));
fragColor=vec4(smoothstep(0., 0.0, d)); //fragColor=vec4(smoothstep(0., border, d));
fragColor=vec4(vec3(d*10),1);
} }
const uint STACK_SIZE = 10;
struct Stack {
uint top;
uint data[STACK_SIZE];
bool empty() {
return top==0;
}
bool full() {
return top==STACK_SIZE;
}
bool getTop(out uint x) {
if(empty())
return false;
x = data[top-1];
return true;
}
bool pop() {
if(empty())
return false;
top--;
return true;
}
bool push(in uint x) {
if(full())
return false;
data[top]=x;
top++;
return true;
}
} stack;
void main() void main()
{ {
//gBaseColor = vec4(TexCoords,1,1); //gBaseColor = vec4(TexCoords,1,1);
//gBaseColor = vec4(240./255, 220./255,157./255,1); //gBaseColor = vec4(240./255, 220./255,157./255,1);
mainImage(gBaseColor, vec2(1.,1.)-TexCoords); //gBaseColor = vec4(bvh[0].bound==vec4(0,0,1,1));
vec2 uv = vec2(1.,1.)-TexCoords*2;
vec3 debugBVH=vec3(0);
stack.top=0;
uint index=0;
while(index<bvhLength||!stack.empty())
{
while (index<bvhLength)
{
vec4 bound = bvhBound[index];
uint leftChild = bvhChildren[index].x;
if(leftChild>=bvhLength)
{
float angle = float(bvhChildren[index].y)/4294967296.*2*PI;
mat2 rotation = {{cos(angle),-sin(angle)},{sin(angle),cos(angle)}};
vec2 localUV = uv-(bound.xy+bound.zw)/2;
localUV=rotation*localUV;
localUV/=(bound.zw-bound.xy)/2;
if(all(lessThan(vec2(-1), localUV))&&all(lessThan( localUV, vec2(1))))
debugBVH.bg+=0.5*(localUV+vec2(1));
index=bvhLength;
}
else if(all(lessThan(bound.xy, uv))&&all(lessThan( uv, bound.zw)))
{
debugBVH.r+=0.2;
stack.push(index);
index = leftChild;
}
else
index=bvhLength;
}
if (!stack.empty()) {
stack.getTop(index);
stack.pop();
index = bvhChildren[index].y;
}
}
gBaseColor = vec4( debugBVH,1 );
//mainImage(gBaseColor, vec2(1.,1.)-TexCoords);
gPosition = WorldPos; gPosition = WorldPos;
gNormal = normalize(Normal); gNormal = normalize(Normal);
//gMetallicRoughness = vec2(1, 46./255); //gMetallicRoughness = vec2(1, 46./255);

View File

@ -1,6 +1,10 @@
#include "MainWindow.h" #include "MainWindow.h"
#include <QtWidgets/QApplication> #include <QtWidgets/QApplication>
extern "C" {
_declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001;
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);