diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj
index 036489e..a28e3b0 100644
--- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj
+++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj
@@ -106,6 +106,8 @@
+
+
diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters
index 280e1a9..bda151c 100644
--- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters
+++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters
@@ -98,6 +98,12 @@
Resource Files\Shaders
+
+ Resource Files\Shaders
+
+
+ Resource Files\Shaders
+
diff --git a/ArchitectureColoredPainting/Drawable.h b/ArchitectureColoredPainting/Drawable.h
index 0a4c784..583cf17 100644
--- a/ArchitectureColoredPainting/Drawable.h
+++ b/ArchitectureColoredPainting/Drawable.h
@@ -3,5 +3,6 @@ class Drawable
{
public:
virtual void draw() = 0;
+ virtual void drawShadow() = 0;
};
diff --git a/ArchitectureColoredPainting/MainWindow.qrc b/ArchitectureColoredPainting/MainWindow.qrc
index fc1c47d..81f0012 100644
--- a/ArchitectureColoredPainting/MainWindow.qrc
+++ b/ArchitectureColoredPainting/MainWindow.qrc
@@ -10,5 +10,7 @@
Shaders/painting.frag
Shaders/painting.vert
Shaders/painting.comp
+ Shaders/model_shadow.frag
+ Shaders/model_shadow.vert
diff --git a/ArchitectureColoredPainting/Mesh.cpp b/ArchitectureColoredPainting/Mesh.cpp
index 39fc7d7..fb8531d 100644
--- a/ArchitectureColoredPainting/Mesh.cpp
+++ b/ArchitectureColoredPainting/Mesh.cpp
@@ -1,8 +1,9 @@
#include "Mesh.h"
-Mesh::Mesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model)
+Mesh::Mesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* shadowProgram, aiMatrix4x4 model)
: glFunc(glFunc)
, shaderProgram(shaderProgram)
+ , shadowProgram(shadowProgram)
, VBO(QOpenGLBuffer::VertexBuffer)
, EBO(QOpenGLBuffer::IndexBuffer)
, model((float*)&model)
@@ -26,8 +27,6 @@ void Mesh::draw()
for (unsigned int i = 0; i < textures.size(); i++)
{
glFunc->glActiveTexture(GL_TEXTURE0 + i); // 在绑定之前激活相应的纹理单元
-
-
textures[i]->texture.bind();
//qDebug() << name + number;
shaderProgram->setUniformValue(textures[i]->type.toStdString().c_str(), i);
@@ -40,6 +39,30 @@ void Mesh::draw()
shaderProgram->release();
}
+void Mesh::drawShadow()
+{
+ shadowProgram->bind();
+
+ unsigned int diffuseNr = 1;
+ unsigned int specularNr = 1;
+ unsigned int normalNr = 1;
+ unsigned int heightNr = 1;
+
+ for (unsigned int i = 0; i < textures.size(); i++)
+ {
+ glFunc->glActiveTexture(GL_TEXTURE0 + i); // 在绑定之前激活相应的纹理单元
+ textures[i]->texture.bind();
+ //qDebug() << name + number;
+ shadowProgram->setUniformValue(textures[i]->type.toStdString().c_str(), i);
+ }
+ // 绘制网格
+
+ QOpenGLVertexArrayObject::Binder bind(&VAO);
+ shadowProgram->setUniformValue("model", model);
+ glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
+
+ shadowProgram->release();
+}
void Mesh::setupMesh()
{
shaderProgram->bind();
diff --git a/ArchitectureColoredPainting/Mesh.h b/ArchitectureColoredPainting/Mesh.h
index 3103c50..a67214d 100644
--- a/ArchitectureColoredPainting/Mesh.h
+++ b/ArchitectureColoredPainting/Mesh.h
@@ -16,45 +16,46 @@
struct Vertex
{
- QVector3D Position;
- QVector3D Normal;
- QVector2D TexCoords;
- QVector3D Tangent;
- QVector3D Bitangent;
+ QVector3D Position;
+ QVector3D Normal;
+ QVector2D TexCoords;
+ QVector3D Tangent;
+ QVector3D Bitangent;
};
struct Texture
{
- QOpenGLTexture texture;
- QString type;
- QString path;
- Texture() :texture(QOpenGLTexture::Target2D) {
- texture.create();
- texture.setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat);
- texture.setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat);
- texture.setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear);
- }
+ QOpenGLTexture texture;
+ QString type;
+ QString path;
+ Texture() :texture(QOpenGLTexture::Target2D) {
+ texture.create();
+ texture.setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat);
+ texture.setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat);
+ texture.setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear);
+ }
};
class Mesh : public Drawable
{
public:
- /* 网格数据 */
- QVector vertices; //顶点数据
- QVector indices; //索引数组
- QVector textures; //纹理数据
- QMatrix4x4 model; //模型矩阵
- QOpenGLFunctions_4_5_Compatibility* glFunc; //opengl函数入口
- QOpenGLShaderProgram* shaderProgram; //着色器程序
+ /* 网格数据 */
+ QVector vertices; //顶点数据
+ QVector indices; //索引数组
+ QVector textures; //纹理数据
+ QMatrix4x4 model; //模型矩阵
+ QOpenGLFunctions_4_5_Compatibility* glFunc; //opengl函数入口
+ QOpenGLShaderProgram* shaderProgram, * shadowProgram; //着色器程序
- /* 函数 */
- Mesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model);
- void draw() override;
- void setupMesh();
+ /* 函数 */
+ Mesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* shadowProgram, aiMatrix4x4 model);
+ void draw() override;
+ void drawShadow() override;
+ void setupMesh();
private:
- /* 渲染数据 */
- QOpenGLVertexArrayObject VAO;
- QOpenGLBuffer VBO, EBO;
+ /* 渲染数据 */
+ QOpenGLVertexArrayObject VAO;
+ QOpenGLBuffer VBO, EBO;
};
diff --git a/ArchitectureColoredPainting/Model.cpp b/ArchitectureColoredPainting/Model.cpp
index 7ed80a3..b12f0e2 100644
--- a/ArchitectureColoredPainting/Model.cpp
+++ b/ArchitectureColoredPainting/Model.cpp
@@ -30,11 +30,12 @@ Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shader
processNode(scene->mRootNode, scene);
}
-Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram, PaintingHelper* paintingHelper)
+Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram, QOpenGLShaderProgram* shadowProgram, PaintingHelper* paintingHelper)
: context(context)
, glFunc(context->versionFunctions())
, shaderProgram(shaderProgram)
, paintingProgram(paintingProgram)
+ , shadowProgram(shadowProgram)
, paintingHelper(paintingHelper)
, directory(path)
{
@@ -71,6 +72,13 @@ void Model::draw() {
}
}
+void Model::drawShadow() {
+ //shaderProgram->bind();
+ for (Drawable* mesh : meshes) {
+ mesh->drawShadow();
+ }
+}
+
void Model::destroy()
{
context->doneCurrent();
@@ -109,7 +117,7 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
{
qDebug() << str.C_Str() << "Replaced";
// 初始化网格
- PaintingMesh* m_mesh = new PaintingMesh(glFunc, paintingProgram, model);
+ PaintingMesh* m_mesh = new PaintingMesh(glFunc, paintingProgram, shadowProgram, model);
// 遍历网格的每个顶点
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
{
@@ -258,7 +266,7 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
else
{
// 初始化网格
- Mesh* m_mesh = new Mesh(glFunc, shaderProgram, model);
+ Mesh* m_mesh = new Mesh(glFunc, shaderProgram, shadowProgram, model);
// 遍历网格的每个顶点
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
{
diff --git a/ArchitectureColoredPainting/Model.h b/ArchitectureColoredPainting/Model.h
index 818e186..9272465 100644
--- a/ArchitectureColoredPainting/Model.h
+++ b/ArchitectureColoredPainting/Model.h
@@ -9,9 +9,10 @@ class Model
{
public:
void draw();
+ void drawShadow();
void destroy();
static Model* createModel(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram);
- Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram, PaintingHelper* paintingHelper);
+ Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram, QOpenGLShaderProgram* shadowProgram, PaintingHelper* paintingHelper);
private:
Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram);
@@ -20,6 +21,7 @@ private:
QOpenGLFunctions_4_5_Compatibility* glFunc;
QOpenGLShaderProgram* shaderProgram = nullptr;
QOpenGLShaderProgram* paintingProgram = nullptr; //彩绘着色器程序
+ QOpenGLShaderProgram* shadowProgram = nullptr;
PaintingHelper* paintingHelper = nullptr;
/* 模型数据 */
diff --git a/ArchitectureColoredPainting/PaintingMesh.cpp b/ArchitectureColoredPainting/PaintingMesh.cpp
index 56ad12d..5bc960c 100644
--- a/ArchitectureColoredPainting/PaintingMesh.cpp
+++ b/ArchitectureColoredPainting/PaintingMesh.cpp
@@ -1,8 +1,9 @@
#include "PaintingMesh.h"
-PaintingMesh::PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model)
+PaintingMesh::PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* shadowProgram, aiMatrix4x4 model)
: glFunc(glFunc)
, shaderProgram(shaderProgram)
+ , shadowProgram(shadowProgram)
, VBO(QOpenGLBuffer::VertexBuffer)
, EBO(QOpenGLBuffer::IndexBuffer)
, model((float*)&model)
@@ -10,14 +11,21 @@ PaintingMesh::PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLSh
}
void PaintingMesh::draw()
{
-
shaderProgram->bind();
QOpenGLVertexArrayObject::Binder bind(&VAO);
shaderProgram->setUniformValue("model", model);
glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
- glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
+
shaderProgram->release();
}
+void PaintingMesh::drawShadow()
+{
+ shadowProgram->bind();
+ QOpenGLVertexArrayObject::Binder bind(&VAO);
+ shadowProgram->setUniformValue("model", model);
+ glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
+ shadowProgram->release();
+}
void PaintingMesh::setupMesh()
{
shaderProgram->bind();
diff --git a/ArchitectureColoredPainting/PaintingMesh.h b/ArchitectureColoredPainting/PaintingMesh.h
index eae18ce..348d97d 100644
--- a/ArchitectureColoredPainting/PaintingMesh.h
+++ b/ArchitectureColoredPainting/PaintingMesh.h
@@ -32,11 +32,12 @@ public:
QVector indices; //索引数组
QMatrix4x4 model; //模型矩阵
QOpenGLFunctions_4_5_Compatibility* glFunc; //opengl函数入口
- QOpenGLShaderProgram* shaderProgram; //着色器程序
+ QOpenGLShaderProgram* shaderProgram, * shadowProgram; //着色器程序
GLuint paintingIndex;
/* 函数 */
- PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model);
+ PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* shadowProgram, aiMatrix4x4 model);
void draw() override;
+ void drawShadow() override;
void setupMesh();
private:
diff --git a/ArchitectureColoredPainting/RendererWidget.cpp b/ArchitectureColoredPainting/RendererWidget.cpp
index b79b8ec..fcace69 100644
--- a/ArchitectureColoredPainting/RendererWidget.cpp
+++ b/ArchitectureColoredPainting/RendererWidget.cpp
@@ -49,6 +49,14 @@ void RendererWidget::initializeGL()
glEnable(GL_DEPTH_TEST);
glClearColor(0, 0, 0, 1);
+ shadowProgramPtr = new QOpenGLShaderProgram;
+ if (!shadowProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/model_shadow.vert"))
+ qDebug() << "ERROR:" << shadowProgramPtr->log();
+ if (!shadowProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/model_shadow.frag"))
+ qDebug() << "ERROR:" << shadowProgramPtr->log();
+ if (!shadowProgramPtr->link())
+ qDebug() << "ERROR:" << shadowProgramPtr->log();
+
modelProgramPtr = new QOpenGLShaderProgram;
if (!modelProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/model.vert"))
qDebug() << "ERROR:" << modelProgramPtr->log();
@@ -85,15 +93,16 @@ void RendererWidget::initializeGL()
finalProgramPtr->setUniformValue("gNormal", 1);
finalProgramPtr->setUniformValue("gPosition", 2);
finalProgramPtr->setUniformValue("gMetallicRoughness", 3);
+ finalProgramPtr->setUniformValue("gShadowMap", 4);
finalProgramPtr->release();
-
+
paintingHelper = new PaintingHelper(QOpenGLContext::currentContext()->versionFunctions());
- model = new Model("Models/Sponza/Sponza.gltf", context(), modelProgramPtr, paintingProgramPtr, paintingHelper);
+ model = new Model("Models/Sponza/Sponza.gltf", context(), modelProgramPtr, paintingProgramPtr, shadowProgramPtr, paintingHelper);
+
-
paintingHelper->allocateBuffers();
paintingCompProgramPtr->bind();
paintingHelper->bindPaintingBuffers();
@@ -127,13 +136,37 @@ void RendererWidget::initializeGL()
}
-QVector3D lightPositions[] = { QVector3D(0,0,0), QVector3D(100,100,100) ,QVector3D(-100,100,100) ,QVector3D(100,100,-100) };
-QVector3D lightColors[] = { QVector3D(150000,150000,130000), QVector3D(0,0,0) ,QVector3D(0,0,0) ,QVector3D(0,0,0) };
+QVector3D lightPositions[] = { 2000 * QVector3D(0.2, 4, 1).normalized(), QVector3D(100,100,100) ,QVector3D(-100,100,100) ,QVector3D(100,100,-100) };
+QVector3D lightColors[] = { 10000000 * QVector3D(0.7529,0.7450,0.6784).normalized(), QVector3D(0,0,0) ,QVector3D(0,0,0) ,QVector3D(0,0,0) };
+static float sunPitch = 90, sunYaw = 80;
void RendererWidget::paintGL()
{
+ QMatrix4x4 lightProjection;
+ lightProjection.ortho(-1200.0f, 1200.0f, -900.0f, 900.0f, 100.f, 5000.0f);
+
+ lightPositions[0].setX(cos(qDegreesToRadians(sunPitch)) * cos(qDegreesToRadians(sunYaw)));
+ lightPositions[0].setY(sin(qDegreesToRadians(sunPitch)));
+ lightPositions[0].setZ(cos(qDegreesToRadians(sunPitch)) * sin(qDegreesToRadians(sunYaw)));
+ lightPositions[0] *= 2000;
+ QMatrix4x4 lightView;
+ lightView.lookAt(lightPositions[0], QVector3D(0, 0, 0), QVector3D(0, 1, 0));
+ if (shadowFboPtr->bind())
+ {
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glViewport(0, 0, shadowMapResolution, shadowMapResolution);
+ shadowProgramPtr->bind();
+ shadowProgramPtr->setUniformValue("projection", lightProjection);
+ shadowProgramPtr->setUniformValue("view", lightView);
+ shadowProgramPtr->release();
+
+ model->drawShadow();
+ shadowFboPtr->release();
+ }
+
if (fboPtr->bind())
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glViewport(0, 0, frameWidth, frameHeight);
QMatrix4x4 projection;
projection.perspective(camera.Zoom, (float)width() / (float)height(), 10.f, 10000.0f);
QMatrix4x4 view = camera.GetViewMatrix();
@@ -156,19 +189,21 @@ void RendererWidget::paintGL()
glBindImageTexture(0, gbuffers[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
glBindImageTexture(1, gbuffers[3], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG8);
glBindImageTexture(2, gbuffers[4], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R16UI);
- glBindImageTexture(3, gbuffers[5], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG16F);
-
+ glBindImageTexture(3, gbuffers[5], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG32F);
+
glDispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1);
//glDispatchCompute(1,1, 1);
//QOpenGLFramebufferObject::blitFramebuffer(nullptr, QRect(0, 0, 2*width(), 2*height()), fboPtr, QRect(0, 0, 1156, 756));
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glViewport(0, 0, frameWidth, frameHeight);
QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO);
finalProgramPtr->bind();
finalProgramPtr->setUniformValue("camPos", camera.Position);
- lightPositions[0] = camera.Position;
+ finalProgramPtr->setUniformValue("lightSpaceMatrix", lightProjection * lightView);
+ //lightPositions[0] = camera.Position;
finalProgramPtr->setUniformValueArray("lightPositions", lightPositions, 4);
finalProgramPtr->setUniformValueArray("lightColors", lightColors, 4);
@@ -181,6 +216,8 @@ void RendererWidget::paintGL()
glBindTexture(GL_TEXTURE_2D, gbuffers[2]);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, gbuffers[3]);
+ glActiveTexture(GL_TEXTURE4);
+ glBindTexture(GL_TEXTURE_2D, shadowGbuffers[3]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
finalProgramPtr->release();
}
@@ -192,6 +229,7 @@ void RendererWidget::resizeGL(int width, int height)
qDebug() << frameWidth << "x" << frameHeight;
//qDebug() << devicePixelRatioF() << width << height;
//glViewport(0, 0, (GLint)devicePixelRatio()*width, (GLint)devicePixelRatio()*height);
+
if (fboPtr != nullptr)
delete fboPtr;
fboPtr = new QOpenGLFramebufferObject(frameWidth, frameHeight, QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D);
@@ -202,36 +240,38 @@ void RendererWidget::resizeGL(int width, int height)
fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RG8);
fboPtr->addColorAttachment(frameWidth, frameHeight, GL_R16F);
fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RG16F);*/
-
+
+ //BaseColor
gbuffers[0] = fboPtr->texture();
- glGenTextures(5, gbuffers+1);
+ glGenTextures(5, gbuffers + 1);
+ //Normal
glBindTexture(GL_TEXTURE_2D, gbuffers[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gbuffers[1], 0);
-
+ //Position
glBindTexture(GL_TEXTURE_2D, gbuffers[2]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gbuffers[2], 0);
-
+ //MetallicRoughness
glBindTexture(GL_TEXTURE_2D, gbuffers[3]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, frameWidth, frameHeight, 0, GL_RG, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, gbuffers[3], 0);
-
+ //gPaintingIndex
glBindTexture(GL_TEXTURE_2D, gbuffers[4]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, frameWidth, frameHeight, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, gbuffers[4], 0);
-
+ //PaintingTexCoord
glBindTexture(GL_TEXTURE_2D, gbuffers[5]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16F, frameWidth, frameHeight, 0, GL_RG, GL_FLOAT, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, frameWidth, frameHeight, 0, GL_RG, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, GL_TEXTURE_2D, gbuffers[5], 0);
@@ -239,10 +279,54 @@ void RendererWidget::resizeGL(int width, int height)
GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5 };
glDrawBuffers(6, attachments);
//gbuffers = fboPtr->textures();
-
+
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+ qDebug() << "Framebuffer not complete!";
fboPtr->release();
}
+ if (shadowFboPtr != nullptr)
+ delete shadowFboPtr;
+
+ shadowMapResolution = 1 * std::max(frameWidth, frameHeight);
+ shadowFboPtr = new QOpenGLFramebufferObject(shadowMapResolution, shadowMapResolution);
+
+ if (shadowFboPtr->bind())
+ {
+
+ shadowGbuffers[0] = shadowFboPtr->texture();
+
+ glGenTextures(3, shadowGbuffers + 1);
+ //Normal
+ glBindTexture(GL_TEXTURE_2D, shadowGbuffers[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, shadowMapResolution, shadowMapResolution, 0, GL_RGB, GL_FLOAT, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, shadowGbuffers[1], 0);
+ //Position
+ glBindTexture(GL_TEXTURE_2D, shadowGbuffers[2]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, shadowMapResolution, shadowMapResolution, 0, GL_RGB, GL_FLOAT, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, shadowGbuffers[2], 0);
+ //Depth
+ glBindTexture(GL_TEXTURE_2D, shadowGbuffers[3]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32,
+ shadowMapResolution, shadowMapResolution, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadowGbuffers[3], 0);
+
+ GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
+ glDrawBuffers(3, attachments);
+
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+ qDebug() << "ShadowFramebuffer not complete!";
+ shadowFboPtr->release();
+ }
+
std::cout << "\033[?25l";
}
@@ -259,8 +343,8 @@ void RendererWidget::timerEvent(QTimerEvent* event)
frameCnt++;
if (accTime > 1.)
{
- std::cout << " \r";
- std::cout << "FPS: " << frameCnt / accTime << "\r";
+ std::cout << " \r";
+ std::cout << "FPS: " << frameCnt / accTime << " " << camera.Position.x() << " " << camera.Position.y() << " " << camera.Position.z() << "\r";
accTime = 0;
frameCnt = 0;
}
@@ -293,6 +377,15 @@ void RendererWidget::timerEvent(QTimerEvent* event)
if (pressedKeys.contains(Qt::Key_Space)) {
camera.ProcessKeyboard(UP, deltaTime);
}
+
+ static int sunSpeed = 10;
+ sunPitch += sunSpeed * deltaTime ;
+ if (sunPitch > 120 || sunPitch < 65)
+ {
+ sunSpeed = -sunSpeed;
+ sunPitch += sunSpeed * deltaTime;
+ }
+
repaint();
}
diff --git a/ArchitectureColoredPainting/RendererWidget.h b/ArchitectureColoredPainting/RendererWidget.h
index ba9d389..ce3ad52 100644
--- a/ArchitectureColoredPainting/RendererWidget.h
+++ b/ArchitectureColoredPainting/RendererWidget.h
@@ -35,12 +35,16 @@ private:
Camera camera;
clock_t lastFrame;
float deltaTime;
+ int shadowMapResolution;
+ QOpenGLShaderProgram* shadowProgramPtr = nullptr;
QOpenGLShaderProgram* modelProgramPtr = nullptr;
QOpenGLShaderProgram* paintingProgramPtr = nullptr;
QOpenGLShaderProgram* paintingCompProgramPtr = nullptr;
QOpenGLShaderProgram* finalProgramPtr = nullptr;
QOpenGLFramebufferObject* fboPtr = nullptr;
+ QOpenGLFramebufferObject* shadowFboPtr = nullptr;
GLuint gbuffers[6];
+ GLuint shadowGbuffers[4];
QOpenGLBuffer quadVBO;
QOpenGLVertexArrayObject quadVAO;
Model* model;
diff --git a/ArchitectureColoredPainting/Shaders/final.frag b/ArchitectureColoredPainting/Shaders/final.frag
index f0df30b..485922e 100644
--- a/ArchitectureColoredPainting/Shaders/final.frag
+++ b/ArchitectureColoredPainting/Shaders/final.frag
@@ -8,10 +8,12 @@ uniform sampler2D gBaseColor;
uniform sampler2D gNormal;
uniform sampler2D gPosition;
uniform sampler2D gMetallicRoughness;
+uniform sampler2D gShadowMap;
// lights
uniform vec3 lightPositions[4];
uniform vec3 lightColors[4];
+uniform mat4 lightSpaceMatrix;
uniform vec3 camPos;
@@ -19,95 +21,161 @@ const float PI = 3.14159265359;
float DistributionGGX(vec3 N, vec3 H, float roughness)
{
- float a = roughness*roughness;
- float a2 = a*a;
- float NdotH = max(dot(N, H), 0.0);
- float NdotH2 = NdotH*NdotH;
+ float a = roughness*roughness;
+ float a2 = a*a;
+ float NdotH = max(dot(N, H), 0.0);
+ float NdotH2 = NdotH*NdotH;
- float nom = a2;
- float denom = (NdotH2 * (a2 - 1.0) + 1.0);
- denom = PI * denom * denom;
+ float nom = a2;
+ float denom = (NdotH2 * (a2 - 1.0) + 1.0);
+ denom = PI * denom * denom;
- return nom / denom;
+ return nom / denom;
}
// ----------------------------------------------------------------------------
float GeometrySchlickGGX(float NdotV, float roughness)
{
- float r = (roughness + 1.0);
- float k = (r*r) / 8.0;
+ float r = (roughness + 1.0);
+ float k = (r*r) / 8.0;
- float nom = NdotV;
- float denom = NdotV * (1.0 - k) + k;
+ float nom = NdotV;
+ float denom = NdotV * (1.0 - k) + k;
- return nom / denom;
+ return nom / denom;
}
// ----------------------------------------------------------------------------
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
{
- float NdotV = max(dot(N, V), 0.0);
- float NdotL = max(dot(N, L), 0.0);
- float ggx2 = GeometrySchlickGGX(NdotV, roughness);
- float ggx1 = GeometrySchlickGGX(NdotL, roughness);
+ float NdotV = max(dot(N, V), 0.0);
+ float NdotL = max(dot(N, L), 0.0);
+ float ggx2 = GeometrySchlickGGX(NdotV, roughness);
+ float ggx1 = GeometrySchlickGGX(NdotL, roughness);
- return ggx1 * ggx2;
+ return ggx1 * ggx2;
}
// ----------------------------------------------------------------------------
vec3 fresnelSchlick(float cosTheta, vec3 F0)
{
- return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
+ return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
}
+
+float Calculate_Avg_Dblockreceiver(vec2 projCoords , int AvgTextureSize)
+{
+ vec2 texelSize =1.0/ textureSize(gShadowMap, 0);
+ float result=0.0f;
+ for(int i=-AvgTextureSize;i<=AvgTextureSize;++i)
+ {
+ for(int j=-AvgTextureSize;j<=AvgTextureSize;j++)
+ {
+ result += texture(gShadowMap, projCoords+vec2(i,j)*texelSize).r;
+ }
+ }
+ return result/(AvgTextureSize*AvgTextureSize*2*2);
+}
+
+float ShadowCalculation(vec4 fragPosLightSpace, float bias)
+{
+ // 执行透视除法
+ vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
+ // 变换到[0,1]的范围
+ projCoords = projCoords * 0.5 + 0.5;
+ // 取得最近点的深度(使用[0,1]范围下的fragPosLight当坐标)
+ float closestDepth = texture(gShadowMap, projCoords.xy).r;
+ // 取得当前片段在光源视角下的深度
+ float currentDepth = projCoords.z;
+
+ vec2 texelSize = 1.0 / textureSize(gShadowMap, 0);
+ float shadow = 0;
+
+ // 检查当前片段是否在阴影中
+ //float shadow = 0;// currentDepth - bias > closestDepth ? 1.0 : 0.0;
+ float fliterArea = 7;
+ int fliterSingleX = int(fliterArea/2);
+
+ for(int i=-fliterSingleX;i<=fliterSingleX;++i)
+ {
+ for(int j=-fliterSingleX;j<=fliterSingleX;j++)
+ {
+ // 采样周围点在ShadowMap中的深度
+ float closestDepth = texture(gShadowMap, projCoords.xy+vec2(i,j)*texelSize).r;
+ shadow += (currentDepth - bias) > closestDepth ? 1.0 : 0.0;
+ }
+ }
+
+ return shadow/(fliterArea*fliterArea);
+ //return clamp(shadow/(fliterArea*fliterArea),0.,1.);
+
+}
+
void main()
{
- vec3 albedo = pow(texture(gBaseColor, TexCoords).rgb, vec3(2.2));
- float metallic = texture(gMetallicRoughness, TexCoords).r;
- float roughness = texture(gMetallicRoughness, TexCoords).g;
+ vec3 albedo = pow(texture(gBaseColor, TexCoords).rgb, vec3(2.2));
+ float metallic = texture(gMetallicRoughness, TexCoords).r;
+ float roughness = texture(gMetallicRoughness, TexCoords).g;
+
+ vec3 N = normalize(texture(gNormal, TexCoords).xyz);
+ vec3 WorldPos = texture(gPosition, TexCoords).xyz;
- vec3 N = normalize(texture(gNormal, TexCoords).xyz);
- vec3 WorldPos = texture(gPosition, TexCoords).xyz;
- vec3 V = normalize(camPos - WorldPos);
+ if(WorldPos==vec3(0))
+ {
+ vec3 color = lightColors[0];
- vec3 F0 = vec3(0.04);
- F0 = mix(F0, albedo, metallic);
+ color = color / (color + vec3(1.0));
+ color = pow(color, vec3(1.0/2.2));
- // reflectance equation
- vec3 Lo = vec3(0.0);
- for(int i = 0; i < 1; ++i)
- {
- // calculate per-light radiance
- vec3 L = normalize(lightPositions[i] - WorldPos);
- vec3 H = normalize(V + L);
- float distance = length(lightPositions[i] - WorldPos);
- float attenuation = 1.0 / (distance * distance);
- vec3 radiance = lightColors[i] * attenuation;
+ FragColor = vec4(color, 1.0);
+ return;
+ }
- // cook-torrance brdf
- float NDF = DistributionGGX(N, H, roughness);
- float G = GeometrySmith(N, V, L, roughness);
- vec3 F = fresnelSchlick(clamp(dot(H, V),0.,1.), F0);
- //F = clamp(F,vec3(0),vec3(1));
+ vec4 FragPosLightSpace = lightSpaceMatrix * vec4(WorldPos, 1.0);
- vec3 kS = F;
- vec3 kD = vec3(1.0) - kS;
- kD *= 1.0 - metallic;
+ vec3 V = normalize(camPos - WorldPos);
- vec3 nominator = NDF * G * F;
- float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.001;
- vec3 specular = nominator / denominator;
+ vec3 F0 = vec3(0.04);
+ F0 = mix(F0, albedo, metallic);
- // add to outgoing radiance Lo
- float NdotL = max(dot(N, L), 0.0);
- Lo += (kD * albedo / PI + specular) * radiance * NdotL;
-
- }
+ // reflectance equation
+ vec3 Lo = vec3(0.0);
- vec3 ambient = vec3(0.03) * albedo;
- vec3 color = ambient + Lo;
+ int i = 0;
+ // calculate per-light radiance
+ vec3 L = normalize(lightPositions[i] - WorldPos);
+ vec3 H = normalize(V + L);
+ float distance = length(lightPositions[i] - WorldPos);
+ float attenuation = 1.0 / (distance * distance);
+ vec3 radiance = lightColors[i] * attenuation;
- color = color / (color + vec3(1.0));
- color = pow(color, vec3(1.0/2.2));
+ // cook-torrance brdf
+ float NDF = DistributionGGX(N, H, roughness);
+ float G = GeometrySmith(N, V, L, roughness);
+ vec3 F = fresnelSchlick(clamp(dot(H, V),0.,1.), F0);
+ //F = clamp(F,vec3(0),vec3(1));
- FragColor = vec4(color, 1.0);
- //FragColor = vec4(texture(gPainting, TexCoords).rgb, 1.0);
+ vec3 kS = F;
+ vec3 kD = vec3(1.0) - kS;
+ kD *= 1.0 - metallic;
+
+ vec3 nominator = NDF * G * F;
+ float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.001;
+ vec3 specular = nominator / denominator;
+
+ // add to outgoing radiance Lo
+ float NdotL = max(dot(N, L), 0.0);
+ Lo += (kD * albedo / PI + specular) * radiance * NdotL;
+
+ vec3 ambient = vec3(0.03) * albedo;
+
+ float bias = 0.08 * max(0.05 * (1.0 - dot(N, L)), 0.005);
+ float shadow = ShadowCalculation(FragPosLightSpace, bias);
+ //vec3 color = ambient + Lo;
+ vec3 color = ambient + (1.0 - shadow) * Lo;
+
+ color = color / (color + vec3(1.0));
+ color = pow(color, vec3(1.0/2.2));
+
+ FragColor = vec4(color, 1.0);
+ //FragColor = vec4(vec3(shadow), 1);
+ //FragColor = vec4(texture(gShadowMap, TexCoords).rgb, 1.0);
}
\ No newline at end of file
diff --git a/ArchitectureColoredPainting/Shaders/model.vert b/ArchitectureColoredPainting/Shaders/model.vert
index f294dc6..0306efb 100644
--- a/ArchitectureColoredPainting/Shaders/model.vert
+++ b/ArchitectureColoredPainting/Shaders/model.vert
@@ -6,11 +6,11 @@ layout (location = 2) in vec2 aTexCoords;
out vec2 TexCoords;
out vec3 WorldPos;
out vec3 Normal;
-
+
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
-
+
void main()
{
TexCoords = aTexCoords;
@@ -19,4 +19,5 @@ void main()
gl_Position = projection * view * vec4(WorldPos, 1.0);
+
}
\ No newline at end of file
diff --git a/ArchitectureColoredPainting/Shaders/model_shadow.frag b/ArchitectureColoredPainting/Shaders/model_shadow.frag
new file mode 100644
index 0000000..3040bd4
--- /dev/null
+++ b/ArchitectureColoredPainting/Shaders/model_shadow.frag
@@ -0,0 +1,42 @@
+#version 450 core
+
+
+uniform sampler2D texture_basecolor;
+uniform sampler2D texture_metallic_roughness;
+uniform sampler2D texture_normal;
+
+layout (location = 0) out vec4 gBaseColor;
+layout (location = 1) out vec3 gNormal;
+layout (location = 2) out vec3 gPosition;
+
+in vec2 TexCoords;
+in vec3 WorldPos;
+in vec3 Normal;
+
+vec3 getNormalFromMap()
+{
+ vec3 tangentNormal = texture(texture_normal, TexCoords).xyz * 2.0 - 1.0;
+
+ vec3 Q1 = dFdx(WorldPos);
+ vec3 Q2 = dFdy(WorldPos);
+ vec2 st1 = dFdx(TexCoords);
+ vec2 st2 = dFdy(TexCoords);
+
+ vec3 N = normalize(Normal);
+ vec3 T = normalize(Q1*st2.t - Q2*st1.t);
+ vec3 B = -normalize(cross(N, T));
+ mat3 TBN = mat3(T, B, N);
+
+ return normalize(TBN * tangentNormal);
+}
+
+void main()
+{
+ //gBaseColor = vec4(1,0,0,1);
+ gBaseColor = texture(texture_basecolor, TexCoords);
+ if(gBaseColor.a<0.4)
+ discard;
+ gPosition = WorldPos;
+ gNormal = getNormalFromMap();
+
+}
\ No newline at end of file
diff --git a/ArchitectureColoredPainting/Shaders/model_shadow.vert b/ArchitectureColoredPainting/Shaders/model_shadow.vert
new file mode 100644
index 0000000..8f4a748
--- /dev/null
+++ b/ArchitectureColoredPainting/Shaders/model_shadow.vert
@@ -0,0 +1,21 @@
+#version 450 core
+layout (location = 0) in vec3 aPos;
+layout (location = 1) in vec3 aNormal;
+layout (location = 2) in vec2 aTexCoords;
+
+out vec2 TexCoords;
+out vec3 WorldPos;
+out vec3 Normal;
+
+uniform mat4 model;
+uniform mat4 view;
+uniform mat4 projection;
+
+void main()
+{
+ TexCoords = aTexCoords;
+ WorldPos = vec3(model * vec4(aPos, 1.0));
+ Normal = mat3(model) * aNormal;
+
+ gl_Position = projection * view * vec4(WorldPos, 1.0);
+}
\ No newline at end of file
diff --git a/ArchitectureColoredPainting/Shaders/painting.comp b/ArchitectureColoredPainting/Shaders/painting.comp
index 2037d52..50dc9c6 100644
--- a/ArchitectureColoredPainting/Shaders/painting.comp
+++ b/ArchitectureColoredPainting/Shaders/painting.comp
@@ -5,7 +5,7 @@ layout (local_size_x = 8, local_size_y = 8) in;
layout(rgba8, binding = 0) uniform image2D gBaseColor;
layout(rg8, binding = 1) uniform image2D gMetallicRoughness;
layout(r16ui, binding = 2) uniform uimage2D gPaintingIndex;
-layout(rg16f, binding = 3) uniform image2D gPaintingTexCoord;
+layout(rg32f, binding = 3) uniform image2D gPaintingTexCoord;
layout(std430, binding = 1) buffer paintingOffsetBuffer
{
diff --git a/README.md b/README.md
index a3fe430..a92cd3f 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
vs2022椤圭洰 qt5.15.2 msvc 2019 64-bit
-閲囩敤pbr鏉愯川锛岀幇鍦ㄦ湁涓涓厜婧愬拰鎽勫儚鏈虹粦瀹氾紝瓒充互鍒嗚鲸鍑轰笉鍚屾潗璐ㄧ殑鏁堟灉
+閲囩敤pbr鏉愯川锛岀幇鍦ㄦ湁涓涓殢鏃堕棿鍙樺寲鐨勬柟鍚戝厜骞舵坊鍔犱簡闃村奖
鎶婁竴鍧楀竷鏇挎崲鎴愪簡锛堝緟瀹屾垚鐨勶級褰╃粯绠$嚎锛岃PaintingMesh绫讳互鍙妏ainting鐫鑹插櫒
@@ -12,4 +12,6 @@ TODO锛
- [x] 鎸囧畾涓鍧楁潗璐ㄤ娇鐢ㄧ嫭绔嬬绾胯繘琛岀汗鐞嗛噰鏍
-- [ ] 褰╃粯鐨勮〃绀恒佽鍙栥侀噰鏍...
\ No newline at end of file
+- [ ] 褰╃粯鐨勮〃绀恒佽鍙栥侀噰鏍...
+
+- [x] PCF Shadow Map
\ No newline at end of file