初步实现Cascaded Shadow Maps
parent
0efd3b1dbc
commit
3bf1444092
|
@ -87,6 +87,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="BvhTree.cpp" />
|
<ClCompile Include="BvhTree.cpp" />
|
||||||
<ClCompile Include="Camera.cpp" />
|
<ClCompile Include="Camera.cpp" />
|
||||||
|
<ClCompile Include="Light.cpp" />
|
||||||
<ClCompile Include="Mesh.cpp" />
|
<ClCompile Include="Mesh.cpp" />
|
||||||
<ClCompile Include="Model.cpp" />
|
<ClCompile Include="Model.cpp" />
|
||||||
<ClCompile Include="PaintingHelper.cpp" />
|
<ClCompile Include="PaintingHelper.cpp" />
|
||||||
|
@ -102,11 +103,14 @@
|
||||||
<QtMoc Include="RendererWidget.h" />
|
<QtMoc Include="RendererWidget.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<None Include="Shaders\depth_init.comp" />
|
||||||
|
<None Include="Shaders\depth_mipmap.comp" />
|
||||||
<None Include="Shaders\final.frag" />
|
<None Include="Shaders\final.frag" />
|
||||||
<None Include="Shaders\final.vert" />
|
<None Include="Shaders\final.vert" />
|
||||||
<None Include="Shaders\model.frag" />
|
<None Include="Shaders\model.frag" />
|
||||||
<None Include="Shaders\model.vert" />
|
<None Include="Shaders\model.vert" />
|
||||||
<None Include="Shaders\model_shadow.frag" />
|
<None Include="Shaders\model_shadow.frag" />
|
||||||
|
<None Include="Shaders\model_shadow.geom" />
|
||||||
<None Include="Shaders\model_shadow.vert" />
|
<None Include="Shaders\model_shadow.vert" />
|
||||||
<None Include="Shaders\painting.comp" />
|
<None Include="Shaders\painting.comp" />
|
||||||
<None Include="Shaders\painting.frag" />
|
<None Include="Shaders\painting.frag" />
|
||||||
|
@ -118,6 +122,7 @@
|
||||||
<ClInclude Include="BvhTree.h" />
|
<ClInclude Include="BvhTree.h" />
|
||||||
<ClInclude Include="Camera.h" />
|
<ClInclude Include="Camera.h" />
|
||||||
<ClInclude Include="Drawable.h" />
|
<ClInclude Include="Drawable.h" />
|
||||||
|
<ClInclude Include="Light.h" />
|
||||||
<ClInclude Include="Mesh.h" />
|
<ClInclude Include="Mesh.h" />
|
||||||
<ClInclude Include="Model.h" />
|
<ClInclude Include="Model.h" />
|
||||||
<ClInclude Include="PaintingHelper.h" />
|
<ClInclude Include="PaintingHelper.h" />
|
||||||
|
|
|
@ -64,6 +64,9 @@
|
||||||
<ClCompile Include="PaintingHelper.cpp">
|
<ClCompile Include="PaintingHelper.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Light.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<QtMoc Include="RendererWidget.h">
|
<QtMoc Include="RendererWidget.h">
|
||||||
|
@ -104,6 +107,15 @@
|
||||||
<None Include="Shaders\model_shadow.vert">
|
<None Include="Shaders\model_shadow.vert">
|
||||||
<Filter>Resource Files\Shaders</Filter>
|
<Filter>Resource Files\Shaders</Filter>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="Shaders\depth_mipmap.comp">
|
||||||
|
<Filter>Resource Files\Shaders</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="Shaders\depth_init.comp">
|
||||||
|
<Filter>Resource Files\Shaders</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="Shaders\model_shadow.geom">
|
||||||
|
<Filter>Resource Files\Shaders</Filter>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Camera.h">
|
<ClInclude Include="Camera.h">
|
||||||
|
@ -127,5 +139,8 @@
|
||||||
<ClInclude Include="PaintingHelper.h">
|
<ClInclude Include="PaintingHelper.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Light.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -41,6 +41,9 @@ public:
|
||||||
float MovementSpeed;
|
float MovementSpeed;
|
||||||
float MouseSensitivity;
|
float MouseSensitivity;
|
||||||
float Zoom;
|
float Zoom;
|
||||||
|
float Ratio;
|
||||||
|
float NearPlane = 10.f;
|
||||||
|
float FarPlane = 10000.f;
|
||||||
|
|
||||||
// constructor with vectors
|
// constructor with vectors
|
||||||
Camera(QVector3D position = QVector3D(0.0f, 0.0f, 0.0f), QVector3D up = QVector3D(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH);
|
Camera(QVector3D position = QVector3D(0.0f, 0.0f, 0.0f), QVector3D up = QVector3D(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH);
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
#include "Light.h"
|
||||||
|
#include <qDebug>
|
||||||
|
|
||||||
|
Light::Light(Camera* camera)
|
||||||
|
: camera(camera)
|
||||||
|
, shadowCascadeLevels{ camera->FarPlane / 50.0f, camera->FarPlane / 25.0f, camera->FarPlane / 10.0f, camera->FarPlane / 2.0f }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<QVector4D> Light::getFrustumCornersWorldSpace(const QMatrix4x4& projview)
|
||||||
|
{
|
||||||
|
const auto inv = projview.inverted();
|
||||||
|
|
||||||
|
std::vector<QVector4D> frustumCorners;
|
||||||
|
for (unsigned int x = 0; x < 2; ++x)
|
||||||
|
{
|
||||||
|
for (unsigned int y = 0; y < 2; ++y)
|
||||||
|
{
|
||||||
|
for (unsigned int z = 0; z < 2; ++z)
|
||||||
|
{
|
||||||
|
const QVector4D pt = inv * QVector4D(2.0f * x - 1.0f, 2.0f * y - 1.0f, 2.0f * z - 1.0f, 1.0f);
|
||||||
|
frustumCorners.push_back(pt / pt.w());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return frustumCorners;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<QVector4D> Light::getFrustumCornersWorldSpace(const QMatrix4x4& proj, const QMatrix4x4& view)
|
||||||
|
{
|
||||||
|
return getFrustumCornersWorldSpace(proj * view);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMatrix4x4 Light::getLightSpaceMatrix(const float nearPlane, const float farPlane)
|
||||||
|
{
|
||||||
|
QMatrix4x4 proj;
|
||||||
|
proj.perspective(camera->Zoom, camera->Ratio, nearPlane, farPlane);
|
||||||
|
|
||||||
|
const std::vector<QVector4D> corners = getFrustumCornersWorldSpace(proj, camera->GetViewMatrix());
|
||||||
|
|
||||||
|
QVector3D center = QVector3D(0, 0, 0);
|
||||||
|
for (const QVector4D& v : corners)
|
||||||
|
{
|
||||||
|
center += QVector3D(v);
|
||||||
|
}
|
||||||
|
center /= corners.size();
|
||||||
|
|
||||||
|
|
||||||
|
QVector3D right = QVector3D::crossProduct(lightDirection, QVector3D(1, 0, 0)).normalized();
|
||||||
|
QVector3D up = QVector3D::crossProduct(right, lightDirection).normalized();
|
||||||
|
QMatrix4x4 lightView;
|
||||||
|
//qDebug() << "lightDirection:" << lightDirection << "up:" << up;
|
||||||
|
lightView.lookAt(center, center - lightDirection, up);
|
||||||
|
|
||||||
|
float minX = std::numeric_limits<float>::max();
|
||||||
|
float maxX = std::numeric_limits<float>::min();
|
||||||
|
float minY = std::numeric_limits<float>::max();
|
||||||
|
float maxY = std::numeric_limits<float>::min();
|
||||||
|
float minZ = std::numeric_limits<float>::max();
|
||||||
|
float maxZ = std::numeric_limits<float>::min();
|
||||||
|
for (const QVector4D& v : corners)
|
||||||
|
{
|
||||||
|
QVector4D trf = lightView * v;
|
||||||
|
//qDebug() << v;
|
||||||
|
//qDebug() << trf;
|
||||||
|
minX = std::min(minX, trf.x());
|
||||||
|
maxX = std::max(maxX, trf.x());
|
||||||
|
minY = std::min(minY, trf.y());
|
||||||
|
maxY = std::max(maxY, trf.y());
|
||||||
|
minZ = std::min(minZ, -trf.z());
|
||||||
|
maxZ = std::max(maxZ, -trf.z());
|
||||||
|
}
|
||||||
|
for (const QVector3D& v : model->AABB)
|
||||||
|
{
|
||||||
|
const QVector4D trf = lightView * QVector4D(v, 1);
|
||||||
|
//qDebug() << v;
|
||||||
|
//qDebug() << trf;
|
||||||
|
//minX = std::min(minX, trf.x());
|
||||||
|
//maxX = std::max(maxX, trf.x());
|
||||||
|
//minY = std::min(minY, trf.y());
|
||||||
|
//maxY = std::max(maxY, trf.y());
|
||||||
|
minZ = std::min(minZ, -trf.z());
|
||||||
|
//maxZ = std::max(maxZ, trf.z());
|
||||||
|
|
||||||
|
}
|
||||||
|
//qDebug() << minZ;
|
||||||
|
// Tune this parameter according to the scene
|
||||||
|
/* constexpr float zMult = 10.0f;
|
||||||
|
if (minZ < 0)
|
||||||
|
{
|
||||||
|
minZ *= zMult;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
minZ /= zMult;
|
||||||
|
}
|
||||||
|
if (maxZ < 0)
|
||||||
|
{
|
||||||
|
maxZ /= zMult;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maxZ *= zMult;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
QMatrix4x4 lightProjection;
|
||||||
|
//qDebug() << minX<< maxX<< minY<< maxY<< minZ<< maxZ;
|
||||||
|
lightProjection.ortho(minX, maxX, minY, maxY, minZ, maxZ);
|
||||||
|
frustumSizes.push_back(std::max(maxX - minX, maxY - minY));
|
||||||
|
return lightProjection * lightView;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<QMatrix4x4> Light::getLightSpaceMatrices()
|
||||||
|
{
|
||||||
|
std::vector<QMatrix4x4> ret;
|
||||||
|
frustumSizes.clear();
|
||||||
|
for (size_t i = 0; i < shadowCascadeLevels.size() + 1; ++i)
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
ret.push_back(getLightSpaceMatrix(camera->NearPlane, shadowCascadeLevels[i]));
|
||||||
|
}
|
||||||
|
else if (i < shadowCascadeLevels.size())
|
||||||
|
{
|
||||||
|
ret.push_back(getLightSpaceMatrix(shadowCascadeLevels[i - 1], shadowCascadeLevels[i]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret.push_back(getLightSpaceMatrix(shadowCascadeLevels[i - 1], camera->FarPlane));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <QVector3D>
|
||||||
|
#include <QVector4D>
|
||||||
|
#include <QMatrix4x4>
|
||||||
|
#include <QtMath>
|
||||||
|
#include <QOpenGLFunctions_4_5_Compatibility>
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "Model.h"
|
||||||
|
|
||||||
|
class Light
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QVector3D lightDirection = QVector3D(0.2, 4, 1).normalized();
|
||||||
|
std::vector<float> shadowCascadeLevels;
|
||||||
|
std::vector<float> frustumSizes;
|
||||||
|
Model* model;
|
||||||
|
Light(Camera* camera);
|
||||||
|
std::vector<QVector4D> getFrustumCornersWorldSpace(const QMatrix4x4& projview);
|
||||||
|
std::vector<QVector4D> getFrustumCornersWorldSpace(const QMatrix4x4& proj, const QMatrix4x4& view);
|
||||||
|
QMatrix4x4 getLightSpaceMatrix(const float nearPlane, const float farPlane);
|
||||||
|
std::vector<QMatrix4x4> getLightSpaceMatrices();
|
||||||
|
private:
|
||||||
|
Camera* camera;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
|
@ -12,5 +12,8 @@
|
||||||
<file>Shaders/painting.comp</file>
|
<file>Shaders/painting.comp</file>
|
||||||
<file>Shaders/model_shadow.frag</file>
|
<file>Shaders/model_shadow.frag</file>
|
||||||
<file>Shaders/model_shadow.vert</file>
|
<file>Shaders/model_shadow.vert</file>
|
||||||
|
<file>Shaders/depth_mipmap.comp</file>
|
||||||
|
<file>Shaders/depth_init.comp</file>
|
||||||
|
<file>Shaders/model_shadow.geom</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -52,6 +52,14 @@ Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shader
|
||||||
qDebug() << "NumTextures: " << scene->mNumTextures;
|
qDebug() << "NumTextures: " << scene->mNumTextures;
|
||||||
directory.cdUp();
|
directory.cdUp();
|
||||||
processNode(scene->mRootNode, scene);
|
processNode(scene->mRootNode, scene);
|
||||||
|
AABB.push_back(QVector3D(minX, minY, minZ));
|
||||||
|
AABB.push_back(QVector3D(minX, minY, maxZ));
|
||||||
|
AABB.push_back(QVector3D(minX, maxY, minZ));
|
||||||
|
AABB.push_back(QVector3D(minX, maxY, maxZ));
|
||||||
|
AABB.push_back(QVector3D(maxX, minY, minZ));
|
||||||
|
AABB.push_back(QVector3D(maxX, minY, maxZ));
|
||||||
|
AABB.push_back(QVector3D(maxX, maxY, minZ));
|
||||||
|
AABB.push_back(QVector3D(maxX, maxY, maxZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
Model::~Model() //Ïú»Ù¶ÔÏó
|
Model::~Model() //Ïú»Ù¶ÔÏó
|
||||||
|
@ -123,6 +131,14 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
|
||||||
{
|
{
|
||||||
PaintingVertex vertex;
|
PaintingVertex vertex;
|
||||||
vertex.Position = QVector3D(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z);
|
vertex.Position = QVector3D(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z);
|
||||||
|
minX = std::min(minX, vertex.Position.x());
|
||||||
|
maxX = std::max(maxX, vertex.Position.x());
|
||||||
|
minY = std::min(minY, vertex.Position.y());
|
||||||
|
maxY = std::max(maxY, vertex.Position.y());
|
||||||
|
minZ = std::min(minZ, vertex.Position.z());
|
||||||
|
maxZ = std::max(maxZ, vertex.Position.z());
|
||||||
|
|
||||||
|
|
||||||
// ·¨ÏòÁ¿
|
// ·¨ÏòÁ¿
|
||||||
if (mesh->mNormals)
|
if (mesh->mNormals)
|
||||||
vertex.Normal = QVector3D(mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z);
|
vertex.Normal = QVector3D(mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z);
|
||||||
|
@ -278,6 +294,14 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
|
||||||
vector.setY(mesh->mVertices[i].y);
|
vector.setY(mesh->mVertices[i].y);
|
||||||
vector.setZ(mesh->mVertices[i].z);
|
vector.setZ(mesh->mVertices[i].z);
|
||||||
vertex.Position = vector;
|
vertex.Position = vector;
|
||||||
|
minX = std::min(minX, vertex.Position.x());
|
||||||
|
maxX = std::max(maxX, vertex.Position.x());
|
||||||
|
minY = std::min(minY, vertex.Position.y());
|
||||||
|
maxY = std::max(maxY, vertex.Position.y());
|
||||||
|
minZ = std::min(minZ, vertex.Position.z());
|
||||||
|
maxZ = std::max(maxZ, vertex.Position.z());
|
||||||
|
|
||||||
|
|
||||||
// ·¨ÏòÁ¿
|
// ·¨ÏòÁ¿
|
||||||
if (mesh->mNormals) {
|
if (mesh->mNormals) {
|
||||||
vector.setX(mesh->mNormals[i].x);
|
vector.setX(mesh->mNormals[i].x);
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
class Model
|
class Model
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
std::vector<QVector3D> AABB;
|
||||||
|
|
||||||
void draw();
|
void draw();
|
||||||
void drawShadow();
|
void drawShadow();
|
||||||
void destroy();
|
void destroy();
|
||||||
|
@ -29,6 +31,13 @@ private:
|
||||||
QVector<Drawable*> meshes; //网格
|
QVector<Drawable*> meshes; //网格
|
||||||
QDir directory; //模型所在路径
|
QDir directory; //模型所在路径
|
||||||
|
|
||||||
|
float minX = std::numeric_limits<float>::max();
|
||||||
|
float maxX = std::numeric_limits<float>::min();
|
||||||
|
float minY = std::numeric_limits<float>::max();
|
||||||
|
float maxY = std::numeric_limits<float>::min();
|
||||||
|
float minZ = std::numeric_limits<float>::max();
|
||||||
|
float maxZ = std::numeric_limits<float>::min();
|
||||||
|
|
||||||
//递归遍历结点
|
//递归遍历结点
|
||||||
void processNode(aiNode* node, const aiScene* scene, aiMatrix4x4 mat4 = aiMatrix4x4());
|
void processNode(aiNode* node, const aiScene* scene, aiMatrix4x4 mat4 = aiMatrix4x4());
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,13 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
|
||||||
RendererWidget::RendererWidget(QWidget* parent)
|
RendererWidget::RendererWidget(QWidget* parent)
|
||||||
: QOpenGLWidget(parent), camera(QVector3D(0.0f, 100.0f, 0.0f))
|
: QOpenGLWidget(parent)
|
||||||
|
, camera(QVector3D(0.0f, 100.0f, 0.0f))
|
||||||
|
, light(&camera)
|
||||||
{
|
{
|
||||||
startTimer(1000 / QGuiApplication::primaryScreen()->refreshRate());
|
startTimer(1000 / QGuiApplication::primaryScreen()->refreshRate());
|
||||||
lastFrame = std::clock();
|
lastFrame = std::clock();
|
||||||
|
@ -40,18 +43,21 @@ RendererWidget::~RendererWidget()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QOpenGLTexture randomMap(QOpenGLTexture::Target2D);
|
||||||
void RendererWidget::initializeGL()
|
void RendererWidget::initializeGL()
|
||||||
{
|
{
|
||||||
initializeOpenGLFunctions();
|
initializeOpenGLFunctions();
|
||||||
qDebug() << "GL_VERSION" << (char*)glGetString(GL_VERSION);
|
qDebug() << "GL_VERSION" << (char*)glGetString(GL_VERSION);
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
glClearColor(0, 0, 0, 1);
|
glClearColor(0, 0, 0, 1);
|
||||||
|
|
||||||
shadowProgramPtr = new QOpenGLShaderProgram;
|
shadowProgramPtr = new QOpenGLShaderProgram;
|
||||||
if (!shadowProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/model_shadow.vert"))
|
if (!shadowProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/model_shadow.vert"))
|
||||||
qDebug() << "ERROR:" << shadowProgramPtr->log();
|
qDebug() << "ERROR:" << shadowProgramPtr->log();
|
||||||
|
if (!shadowProgramPtr->addShaderFromSourceFile(QOpenGLShader::Geometry, ":/Shaders/model_shadow.geom"))
|
||||||
|
qDebug() << "ERROR:" << shadowProgramPtr->log();
|
||||||
if (!shadowProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/model_shadow.frag"))
|
if (!shadowProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/model_shadow.frag"))
|
||||||
qDebug() << "ERROR:" << shadowProgramPtr->log();
|
qDebug() << "ERROR:" << shadowProgramPtr->log();
|
||||||
if (!shadowProgramPtr->link())
|
if (!shadowProgramPtr->link())
|
||||||
|
@ -79,6 +85,18 @@ void RendererWidget::initializeGL()
|
||||||
if (!paintingCompProgramPtr->link())
|
if (!paintingCompProgramPtr->link())
|
||||||
qDebug() << "ERROR:" << paintingCompProgramPtr->log();
|
qDebug() << "ERROR:" << paintingCompProgramPtr->log();
|
||||||
|
|
||||||
|
depthInitProgramPtr = new QOpenGLShaderProgram;
|
||||||
|
if (!depthInitProgramPtr->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/depth_init.comp"))
|
||||||
|
qDebug() << "ERROR:" << depthInitProgramPtr->log();
|
||||||
|
if (!depthInitProgramPtr->link())
|
||||||
|
qDebug() << "ERROR:" << depthInitProgramPtr->log();
|
||||||
|
|
||||||
|
depthMipmapProgramPtr = new QOpenGLShaderProgram;
|
||||||
|
if (!depthMipmapProgramPtr->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/depth_mipmap.comp"))
|
||||||
|
qDebug() << "ERROR:" << depthMipmapProgramPtr->log();
|
||||||
|
if (!depthMipmapProgramPtr->link())
|
||||||
|
qDebug() << "ERROR:" << depthMipmapProgramPtr->log();
|
||||||
|
|
||||||
finalProgramPtr = new QOpenGLShaderProgram;
|
finalProgramPtr = new QOpenGLShaderProgram;
|
||||||
if (!finalProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/final.vert"))
|
if (!finalProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/final.vert"))
|
||||||
qDebug() << "ERROR:" << finalProgramPtr->log();
|
qDebug() << "ERROR:" << finalProgramPtr->log();
|
||||||
|
@ -88,12 +106,50 @@ void RendererWidget::initializeGL()
|
||||||
qDebug() << "ERROR:" << finalProgramPtr->log();
|
qDebug() << "ERROR:" << finalProgramPtr->log();
|
||||||
|
|
||||||
|
|
||||||
|
shadowProgramPtr->bind();
|
||||||
|
glGenBuffers(1, &lightSpaceMatricesUBO);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, lightSpaceMatricesUBO);
|
||||||
|
glBufferData(GL_UNIFORM_BUFFER, sizeof(QMatrix4x4) * 16, nullptr, GL_STATIC_DRAW);
|
||||||
|
glBindBufferBase(GL_UNIFORM_BUFFER, 0, lightSpaceMatricesUBO);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
shadowProgramPtr->release();
|
||||||
|
|
||||||
|
|
||||||
|
depthInitProgramPtr->bind();
|
||||||
|
depthInitProgramPtr->setUniformValue("depthBuffer", 6);
|
||||||
|
depthInitProgramPtr->release();
|
||||||
|
|
||||||
|
|
||||||
finalProgramPtr->bind();
|
finalProgramPtr->bind();
|
||||||
finalProgramPtr->setUniformValue("gBaseColor", 0);
|
finalProgramPtr->setUniformValue("gBaseColor", 0);
|
||||||
finalProgramPtr->setUniformValue("gNormal", 1);
|
finalProgramPtr->setUniformValue("gNormal", 1);
|
||||||
finalProgramPtr->setUniformValue("gPosition", 2);
|
finalProgramPtr->setUniformValue("gPosition", 2);
|
||||||
finalProgramPtr->setUniformValue("gMetallicRoughness", 3);
|
finalProgramPtr->setUniformValue("gMetallicRoughness", 3);
|
||||||
finalProgramPtr->setUniformValue("gShadowMap", 4);
|
finalProgramPtr->setUniformValue("gDepth", 4);
|
||||||
|
finalProgramPtr->setUniformValue("gShadowMap", 5);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//std::vector<QVector3D> rsmSampleCoordsAndWeights;
|
||||||
|
//std::default_random_engine e;
|
||||||
|
//std::uniform_real_distribution<float> u(0, 1);
|
||||||
|
//int rsmSampleNum = 50;
|
||||||
|
//finalProgramPtr->setUniformValue("rsmSampleNum", rsmSampleNum);
|
||||||
|
//for (int i = 0; i < rsmSampleNum; ++i)
|
||||||
|
//{
|
||||||
|
// float xi1 = u(e);
|
||||||
|
// float xi2 = u(e);
|
||||||
|
// rsmSampleCoordsAndWeights.push_back(QVector3D(xi1 * sin(2 * M_PI * xi2), xi1 * cos(2 * M_PI * xi2), xi1 * xi1));
|
||||||
|
//}
|
||||||
|
////QOpenGLTexture randomMap(QOpenGLTexture::Target2D);
|
||||||
|
//randomMap.create();
|
||||||
|
//randomMap.setSize(rsmSampleCoordsAndWeights.size());
|
||||||
|
//randomMap.setFormat(QOpenGLTexture::RGB8_UNorm);
|
||||||
|
//randomMap.allocateStorage();
|
||||||
|
//randomMap.setData(QOpenGLTexture::RGB, QOpenGLTexture::Float32, rsmSampleCoordsAndWeights.data());
|
||||||
|
//randomMap.setMinMagFilters(QOpenGLTexture::Nearest, QOpenGLTexture::Nearest);
|
||||||
|
|
||||||
|
|
||||||
finalProgramPtr->release();
|
finalProgramPtr->release();
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,7 +157,8 @@ void RendererWidget::initializeGL()
|
||||||
paintingHelper = new PaintingHelper(QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Compatibility>());
|
paintingHelper = new PaintingHelper(QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Compatibility>());
|
||||||
|
|
||||||
model = new Model("Models/Sponza/Sponza.gltf", context(), modelProgramPtr, paintingProgramPtr, shadowProgramPtr, paintingHelper);
|
model = new Model("Models/Sponza/Sponza.gltf", context(), modelProgramPtr, paintingProgramPtr, shadowProgramPtr, paintingHelper);
|
||||||
|
light.model = model;
|
||||||
|
qDebug() << model->AABB;
|
||||||
|
|
||||||
paintingHelper->allocateBuffers();
|
paintingHelper->allocateBuffers();
|
||||||
paintingCompProgramPtr->bind();
|
paintingCompProgramPtr->bind();
|
||||||
|
@ -137,39 +194,59 @@ void RendererWidget::initializeGL()
|
||||||
|
|
||||||
}
|
}
|
||||||
QVector3D lightPositions[] = { 2000 * QVector3D(0.2, 4, 1).normalized(), QVector3D(100,100,100) ,QVector3D(-100,100,100) ,QVector3D(100,100,-100) };
|
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) };
|
QVector3D lightColors[] = { 20 * 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;
|
static float sunPitch = 90, sunYaw = 80;
|
||||||
|
static int sunSpeed = 10;
|
||||||
void RendererWidget::paintGL()
|
void RendererWidget::paintGL()
|
||||||
{
|
{
|
||||||
QMatrix4x4 lightProjection;
|
QMatrix4x4 lightProjection;
|
||||||
lightProjection.ortho(-1200.0f, 1200.0f, -900.0f, 900.0f, 100.f, 5000.0f);
|
lightProjection.ortho(-1200.0f, 1200.0f, -900.0f, 900.0f, -2000.f, 5000.0f);
|
||||||
|
|
||||||
|
light.lightDirection.setX(cos(qDegreesToRadians(sunPitch)) * cos(qDegreesToRadians(sunYaw)));
|
||||||
|
light.lightDirection.setY(sin(qDegreesToRadians(sunPitch)));
|
||||||
|
light.lightDirection.setZ(cos(qDegreesToRadians(sunPitch)) * sin(qDegreesToRadians(sunYaw)));
|
||||||
|
light.lightDirection.normalize();
|
||||||
lightPositions[0].setX(cos(qDegreesToRadians(sunPitch)) * cos(qDegreesToRadians(sunYaw)));
|
lightPositions[0].setX(cos(qDegreesToRadians(sunPitch)) * cos(qDegreesToRadians(sunYaw)));
|
||||||
lightPositions[0].setY(sin(qDegreesToRadians(sunPitch)));
|
lightPositions[0].setY(sin(qDegreesToRadians(sunPitch)));
|
||||||
lightPositions[0].setZ(cos(qDegreesToRadians(sunPitch)) * sin(qDegreesToRadians(sunYaw)));
|
lightPositions[0].setZ(cos(qDegreesToRadians(sunPitch)) * sin(qDegreesToRadians(sunYaw)));
|
||||||
lightPositions[0] *= 2000;
|
//lightPositions[0] *= 2000;
|
||||||
QMatrix4x4 lightView;
|
QMatrix4x4 lightView;
|
||||||
lightView.lookAt(lightPositions[0], QVector3D(0, 0, 0), QVector3D(0, 1, 0));
|
lightView.lookAt(lightPositions[0], QVector3D(0, 0, 0), QVector3D(0, 1, 0));
|
||||||
if (shadowFboPtr->bind())
|
|
||||||
|
const std::vector<QMatrix4x4> lightMatrices = light.getLightSpaceMatrices();
|
||||||
|
//qDebug() << lightMatrices;
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, lightSpaceMatricesUBO);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < lightMatrices.size(); i++)
|
||||||
{
|
{
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glBufferSubData(GL_UNIFORM_BUFFER, i * 16 * sizeof(GLfloat), 16 * sizeof(GLfloat), lightMatrices[i].data());
|
||||||
|
}
|
||||||
|
//glBufferSubData(GL_UNIFORM_BUFFER, 0 * 16 * sizeof(GLfloat), 16 * sizeof(GLfloat), (lightProjection * lightView).data());
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
{
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle);
|
||||||
glViewport(0, 0, shadowMapResolution, shadowMapResolution);
|
glViewport(0, 0, shadowMapResolution, shadowMapResolution);
|
||||||
shadowProgramPtr->bind();
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
|
/*shadowProgramPtr->bind();
|
||||||
shadowProgramPtr->setUniformValue("projection", lightProjection);
|
shadowProgramPtr->setUniformValue("projection", lightProjection);
|
||||||
shadowProgramPtr->setUniformValue("view", lightView);
|
shadowProgramPtr->setUniformValue("view", lightView);
|
||||||
shadowProgramPtr->release();
|
shadowProgramPtr->setUniformValue("mainLightPositon", lightPositions[0]);
|
||||||
|
shadowProgramPtr->setUniformValue("mainLightColor", lightColors[0]);
|
||||||
|
shadowProgramPtr->release();*/
|
||||||
|
//glCullFace(GL_FRONT);
|
||||||
model->drawShadow();
|
model->drawShadow();
|
||||||
shadowFboPtr->release();
|
//glCullFace(GL_BACK);
|
||||||
}
|
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
|
QMatrix4x4 projection;
|
||||||
|
projection.perspective(camera.Zoom, camera.Ratio, camera.NearPlane, camera.FarPlane);
|
||||||
|
QMatrix4x4 view = camera.GetViewMatrix();
|
||||||
if (fboPtr->bind())
|
if (fboPtr->bind())
|
||||||
{
|
{
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
glViewport(0, 0, frameWidth, frameHeight);
|
glViewport(0, 0, frameWidth, frameHeight);
|
||||||
QMatrix4x4 projection;
|
|
||||||
projection.perspective(camera.Zoom, (float)width() / (float)height(), 10.f, 10000.0f);
|
|
||||||
QMatrix4x4 view = camera.GetViewMatrix();
|
|
||||||
modelProgramPtr->bind();
|
modelProgramPtr->bind();
|
||||||
modelProgramPtr->setUniformValue("projection", projection);
|
modelProgramPtr->setUniformValue("projection", projection);
|
||||||
modelProgramPtr->setUniformValue("view", view);
|
modelProgramPtr->setUniformValue("view", view);
|
||||||
|
@ -178,14 +255,15 @@ void RendererWidget::paintGL()
|
||||||
paintingProgramPtr->setUniformValue("projection", projection);
|
paintingProgramPtr->setUniformValue("projection", projection);
|
||||||
paintingProgramPtr->setUniformValue("view", view);
|
paintingProgramPtr->setUniformValue("view", view);
|
||||||
paintingProgramPtr->release();
|
paintingProgramPtr->release();
|
||||||
|
|
||||||
model->draw();
|
model->draw();
|
||||||
|
|
||||||
|
|
||||||
fboPtr->release();
|
fboPtr->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
paintingCompProgramPtr->bind();
|
paintingCompProgramPtr->bind();
|
||||||
glActiveTexture(GL_TEXTURE4);
|
//glActiveTexture(GL_TEXTURE4);
|
||||||
glBindTexture(GL_TEXTURE_2D, gbuffers[4]);
|
//glBindTexture(GL_TEXTURE_2D, gbuffers[4]);
|
||||||
glBindImageTexture(0, gbuffers[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
|
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(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(2, gbuffers[4], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R16UI);
|
||||||
|
@ -193,21 +271,44 @@ void RendererWidget::paintGL()
|
||||||
|
|
||||||
glDispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1);
|
glDispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1);
|
||||||
//glDispatchCompute(1,1, 1);
|
//glDispatchCompute(1,1, 1);
|
||||||
|
paintingCompProgramPtr->release();
|
||||||
|
|
||||||
|
depthInitProgramPtr->bind();
|
||||||
|
glActiveTexture(GL_TEXTURE6);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, gbuffers[6]);
|
||||||
|
glBindImageTexture(0, gbuffers[7], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
|
||||||
|
glDispatchCompute(ceil(depthWidth / 8.), ceil(depthHeight / 8.), 1);
|
||||||
|
depthInitProgramPtr->release();
|
||||||
|
|
||||||
|
depthMipmapProgramPtr->bind();
|
||||||
|
for (int i = 0; i <= 3; i++)
|
||||||
|
glBindImageTexture(i, gbuffers[7], i, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
|
||||||
|
glDispatchCompute(ceil(depthWidth / 2 / 8.), ceil(depthHeight / 2 / 8.), 1);
|
||||||
|
for (int i = 0; i <= 3; i++)
|
||||||
|
glBindImageTexture(i, gbuffers[7], i + 3, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
|
||||||
|
glDispatchCompute(ceil(depthWidth / 2 / 8 / 8.), ceil(depthHeight / 2 / 8 / 8.), 1);
|
||||||
|
depthMipmapProgramPtr->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);
|
|
||||||
glViewport(0, 0, frameWidth, frameHeight);
|
glViewport(0, 0, frameWidth, frameHeight);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO);
|
QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO);
|
||||||
finalProgramPtr->bind();
|
finalProgramPtr->bind();
|
||||||
|
|
||||||
finalProgramPtr->setUniformValue("camPos", camera.Position);
|
finalProgramPtr->setUniformValue("camPos", camera.Position);
|
||||||
finalProgramPtr->setUniformValue("lightSpaceMatrix", lightProjection * lightView);
|
//finalProgramPtr->setUniformValue("lightSpaceMatrix", lightProjection * lightView);
|
||||||
//lightPositions[0] = camera.Position;
|
//lightPositions[0] = camera.Position;
|
||||||
finalProgramPtr->setUniformValueArray("lightPositions", lightPositions, 4);
|
//finalProgramPtr->setUniformValueArray("lightPositions", lightPositions, 4);
|
||||||
finalProgramPtr->setUniformValueArray("lightColors", lightColors, 4);
|
//finalProgramPtr->setUniformValueArray("lightColors", lightColors, 4);
|
||||||
|
finalProgramPtr->setUniformValue("view", view);
|
||||||
|
finalProgramPtr->setUniformValue("farPlane", camera.FarPlane);
|
||||||
|
finalProgramPtr->setUniformValueArray("shadowCascadePlaneDistances", light.shadowCascadeLevels.data(), light.shadowCascadeLevels.size(), 1);
|
||||||
|
finalProgramPtr->setUniformValueArray("shadowBiases", light.frustumSizes.data(), light.frustumSizes.size(), 1);
|
||||||
|
//qDebug() << light.frustumSizes;
|
||||||
|
finalProgramPtr->setUniformValue("shadowCascadeCount", (GLint)light.shadowCascadeLevels.size());
|
||||||
|
finalProgramPtr->setUniformValue("mainLightDirection", light.lightDirection);
|
||||||
|
finalProgramPtr->setUniformValue("mainLightRadiance", lightColors[0]);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, gbuffers[0]);
|
glBindTexture(GL_TEXTURE_2D, gbuffers[0]);
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
@ -217,7 +318,9 @@ void RendererWidget::paintGL()
|
||||||
glActiveTexture(GL_TEXTURE3);
|
glActiveTexture(GL_TEXTURE3);
|
||||||
glBindTexture(GL_TEXTURE_2D, gbuffers[3]);
|
glBindTexture(GL_TEXTURE_2D, gbuffers[3]);
|
||||||
glActiveTexture(GL_TEXTURE4);
|
glActiveTexture(GL_TEXTURE4);
|
||||||
glBindTexture(GL_TEXTURE_2D, shadowGbuffers[3]);
|
glBindTexture(GL_TEXTURE_2D, gbuffers[7]);
|
||||||
|
glActiveTexture(GL_TEXTURE5);
|
||||||
|
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowGbuffer);
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
finalProgramPtr->release();
|
finalProgramPtr->release();
|
||||||
}
|
}
|
||||||
|
@ -227,24 +330,23 @@ void RendererWidget::resizeGL(int width, int height)
|
||||||
frameWidth = devicePixelRatioF() * width;
|
frameWidth = devicePixelRatioF() * width;
|
||||||
frameHeight = devicePixelRatioF() * height;
|
frameHeight = devicePixelRatioF() * height;
|
||||||
qDebug() << frameWidth << "x" << frameHeight;
|
qDebug() << frameWidth << "x" << frameHeight;
|
||||||
|
camera.Ratio = (float)frameWidth / (float)frameHeight;
|
||||||
//qDebug() << devicePixelRatioF() << width << height;
|
//qDebug() << devicePixelRatioF() << width << height;
|
||||||
//glViewport(0, 0, (GLint)devicePixelRatio()*width, (GLint)devicePixelRatio()*height);
|
//glViewport(0, 0, (GLint)devicePixelRatio()*width, (GLint)devicePixelRatio()*height);
|
||||||
|
|
||||||
if (fboPtr != nullptr)
|
if (fboPtr != nullptr)
|
||||||
|
{
|
||||||
|
glDeleteTextures(7, gbuffers + 1);
|
||||||
delete fboPtr;
|
delete fboPtr;
|
||||||
fboPtr = new QOpenGLFramebufferObject(frameWidth, frameHeight, QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D);
|
}
|
||||||
|
|
||||||
|
fboPtr = new QOpenGLFramebufferObject(frameWidth, frameHeight, QOpenGLFramebufferObject::NoAttachment, GL_TEXTURE_2D);
|
||||||
if (fboPtr->bind())
|
if (fboPtr->bind())
|
||||||
{
|
{
|
||||||
/*fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RGB16F);
|
|
||||||
fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RGB16F);
|
|
||||||
fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RG8);
|
|
||||||
fboPtr->addColorAttachment(frameWidth, frameHeight, GL_R16F);
|
|
||||||
fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RG16F);*/
|
|
||||||
|
|
||||||
//BaseColor
|
//BaseColor
|
||||||
gbuffers[0] = fboPtr->texture();
|
gbuffers[0] = fboPtr->texture();
|
||||||
|
|
||||||
glGenTextures(5, gbuffers + 1);
|
glGenTextures(7, gbuffers + 1);
|
||||||
//Normal
|
//Normal
|
||||||
glBindTexture(GL_TEXTURE_2D, gbuffers[1]);
|
glBindTexture(GL_TEXTURE_2D, gbuffers[1]);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, frameWidth, frameHeight, 0, GL_RGB, GL_FLOAT, NULL);
|
||||||
|
@ -275,6 +377,30 @@ void RendererWidget::resizeGL(int width, int height)
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
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_MAG_FILTER, GL_NEAREST);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, GL_TEXTURE_2D, gbuffers[5], 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, GL_TEXTURE_2D, gbuffers[5], 0);
|
||||||
|
//Depth
|
||||||
|
glBindTexture(GL_TEXTURE_2D, gbuffers[6]);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, frameWidth, frameHeight, 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);
|
||||||
|
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::begin({ 1.0f, 1.0f, 1.0f, 1.0f }));
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, gbuffers[6], 0);
|
||||||
|
|
||||||
|
depthWidth = ceil(frameWidth / 64.) * 64;
|
||||||
|
depthHeight = ceil(frameHeight / 64.) * 64;
|
||||||
|
qDebug() << depthWidth << depthHeight;
|
||||||
|
glBindTexture(GL_TEXTURE_2D, gbuffers[7]);
|
||||||
|
for (int i = 0; i <= 6; i++)
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, i, GL_R32F, depthWidth / pow(2, i), depthHeight / pow(2, i), 0, GL_RED, GL_FLOAT, NULL);
|
||||||
|
//glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, depthWidth, depthHeight, 0, GL_RED, GL_FLOAT, NULL);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 6);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_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);
|
||||||
|
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::begin({ 1.0f, 1.0f, 1.0f, 1.0f }));
|
||||||
|
|
||||||
GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5 };
|
GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5 };
|
||||||
glDrawBuffers(6, attachments);
|
glDrawBuffers(6, attachments);
|
||||||
|
@ -285,46 +411,43 @@ void RendererWidget::resizeGL(int width, int height)
|
||||||
fboPtr->release();
|
fboPtr->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shadowFboPtr != nullptr)
|
|
||||||
delete shadowFboPtr;
|
|
||||||
|
|
||||||
shadowMapResolution = 1 * std::max(frameWidth, frameHeight);
|
|
||||||
shadowFboPtr = new QOpenGLFramebufferObject(shadowMapResolution, shadowMapResolution);
|
|
||||||
|
|
||||||
if (shadowFboPtr->bind())
|
|
||||||
|
if (shadowFboHandle != 0)
|
||||||
{
|
{
|
||||||
|
glDeleteTextures(1, &shadowGbuffer);
|
||||||
|
glDeleteFramebuffers(1, &shadowFboHandle);
|
||||||
|
}
|
||||||
|
|
||||||
shadowGbuffers[0] = shadowFboPtr->texture();
|
//shadowMapResolution = 1.5 * std::max(frameWidth, frameHeight);
|
||||||
|
shadowMapResolution = 4096;
|
||||||
glGenTextures(3, shadowGbuffers + 1);
|
glGenFramebuffers(1, &shadowFboHandle);
|
||||||
//Normal
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D, shadowGbuffers[1]);
|
glBindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, shadowMapResolution, shadowMapResolution, 0, GL_RGB, GL_FLOAT, NULL);
|
glGenTextures(1, &shadowGbuffer);
|
||||||
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
|
//Depth
|
||||||
glBindTexture(GL_TEXTURE_2D, shadowGbuffers[3]);
|
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowGbuffer);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32,
|
glTexImage3D(
|
||||||
shadowMapResolution, shadowMapResolution, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32F, shadowMapResolution, shadowMapResolution, int(light.shadowCascadeLevels.size()) + 1,
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
|
||||||
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 };
|
/*glBindTexture(GL_TEXTURE_2D, shadowGbuffer);
|
||||||
glDrawBuffers(3, attachments);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32,
|
||||||
|
shadowMapResolution, shadowMapResolution, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);*/
|
||||||
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
|
glTexParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, std::begin({ 1.0f, 1.0f, 1.0f, 1.0f }));
|
||||||
|
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowGbuffer, 0);
|
||||||
|
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadowGbuffer, 0);
|
||||||
|
glDrawBuffer(GL_NONE);
|
||||||
|
glReadBuffer(GL_NONE);
|
||||||
|
|
||||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
qDebug() << "ShadowFramebuffer not complete!";
|
qDebug() << "ShadowFramebuffer not complete!";
|
||||||
shadowFboPtr->release();
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -378,8 +501,8 @@ void RendererWidget::timerEvent(QTimerEvent* event)
|
||||||
camera.ProcessKeyboard(UP, deltaTime);
|
camera.ProcessKeyboard(UP, deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sunSpeed = 10;
|
|
||||||
sunPitch += sunSpeed * deltaTime ;
|
sunPitch += sunSpeed * deltaTime;
|
||||||
if (sunPitch > 120 || sunPitch < 65)
|
if (sunPitch > 120 || sunPitch < 65)
|
||||||
{
|
{
|
||||||
sunSpeed = -sunSpeed;
|
sunSpeed = -sunSpeed;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <QOpenGLFramebufferObject>
|
#include <QOpenGLFramebufferObject>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
|
#include "Light.h"
|
||||||
#include "Model.h"
|
#include "Model.h"
|
||||||
#include "PaintingHelper.h"
|
#include "PaintingHelper.h"
|
||||||
|
|
||||||
|
@ -31,20 +32,26 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int frameWidth, frameHeight;
|
int frameWidth, frameHeight;
|
||||||
|
int depthWidth, depthHeight;
|
||||||
QSet<int> pressedKeys;
|
QSet<int> pressedKeys;
|
||||||
Camera camera;
|
Camera camera;
|
||||||
|
Light light;
|
||||||
clock_t lastFrame;
|
clock_t lastFrame;
|
||||||
float deltaTime;
|
float deltaTime;
|
||||||
int shadowMapResolution;
|
int shadowMapResolution;
|
||||||
|
|
||||||
QOpenGLShaderProgram* shadowProgramPtr = nullptr;
|
QOpenGLShaderProgram* shadowProgramPtr = nullptr;
|
||||||
QOpenGLShaderProgram* modelProgramPtr = nullptr;
|
QOpenGLShaderProgram* modelProgramPtr = nullptr;
|
||||||
QOpenGLShaderProgram* paintingProgramPtr = nullptr;
|
QOpenGLShaderProgram* paintingProgramPtr = nullptr;
|
||||||
QOpenGLShaderProgram* paintingCompProgramPtr = nullptr;
|
QOpenGLShaderProgram* paintingCompProgramPtr = nullptr;
|
||||||
|
QOpenGLShaderProgram* depthInitProgramPtr = nullptr;
|
||||||
|
QOpenGLShaderProgram* depthMipmapProgramPtr = nullptr;
|
||||||
QOpenGLShaderProgram* finalProgramPtr = nullptr;
|
QOpenGLShaderProgram* finalProgramPtr = nullptr;
|
||||||
QOpenGLFramebufferObject* fboPtr = nullptr;
|
QOpenGLFramebufferObject* fboPtr = nullptr;
|
||||||
QOpenGLFramebufferObject* shadowFboPtr = nullptr;
|
GLuint gbuffers[8];
|
||||||
GLuint gbuffers[6];
|
GLuint shadowFboHandle = 0;
|
||||||
GLuint shadowGbuffers[4];
|
GLuint shadowGbuffer;
|
||||||
|
GLuint lightSpaceMatricesUBO;
|
||||||
QOpenGLBuffer quadVBO;
|
QOpenGLBuffer quadVBO;
|
||||||
QOpenGLVertexArrayObject quadVAO;
|
QOpenGLVertexArrayObject quadVAO;
|
||||||
Model* model;
|
Model* model;
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
#version 450 core
|
||||||
|
|
||||||
|
layout (local_size_x = 8, local_size_y = 8) in;
|
||||||
|
|
||||||
|
uniform sampler2D depthBuffer;
|
||||||
|
|
||||||
|
layout(r32f, binding = 0) uniform image2D gDepth;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ivec2 pixelLocation = ivec2(gl_GlobalInvocationID.xy);
|
||||||
|
float depth = textureLod(depthBuffer, vec2(pixelLocation)/textureSize(depthBuffer, 0), 0).r;
|
||||||
|
imageStore(gDepth, pixelLocation, vec4(depth));
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#version 450 core
|
||||||
|
|
||||||
|
layout (local_size_x = 8, local_size_y = 8) in;
|
||||||
|
|
||||||
|
layout(r32f, binding = 0) uniform image2D gDepth[4];
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ivec2 targetLocation = ivec2(gl_GlobalInvocationID.xy);
|
||||||
|
ivec2 sourceLocation = targetLocation * 2;
|
||||||
|
float depth0 = min(imageLoad(gDepth[0], sourceLocation).r, imageLoad(gDepth[0], sourceLocation+ivec2(0,1)).r);
|
||||||
|
float depth1 = min(imageLoad(gDepth[0], sourceLocation+ivec2(1,0)).r, imageLoad(gDepth[0], sourceLocation+ivec2(1,1)).r);
|
||||||
|
imageStore(gDepth[1], targetLocation, vec4(min(depth0,depth1)));
|
||||||
|
if(targetLocation.x%2==0 && targetLocation.y%2==0)
|
||||||
|
{
|
||||||
|
sourceLocation = targetLocation;
|
||||||
|
targetLocation /= 2;
|
||||||
|
float depth0 = min(imageLoad(gDepth[1], sourceLocation).r, imageLoad(gDepth[1], sourceLocation+ivec2(0,1)).r);
|
||||||
|
float depth1 = min(imageLoad(gDepth[1], sourceLocation+ivec2(1,0)).r, imageLoad(gDepth[1], sourceLocation+ivec2(1,1)).r);
|
||||||
|
imageStore(gDepth[2], targetLocation, vec4(min(depth0,depth1)));
|
||||||
|
if(targetLocation.x%2==0 && targetLocation.y%2==0)
|
||||||
|
{
|
||||||
|
sourceLocation = targetLocation;
|
||||||
|
targetLocation /= 2;
|
||||||
|
float depth0 = min(imageLoad(gDepth[2], sourceLocation).r, imageLoad(gDepth[2], sourceLocation+ivec2(0,1)).r);
|
||||||
|
float depth1 = min(imageLoad(gDepth[2], sourceLocation+ivec2(1,0)).r, imageLoad(gDepth[2], sourceLocation+ivec2(1,1)).r);
|
||||||
|
imageStore(gDepth[3], targetLocation, vec4(min(depth0,depth1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,12 +8,23 @@ uniform sampler2D gBaseColor;
|
||||||
uniform sampler2D gNormal;
|
uniform sampler2D gNormal;
|
||||||
uniform sampler2D gPosition;
|
uniform sampler2D gPosition;
|
||||||
uniform sampler2D gMetallicRoughness;
|
uniform sampler2D gMetallicRoughness;
|
||||||
uniform sampler2D gShadowMap;
|
uniform sampler2D gDepth;
|
||||||
|
|
||||||
|
uniform sampler2DArray gShadowMap;
|
||||||
|
layout (std140, binding = 0) uniform LightSpaceMatrices
|
||||||
|
{
|
||||||
|
mat4 lightSpaceMatrices[16];
|
||||||
|
};
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform float farPlane;
|
||||||
|
uniform float shadowCascadePlaneDistances[16];
|
||||||
|
uniform float shadowBiases[16];
|
||||||
|
uniform int shadowCascadeCount;
|
||||||
|
uniform vec3 mainLightDirection;
|
||||||
|
uniform vec3 mainLightRadiance;
|
||||||
// lights
|
// lights
|
||||||
uniform vec3 lightPositions[4];
|
//uniform vec3 lightPositions[4];
|
||||||
uniform vec3 lightColors[4];
|
//uniform vec3 lightColors[4];
|
||||||
uniform mat4 lightSpaceMatrix;
|
|
||||||
|
|
||||||
uniform vec3 camPos;
|
uniform vec3 camPos;
|
||||||
|
|
||||||
|
@ -61,54 +72,99 @@ vec3 fresnelSchlick(float cosTheta, vec3 F0)
|
||||||
|
|
||||||
float Calculate_Avg_Dblockreceiver(vec2 projCoords , int AvgTextureSize)
|
float Calculate_Avg_Dblockreceiver(vec2 projCoords , int AvgTextureSize)
|
||||||
{
|
{
|
||||||
vec2 texelSize =1.0/ textureSize(gShadowMap, 0);
|
vec2 texelSize =1.0/ textureSize(gShadowMap, 0).xy;
|
||||||
float result=0.0f;
|
float result=0.0f;
|
||||||
for(int i=-AvgTextureSize;i<=AvgTextureSize;++i)
|
for(int i=-AvgTextureSize;i<=AvgTextureSize;++i)
|
||||||
{
|
{
|
||||||
for(int j=-AvgTextureSize;j<=AvgTextureSize;j++)
|
for(int j=-AvgTextureSize;j<=AvgTextureSize;j++)
|
||||||
{
|
{
|
||||||
result += texture(gShadowMap, projCoords+vec2(i,j)*texelSize).r;
|
result += texture(gShadowMap, vec3( projCoords+vec2(i,j)*texelSize, 0)).r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result/(AvgTextureSize*AvgTextureSize*2*2);
|
return result/(AvgTextureSize*AvgTextureSize*2*2);
|
||||||
}
|
}
|
||||||
|
|
||||||
float ShadowCalculation(vec4 fragPosLightSpace, float bias)
|
float ShadowCalculation(vec3 fragPosWorldSpace, vec3 normal)
|
||||||
{
|
{
|
||||||
// 执行透视除法
|
// select cascade layer
|
||||||
|
vec4 fragPosViewSpace = view * vec4(fragPosWorldSpace, 1.0);
|
||||||
|
float depthValue = abs(fragPosViewSpace.z);
|
||||||
|
|
||||||
|
int layer = -1;
|
||||||
|
for (int i = 0; i < shadowCascadeCount; ++i)
|
||||||
|
{
|
||||||
|
if (depthValue < shadowCascadePlaneDistances[i])
|
||||||
|
{
|
||||||
|
layer = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (layer == -1)
|
||||||
|
{
|
||||||
|
layer = shadowCascadeCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pcfRadius = 3;
|
||||||
|
float normalBias = 4. /** (1+pcfRadius)*/ * shadowBiases[layer]*max((1.0 - dot(normal, mainLightDirection)), 0.1)/textureSize(gShadowMap, 0).x;
|
||||||
|
vec4 fragPosLightSpace = lightSpaceMatrices[layer] * vec4(fragPosWorldSpace+normal*normalBias, 1.0);
|
||||||
|
// perform perspective divide
|
||||||
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
|
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
|
||||||
// 变换到[0,1]的范围
|
// transform to [0,1] range
|
||||||
projCoords = projCoords * 0.5 + 0.5;
|
projCoords = projCoords * 0.5 + 0.5;
|
||||||
// 取得最近点的深度(使用[0,1]范围下的fragPosLight当坐标)
|
|
||||||
float closestDepth = texture(gShadowMap, projCoords.xy).r;
|
// get depth of current fragment from light's perspective
|
||||||
// 取得当前片段在光源视角下的深度
|
|
||||||
float currentDepth = projCoords.z;
|
float currentDepth = projCoords.z;
|
||||||
|
|
||||||
vec2 texelSize = 1.0 / textureSize(gShadowMap, 0);
|
// keep the shadow at 0.0 when outside the far_plane region of the light's frustum.
|
||||||
float shadow = 0;
|
if (currentDepth > 1.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++)
|
return 0.0;
|
||||||
|
}
|
||||||
|
// calculate bias (based on depth map resolution and slope)
|
||||||
|
|
||||||
|
//float bias = 1* max(0.05 * (1.0 - dot(normal, mainLightDirection)), 0.005);
|
||||||
|
//const float biasModifier = 0.5f;
|
||||||
|
// if (layer == shadowCascadeCount)
|
||||||
|
// {
|
||||||
|
// bias *= 1 / (farPlane * biasModifier);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// bias *= 1 / (shadowCascadePlaneDistances[layer] * biasModifier);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// PCF
|
||||||
|
float shadow = 0.0;
|
||||||
|
vec2 texelSize = 1.0 / vec2(textureSize(gShadowMap, 0));
|
||||||
|
for(int x = -pcfRadius; x <= pcfRadius; ++x)
|
||||||
{
|
{
|
||||||
// 采样周围点在ShadowMap中的深度
|
for(int y = -pcfRadius; y <= pcfRadius; ++y)
|
||||||
float closestDepth = texture(gShadowMap, projCoords.xy+vec2(i,j)*texelSize).r;
|
{
|
||||||
shadow += (currentDepth - bias) > closestDepth ? 1.0 : 0.0;
|
float pcfDepth = texture(gShadowMap, vec3(projCoords.xy + vec2(x, y) * texelSize, layer)).r;
|
||||||
|
//shadow += (currentDepth - bias) > pcfDepth ? 1.0 : 0.0;
|
||||||
|
shadow += currentDepth > pcfDepth ? 1.0 : 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
shadow /= (2*pcfRadius+1)*(2*pcfRadius+1);
|
||||||
|
|
||||||
return shadow/(fliterArea*fliterArea);
|
return shadow;
|
||||||
//return clamp(shadow/(fliterArea*fliterArea),0.,1.);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//FragColor = vec4(vec3(textureLod(gDepth, TexCoords, 1).x), 1.0);
|
||||||
|
//FragColor -= vec4(vec3(textureLod(gDepth, TexCoords, 0).x), 1.0);
|
||||||
|
//ivec2 depthCoords = ivec2(TexCoords*(textureSize(gDepth,0)-ivec2(1)) + vec2(0.5));
|
||||||
|
//float depth = texelFetch(gDepth, depthCoords/64, 6).x;
|
||||||
|
//depth -= texelFetch(gDepth, depthCoords, 0).x;
|
||||||
|
//FragColor = vec4(vec3(depth*10000),1);
|
||||||
|
//FragColor = vec4(vec3(textureSize(gShadowMap, 0)-vec3(1)),1);
|
||||||
|
//FragColor = vec4(texture(gBaseColor, TexCoords).rgb, 1);
|
||||||
|
//return;
|
||||||
|
|
||||||
|
|
||||||
vec3 albedo = pow(texture(gBaseColor, TexCoords).rgb, vec3(2.2));
|
vec3 albedo = pow(texture(gBaseColor, TexCoords).rgb, vec3(2.2));
|
||||||
float metallic = texture(gMetallicRoughness, TexCoords).r;
|
float metallic = texture(gMetallicRoughness, TexCoords).r;
|
||||||
float roughness = texture(gMetallicRoughness, TexCoords).g;
|
float roughness = texture(gMetallicRoughness, TexCoords).g;
|
||||||
|
@ -119,7 +175,7 @@ void main()
|
||||||
|
|
||||||
if(WorldPos==vec3(0))
|
if(WorldPos==vec3(0))
|
||||||
{
|
{
|
||||||
vec3 color = lightColors[0];
|
vec3 color = mainLightRadiance;
|
||||||
|
|
||||||
color = color / (color + vec3(1.0));
|
color = color / (color + vec3(1.0));
|
||||||
color = pow(color, vec3(1.0/2.2));
|
color = pow(color, vec3(1.0/2.2));
|
||||||
|
@ -128,7 +184,6 @@ void main()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 FragPosLightSpace = lightSpaceMatrix * vec4(WorldPos, 1.0);
|
|
||||||
|
|
||||||
vec3 V = normalize(camPos - WorldPos);
|
vec3 V = normalize(camPos - WorldPos);
|
||||||
|
|
||||||
|
@ -138,13 +193,13 @@ void main()
|
||||||
// reflectance equation
|
// reflectance equation
|
||||||
vec3 Lo = vec3(0.0);
|
vec3 Lo = vec3(0.0);
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
// calculate per-light radiance
|
// calculate per-light radiance
|
||||||
vec3 L = normalize(lightPositions[i] - WorldPos);
|
vec3 L = normalize(mainLightDirection);
|
||||||
vec3 H = normalize(V + L);
|
vec3 H = normalize(V + L);
|
||||||
float distance = length(lightPositions[i] - WorldPos);
|
//float distance = length(lightPositions[i] - WorldPos);
|
||||||
float attenuation = 1.0 / (distance * distance);
|
//float attenuation = 1.0 / (distance * distance);
|
||||||
vec3 radiance = lightColors[i] * attenuation;
|
vec3 radiance = mainLightRadiance ;//* attenuation;
|
||||||
|
|
||||||
// cook-torrance brdf
|
// cook-torrance brdf
|
||||||
float NDF = DistributionGGX(N, H, roughness);
|
float NDF = DistributionGGX(N, H, roughness);
|
||||||
|
@ -166,16 +221,22 @@ void main()
|
||||||
|
|
||||||
vec3 ambient = vec3(0.03) * albedo;
|
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;
|
|
||||||
|
|
||||||
|
|
||||||
|
//vec4 FragPosLightSpace = lightSpaceMatrix * vec4(WorldPos, 1.0);
|
||||||
|
//float bias = 0.08 * max(0.05 * (1.0 - dot(N, L)), 0.005);
|
||||||
|
float shadow = ShadowCalculation(WorldPos, N);
|
||||||
|
|
||||||
|
//vec3 color = ambient + Lo;
|
||||||
|
//vec3 color = indirect*1;
|
||||||
|
vec3 color = ambient + (1.0 - shadow) * Lo;
|
||||||
|
//vec3 color = (1.0 - shadow) * Lo;
|
||||||
|
//vec3 color = (1.0 - shadow) * Lo + indirect*10;
|
||||||
color = color / (color + vec3(1.0));
|
color = color / (color + vec3(1.0));
|
||||||
color = pow(color, vec3(1.0/2.2));
|
color = pow(color, vec3(1.0/2.2));
|
||||||
|
|
||||||
FragColor = vec4(color, 1.0);
|
FragColor = vec4(color, 1.0);
|
||||||
//FragColor = vec4(vec3(shadow), 1);
|
//FragColor = vec4(vec3(shadow), 1);
|
||||||
//FragColor = vec4(texture(gShadowMap, TexCoords).rgb, 1.0);
|
//FragColor = vec4(texture(gShadowNormal, TexCoords).rgb, 1.0);
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,42 +1,13 @@
|
||||||
#version 450 core
|
#version 450 core
|
||||||
|
|
||||||
|
|
||||||
uniform sampler2D texture_basecolor;
|
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 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()
|
void main()
|
||||||
{
|
{
|
||||||
//gBaseColor = vec4(1,0,0,1);
|
//gBaseColor = vec4(1,0,0,1);
|
||||||
gBaseColor = texture(texture_basecolor, TexCoords);
|
vec4 baseColor = texture(texture_basecolor, TexCoords);
|
||||||
if(gBaseColor.a<0.4)
|
if(baseColor.a<0.4)
|
||||||
discard;
|
discard;
|
||||||
gPosition = WorldPos;
|
|
||||||
gNormal = getNormalFromMap();
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
#version 450 core
|
||||||
|
|
||||||
|
layout(triangles, invocations = 5) in;
|
||||||
|
layout(triangle_strip, max_vertices = 3) out;
|
||||||
|
|
||||||
|
layout (std140, binding = 0) uniform LightSpaceMatrices
|
||||||
|
{
|
||||||
|
mat4 lightSpaceMatrices[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
in vec2 vTexCoords[];
|
||||||
|
out vec2 TexCoords;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
TexCoords = vTexCoords[i];
|
||||||
|
gl_Position = lightSpaceMatrices[gl_InvocationID] * gl_in[i].gl_Position;
|
||||||
|
gl_Layer = gl_InvocationID;
|
||||||
|
EmitVertex();
|
||||||
|
}
|
||||||
|
EndPrimitive();
|
||||||
|
}
|
|
@ -3,19 +3,12 @@ layout (location = 0) in vec3 aPos;
|
||||||
layout (location = 1) in vec3 aNormal;
|
layout (location = 1) in vec3 aNormal;
|
||||||
layout (location = 2) in vec2 aTexCoords;
|
layout (location = 2) in vec2 aTexCoords;
|
||||||
|
|
||||||
out vec2 TexCoords;
|
out vec2 vTexCoords;
|
||||||
out vec3 WorldPos;
|
|
||||||
out vec3 Normal;
|
|
||||||
|
|
||||||
uniform mat4 model;
|
uniform mat4 model;
|
||||||
uniform mat4 view;
|
|
||||||
uniform mat4 projection;
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
TexCoords = aTexCoords;
|
vTexCoords = aTexCoords;
|
||||||
WorldPos = vec3(model * vec4(aPos, 1.0));
|
gl_Position = model * vec4(aPos, 1.0);
|
||||||
Normal = mat3(model) * aNormal;
|
|
||||||
|
|
||||||
gl_Position = projection * view * vec4(WorldPos, 1.0);
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue