改用论文的分割方案,实现画线
parent
ddff01d880
commit
fa112820cc
|
@ -117,6 +117,8 @@
|
||||||
<None Include="Shaders\painting.vert" />
|
<None Include="Shaders\painting.vert" />
|
||||||
<None Include="Shaders\shader.frag" />
|
<None Include="Shaders\shader.frag" />
|
||||||
<None Include="Shaders\shader.vert" />
|
<None Include="Shaders\shader.vert" />
|
||||||
|
<None Include="Shaders\shadow_mapping.comp" />
|
||||||
|
<None Include="Shaders\ssgi.comp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="BvhTree.h" />
|
<ClInclude Include="BvhTree.h" />
|
||||||
|
|
|
@ -116,6 +116,12 @@
|
||||||
<None Include="Shaders\model_shadow.geom">
|
<None Include="Shaders\model_shadow.geom">
|
||||||
<Filter>Resource Files\Shaders</Filter>
|
<Filter>Resource Files\Shaders</Filter>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="Shaders\shadow_mapping.comp">
|
||||||
|
<Filter>Resource Files\Shaders</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="Shaders\ssgi.comp">
|
||||||
|
<Filter>Resource Files\Shaders</Filter>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Camera.h">
|
<ClInclude Include="Camera.h">
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
<file>Shaders/model.vert</file>
|
<file>Shaders/model.vert</file>
|
||||||
<file>Shaders/final.frag</file>
|
<file>Shaders/final.frag</file>
|
||||||
<file>Shaders/final.vert</file>
|
<file>Shaders/final.vert</file>
|
||||||
<file>container.jpg</file>
|
|
||||||
<file>Shaders/painting.frag</file>
|
<file>Shaders/painting.frag</file>
|
||||||
<file>Shaders/painting.vert</file>
|
<file>Shaders/painting.vert</file>
|
||||||
<file>Shaders/painting.comp</file>
|
<file>Shaders/painting.comp</file>
|
||||||
|
@ -15,5 +14,7 @@
|
||||||
<file>Shaders/depth_mipmap.comp</file>
|
<file>Shaders/depth_mipmap.comp</file>
|
||||||
<file>Shaders/depth_init.comp</file>
|
<file>Shaders/depth_init.comp</file>
|
||||||
<file>Shaders/model_shadow.geom</file>
|
<file>Shaders/model_shadow.geom</file>
|
||||||
|
<file>Shaders/shadow_mapping.comp</file>
|
||||||
|
<file>Shaders/ssgi.comp</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -191,10 +191,9 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
|
||||||
7,0, 7,GLuint(30. / 360 * 65536 + 1 * 65536) /*右儿子用来表示旋转角度和zIndex*/, 8,0, 7,0,
|
7,0, 7,GLuint(30. / 360 * 65536 + 1 * 65536) /*右儿子用来表示旋转角度和zIndex*/, 8,0, 7,0,
|
||||||
//elememt0
|
//elememt0
|
||||||
1,2,
|
1,2,
|
||||||
5 + 0/*contour索引*/,5 + 12/*style索引,在elementData中位置*/, 3,4,
|
3 + 20/*contour索引,由于contour不定长,这里需要给到contour在elementIndex中位置*/,3 + 14/*style索引,在elementData中位置*/, 3+24,3+14,
|
||||||
5 + 2,5 + 12, 5 + 1,5 + 12,
|
|
||||||
//elememt1
|
//elememt1
|
||||||
1 + 0/*line索引,element中第几条*/,1 + 25
|
1 + 0/*line索引,element中第几条*/,1 + 27
|
||||||
|
|
||||||
};
|
};
|
||||||
std::vector<QVector4D> bvhBounds = {
|
std::vector<QVector4D> bvhBounds = {
|
||||||
|
@ -204,49 +203,43 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
|
||||||
QVector4D(-0.8,-0.8,-0.2,-0.1), QVector4D(-0.7,0.2,-0.2,0.7), QVector4D(0.2,-0.8,0.8,-0.1), QVector4D(0.2,0.1,0.8,0.8),
|
QVector4D(-0.8,-0.8,-0.2,-0.1), QVector4D(-0.7,0.2,-0.2,0.7), QVector4D(0.2,-0.8,0.8,-0.1), QVector4D(0.2,0.1,0.8,0.8),
|
||||||
//elememt0
|
//elememt0
|
||||||
QVector4D(-1,-1,1,1),
|
QVector4D(-1,-1,1,1),
|
||||||
QVector4D(-1,-0.5,1,1), QVector4D(-1,-1,1,0.5),
|
QVector4D(-1,-1,-0.2,1), QVector4D(-0.2,-1,1,1),
|
||||||
QVector4D(-1,-1,1,-0.5), QVector4D(-1,-0.5,1,0.5),
|
//elememt1
|
||||||
//elememt1
|
QVector4D(-1,0,1,1)
|
||||||
QVector4D(-1,0,1,1),
|
|
||||||
};
|
};
|
||||||
std::vector<GLuint> elementOffset = {
|
std::vector<GLuint> elementOffset = {
|
||||||
//element0
|
//element0
|
||||||
7, //elementBvhRoot
|
7, //elementBvhRoot
|
||||||
5, //elementBvhLength
|
3, //elementBvhLength
|
||||||
0, //pointsOffset
|
0, //pointsOffset
|
||||||
0, //linesOffset
|
0, //linesOffset
|
||||||
28, //contoursOffset
|
|
||||||
//element1
|
//element1
|
||||||
12, //elementBvhRoot
|
10, //elementBvhRoot
|
||||||
1, //elementBvhLength
|
1, //elementBvhLength
|
||||||
19, //pointsOffset
|
21, //pointsOffset
|
||||||
40, //linesOffset
|
28, //linesOffset
|
||||||
44 //contoursOffset
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<GLuint> elementIndex = {
|
std::vector<GLuint> elementIndex = {
|
||||||
//element0
|
//element0
|
||||||
//lines, 全部当作三阶贝塞尔, 每条线四个点索引
|
//lines, 全部当作三阶贝塞尔, 每条线四个点索引
|
||||||
4,2,2,0,
|
0,1,1,2,
|
||||||
0,0,1,1,
|
0,0,3,3,
|
||||||
1,1,4,4,
|
3,4,4,5,
|
||||||
1,1,5,5,
|
2,2,5,5,
|
||||||
4,4,5,5,
|
5,5,6,6,
|
||||||
1,1,3,3,
|
//contours, 第一个元素为线数,后面为轮廓线索引
|
||||||
3,3,5,5,
|
3, 1,2,4,
|
||||||
//contours, 每个轮廓三个线索引
|
3, 0,2,3,
|
||||||
0,1,2,
|
//element1
|
||||||
2,3,4,
|
|
||||||
3,5,6,
|
|
||||||
//element2
|
|
||||||
//lines
|
//lines
|
||||||
0,1,2
|
0,1,1,2
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<GLfloat> elementData = {
|
std::vector<GLfloat> elementData = {
|
||||||
//element0
|
//element0
|
||||||
//points
|
//points
|
||||||
-1,0.5, -1,-0.5, 0,1, 0,-1, 1,0.5, 1,-0.5,
|
-0.2,1, -0.2,-0.2, 1,-0.2, -1,1, -1,-1, 1,-1, 1,1,
|
||||||
//fillStyle
|
//fillStyle
|
||||||
//fill
|
//fill
|
||||||
0,
|
0,
|
||||||
|
|
|
@ -13,9 +13,13 @@ RendererWidget::RendererWidget(QWidget* parent)
|
||||||
, camera(QVector3D(0.0f, 100.0f, 0.0f))
|
, camera(QVector3D(0.0f, 100.0f, 0.0f))
|
||||||
, light(&camera)
|
, light(&camera)
|
||||||
{
|
{
|
||||||
startTimer(1000 / QGuiApplication::primaryScreen()->refreshRate());
|
//startTimer(1000 / QGuiApplication::primaryScreen()->refreshRate());
|
||||||
|
startTimer(1);
|
||||||
lastFrame = std::clock();
|
lastFrame = std::clock();
|
||||||
setFocusPolicy(Qt::StrongFocus);
|
setFocusPolicy(Qt::StrongFocus);
|
||||||
|
QSurfaceFormat format;
|
||||||
|
format.setSwapInterval(0);
|
||||||
|
setFormat(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
RendererWidget::~RendererWidget()
|
RendererWidget::~RendererWidget()
|
||||||
|
@ -97,6 +101,18 @@ void RendererWidget::initializeGL()
|
||||||
if (!depthMipmapProgramPtr->link())
|
if (!depthMipmapProgramPtr->link())
|
||||||
qDebug() << "ERROR:" << depthMipmapProgramPtr->log();
|
qDebug() << "ERROR:" << depthMipmapProgramPtr->log();
|
||||||
|
|
||||||
|
shadowMappingProgramPtr = new QOpenGLShaderProgram;
|
||||||
|
if (!shadowMappingProgramPtr->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/shadow_mapping.comp"))
|
||||||
|
qDebug() << "ERROR:" << shadowMappingProgramPtr->log();
|
||||||
|
if (!shadowMappingProgramPtr->link())
|
||||||
|
qDebug() << "ERROR:" << shadowMappingProgramPtr->log();
|
||||||
|
|
||||||
|
ssgiProgramPtr = new QOpenGLShaderProgram;
|
||||||
|
if (!ssgiProgramPtr->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/ssgi.comp"))
|
||||||
|
qDebug() << "ERROR:" << ssgiProgramPtr->log();
|
||||||
|
if (!ssgiProgramPtr->link())
|
||||||
|
qDebug() << "ERROR:" << ssgiProgramPtr->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();
|
||||||
|
@ -116,17 +132,34 @@ void RendererWidget::initializeGL()
|
||||||
|
|
||||||
|
|
||||||
depthInitProgramPtr->bind();
|
depthInitProgramPtr->bind();
|
||||||
depthInitProgramPtr->setUniformValue("depthBuffer", 6);
|
depthInitProgramPtr->setUniformValue("depthBuffer", 0);
|
||||||
depthInitProgramPtr->release();
|
depthInitProgramPtr->release();
|
||||||
|
|
||||||
|
shadowMappingProgramPtr->bind();
|
||||||
|
shadowMappingProgramPtr->setUniformValue("gBaseColor", 0);
|
||||||
|
shadowMappingProgramPtr->setUniformValue("gNormal", 1);
|
||||||
|
shadowMappingProgramPtr->setUniformValue("gPosition", 2);
|
||||||
|
shadowMappingProgramPtr->setUniformValue("gMetallicRoughness", 3);
|
||||||
|
shadowMappingProgramPtr->setUniformValue("gShadowMap", 4);
|
||||||
|
shadowMappingProgramPtr->release();
|
||||||
|
|
||||||
|
ssgiProgramPtr->bind();
|
||||||
|
ssgiProgramPtr->setUniformValue("gBaseColor", 0);
|
||||||
|
ssgiProgramPtr->setUniformValue("gNormal", 1);
|
||||||
|
ssgiProgramPtr->setUniformValue("gPosition", 2);
|
||||||
|
ssgiProgramPtr->setUniformValue("gMetallicRoughness", 3);
|
||||||
|
ssgiProgramPtr->setUniformValue("gDepth", 4);
|
||||||
|
ssgiProgramPtr->setUniformValue("gDirectLight", 5);
|
||||||
|
|
||||||
finalProgramPtr->bind();
|
finalProgramPtr->bind();
|
||||||
finalProgramPtr->setUniformValue("gBaseColor", 0);
|
finalProgramPtr->setUniformValue("gBaseColor", 0);
|
||||||
finalProgramPtr->setUniformValue("gNormal", 1);
|
finalProgramPtr->setUniformValue("gDirectLight", 1);
|
||||||
|
finalProgramPtr->setUniformValue("gIndirectLight", 2);
|
||||||
|
/*finalProgramPtr->setUniformValue("gNormal", 1);
|
||||||
finalProgramPtr->setUniformValue("gPosition", 2);
|
finalProgramPtr->setUniformValue("gPosition", 2);
|
||||||
finalProgramPtr->setUniformValue("gMetallicRoughness", 3);
|
finalProgramPtr->setUniformValue("gMetallicRoughness", 3);
|
||||||
finalProgramPtr->setUniformValue("gDepth", 4);
|
finalProgramPtr->setUniformValue("gDepth", 4);
|
||||||
finalProgramPtr->setUniformValue("gShadowMap", 5);
|
finalProgramPtr->setUniformValue("gDirectLight", 5);*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -193,46 +226,29 @@ 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[] = { 20 * 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;
|
static int sunSpeed = 10;
|
||||||
void RendererWidget::paintGL()
|
void RendererWidget::paintGL()
|
||||||
{
|
{
|
||||||
QMatrix4x4 lightProjection;
|
|
||||||
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.setX(cos(qDegreesToRadians(sunPitch)) * cos(qDegreesToRadians(sunYaw)));
|
||||||
light.lightDirection.setY(sin(qDegreesToRadians(sunPitch)));
|
light.lightDirection.setY(sin(qDegreesToRadians(sunPitch)));
|
||||||
light.lightDirection.setZ(cos(qDegreesToRadians(sunPitch)) * sin(qDegreesToRadians(sunYaw)));
|
light.lightDirection.setZ(cos(qDegreesToRadians(sunPitch)) * sin(qDegreesToRadians(sunYaw)));
|
||||||
light.lightDirection.normalize();
|
light.lightDirection.normalize();
|
||||||
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));
|
|
||||||
|
|
||||||
const std::vector<QMatrix4x4> lightMatrices = light.getLightSpaceMatrices();
|
const std::vector<QMatrix4x4> lightMatrices = light.getLightSpaceMatrices();
|
||||||
//qDebug() << lightMatrices;
|
//qDebug() << lightMatrices;
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, lightSpaceMatricesUBO);
|
glBindBuffer(GL_UNIFORM_BUFFER, lightSpaceMatricesUBO);
|
||||||
|
|
||||||
for (size_t i = 0; i < lightMatrices.size(); i++)
|
for (size_t i = 0; i < lightMatrices.size(); i++)
|
||||||
{
|
{
|
||||||
glBufferSubData(GL_UNIFORM_BUFFER, i * 16 * sizeof(GLfloat), 16 * sizeof(GLfloat), lightMatrices[i].data());
|
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);
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
{
|
{
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle);
|
glBindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle);
|
||||||
glViewport(0, 0, shadowMapResolution, shadowMapResolution);
|
glViewport(0, 0, shadowMapResolution, shadowMapResolution);
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
/*shadowProgramPtr->bind();
|
|
||||||
shadowProgramPtr->setUniformValue("projection", lightProjection);
|
|
||||||
shadowProgramPtr->setUniformValue("view", lightView);
|
|
||||||
shadowProgramPtr->setUniformValue("mainLightPositon", lightPositions[0]);
|
|
||||||
shadowProgramPtr->setUniformValue("mainLightColor", lightColors[0]);
|
|
||||||
shadowProgramPtr->release();*/
|
|
||||||
//glCullFace(GL_FRONT);
|
//glCullFace(GL_FRONT);
|
||||||
model->drawShadow();
|
model->drawShadow();
|
||||||
//glCullFace(GL_BACK);
|
//glCullFace(GL_BACK);
|
||||||
|
@ -262,19 +278,16 @@ void RendererWidget::paintGL()
|
||||||
}
|
}
|
||||||
|
|
||||||
paintingCompProgramPtr->bind();
|
paintingCompProgramPtr->bind();
|
||||||
//glActiveTexture(GL_TEXTURE4);
|
|
||||||
//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);
|
||||||
glBindImageTexture(3, gbuffers[5], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG32F);
|
glBindImageTexture(3, gbuffers[5], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG32F);
|
||||||
|
|
||||||
glDispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1);
|
glDispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1);
|
||||||
//glDispatchCompute(1,1, 1);
|
|
||||||
paintingCompProgramPtr->release();
|
paintingCompProgramPtr->release();
|
||||||
|
|
||||||
depthInitProgramPtr->bind();
|
depthInitProgramPtr->bind();
|
||||||
glActiveTexture(GL_TEXTURE6);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, gbuffers[6]);
|
glBindTexture(GL_TEXTURE_2D, gbuffers[6]);
|
||||||
glBindImageTexture(0, gbuffers[7], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
|
glBindImageTexture(0, gbuffers[7], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
|
||||||
glDispatchCompute(ceil(depthWidth / 8.), ceil(depthHeight / 8.), 1);
|
glDispatchCompute(ceil(depthWidth / 8.), ceil(depthHeight / 8.), 1);
|
||||||
|
@ -289,26 +302,38 @@ void RendererWidget::paintGL()
|
||||||
glDispatchCompute(ceil(depthWidth / 2 / 8 / 8.), ceil(depthHeight / 2 / 8 / 8.), 1);
|
glDispatchCompute(ceil(depthWidth / 2 / 8 / 8.), ceil(depthHeight / 2 / 8 / 8.), 1);
|
||||||
depthMipmapProgramPtr->release();
|
depthMipmapProgramPtr->release();
|
||||||
|
|
||||||
|
shadowMappingProgramPtr->bind();
|
||||||
|
shadowMappingProgramPtr->setUniformValue("view", view);
|
||||||
glViewport(0, 0, frameWidth, frameHeight);
|
shadowMappingProgramPtr->setUniformValue("farPlane", camera.FarPlane);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
shadowMappingProgramPtr->setUniformValueArray("shadowCascadePlaneDistances", light.shadowCascadeLevels.data(), light.shadowCascadeLevels.size(), 1);
|
||||||
QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO);
|
shadowMappingProgramPtr->setUniformValueArray("shadowBiases", light.frustumSizes.data(), light.frustumSizes.size(), 1);
|
||||||
finalProgramPtr->bind();
|
|
||||||
|
|
||||||
finalProgramPtr->setUniformValue("camPos", camera.Position);
|
|
||||||
//finalProgramPtr->setUniformValue("lightSpaceMatrix", lightProjection * lightView);
|
|
||||||
//lightPositions[0] = camera.Position;
|
|
||||||
//finalProgramPtr->setUniformValueArray("lightPositions", lightPositions, 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;
|
//qDebug() << light.frustumSizes;
|
||||||
finalProgramPtr->setUniformValue("shadowCascadeCount", (GLint)light.shadowCascadeLevels.size());
|
shadowMappingProgramPtr->setUniformValue("shadowCascadeCount", (GLint)light.shadowCascadeLevels.size());
|
||||||
finalProgramPtr->setUniformValue("mainLightDirection", light.lightDirection);
|
shadowMappingProgramPtr->setUniformValue("camPos", camera.Position);
|
||||||
finalProgramPtr->setUniformValue("mainLightRadiance", lightColors[0]);
|
shadowMappingProgramPtr->setUniformValue("mainLightDirection", light.lightDirection);
|
||||||
|
shadowMappingProgramPtr->setUniformValue("mainLightRadiance", lightColors[0]);
|
||||||
|
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]);
|
||||||
|
glActiveTexture(GL_TEXTURE4);
|
||||||
|
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowGbuffer);
|
||||||
|
glBindImageTexture(1, gbuffers[8], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA16F);
|
||||||
|
glDispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1);
|
||||||
|
shadowMappingProgramPtr->release();
|
||||||
|
|
||||||
|
ssgiProgramPtr->bind();
|
||||||
|
ssgiProgramPtr->setUniformValue("camPos", camera.Position);
|
||||||
|
ssgiProgramPtr->setUniformValue("cameraMatrix", projection * view);
|
||||||
|
ssgiProgramPtr->setUniformValue("projectionMatrix", projection);
|
||||||
|
ssgiProgramPtr->setUniformValue("viewMatrix", view);
|
||||||
|
ssgiProgramPtr->setUniformValue("mainLightDirection", light.lightDirection);
|
||||||
|
ssgiProgramPtr->setUniformValue("mainLightRadiance", lightColors[0]);
|
||||||
|
ssgiProgramPtr->setUniformValue("rdSeed", QVector4D(rand(), rand(), rand(), rand()));
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, gbuffers[0]);
|
glBindTexture(GL_TEXTURE_2D, gbuffers[0]);
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
@ -320,7 +345,34 @@ void RendererWidget::paintGL()
|
||||||
glActiveTexture(GL_TEXTURE4);
|
glActiveTexture(GL_TEXTURE4);
|
||||||
glBindTexture(GL_TEXTURE_2D, gbuffers[7]);
|
glBindTexture(GL_TEXTURE_2D, gbuffers[7]);
|
||||||
glActiveTexture(GL_TEXTURE5);
|
glActiveTexture(GL_TEXTURE5);
|
||||||
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowGbuffer);
|
glBindTexture(GL_TEXTURE_2D, gbuffers[8]);
|
||||||
|
glBindImageTexture(1, gbuffers[9], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA16F);
|
||||||
|
glDispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1);
|
||||||
|
ssgiProgramPtr->release();
|
||||||
|
|
||||||
|
glViewport(0, 0, frameWidth, frameHeight);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO);
|
||||||
|
finalProgramPtr->bind();
|
||||||
|
/*finalProgramPtr->setUniformValue("camPos", camera.Position);
|
||||||
|
finalProgramPtr->setUniformValue("mainLightDirection", light.lightDirection);
|
||||||
|
finalProgramPtr->setUniformValue("mainLightRadiance", lightColors[0]);*/
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, gbuffers[0]);
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, gbuffers[8]);
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, gbuffers[9]);
|
||||||
|
//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]);
|
||||||
|
//glActiveTexture(GL_TEXTURE4);
|
||||||
|
//glBindTexture(GL_TEXTURE_2D, gbuffers[7]);
|
||||||
|
//glActiveTexture(GL_TEXTURE5);
|
||||||
|
//glBindTexture(GL_TEXTURE_2D, gbuffers[8]);
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
finalProgramPtr->release();
|
finalProgramPtr->release();
|
||||||
}
|
}
|
||||||
|
@ -336,7 +388,7 @@ void RendererWidget::resizeGL(int width, int height)
|
||||||
|
|
||||||
if (fboPtr != nullptr)
|
if (fboPtr != nullptr)
|
||||||
{
|
{
|
||||||
glDeleteTextures(7, gbuffers + 1);
|
glDeleteTextures(9, gbuffers + 1);
|
||||||
delete fboPtr;
|
delete fboPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,7 +398,7 @@ void RendererWidget::resizeGL(int width, int height)
|
||||||
//BaseColor
|
//BaseColor
|
||||||
gbuffers[0] = fboPtr->texture();
|
gbuffers[0] = fboPtr->texture();
|
||||||
|
|
||||||
glGenTextures(7, gbuffers + 1);
|
glGenTextures(9, 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);
|
||||||
|
@ -387,13 +439,20 @@ void RendererWidget::resizeGL(int width, int height)
|
||||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::begin({ 1.0f, 1.0f, 1.0f, 1.0f }));
|
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);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, gbuffers[6], 0);
|
||||||
|
|
||||||
|
GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5 };
|
||||||
|
glDrawBuffers(6, attachments);
|
||||||
|
//gbuffers = fboPtr->textures();
|
||||||
|
|
||||||
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
qDebug() << "Framebuffer not complete!";
|
||||||
|
|
||||||
|
//HiZ, not bind to fbo
|
||||||
depthWidth = ceil(frameWidth / 64.) * 64;
|
depthWidth = ceil(frameWidth / 64.) * 64;
|
||||||
depthHeight = ceil(frameHeight / 64.) * 64;
|
depthHeight = ceil(frameHeight / 64.) * 64;
|
||||||
qDebug() << depthWidth << depthHeight;
|
qDebug() << depthWidth << depthHeight;
|
||||||
glBindTexture(GL_TEXTURE_2D, gbuffers[7]);
|
glBindTexture(GL_TEXTURE_2D, gbuffers[7]);
|
||||||
for (int i = 0; i <= 6; i++)
|
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, 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_BASE_LEVEL, 0);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 6);
|
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_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||||
|
@ -401,13 +460,17 @@ void RendererWidget::resizeGL(int width, int height)
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 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 }));
|
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::begin({ 1.0f, 1.0f, 1.0f, 1.0f }));
|
||||||
|
//DirectLight
|
||||||
|
glBindTexture(GL_TEXTURE_2D, gbuffers[8]);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, frameWidth, frameHeight, 0, GL_RGBA, GL_FLOAT, NULL);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
//InDirectLight
|
||||||
|
glBindTexture(GL_TEXTURE_2D, gbuffers[9]);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, frameWidth, frameHeight, 0, GL_RGBA, GL_FLOAT, NULL);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5 };
|
|
||||||
glDrawBuffers(6, attachments);
|
|
||||||
//gbuffers = fboPtr->textures();
|
|
||||||
|
|
||||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
|
||||||
qDebug() << "Framebuffer not complete!";
|
|
||||||
fboPtr->release();
|
fboPtr->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,7 +484,7 @@ void RendererWidget::resizeGL(int width, int height)
|
||||||
}
|
}
|
||||||
|
|
||||||
//shadowMapResolution = 1.5 * std::max(frameWidth, frameHeight);
|
//shadowMapResolution = 1.5 * std::max(frameWidth, frameHeight);
|
||||||
shadowMapResolution = 4096;
|
shadowMapResolution = 2048;
|
||||||
glGenFramebuffers(1, &shadowFboHandle);
|
glGenFramebuffers(1, &shadowFboHandle);
|
||||||
{
|
{
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle);
|
glBindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle);
|
||||||
|
|
|
@ -46,9 +46,11 @@ private:
|
||||||
QOpenGLShaderProgram* paintingCompProgramPtr = nullptr;
|
QOpenGLShaderProgram* paintingCompProgramPtr = nullptr;
|
||||||
QOpenGLShaderProgram* depthInitProgramPtr = nullptr;
|
QOpenGLShaderProgram* depthInitProgramPtr = nullptr;
|
||||||
QOpenGLShaderProgram* depthMipmapProgramPtr = nullptr;
|
QOpenGLShaderProgram* depthMipmapProgramPtr = nullptr;
|
||||||
|
QOpenGLShaderProgram* shadowMappingProgramPtr = nullptr;
|
||||||
|
QOpenGLShaderProgram* ssgiProgramPtr = nullptr;
|
||||||
QOpenGLShaderProgram* finalProgramPtr = nullptr;
|
QOpenGLShaderProgram* finalProgramPtr = nullptr;
|
||||||
QOpenGLFramebufferObject* fboPtr = nullptr;
|
QOpenGLFramebufferObject* fboPtr = nullptr;
|
||||||
GLuint gbuffers[8];
|
GLuint gbuffers[10];
|
||||||
GLuint shadowFboHandle = 0;
|
GLuint shadowFboHandle = 0;
|
||||||
GLuint shadowGbuffer;
|
GLuint shadowGbuffer;
|
||||||
GLuint lightSpaceMatricesUBO;
|
GLuint lightSpaceMatricesUBO;
|
||||||
|
|
|
@ -9,6 +9,6 @@ layout(r32f, binding = 0) uniform image2D gDepth;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
ivec2 pixelLocation = ivec2(gl_GlobalInvocationID.xy);
|
ivec2 pixelLocation = ivec2(gl_GlobalInvocationID.xy);
|
||||||
float depth = textureLod(depthBuffer, vec2(pixelLocation)/textureSize(depthBuffer, 0), 0).r;
|
float depth = textureLod(depthBuffer, vec2(pixelLocation+vec2(0.5))/textureSize(depthBuffer, 0), 0).r;
|
||||||
imageStore(gDepth, pixelLocation, vec4(depth));
|
imageStore(gDepth, pixelLocation, vec4(depth));
|
||||||
}
|
}
|
|
@ -9,22 +9,11 @@ uniform sampler2D gNormal;
|
||||||
uniform sampler2D gPosition;
|
uniform sampler2D gPosition;
|
||||||
uniform sampler2D gMetallicRoughness;
|
uniform sampler2D gMetallicRoughness;
|
||||||
uniform sampler2D gDepth;
|
uniform sampler2D gDepth;
|
||||||
|
uniform sampler2D gDirectLight;
|
||||||
|
uniform sampler2D gIndirectLight;
|
||||||
|
|
||||||
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 mainLightDirection;
|
||||||
uniform vec3 mainLightRadiance;
|
uniform vec3 mainLightRadiance;
|
||||||
// lights
|
|
||||||
//uniform vec3 lightPositions[4];
|
|
||||||
//uniform vec3 lightColors[4];
|
|
||||||
|
|
||||||
uniform vec3 camPos;
|
uniform vec3 camPos;
|
||||||
|
|
||||||
|
@ -70,87 +59,6 @@ vec3 fresnelSchlick(float cosTheta, vec3 F0)
|
||||||
return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
|
return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
float Calculate_Avg_Dblockreceiver(vec2 projCoords , int AvgTextureSize)
|
|
||||||
{
|
|
||||||
vec2 texelSize =1.0/ textureSize(gShadowMap, 0).xy;
|
|
||||||
float result=0.0f;
|
|
||||||
for(int i=-AvgTextureSize;i<=AvgTextureSize;++i)
|
|
||||||
{
|
|
||||||
for(int j=-AvgTextureSize;j<=AvgTextureSize;j++)
|
|
||||||
{
|
|
||||||
result += texture(gShadowMap, vec3( projCoords+vec2(i,j)*texelSize, 0)).r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result/(AvgTextureSize*AvgTextureSize*2*2);
|
|
||||||
}
|
|
||||||
|
|
||||||
float ShadowCalculation(vec3 fragPosWorldSpace, vec3 normal, out int layer)
|
|
||||||
{
|
|
||||||
// select cascade layer
|
|
||||||
vec4 fragPosViewSpace = view * vec4(fragPosWorldSpace, 1.0);
|
|
||||||
float depthValue = abs(fragPosViewSpace.z);
|
|
||||||
|
|
||||||
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;
|
|
||||||
// transform to [0,1] range
|
|
||||||
projCoords = projCoords * 0.5 + 0.5;
|
|
||||||
|
|
||||||
// get depth of current fragment from light's perspective
|
|
||||||
float currentDepth = projCoords.z;
|
|
||||||
|
|
||||||
// keep the shadow at 0.0 when outside the far_plane region of the light's frustum.
|
|
||||||
if (currentDepth > 1.0)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
for(int y = -pcfRadius; y <= pcfRadius; ++y)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -161,19 +69,24 @@ void main()
|
||||||
//depth -= texelFetch(gDepth, depthCoords, 0).x;
|
//depth -= texelFetch(gDepth, depthCoords, 0).x;
|
||||||
//FragColor = vec4(vec3(depth*10000),1);
|
//FragColor = vec4(vec3(depth*10000),1);
|
||||||
//FragColor = vec4(vec3(textureSize(gShadowMap, 0)-vec3(1)),1);
|
//FragColor = vec4(vec3(textureSize(gShadowMap, 0)-vec3(1)),1);
|
||||||
//FragColor = vec4(texture(gBaseColor, TexCoords).rgb, 1);
|
//FragColor = vec4(texture(gRadiance, TexCoords).rgb, 1);
|
||||||
//return;
|
vec3 albedo = pow(texture(gBaseColor, TexCoords).rgb, vec3(2.2));
|
||||||
|
vec3 color = albedo * texture(gIndirectLight, TexCoords).rgb + texture(gDirectLight, TexCoords).rgb;
|
||||||
|
color = color / (color + vec3(1.0));
|
||||||
|
color = pow(color, vec3(1.0/2.2));
|
||||||
|
FragColor = vec4(color, 1.0);
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
|
||||||
vec3 N = normalize(texture(gNormal, TexCoords).xyz);
|
vec3 N = texture(gNormal, TexCoords).xyz;
|
||||||
vec3 WorldPos = texture(gPosition, TexCoords).xyz;
|
vec3 WorldPos = texture(gPosition, TexCoords).xyz;
|
||||||
|
|
||||||
if(WorldPos==vec3(0))
|
if(N==vec3(0))
|
||||||
{
|
{
|
||||||
vec3 color = mainLightRadiance;
|
vec3 color = mainLightRadiance;
|
||||||
|
|
||||||
|
@ -225,12 +138,13 @@ void main()
|
||||||
|
|
||||||
//vec4 FragPosLightSpace = lightSpaceMatrix * vec4(WorldPos, 1.0);
|
//vec4 FragPosLightSpace = lightSpaceMatrix * vec4(WorldPos, 1.0);
|
||||||
//float bias = 0.08 * max(0.05 * (1.0 - dot(N, L)), 0.005);
|
//float bias = 0.08 * max(0.05 * (1.0 - dot(N, L)), 0.005);
|
||||||
int debugLayer;
|
//int debugLayer;
|
||||||
float shadow = ShadowCalculation(WorldPos, N, debugLayer);
|
//float shadow = ShadowCalculation(WorldPos, N, debugLayer);
|
||||||
|
|
||||||
//vec3 color = ambient + Lo;
|
//vec3 color = ambient + Lo;
|
||||||
//vec3 color = indirect*1;
|
//vec3 color = indirect*1;
|
||||||
vec3 color = ambient + (1.0 - shadow) * Lo;
|
float directLight = texture(gDirectLight, TexCoords).r;
|
||||||
|
color = ambient + directLight * Lo;
|
||||||
//color*=mix(mix(vec3(1,0,0), vec3(0,1,0), float(debugLayer)/shadowCascadeCount/0.5),
|
//color*=mix(mix(vec3(1,0,0), vec3(0,1,0), float(debugLayer)/shadowCascadeCount/0.5),
|
||||||
//mix(vec3(0,1,0), vec3(0,0,1), float(debugLayer)/(shadowCascadeCount)/0.5-1), float(debugLayer)/(shadowCascadeCount));
|
//mix(vec3(0,1,0), vec3(0,0,1), float(debugLayer)/(shadowCascadeCount)/0.5-1), float(debugLayer)/(shadowCascadeCount));
|
||||||
//vec3 color = (1.0 - shadow) * Lo;
|
//vec3 color = (1.0 - shadow) * Lo;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,177 @@
|
||||||
|
#version 450 core
|
||||||
|
|
||||||
|
layout (local_size_x = 8, local_size_y = 8) in;
|
||||||
|
|
||||||
|
uniform sampler2D gBaseColor;
|
||||||
|
uniform sampler2D gNormal;
|
||||||
|
uniform sampler2D gPosition;
|
||||||
|
uniform sampler2D gMetallicRoughness;
|
||||||
|
uniform sampler2DArray gShadowMap;
|
||||||
|
layout(rgba16f, binding = 1) uniform image2D gDirectLight;
|
||||||
|
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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
float ShadowCalculation(vec3 fragPosWorldSpace, vec3 normal, out int layer)
|
||||||
|
{
|
||||||
|
// select cascade layer
|
||||||
|
vec4 fragPosViewSpace = view * vec4(fragPosWorldSpace, 1.0);
|
||||||
|
float depthValue = abs(fragPosViewSpace.z);
|
||||||
|
|
||||||
|
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;
|
||||||
|
// transform to [0,1] range
|
||||||
|
projCoords = projCoords * 0.5 + 0.5;
|
||||||
|
|
||||||
|
// get depth of current fragment from light's perspective
|
||||||
|
float currentDepth = projCoords.z;
|
||||||
|
|
||||||
|
// keep the shadow at 0.0 when outside the far_plane region of the light's frustum.
|
||||||
|
if (currentDepth > 1.0)
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PCF
|
||||||
|
float shadow = 0.0;
|
||||||
|
vec2 texelSize = 1.0 / vec2(textureSize(gShadowMap, 0));
|
||||||
|
for(int x = -pcfRadius; x <= pcfRadius; ++x)
|
||||||
|
{
|
||||||
|
for(int y = -pcfRadius; y <= pcfRadius; ++y)
|
||||||
|
{
|
||||||
|
float pcfDepth = texture(gShadowMap, vec3(projCoords.xy + vec2(x, y) * texelSize, layer)).r;
|
||||||
|
shadow += currentDepth > pcfDepth ? 1.0 : 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shadow /= (2*pcfRadius+1)*(2*pcfRadius+1);
|
||||||
|
|
||||||
|
return shadow;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ivec2 pixelLocation = ivec2(gl_GlobalInvocationID.xy);
|
||||||
|
|
||||||
|
vec3 albedo = pow(texelFetch(gBaseColor, pixelLocation, 0).rgb, vec3(2.2));
|
||||||
|
float metallic = texelFetch(gMetallicRoughness, pixelLocation, 0).r;
|
||||||
|
float roughness = texelFetch(gMetallicRoughness, pixelLocation, 0).g;
|
||||||
|
|
||||||
|
vec3 worldPos = texelFetch(gPosition, pixelLocation,0).xyz;
|
||||||
|
vec3 normal = texelFetch(gNormal, pixelLocation,0).xyz;
|
||||||
|
|
||||||
|
if(normal==vec3(0))
|
||||||
|
{
|
||||||
|
vec3 color = mainLightRadiance;
|
||||||
|
|
||||||
|
//color = color / (color + vec3(1.0));
|
||||||
|
//color = pow(color, vec3(1.0/2.2));
|
||||||
|
|
||||||
|
imageStore(gDirectLight, pixelLocation, vec4(color, 1.0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3 V = normalize(camPos - worldPos);
|
||||||
|
|
||||||
|
vec3 F0 = vec3(0.04);
|
||||||
|
F0 = mix(F0, albedo, metallic);
|
||||||
|
|
||||||
|
// calculate light radiance
|
||||||
|
vec3 L = normalize(mainLightDirection);
|
||||||
|
vec3 H = normalize(V + L);
|
||||||
|
//float distance = length(lightPositions[i] - WorldPos);
|
||||||
|
//float attenuation = 1.0 / (distance * distance);
|
||||||
|
vec3 radiance = mainLightRadiance ;//* attenuation;
|
||||||
|
|
||||||
|
// cook-torrance brdf
|
||||||
|
float NDF = DistributionGGX(normal, H, roughness);
|
||||||
|
float G = GeometrySmith(normal, V, L, roughness);
|
||||||
|
vec3 F = fresnelSchlick(clamp(dot(H, V),0.,1.), 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(normal, V), 0.0) * max(dot(normal, L), 0.0) + 0.001;
|
||||||
|
vec3 specular = nominator / denominator;
|
||||||
|
|
||||||
|
float NdotL = max(dot(normal, L), 0.0);
|
||||||
|
vec3 Lo = (kD * albedo / PI + specular) * radiance * NdotL;
|
||||||
|
|
||||||
|
int debugLayer;
|
||||||
|
float shadow = ShadowCalculation(worldPos, normal, debugLayer);
|
||||||
|
|
||||||
|
imageStore(gDirectLight, pixelLocation, vec4((1-shadow)*Lo, 1));
|
||||||
|
}
|
|
@ -0,0 +1,413 @@
|
||||||
|
#version 450 core
|
||||||
|
|
||||||
|
layout (local_size_x = 8, local_size_y = 8) in;
|
||||||
|
|
||||||
|
layout(rgba16f, binding = 1) uniform image2D gIndirectLight;
|
||||||
|
|
||||||
|
uniform sampler2D gBaseColor;
|
||||||
|
uniform sampler2D gNormal;
|
||||||
|
uniform sampler2D gPosition;
|
||||||
|
uniform sampler2D gMetallicRoughness;
|
||||||
|
uniform sampler2D gDepth;
|
||||||
|
uniform sampler2D gDirectLight;
|
||||||
|
|
||||||
|
uniform float u_Near = 10;
|
||||||
|
uniform float u_Far = 5000;
|
||||||
|
uniform vec3 camPos;
|
||||||
|
uniform mat4 cameraMatrix;
|
||||||
|
uniform mat4 projectionMatrix;
|
||||||
|
uniform mat4 viewMatrix;
|
||||||
|
|
||||||
|
uniform vec3 mainLightDirection;
|
||||||
|
uniform vec3 mainLightRadiance;
|
||||||
|
|
||||||
|
#define PI 3.14159265359
|
||||||
|
#define HIZ_START_LEVEL 0
|
||||||
|
#define HIZ_STOP_LEVEL 0
|
||||||
|
#define HIZ_MAX_LEVEL 6
|
||||||
|
#define MAX_ITERATIONS 60
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 mainLightRadianceCalculation(ivec2 fragPos, vec3 targetWorldPos, vec3 worldPos)
|
||||||
|
{
|
||||||
|
if(texelFetch(gDirectLight, fragPos, 0).rgb==vec3(0))
|
||||||
|
return vec3(0);
|
||||||
|
vec3 albedo = pow(texelFetch(gBaseColor, fragPos, 0).rgb, vec3(2.2));
|
||||||
|
vec3 normal = texelFetch(gNormal, fragPos, 0).xyz;
|
||||||
|
float metallic = texelFetch(gMetallicRoughness, fragPos, 0).r;
|
||||||
|
float roughness = texelFetch(gMetallicRoughness, fragPos, 0).g;
|
||||||
|
|
||||||
|
vec3 V = normalize(targetWorldPos - worldPos);
|
||||||
|
|
||||||
|
vec3 F0 = vec3(0.04);
|
||||||
|
F0 = mix(F0, albedo, metallic);
|
||||||
|
|
||||||
|
// calculate light radiance
|
||||||
|
vec3 L = normalize(mainLightDirection);
|
||||||
|
vec3 H = normalize(V + L);
|
||||||
|
|
||||||
|
vec3 radiance = mainLightRadiance ;
|
||||||
|
|
||||||
|
// cook-torrance brdf
|
||||||
|
float NDF = DistributionGGX(normal, H, roughness);
|
||||||
|
float G = GeometrySmith(normal, V, L, roughness);
|
||||||
|
vec3 F = fresnelSchlick(clamp(dot(H, V),0.,1.), F0);
|
||||||
|
|
||||||
|
vec3 kS = F;
|
||||||
|
vec3 kD = vec3(1.0) - kS;
|
||||||
|
kD *= 1.0 - metallic;
|
||||||
|
|
||||||
|
vec3 nominator = NDF * G * F;
|
||||||
|
float denominator = 4.0 * max(dot(normal, V), 0.0) * max(dot(normal, L), 0.0) + 0.001;
|
||||||
|
vec3 specular = nominator / denominator;
|
||||||
|
|
||||||
|
float NdotL = max(dot(normal, L), 0.0);
|
||||||
|
return (kD * albedo / PI + specular) * radiance * NdotL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 indirectLightRadianceCalculation(ivec2 fragPos, vec3 lightPos, vec3 lightRadiance)
|
||||||
|
{
|
||||||
|
//if(texelFetch(gDirectLight, fragPos, 0).rgb!=vec3(0))
|
||||||
|
// return vec3(0);
|
||||||
|
vec3 albedo = pow(texelFetch(gBaseColor, fragPos, 0).rgb, vec3(2.2));
|
||||||
|
vec3 worldPos = texelFetch(gPosition, fragPos, 0).xyz;
|
||||||
|
vec3 normal = texelFetch(gNormal, fragPos, 0).xyz;
|
||||||
|
float metallic = texelFetch(gMetallicRoughness, fragPos, 0).r;
|
||||||
|
float roughness = texelFetch(gMetallicRoughness, fragPos, 0).g;
|
||||||
|
|
||||||
|
vec3 V = normalize(camPos - worldPos);
|
||||||
|
|
||||||
|
vec3 F0 = vec3(0.04);
|
||||||
|
F0 = mix(F0, albedo, metallic);
|
||||||
|
|
||||||
|
// calculate light radiance
|
||||||
|
vec3 L = normalize(lightPos - worldPos);
|
||||||
|
vec3 H = normalize(V + L);
|
||||||
|
float distance = length(lightPos - worldPos);
|
||||||
|
float attenuation = 1.0 / (distance * distance);
|
||||||
|
vec3 radiance = lightRadiance * attenuation;
|
||||||
|
|
||||||
|
// cook-torrance brdf
|
||||||
|
float NDF = DistributionGGX(normal, H, roughness);
|
||||||
|
float G = GeometrySmith(normal, V, L, roughness);
|
||||||
|
vec3 F = fresnelSchlick(clamp(dot(H, V),0.,1.), F0);
|
||||||
|
|
||||||
|
vec3 kS = F;
|
||||||
|
vec3 kD = vec3(1.0) - kS;
|
||||||
|
kD *= 1.0 - metallic;
|
||||||
|
|
||||||
|
//float NdotL = max(dot(normal, L), 0.0);
|
||||||
|
return kD * radiance;
|
||||||
|
//return kD * albedo * radiance* (dot(normal, L)>0?1:0);
|
||||||
|
//return (kD * albedo / PI ) * radiance * NdotL;
|
||||||
|
}
|
||||||
|
|
||||||
|
float LinearizeDepth(float vDepth)
|
||||||
|
{
|
||||||
|
float z = vDepth * 2.0 - 1.0;
|
||||||
|
return (2.0 * u_Near * u_Far) / (u_Far + u_Near - z * (u_Far - u_Near));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Ray
|
||||||
|
{
|
||||||
|
vec3 o;
|
||||||
|
vec3 d;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ScreenSpaceRay
|
||||||
|
{
|
||||||
|
vec3 o;
|
||||||
|
vec3 d;
|
||||||
|
float tmax;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SSTraceRecord
|
||||||
|
{
|
||||||
|
Ray ray;
|
||||||
|
float tmax;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HitRecord
|
||||||
|
{
|
||||||
|
float t;
|
||||||
|
vec2 pixel;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
vec3 projectToViewSpace(vec3 vPointInViewSpace)
|
||||||
|
{
|
||||||
|
return vec3(viewMatrix * vec4(vPointInViewSpace,1));
|
||||||
|
}
|
||||||
|
vec4 projectToScreenSpace(vec3 vPoint)
|
||||||
|
{
|
||||||
|
return projectionMatrix * vec4(vPoint,1);
|
||||||
|
}
|
||||||
|
vec3 ndcToPixel(vec4 p)
|
||||||
|
{
|
||||||
|
vec3 pos = p.xyz/p.w;
|
||||||
|
pos= (pos+1)/2;
|
||||||
|
pos.xy*=textureSize(gBaseColor,0);
|
||||||
|
//pos.z = -LinearizeDepth(pos.z);
|
||||||
|
//pos.z = -(pos.z);
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool testHit(vec3 p, int level)
|
||||||
|
{
|
||||||
|
//float sampleDepth = -LinearizeDepth(texelFetch(gDepth, ivec2(p.xy/exp2(level)) ,level).r);
|
||||||
|
//return p.z < sampleDepth && sampleDepth-p.z<50;
|
||||||
|
float sampleDepth = (texelFetch(gDepth, ivec2(p.xy/exp2(level)) ,level).r);
|
||||||
|
return p.z > sampleDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenSpaceRay create_ss_ray(const Ray ray, float tmax)
|
||||||
|
{
|
||||||
|
|
||||||
|
vec3 p0 = projectToViewSpace(ray.o);
|
||||||
|
vec3 d = normalize(mat3(viewMatrix) * ray.d);
|
||||||
|
if(d.z > 0.0){
|
||||||
|
tmax = min(tmax, abs(p0.z / d.z) * 0.999);
|
||||||
|
}
|
||||||
|
vec3 p1 = p0 + tmax * d;
|
||||||
|
p0 = ndcToPixel(projectToScreenSpace(p0));
|
||||||
|
p1 = ndcToPixel(projectToScreenSpace(p1));
|
||||||
|
ScreenSpaceRay ssray;
|
||||||
|
ssray.o = p0;
|
||||||
|
d = p1 - p0;
|
||||||
|
float len = length(d.xy);
|
||||||
|
ssray.d = d / len;
|
||||||
|
ssray.tmax = len;
|
||||||
|
return ssray;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool trace(const in SSTraceRecord record, inout HitRecord hit, inout vec3 debug)
|
||||||
|
{
|
||||||
|
ivec2 screenSize = textureSize(gBaseColor,0);
|
||||||
|
ScreenSpaceRay ray = create_ss_ray(record.ray, record.tmax);
|
||||||
|
if(dot(ray.d, ray.d)< 1e-5){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
debug = vec3(normalize(vec2(ray.d.xy)), 0.0);
|
||||||
|
float march_step_base = 1.01;
|
||||||
|
vec3 dir = normalize(ray.d);
|
||||||
|
float t = 1.001;
|
||||||
|
ivec2 prev_pixel = ivec2(ray.o.xy);
|
||||||
|
int level = 0;
|
||||||
|
|
||||||
|
int accum_level0_steps = 0;
|
||||||
|
|
||||||
|
while(t < ray.tmax){
|
||||||
|
float march_step = march_step_base;
|
||||||
|
for(int i =0;i<level;i++){
|
||||||
|
march_step *= 1.6;
|
||||||
|
}
|
||||||
|
float next_t = t + march_step;
|
||||||
|
|
||||||
|
vec3 p = ray.o + ray.d * next_t;
|
||||||
|
ivec2 pixel = ivec2(p.xy);
|
||||||
|
bool oob = false;
|
||||||
|
if(any(greaterThanEqual(pixel, screenSize)))
|
||||||
|
oob = true;
|
||||||
|
if(any(lessThan(pixel, ivec2(0))))
|
||||||
|
oob = true;
|
||||||
|
if(next_t > ray.tmax || oob){
|
||||||
|
if(level == 0)
|
||||||
|
break;
|
||||||
|
level--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(testHit(p, level)) {
|
||||||
|
if(level == 0){
|
||||||
|
hit.t = next_t;
|
||||||
|
hit.pixel = p.xy;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
level--;
|
||||||
|
continue;
|
||||||
|
}else{
|
||||||
|
t = next_t;
|
||||||
|
}
|
||||||
|
if(level == 0){
|
||||||
|
accum_level0_steps++;
|
||||||
|
}else{
|
||||||
|
accum_level0_steps = 0;
|
||||||
|
}
|
||||||
|
if(level == 0){
|
||||||
|
if(accum_level0_steps >= 8) {
|
||||||
|
level = min(level+1,HIZ_MAX_LEVEL);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
level = min(level+1,HIZ_MAX_LEVEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetTangentSpace(vec3 normal, inout vec3 tangent, inout vec3 binormal)
|
||||||
|
{
|
||||||
|
// Choose a helper vector for the cross product
|
||||||
|
vec3 helper = vec3(1, 0, 0);
|
||||||
|
if (abs(normal.x) > 0.99)
|
||||||
|
helper = vec3(0, 0, 1);
|
||||||
|
// Generate vectors
|
||||||
|
tangent = normalize(cross(normal, helper));
|
||||||
|
binormal = normalize(cross(normal, tangent));
|
||||||
|
}
|
||||||
|
float RandXY(float x, float y){
|
||||||
|
return fract(cos(x * (12.9898) + y * (4.1414)) * 43758.5453);
|
||||||
|
}
|
||||||
|
uniform vec4 rdSeed;
|
||||||
|
float rdCnt=0;
|
||||||
|
float Rand(){
|
||||||
|
float a = RandXY(gl_GlobalInvocationID.x, rdSeed[0]);
|
||||||
|
float b = RandXY(rdSeed[1], gl_GlobalInvocationID.y);
|
||||||
|
float c = RandXY(rdCnt++, rdSeed[2]);
|
||||||
|
float d = RandXY(rdSeed[3], a);
|
||||||
|
float e = RandXY(b, c);
|
||||||
|
float f = RandXY(d, e);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
vec3 randomOnHemisphere(vec3 normal, float alpha)
|
||||||
|
{
|
||||||
|
//p(w)=(¦Á+1)/2¦Ð*cos<w,n>^¦Á
|
||||||
|
float theta = (2.0 * PI * Rand());
|
||||||
|
float phi = acos(pow(Rand(), 1.0 / (alpha + 1.0)));
|
||||||
|
vec3 v = vec3((sin(phi) * cos(theta)), (sin(phi) * sin(theta)), cos(phi));
|
||||||
|
|
||||||
|
vec3 tangent, binormal;
|
||||||
|
GetTangentSpace(normal, tangent, binormal);
|
||||||
|
return vec3(dot(v, vec3(tangent.x, binormal.x, normal.x)), dot(v, vec3(tangent.y, binormal.y, normal.y)), dot(v, vec3(tangent.z, binormal.z, normal.z)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ivec2 pixelLocation = ivec2(gl_GlobalInvocationID.xy);
|
||||||
|
|
||||||
|
vec3 worldPos = texelFetch(gPosition, pixelLocation,0).xyz;
|
||||||
|
vec4 viewPos = viewMatrix * vec4(worldPos,1);
|
||||||
|
vec3 normal = texelFetch(gNormal, pixelLocation,0).xyz;
|
||||||
|
|
||||||
|
if(normal==vec3(0))
|
||||||
|
{
|
||||||
|
imageStore(gIndirectLight, pixelLocation, vec4(0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//vec3 albedo = pow(texelFetch(gBaseColor, pixelLocation, 0).rgb, vec3(2.2));
|
||||||
|
vec3 ambient = vec3(0.03);
|
||||||
|
imageStore(gIndirectLight, pixelLocation, vec4(ambient,1));
|
||||||
|
return;
|
||||||
|
vec3 color=vec3(0);
|
||||||
|
int spp=1;
|
||||||
|
for(int i=0;i<spp;i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
Ray ray;
|
||||||
|
ray.o = worldPos;
|
||||||
|
ray.d = normalize(randomOnHemisphere(normal, 1));
|
||||||
|
SSTraceRecord traceRecord;
|
||||||
|
traceRecord.ray = ray;
|
||||||
|
traceRecord.tmax = 500;
|
||||||
|
HitRecord hitRecord;
|
||||||
|
vec3 debug;
|
||||||
|
|
||||||
|
bool Hit = trace(traceRecord, hitRecord, debug);
|
||||||
|
|
||||||
|
if(Hit)
|
||||||
|
{
|
||||||
|
vec3 hitWorldPos = texelFetch(gPosition, ivec2(hitRecord.pixel), 0).xyz;;
|
||||||
|
vec3 lightRadiance = mainLightRadianceCalculation(ivec2(hitRecord.pixel), worldPos, hitWorldPos);
|
||||||
|
vec3 indirectRadiance = indirectLightRadianceCalculation(pixelLocation, hitWorldPos, lightRadiance*10000);
|
||||||
|
color+=indirectRadiance;
|
||||||
|
|
||||||
|
//color+= pow(texelFetch(gBaseColor, ivec2(result.UV), 0).rgb, vec3(2.2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
imageStore(gIndirectLight, pixelLocation, vec4(color/spp, 1));
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(normal.y>0.95)
|
||||||
|
{
|
||||||
|
normal = vec3(0,1,0);
|
||||||
|
|
||||||
|
|
||||||
|
Ray ray;
|
||||||
|
ray.o = worldPos;
|
||||||
|
ray.d = normalize(reflect(worldPos-camPos, normal));
|
||||||
|
SSTraceRecord traceRecord;
|
||||||
|
traceRecord.ray = ray;
|
||||||
|
traceRecord.tmax = 6000;
|
||||||
|
HitRecord hitRecord;
|
||||||
|
vec3 debug;
|
||||||
|
|
||||||
|
bool Hit = trace(traceRecord, hitRecord, debug);
|
||||||
|
|
||||||
|
// Ray ray;
|
||||||
|
// ray.Origin = worldPos;
|
||||||
|
// ray.Direction = normalize(reflect(worldPos-camPos, normal));
|
||||||
|
// //ray.Direction = normalize(vec3(0,1,0));
|
||||||
|
// ray.Origin += normal* (-viewPos.z / u_Far * 2 + 0.5);
|
||||||
|
// Result result = hiZTrace(ray);
|
||||||
|
//vec4 result = hiZTrace(pixelLocation, textureSize(gBaseColor, 0), worldPos, reflect(normalize(worldPos-camPos), normal));
|
||||||
|
|
||||||
|
if(Hit)
|
||||||
|
{
|
||||||
|
//imageStore(gIndirectLight, pixelLocation, vec4(1,0,0,1));
|
||||||
|
imageStore(gIndirectLight, pixelLocation, pow(texelFetch(gBaseColor, ivec2(hitRecord.pixel), 0), vec4(2.2)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
imageStore(gIndirectLight, pixelLocation, vec4(1,1,0,1));
|
||||||
|
//imageStore(gIndirectLight, pixelLocation, pow(texelFetch(gBaseColor, ivec2(result.UV), 0), vec4(2.2)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
imageStore(gIndirectLight, pixelLocation, pow(texelFetch(gBaseColor, pixelLocation, 0), vec4(2.2)));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 119 KiB |
Loading…
Reference in New Issue