实现PCF Shadow Map
parent
762fb474e5
commit
0efd3b1dbc
|
@ -106,6 +106,8 @@
|
|||
<None Include="Shaders\final.vert" />
|
||||
<None Include="Shaders\model.frag" />
|
||||
<None Include="Shaders\model.vert" />
|
||||
<None Include="Shaders\model_shadow.frag" />
|
||||
<None Include="Shaders\model_shadow.vert" />
|
||||
<None Include="Shaders\painting.comp" />
|
||||
<None Include="Shaders\painting.frag" />
|
||||
<None Include="Shaders\painting.vert" />
|
||||
|
|
|
@ -98,6 +98,12 @@
|
|||
<None Include="Shaders\painting.comp">
|
||||
<Filter>Resource Files\Shaders</Filter>
|
||||
</None>
|
||||
<None Include="Shaders\model_shadow.frag">
|
||||
<Filter>Resource Files\Shaders</Filter>
|
||||
</None>
|
||||
<None Include="Shaders\model_shadow.vert">
|
||||
<Filter>Resource Files\Shaders</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Camera.h">
|
||||
|
|
|
@ -3,5 +3,6 @@ class Drawable
|
|||
{
|
||||
public:
|
||||
virtual void draw() = 0;
|
||||
virtual void drawShadow() = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -10,5 +10,7 @@
|
|||
<file>Shaders/painting.frag</file>
|
||||
<file>Shaders/painting.vert</file>
|
||||
<file>Shaders/painting.comp</file>
|
||||
<file>Shaders/model_shadow.frag</file>
|
||||
<file>Shaders/model_shadow.vert</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -45,11 +45,12 @@ public:
|
|||
QVector<Texture*> textures; //纹理数据
|
||||
QMatrix4x4 model; //模型矩阵
|
||||
QOpenGLFunctions_4_5_Compatibility* glFunc; //opengl函数入口
|
||||
QOpenGLShaderProgram* shaderProgram; //着色器程序
|
||||
QOpenGLShaderProgram* shaderProgram, * shadowProgram; //着色器程序
|
||||
|
||||
/* 函数 */
|
||||
Mesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model);
|
||||
Mesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* shadowProgram, aiMatrix4x4 model);
|
||||
void draw() override;
|
||||
void drawShadow() override;
|
||||
void setupMesh();
|
||||
|
||||
private:
|
||||
|
|
|
@ -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<QOpenGLFunctions_4_5_Compatibility>())
|
||||
, 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++)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
/* 模型数据 */
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -32,11 +32,12 @@ public:
|
|||
QVector<unsigned int> 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:
|
||||
|
|
|
@ -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,13 +93,14 @@ 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<QOpenGLFunctions_4_5_Compatibility>());
|
||||
|
||||
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();
|
||||
|
@ -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,7 +189,7 @@ 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);
|
||||
|
@ -164,11 +197,13 @@ void RendererWidget::paintGL()
|
|||
|
||||
//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);
|
||||
|
@ -203,35 +241,37 @@ void RendererWidget::resizeGL(int width, int height)
|
|||
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);
|
||||
|
@ -240,9 +280,53 @@ void RendererWidget::resizeGL(int width, int height)
|
|||
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";
|
||||
}
|
||||
|
@ -260,7 +344,7 @@ void RendererWidget::timerEvent(QTimerEvent* event)
|
|||
if (accTime > 1.)
|
||||
{
|
||||
std::cout << " \r";
|
||||
std::cout << "FPS: " << frameCnt / accTime << "\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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -56,6 +58,55 @@ vec3 fresnelSchlick(float cosTheta, vec3 F0)
|
|||
{
|
||||
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));
|
||||
|
@ -65,6 +116,20 @@ void main()
|
|||
|
||||
vec3 N = normalize(texture(gNormal, TexCoords).xyz);
|
||||
vec3 WorldPos = texture(gPosition, TexCoords).xyz;
|
||||
|
||||
if(WorldPos==vec3(0))
|
||||
{
|
||||
vec3 color = lightColors[0];
|
||||
|
||||
color = color / (color + vec3(1.0));
|
||||
color = pow(color, vec3(1.0/2.2));
|
||||
|
||||
FragColor = vec4(color, 1.0);
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 FragPosLightSpace = lightSpaceMatrix * vec4(WorldPos, 1.0);
|
||||
|
||||
vec3 V = normalize(camPos - WorldPos);
|
||||
|
||||
vec3 F0 = vec3(0.04);
|
||||
|
@ -72,8 +137,8 @@ void main()
|
|||
|
||||
// reflectance equation
|
||||
vec3 Lo = vec3(0.0);
|
||||
for(int i = 0; i < 1; ++i)
|
||||
{
|
||||
|
||||
int i = 0;
|
||||
// calculate per-light radiance
|
||||
vec3 L = normalize(lightPositions[i] - WorldPos);
|
||||
vec3 H = normalize(V + L);
|
||||
|
@ -99,15 +164,18 @@ void main()
|
|||
float NdotL = max(dot(N, L), 0.0);
|
||||
Lo += (kD * albedo / PI + specular) * radiance * NdotL;
|
||||
|
||||
}
|
||||
|
||||
vec3 ambient = vec3(0.03) * albedo;
|
||||
vec3 color = ambient + Lo;
|
||||
|
||||
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(texture(gPainting, TexCoords).rgb, 1.0);
|
||||
//FragColor = vec4(vec3(shadow), 1);
|
||||
//FragColor = vec4(texture(gShadowMap, TexCoords).rgb, 1.0);
|
||||
|
||||
}
|
|
@ -19,4 +19,5 @@ void main()
|
|||
|
||||
gl_Position = projection * view * vec4(WorldPos, 1.0);
|
||||
|
||||
|
||||
}
|
|
@ -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();
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue