diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj
index d4bc6d4..d89b5f2 100644
--- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj
+++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj
@@ -99,6 +99,10 @@
+
+
+
+
diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters
index b1417b5..8e6f9a5 100644
--- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters
+++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters
@@ -68,6 +68,18 @@
Resource Files\Shaders
+
+ Resource Files\Shaders
+
+
+ Resource Files\Shaders
+
+
+ Resource Files\Shaders
+
+
+ Resource Files\Shaders
+
diff --git a/ArchitectureColoredPainting/MainWindow.qrc b/ArchitectureColoredPainting/MainWindow.qrc
index a7b91f5..abee18a 100644
--- a/ArchitectureColoredPainting/MainWindow.qrc
+++ b/ArchitectureColoredPainting/MainWindow.qrc
@@ -2,5 +2,10 @@
Shaders/shader.frag
Shaders/shader.vert
+ Shaders/model.frag
+ Shaders/model.vert
+ Shaders/final.frag
+ Shaders/final.vert
+ container.jpg
diff --git a/ArchitectureColoredPainting/RendererWidget.cpp b/ArchitectureColoredPainting/RendererWidget.cpp
index 669a5b3..c6b8aa2 100644
--- a/ArchitectureColoredPainting/RendererWidget.cpp
+++ b/ArchitectureColoredPainting/RendererWidget.cpp
@@ -15,12 +15,11 @@ RendererWidget::RendererWidget(QWidget* parent)
RendererWidget::~RendererWidget()
{
- if (m_program == nullptr)
+ if (modelProgramPtr == nullptr)
return;
makeCurrent();
- m_vbo.destroy();
- delete m_program;
- m_program = nullptr;
+ delete modelProgramPtr;
+ modelProgramPtr = nullptr;
doneCurrent();
}
@@ -32,33 +31,46 @@ void RendererWidget::initializeGL()
glEnable(GL_DEPTH_TEST);
glClearColor(0, 0, 0, 1);
- m_program = new QOpenGLShaderProgram;
- if (!m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/shader.vert"))
- qDebug() << "ERROR:" << m_program->log();
- if (!m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/shader.frag"))
- qDebug() << "ERROR:" << m_program->log();
- if (!m_program->link())
- qDebug() << "ERROR:" << m_program->log();
- m_program->bind();
+ modelProgramPtr = new QOpenGLShaderProgram;
+ if (!modelProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/model.vert"))
+ qDebug() << "ERROR:" << modelProgramPtr->log();
+ if (!modelProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/model.frag"))
+ qDebug() << "ERROR:" << modelProgramPtr->log();
+ if (!modelProgramPtr->link())
+ qDebug() << "ERROR:" << modelProgramPtr->log();
- model = Model::createModel("Models/Sponza/Sponza.gltf", context(), m_program);
+ finalProgramPtr = new QOpenGLShaderProgram;
+ if (!finalProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/final.vert"))
+ qDebug() << "ERROR:" << finalProgramPtr->log();
+ if (!finalProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/final.frag"))
+ qDebug() << "ERROR:" << finalProgramPtr->log();
+ if (!finalProgramPtr->link())
+ qDebug() << "ERROR:" << finalProgramPtr->log();
+ finalProgramPtr->bind();
+ finalProgramPtr->setUniformValue("gBaseColor", 0);
+ finalProgramPtr->setUniformValue("gNormal", 1);
+ finalProgramPtr->setUniformValue("gPosition", 2);
+ finalProgramPtr->setUniformValue("gMetallicRoughness", 3);
+ finalProgramPtr->release();
- /*m_vao.create();
- QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
-
- m_vbo.create();
- m_vbo.bind();
+ model = Model::createModel("Models/Sponza/Sponza.gltf", context(), modelProgramPtr);
+ quadVAO.create();
+ QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO);
+ quadVBO.create();
+ quadVBO.bind();
GLfloat vertex[] = {
- -1,-1, 0, 0,0,
- 1,-1, 0, 1,0,
- -1, 1, 0, 0,1,
+ // positions // texture Coords
+ -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
+ -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
};
- m_vbo.allocate(vertex, sizeof(vertex));
- m_vbo.bind();
+ quadVBO.allocate(vertex, sizeof(vertex));
+ quadVBO.bind();
QOpenGLFunctions_4_5_Compatibility* f = QOpenGLContext::currentContext()->versionFunctions();
f->glEnableVertexAttribArray(0);
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat),
@@ -66,37 +78,70 @@ void RendererWidget::initializeGL()
f->glEnableVertexAttribArray(1);
f->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat),
reinterpret_cast(3 * sizeof(GLfloat)));
- m_vbo.release();*/
+ quadVBO.release();
+
+
+
}
QVector3D lightPositions[] = { QVector3D(0,0,0), QVector3D(100,100,100) ,QVector3D(-100,100,100) ,QVector3D(100,100,-100) };
-QVector3D lightColors[] = { QVector3D(150000,150000,150000), QVector3D(0,0,0) ,QVector3D(0,0,0) ,QVector3D(0,0,0) };
+QVector3D lightColors[] = { QVector3D(150000,150000,130000), QVector3D(0,0,0) ,QVector3D(0,0,0) ,QVector3D(0,0,0) };
void RendererWidget::paintGL()
{
- //std::cout << (double)CLOCKS_PER_SEC/(std::clock() -lastFrame) << std::endl;
+ fboPtr->bind();
+ {
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ modelProgramPtr->bind();
+ modelProgramPtr->setUniformValue("view", camera.GetViewMatrix());
+ model->draw();
+ modelProgramPtr->release();
+ }
+ fboPtr->release();
+ //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);
+ QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO);
+ finalProgramPtr->bind();
- QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
- m_program->bind();
- // camera/view transformation
- QMatrix4x4 view = camera.GetViewMatrix();
- m_program->setUniformValue(m_program->uniformLocation("view"), view);
- m_program->setUniformValue(m_program->uniformLocation("camPos"), camera.Position);
+ finalProgramPtr->setUniformValue(modelProgramPtr->uniformLocation("camPos"), camera.Position);
lightPositions[0] = camera.Position;
- m_program->setUniformValueArray("lightPositions", lightPositions, 4);
- m_program->setUniformValueArray("lightColors", lightColors, 4);
- //glDrawArrays(GL_TRIANGLES, 0, 3);
- model->draw();
- m_program->release();
+ finalProgramPtr->setUniformValueArray("lightPositions", lightPositions, 4);
+ finalProgramPtr->setUniformValueArray("lightColors", lightColors, 4);
+
+ QVector gbuffers = fboPtr->textures();
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, gbuffers[0]);
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, gbuffers[1]);
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, gbuffers[2]);
+ glActiveTexture(GL_TEXTURE3);
+ glBindTexture(GL_TEXTURE_2D, gbuffers[3]);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ finalProgramPtr->release();
}
void RendererWidget::resizeGL(int width, int height)
{
- m_program->bind();
- QMatrix4x4 projection;
- projection.perspective(camera.Zoom, (float)width / (float)height, 10.f, 10000.0f);
- m_program->setUniformValue(m_program->uniformLocation("projection"), projection);
-
+ //qDebug() << devicePixelRatio() << width << height;
+ //glViewport(0, 0, (GLint)devicePixelRatio()*width, (GLint)devicePixelRatio()*height);
+ if (fboPtr != nullptr)
+ delete fboPtr;
+ fboPtr = new QOpenGLFramebufferObject(devicePixelRatio() * width, devicePixelRatio() * height, QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D);
+ fboPtr->bind();
+ fboPtr->addColorAttachment(devicePixelRatio() * width, devicePixelRatio() * height, GL_RGB16F);
+ fboPtr->addColorAttachment(devicePixelRatio() * width, devicePixelRatio() * height, GL_RGB16F);
+ fboPtr->addColorAttachment(devicePixelRatio() * width, devicePixelRatio() * height, GL_RG);
+ GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 };
+ glDrawBuffers(4, attachments);
+ fboPtr->bind();
+ {
+ modelProgramPtr->bind();
+ QMatrix4x4 projection;
+ projection.perspective(camera.Zoom, (float)width / (float)height, 10.f, 10000.0f);
+ modelProgramPtr->setUniformValue("projection", projection);
+ modelProgramPtr->release();
+ }
+ fboPtr->release();
}
void RendererWidget::timerEvent(QTimerEvent* event)
diff --git a/ArchitectureColoredPainting/RendererWidget.h b/ArchitectureColoredPainting/RendererWidget.h
index 3b25b67..ea254c8 100644
--- a/ArchitectureColoredPainting/RendererWidget.h
+++ b/ArchitectureColoredPainting/RendererWidget.h
@@ -5,6 +5,7 @@
#include
#include
#include
+#include
#include
#include "Camera.h"
#include "Model.h"
@@ -30,9 +31,11 @@ private:
Camera camera;
clock_t lastFrame;
float deltaTime;
- QOpenGLShaderProgram* m_program = nullptr;
- QOpenGLBuffer m_vbo;
- QOpenGLVertexArrayObject m_vao;
+ QOpenGLShaderProgram* modelProgramPtr = nullptr;
+ QOpenGLShaderProgram* finalProgramPtr = nullptr;
+ QOpenGLFramebufferObject* fboPtr = nullptr;
+ QOpenGLBuffer quadVBO;
+ QOpenGLVertexArrayObject quadVAO;
Model* model;
};
diff --git a/ArchitectureColoredPainting/Shaders/final.frag b/ArchitectureColoredPainting/Shaders/final.frag
new file mode 100644
index 0000000..869800b
--- /dev/null
+++ b/ArchitectureColoredPainting/Shaders/final.frag
@@ -0,0 +1,112 @@
+#version 330 core
+
+out vec4 FragColor;
+
+in vec2 TexCoords;
+
+uniform sampler2D gBaseColor;
+uniform sampler2D gNormal;
+uniform sampler2D gPosition;
+uniform sampler2D gMetallicRoughness;
+
+// lights
+uniform vec3 lightPositions[4];
+uniform vec3 lightColors[4];
+
+uniform vec3 camPos;
+
+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 nom = a2;
+ float denom = (NdotH2 * (a2 - 1.0) + 1.0);
+ denom = PI * denom * denom;
+
+ return nom / denom;
+}
+// ----------------------------------------------------------------------------
+float GeometrySchlickGGX(float NdotV, float roughness)
+{
+ float r = (roughness + 1.0);
+ float k = (r*r) / 8.0;
+
+ float nom = NdotV;
+ float denom = NdotV * (1.0 - k) + k;
+
+ 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);
+
+ return ggx1 * ggx2;
+}
+// ----------------------------------------------------------------------------
+vec3 fresnelSchlick(float cosTheta, vec3 F0)
+{
+ return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
+}
+void main()
+{
+ vec3 albedo = pow(texture(gBaseColor, TexCoords).rgb, vec3(2.2));
+ float metallic = texture(gMetallicRoughness, TexCoords).g;
+ float roughness = texture(gMetallicRoughness, TexCoords).r;
+
+
+ vec3 N = texture(gNormal, TexCoords).xyz;
+ vec3 WorldPos = texture(gPosition, TexCoords).xyz;
+ vec3 V = normalize(camPos - WorldPos);
+
+ vec3 F0 = vec3(0.04);
+ F0 = mix(F0, albedo, metallic);
+
+ // 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;
+
+ // cook-torrance brdf
+ float NDF = DistributionGGX(N, H, roughness);
+ float G = GeometrySmith(N, V, L, roughness);
+ vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
+ F = clamp(F,vec3(0),vec3(1));
+
+ 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;
+ vec3 color = ambient + Lo;
+
+ color = color / (color + vec3(1.0));
+ color = pow(color, vec3(1.0/2.2));
+
+ FragColor = vec4(color, 1.0);
+
+}
\ No newline at end of file
diff --git a/ArchitectureColoredPainting/Shaders/final.vert b/ArchitectureColoredPainting/Shaders/final.vert
new file mode 100644
index 0000000..9988a20
--- /dev/null
+++ b/ArchitectureColoredPainting/Shaders/final.vert
@@ -0,0 +1,11 @@
+#version 330 core
+layout (location = 0) in vec3 aPos;
+layout (location = 1) in vec2 aTexCoords;
+
+out vec2 TexCoords;
+
+void main()
+{
+ TexCoords = aTexCoords;
+ gl_Position = vec4(aPos, 1.0);
+}
\ No newline at end of file
diff --git a/ArchitectureColoredPainting/Shaders/model.frag b/ArchitectureColoredPainting/Shaders/model.frag
new file mode 100644
index 0000000..594331a
--- /dev/null
+++ b/ArchitectureColoredPainting/Shaders/model.frag
@@ -0,0 +1,47 @@
+#version 330 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;
+layout (location = 3) out vec2 gMetallicRoughness;
+
+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();
+ gMetallicRoughness = texture(texture_metallic_roughness, TexCoords).gb;
+
+
+}
\ No newline at end of file
diff --git a/ArchitectureColoredPainting/Shaders/model.vert b/ArchitectureColoredPainting/Shaders/model.vert
new file mode 100644
index 0000000..8e2587b
--- /dev/null
+++ b/ArchitectureColoredPainting/Shaders/model.vert
@@ -0,0 +1,22 @@
+#version 330 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/shader.frag b/ArchitectureColoredPainting/Shaders/shader.frag
index 31971f1..6062cfb 100644
--- a/ArchitectureColoredPainting/Shaders/shader.frag
+++ b/ArchitectureColoredPainting/Shaders/shader.frag
@@ -77,7 +77,7 @@ vec3 fresnelSchlick(float cosTheta, vec3 F0)
void main()
{
vec4 baseColor = texture(texture_basecolor, TexCoords);
- if(baseColor.a==0)
+ if(baseColor.a<0.4)
discard;
vec3 albedo = pow(baseColor.rgb, vec3(2.2));
diff --git a/ArchitectureColoredPainting/container.jpg b/ArchitectureColoredPainting/container.jpg
new file mode 100644
index 0000000..50aa4c9
Binary files /dev/null and b/ArchitectureColoredPainting/container.jpg differ
diff --git a/README.md b/README.md
index c28cd9c..53d85ce 100644
--- a/README.md
+++ b/README.md
@@ -2,4 +2,8 @@
采用pbr材质,现在有一个光源和摄像机绑定,足以分辨出不同材质的效果
-TODO:改用延迟渲染,并指定一块材质使用独立管线进行纹理采样
\ No newline at end of file
+TODO:
+
+- [x] 改用延迟渲染
+
+- [ ] 指定一块材质使用独立管线进行纹理采样
\ No newline at end of file