支持线条方角,调整BVH叶子结点编码方式,级联阴影平滑过渡,添加滑动条便于调整光源

dev-VirtualTexture
wuyize 2022-10-02 22:19:19 +08:00
parent fa112820cc
commit 898b08e023
9 changed files with 216 additions and 64 deletions

View File

@ -14,7 +14,7 @@ Light::Light(Camera* camera)
+ (1 - lambda) * (camera->NearPlane + i / levelCount * (camera->FarPlane - camera->NearPlane))); + (1 - lambda) * (camera->NearPlane + i / levelCount * (camera->FarPlane - camera->NearPlane)));
//qDebug() << shadowCascadeLevels[i-1]; //qDebug() << shadowCascadeLevels[i-1];
} }
shadowCascadeLevels.push_back(camera->FarPlane);
} }
@ -127,19 +127,19 @@ std::vector<QMatrix4x4> Light::getLightSpaceMatrices()
{ {
std::vector<QMatrix4x4> ret; std::vector<QMatrix4x4> ret;
frustumSizes.clear(); frustumSizes.clear();
for (size_t i = 0; i < shadowCascadeLevels.size() + 1; ++i) for (size_t i = 0; i < shadowCascadeLevels.size(); ++i)
{ {
if (i == 0) if (i == 0)
{ {
ret.push_back(getLightSpaceMatrix(camera->NearPlane, shadowCascadeLevels[i])); ret.push_back(getLightSpaceMatrix(camera->NearPlane, shadowCascadeLevels[i]));
} }
else if (i < shadowCascadeLevels.size()) else if (i == 1)
{ {
ret.push_back(getLightSpaceMatrix(shadowCascadeLevels[i - 1], shadowCascadeLevels[i])); ret.push_back(getLightSpaceMatrix((1 - blendRatio) * shadowCascadeLevels[i - 1] + blendRatio * camera->NearPlane, shadowCascadeLevels[i]));
} }
else else
{ {
ret.push_back(getLightSpaceMatrix(shadowCascadeLevels[i - 1], camera->FarPlane)); ret.push_back(getLightSpaceMatrix((1 - blendRatio) * shadowCascadeLevels[i - 1] + blendRatio * shadowCascadeLevels[i - 2], shadowCascadeLevels[i]));
} }
} }
return ret; return ret;

View File

@ -14,6 +14,7 @@ class Light
public: public:
QVector3D lightDirection = QVector3D(0.2, 4, 1).normalized(); QVector3D lightDirection = QVector3D(0.2, 4, 1).normalized();
std::vector<float> shadowCascadeLevels; std::vector<float> shadowCascadeLevels;
float blendRatio = 0.3;
std::vector<float> frustumSizes; std::vector<float> frustumSizes;
Model* model; Model* model;
Light(Camera* camera); Light(Camera* camera);

View File

@ -1,9 +1,15 @@
#include "MainWindow.h" #include "MainWindow.h"
#include "RendererWidget.h"
#include "qslider.h"
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
{ {
ui.setupUi(this); ui.setupUi(this);
QObject::connect(ui.horizontalSlider, &QSlider::valueChanged,
ui.openGLWidget, &RendererWidget::setMainLightPitch);
QObject::connect(ui.horizontalSlider_2, &QSlider::valueChanged,
ui.openGLWidget, &RendererWidget::setMainLightYaw);
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()

View File

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>600</width> <width>800</width>
<height>400</height> <height>400</height>
</rect> </rect>
</property> </property>
@ -14,9 +14,71 @@
<string>MainWindow</string> <string>MainWindow</string>
</property> </property>
<widget class="QWidget" name="centralWidget"> <widget class="QWidget" name="centralWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item> <item>
<widget class="RendererWidget" name="openGLWidget"/> <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<widget class="RendererWidget" name="openGLWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QSlider" name="horizontalSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>180</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="horizontalSlider_2">
<property name="maximum">
<number>360</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item> </item>
</layout> </layout>
</widget> </widget>

View File

@ -114,6 +114,12 @@ void Model::processNode(aiNode* node, const aiScene* scene, aiMatrix4x4 mat4)
processNode(node->mChildren[i], scene, mat4 * node->mChildren[i]->mTransformation); processNode(node->mChildren[i], scene, mat4 * node->mChildren[i]->mTransformation);
} }
} }
GLuint encodeChild(GLuint index)
{
return 0x80000000 + index;
}
Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model) Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model)
{ {
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex]; aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
@ -188,12 +194,12 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
//root //root
1,2, 1,2,
3,4, 5,6, 3,4, 5,6,
7,0, 7,GLuint(30. / 360 * 65536 + 1 * 65536) /*右儿子用来表示旋转角度和zIndex*/, 8,0, 7,0, encodeChild(0),0, encodeChild(0),GLuint(30. / 360 * 65536 + 1 * 65536) /*右儿子用来表示旋转角度和zIndex*/, encodeChild(1),0, encodeChild(0),0,
//elememt0 //elememt0
1,2, 1,2,
3 + 20/*contour索引由于contour不定长这里需要给到contour在elementIndex中位置*/,3 + 14/*style索引在elementData中位置*/, 3+24,3+14, encodeChild(20)/*contour索引由于contour不定长这里需要给到contour在elementIndex中位置*/,14/*style索引在elementData中位置*/, encodeChild(24), 14,
//elememt1 //elememt1
1 + 0/*line索引element中第几条*/,1 + 27 encodeChild(0)/*line索引element中第几条*/, 27
}; };
std::vector<QVector4D> bvhBounds = { std::vector<QVector4D> bvhBounds = {
@ -205,7 +211,7 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
QVector4D(-1,-1,1,1), QVector4D(-1,-1,1,1),
QVector4D(-1,-1,-0.2,1), QVector4D(-0.2,-1,1,1), QVector4D(-1,-1,-0.2,1), QVector4D(-0.2,-1,1,1),
//elememt1 //elememt1
QVector4D(-1,0,1,1) QVector4D(-1,-1,1,1)
}; };
std::vector<GLuint> elementOffset = { std::vector<GLuint> elementOffset = {
//element0 //element0
@ -250,7 +256,7 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
//element1 //element1
//points //points
-1,0.5, 0,1, 1,0.5, 0,0.8, 1,0, 0,-0.8,
//strokeStyle //strokeStyle
//stroke //stroke
1, 1,
@ -260,8 +266,14 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
0, //Ô²½Ç 0, //Ô²½Ç
//strokeFillType //strokeFillType
0, //µ¥É« 0, //µ¥É«
//线类型
1, //左侧
//线外描边宽度
0,
//线外描边方式
0, //单色
//strokeFillColorMetallicRoughness //strokeFillColorMetallicRoughness
0,1,0, 0,0.8 1,0,1, 0,0.8
}; };
//m_mesh->paintingIndex = paintingHelper->addPainting(bounds.size(), std::vector<GLuint>(children.begin()+2, children.end()), bounds, //m_mesh->paintingIndex = paintingHelper->addPainting(bounds.size(), std::vector<GLuint>(children.begin()+2, children.end()), bounds,

View File

@ -7,6 +7,10 @@
#include <QGuiApplication> #include <QGuiApplication>
#include <random> #include <random>
//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) };
static float sunPitch = 90, sunYaw = 80;
static int sunSpeed = 10;
RendererWidget::RendererWidget(QWidget* parent) RendererWidget::RendererWidget(QWidget* parent)
: QOpenGLWidget(parent) : QOpenGLWidget(parent)
@ -47,6 +51,17 @@ RendererWidget::~RendererWidget()
} }
} }
void RendererWidget::setMainLightPitch(float pitch)
{
//qDebug() << "pitch" << pitch;
sunPitch = pitch;
}
void RendererWidget::setMainLightYaw(float yaw)
{
//qDebug() << "yaw" << yaw;
sunYaw = yaw;
}
QOpenGLTexture randomMap(QOpenGLTexture::Target2D); QOpenGLTexture randomMap(QOpenGLTexture::Target2D);
void RendererWidget::initializeGL() void RendererWidget::initializeGL()
{ {
@ -190,6 +205,7 @@ 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);
//model = new Model("E:\\3D Objects\\gallery_gltf\\gallery_gltf.gltf", context(), modelProgramPtr, paintingProgramPtr, shadowProgramPtr, paintingHelper);
light.model = model; light.model = model;
qDebug() << model->AABB; qDebug() << model->AABB;
@ -226,10 +242,7 @@ 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 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 int sunSpeed = 10;
void RendererWidget::paintGL() void RendererWidget::paintGL()
{ {
light.lightDirection.setX(cos(qDegreesToRadians(sunPitch)) * cos(qDegreesToRadians(sunYaw))); light.lightDirection.setX(cos(qDegreesToRadians(sunPitch)) * cos(qDegreesToRadians(sunYaw)));
@ -309,6 +322,7 @@ void RendererWidget::paintGL()
shadowMappingProgramPtr->setUniformValueArray("shadowBiases", light.frustumSizes.data(), light.frustumSizes.size(), 1); shadowMappingProgramPtr->setUniformValueArray("shadowBiases", light.frustumSizes.data(), light.frustumSizes.size(), 1);
//qDebug() << light.frustumSizes; //qDebug() << light.frustumSizes;
shadowMappingProgramPtr->setUniformValue("shadowCascadeCount", (GLint)light.shadowCascadeLevels.size()); shadowMappingProgramPtr->setUniformValue("shadowCascadeCount", (GLint)light.shadowCascadeLevels.size());
shadowMappingProgramPtr->setUniformValue("shadowBlendRatio", light.blendRatio);
shadowMappingProgramPtr->setUniformValue("camPos", camera.Position); shadowMappingProgramPtr->setUniformValue("camPos", camera.Position);
shadowMappingProgramPtr->setUniformValue("mainLightDirection", light.lightDirection); shadowMappingProgramPtr->setUniformValue("mainLightDirection", light.lightDirection);
shadowMappingProgramPtr->setUniformValue("mainLightRadiance", lightColors[0]); shadowMappingProgramPtr->setUniformValue("mainLightRadiance", lightColors[0]);
@ -379,8 +393,8 @@ void RendererWidget::paintGL()
void RendererWidget::resizeGL(int width, int height) void RendererWidget::resizeGL(int width, int height)
{ {
frameWidth = devicePixelRatioF() * width; frameWidth = ceil( devicePixelRatioF() * width);
frameHeight = devicePixelRatioF() * height; frameHeight = ceil(devicePixelRatioF() * height);
qDebug() << frameWidth << "x" << frameHeight; qDebug() << frameWidth << "x" << frameHeight;
camera.Ratio = (float)frameWidth / (float)frameHeight; camera.Ratio = (float)frameWidth / (float)frameHeight;
//qDebug() << devicePixelRatioF() << width << height; //qDebug() << devicePixelRatioF() << width << height;
@ -492,7 +506,7 @@ void RendererWidget::resizeGL(int width, int height)
//Depth //Depth
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowGbuffer); glBindTexture(GL_TEXTURE_2D_ARRAY, shadowGbuffer);
glTexImage3D( glTexImage3D(
GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32F, shadowMapResolution, shadowMapResolution, int(light.shadowCascadeLevels.size()) + 1, GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT32F, shadowMapResolution, shadowMapResolution, int(light.shadowCascadeLevels.size()),
0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
/*glBindTexture(GL_TEXTURE_2D, shadowGbuffer); /*glBindTexture(GL_TEXTURE_2D, shadowGbuffer);
@ -565,12 +579,12 @@ void RendererWidget::timerEvent(QTimerEvent* event)
} }
sunPitch += sunSpeed * deltaTime; /*sunPitch += sunSpeed * deltaTime;
if (sunPitch > 120 || sunPitch < 65) if (sunPitch > 120 || sunPitch < 65)
{ {
sunSpeed = -sunSpeed; sunSpeed = -sunSpeed;
sunPitch += sunSpeed * deltaTime; sunPitch += sunSpeed * deltaTime;
} }*/
repaint(); repaint();
} }

View File

@ -19,6 +19,9 @@ public:
RendererWidget(QWidget* parent = nullptr); RendererWidget(QWidget* parent = nullptr);
~RendererWidget(); ~RendererWidget();
public slots:
void setMainLightPitch(float pitch);
void setMainLightYaw(float yaw);
protected: protected:
void initializeGL() override; void initializeGL() override;
void paintGL() override; void paintGL() override;

View File

@ -486,7 +486,7 @@ int solve_quartic(vec4 coeffs, inout vec4 s){
return num; return num;
} }
float cubic_bezier_dis(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3){ float cubic_bezier_dis(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3, bool roundEnd){
//switch points when near to end point to minimize numerical error //switch points when near to end point to minimize numerical error
//only needed when control point(s) very far away //only needed when control point(s) very far away
@ -689,18 +689,32 @@ float cubic_bezier_dis(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3){
//compute squared distance to nearest point on curve //compute squared distance to nearest point on curve
if(roundEnd)
{
roots[i] = clamp(roots[i],0.,1.); roots[i] = clamp(roots[i],0.,1.);
vec2 to_curve = uv - parametric_cub_bezier(roots[i],p0,p1,p2,p3); vec2 to_curve = uv - parametric_cub_bezier(roots[i],p0,p1,p2,p3);
d0 = min(d0,dot(to_curve,to_curve)); d0 = min(d0,dot(to_curve,to_curve));
} }
else
{
if(roots[i]<0.||roots[i]>1.) d0=min(d0,1e38);
else
{
vec2 to_curve = uv - parametric_cub_bezier(roots[i],p0,p1,p2,p3);
d0 = min(d0,dot(to_curve,to_curve));
}
}
}
} }
return sqrt(d0); return sqrt(d0);
} }
vec3 drawElement(uint elementIndex, vec2 localUV, inout vec3 debugBVH = vec3(0)) bool drawElement(uint elementIndex, vec2 localUV, out vec3 color, inout vec3 debugBVH = vec3(0))
{ {
vec4 elementColor = vec4(0); bool hitElement = false;
vec4 elementColor = vec4(-1);
uint currentOffset[4] = elementOffset[elementIndex]; uint currentOffset[4] = elementOffset[elementIndex];
uint elementBvhRoot = currentOffset[0]; uint elementBvhRoot = currentOffset[0];
@ -724,11 +738,11 @@ vec3 drawElement(uint elementIndex, vec2 localUV, inout vec3 debugBVH = vec3(0))
{ {
debugBVH.g += 0.5; debugBVH.g += 0.5;
uint styleIndex = bvhChildren[elementBvhRoot + elementBvhIndex].y - elementBvhLength; uint styleIndex = bvhChildren[elementBvhRoot + elementBvhIndex].y;
// for(int i = 0; i<200;i++) // for(int i = 0; i<200;i++)
if (elementData[styleIndex] == 0.) //Ãæ if (elementData[styleIndex] == 0.) //Ãæ
{ {
uint contourIndex = leftChild - elementBvhLength; uint contourIndex = leftChild - 0x80000000;
uint num_its = 0; uint num_its = 0;
@ -760,16 +774,22 @@ vec3 drawElement(uint elementIndex, vec2 localUV, inout vec3 debugBVH = vec3(0))
num_its += cubic_bezier_int_test(localUV, p0, p1, p2, p3); num_its += cubic_bezier_int_test(localUV, p0, p1, p2, p3);
} }
if (num_its % 2 == 1) if (num_its % 2 == 1 && elementColor.a<1)
{ {
elementColor = vec4(1); hitElement = true;
//debugHit = true; elementColor = vec4(1,1,0,0);
if(elementData[styleIndex+1]==0)
{
elementColor = vec4(elementData[styleIndex+2],elementData[styleIndex+3],elementData[styleIndex+4],0);
}
} }
} }
else if (elementData[styleIndex] == 1) //Ïß else if (elementData[styleIndex] == 1) //Ïß
{ {
float strokeWidth = elementData[styleIndex+1]; float strokeWidth = elementData[styleIndex+1];
uint lineIndex = leftChild - elementBvhLength; uint lineIndex = leftChild - 0x80000000;
uint p0Index = elementIndexs[linesOffset + 4 * lineIndex]; uint p0Index = elementIndexs[linesOffset + 4 * lineIndex];
uint p1Index = elementIndexs[linesOffset + 4 * lineIndex + 1]; uint p1Index = elementIndexs[linesOffset + 4 * lineIndex + 1];
uint p2Index = elementIndexs[linesOffset + 4 * lineIndex + 2]; uint p2Index = elementIndexs[linesOffset + 4 * lineIndex + 2];
@ -784,9 +804,23 @@ vec3 drawElement(uint elementIndex, vec2 localUV, inout vec3 debugBVH = vec3(0))
vec2 p3 = vec2(elementData[pointsOffset + 2 * p3Index], vec2 p3 = vec2(elementData[pointsOffset + 2 * p3Index],
elementData[pointsOffset + 2 * p3Index + 1]); elementData[pointsOffset + 2 * p3Index + 1]);
if(cubic_bezier_dis(localUV, p0, p1, p2, p3)<=strokeWidth) float lineType = elementData[styleIndex+4];
/*if(cubic_bezier_dis(localUV, p0, p1, p2, p3, true)<=0.001)
{
hitElement = true;
elementColor = vec4(1); elementColor = vec4(1);
} }
else */if(cubic_bezier_dis(localUV, p0, p1, p2, p3, elementData[styleIndex+2]==0)<=strokeWidth
&&(lineType==2 ||cubic_bezier_int_test(localUV, p0, p1, p2, p3)==lineType))
{
hitElement = true;
elementColor = vec4(1);
if(elementData[styleIndex+3]==0)
{
elementColor = vec4(elementData[styleIndex+7],elementData[styleIndex+8],elementData[styleIndex+9],1);
}
}
}
elementBvhIndex = elementBvhLength; elementBvhIndex = elementBvhLength;
} }
@ -807,7 +841,8 @@ vec3 drawElement(uint elementIndex, vec2 localUV, inout vec3 debugBVH = vec3(0))
elementBvhIndex = bvhChildren[elementBvhRoot + elementBvhIndex].y; elementBvhIndex = bvhChildren[elementBvhRoot + elementBvhIndex].y;
} }
} }
return elementColor.xyz; color = elementColor.xyz;
return hitElement;
} }
@ -824,7 +859,8 @@ void main()
vec2 uv = imageLoad(gPaintingTexCoord, pixelLocation).rg; vec2 uv = imageLoad(gPaintingTexCoord, pixelLocation).rg;
vec3 debugBVH = vec3(0); vec3 debugBVH = vec3(0);
bool debugHit = false; //bool debugHit = false;
vec4 color = vec4(-1);
stack.top = 0; stack.top = 0;
uint index = 0, visitTime = 0; uint index = 0, visitTime = 0;
uint bvhLength = paintingOffsets[paintingIndex-1].y; uint bvhLength = paintingOffsets[paintingIndex-1].y;
@ -844,15 +880,17 @@ void main()
vec2 localUV = uv - (bound.xy + bound.zw) / 2; vec2 localUV = uv - (bound.xy + bound.zw) / 2;
localUV = rotation * localUV; localUV = rotation * localUV;
localUV /= (bound.zw - bound.xy) / 2; localUV /= (bound.zw - bound.xy) / 2;
if (all(lessThan(vec2(-1), localUV)) && all(lessThan(localUV, vec2(1)))) if (all(lessThan(vec2(-1), localUV)) && all(lessThan(localUV, vec2(1))) && zIndex>color.w)
{ {
if (zIndex == 1) if (zIndex == 1)
debugBVH = vec3(1, 0, 1); debugBVH = vec3(1, 0, 1);
uint elementIndex = leftChild - bvhLength; //uint elementIndex = leftChild - bvhLength;
debugBVH.bg += 0.5 * (localUV + vec2(1)); debugBVH.bg += 0.5 * (localUV + vec2(1));
debugBVH = vec3(0); debugBVH = vec3(0);
debugHit = drawElement(leftChild - bvhLength, localUV, debugBVH) == vec3(1); vec3 elementColor;
if(drawElement(leftChild - 0x80000000, localUV, elementColor, debugBVH))
color = vec4(elementColor, zIndex);
} }
@ -875,7 +913,9 @@ void main()
} }
} }
if (debugHit) imageStore(gBaseColor, pixelLocation, vec4(color.rgb,1));
return;
if (color.a!=-1)
imageStore(gBaseColor, pixelLocation, vec4(vec3(1, 1, 0),1)); imageStore(gBaseColor, pixelLocation, vec4(vec3(1, 1, 0),1));
else else
imageStore(gBaseColor, pixelLocation, vec4(debugBVH,1)); imageStore(gBaseColor, pixelLocation, vec4(debugBVH,1));

View File

@ -17,6 +17,7 @@ uniform float farPlane;
uniform float shadowCascadePlaneDistances[16]; uniform float shadowCascadePlaneDistances[16];
uniform float shadowBiases[16]; uniform float shadowBiases[16];
uniform int shadowCascadeCount; uniform int shadowCascadeCount;
uniform float shadowBlendRatio;
uniform vec3 mainLightDirection; uniform vec3 mainLightDirection;
uniform vec3 mainLightRadiance; uniform vec3 mainLightRadiance;
@ -64,28 +65,9 @@ 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);
} }
const int pcfRadius = 3;
float ShadowCalculation(vec3 fragPosWorldSpace, vec3 normal, out int layer) float getShadowFromLayer(vec3 fragPosWorldSpace, vec3 normal,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; 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); vec4 fragPosLightSpace = lightSpaceMatrices[layer] * vec4(fragPosWorldSpace+normal*normalBias, 1.0);
// perform perspective divide // perform perspective divide
@ -114,7 +96,39 @@ float ShadowCalculation(vec3 fragPosWorldSpace, vec3 normal, out int layer)
} }
} }
shadow /= (2*pcfRadius+1)*(2*pcfRadius+1); shadow /= (2*pcfRadius+1)*(2*pcfRadius+1);
return shadow;
}
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;
// }
float shadow = getShadowFromLayer(fragPosWorldSpace,normal,layer);
float nextLayerBeginDepth = layer==0? (1-shadowBlendRatio)*shadowCascadePlaneDistances[layer]
:(1-shadowBlendRatio)*shadowCascadePlaneDistances[layer]+shadowBlendRatio*shadowCascadePlaneDistances[layer-1];
if(depthValue > nextLayerBeginDepth)
{
float shadowNext = getShadowFromLayer(fragPosWorldSpace,normal,layer+1);
shadow = mix(shadow,shadowNext, (depthValue-nextLayerBeginDepth)/(shadowCascadePlaneDistances[layer]-nextLayerBeginDepth));
}
return shadow; return shadow;
} }