支持线条方角,调整BVH叶子结点编码方式,级联阴影平滑过渡,添加滑动条便于调整光源
parent
fa112820cc
commit
898b08e023
|
@ -14,7 +14,7 @@ Light::Light(Camera* camera)
|
|||
+ (1 - lambda) * (camera->NearPlane + i / levelCount * (camera->FarPlane - camera->NearPlane)));
|
||||
//qDebug() << shadowCascadeLevels[i-1];
|
||||
}
|
||||
|
||||
shadowCascadeLevels.push_back(camera->FarPlane);
|
||||
}
|
||||
|
||||
|
||||
|
@ -127,19 +127,19 @@ std::vector<QMatrix4x4> Light::getLightSpaceMatrices()
|
|||
{
|
||||
std::vector<QMatrix4x4> ret;
|
||||
frustumSizes.clear();
|
||||
for (size_t i = 0; i < shadowCascadeLevels.size() + 1; ++i)
|
||||
for (size_t i = 0; i < shadowCascadeLevels.size(); ++i)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
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
|
||||
{
|
||||
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;
|
||||
|
|
|
@ -14,6 +14,7 @@ class Light
|
|||
public:
|
||||
QVector3D lightDirection = QVector3D(0.2, 4, 1).normalized();
|
||||
std::vector<float> shadowCascadeLevels;
|
||||
float blendRatio = 0.3;
|
||||
std::vector<float> frustumSizes;
|
||||
Model* model;
|
||||
Light(Camera* camera);
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
#include "MainWindow.h"
|
||||
#include "RendererWidget.h"
|
||||
#include "qslider.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
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()
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>600</width>
|
||||
<width>800</width>
|
||||
<height>400</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -14,9 +14,71 @@
|
|||
<string>MainWindow</string>
|
||||
</property>
|
||||
<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">
|
||||
<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>
|
||||
<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>
|
||||
</layout>
|
||||
</widget>
|
||||
|
|
|
@ -114,6 +114,12 @@ void Model::processNode(aiNode* node, const aiScene* scene, aiMatrix4x4 mat4)
|
|||
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)
|
||||
{
|
||||
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
||||
|
@ -188,12 +194,12 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
|
|||
//root
|
||||
1,2,
|
||||
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
|
||||
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
|
||||
1 + 0/*line索引,element中第几条*/,1 + 27
|
||||
encodeChild(0)/*line索引,element中第几条*/, 27
|
||||
|
||||
};
|
||||
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,-0.2,1), QVector4D(-0.2,-1,1,1),
|
||||
//elememt1
|
||||
QVector4D(-1,0,1,1)
|
||||
QVector4D(-1,-1,1,1)
|
||||
};
|
||||
std::vector<GLuint> elementOffset = {
|
||||
//element0
|
||||
|
@ -250,7 +256,7 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
|
|||
|
||||
//element1
|
||||
//points
|
||||
-1,0.5, 0,1, 1,0.5,
|
||||
0,0.8, 1,0, 0,-0.8,
|
||||
//strokeStyle
|
||||
//stroke
|
||||
1,
|
||||
|
@ -260,8 +266,14 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
|
|||
0, //Ô²½Ç
|
||||
//strokeFillType
|
||||
0, //µ¥É«
|
||||
//线类型
|
||||
1, //左侧
|
||||
//线外描边宽度
|
||||
0,
|
||||
//线外描边方式
|
||||
0, //单色
|
||||
//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,
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
#include <QGuiApplication>
|
||||
#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)
|
||||
: 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);
|
||||
void RendererWidget::initializeGL()
|
||||
{
|
||||
|
@ -190,6 +205,7 @@ void RendererWidget::initializeGL()
|
|||
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("E:\\3D Objects\\gallery_gltf\\gallery_gltf.gltf", context(), modelProgramPtr, paintingProgramPtr, shadowProgramPtr, paintingHelper);
|
||||
light.model = model;
|
||||
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()
|
||||
{
|
||||
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);
|
||||
//qDebug() << light.frustumSizes;
|
||||
shadowMappingProgramPtr->setUniformValue("shadowCascadeCount", (GLint)light.shadowCascadeLevels.size());
|
||||
shadowMappingProgramPtr->setUniformValue("shadowBlendRatio", light.blendRatio);
|
||||
shadowMappingProgramPtr->setUniformValue("camPos", camera.Position);
|
||||
shadowMappingProgramPtr->setUniformValue("mainLightDirection", light.lightDirection);
|
||||
shadowMappingProgramPtr->setUniformValue("mainLightRadiance", lightColors[0]);
|
||||
|
@ -379,8 +393,8 @@ void RendererWidget::paintGL()
|
|||
|
||||
void RendererWidget::resizeGL(int width, int height)
|
||||
{
|
||||
frameWidth = devicePixelRatioF() * width;
|
||||
frameHeight = devicePixelRatioF() * height;
|
||||
frameWidth = ceil( devicePixelRatioF() * width);
|
||||
frameHeight = ceil(devicePixelRatioF() * height);
|
||||
qDebug() << frameWidth << "x" << frameHeight;
|
||||
camera.Ratio = (float)frameWidth / (float)frameHeight;
|
||||
//qDebug() << devicePixelRatioF() << width << height;
|
||||
|
@ -492,7 +506,7 @@ void RendererWidget::resizeGL(int width, int height)
|
|||
//Depth
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowGbuffer);
|
||||
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);
|
||||
|
||||
/*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)
|
||||
{
|
||||
sunSpeed = -sunSpeed;
|
||||
sunPitch += sunSpeed * deltaTime;
|
||||
}
|
||||
}*/
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,9 @@ public:
|
|||
RendererWidget(QWidget* parent = nullptr);
|
||||
~RendererWidget();
|
||||
|
||||
public slots:
|
||||
void setMainLightPitch(float pitch);
|
||||
void setMainLightYaw(float yaw);
|
||||
protected:
|
||||
void initializeGL() override;
|
||||
void paintGL() override;
|
||||
|
|
|
@ -486,7 +486,7 @@ int solve_quartic(vec4 coeffs, inout vec4 s){
|
|||
|
||||
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
|
||||
//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
|
||||
roots[i] = clamp(roots[i],0.,1.);
|
||||
vec2 to_curve = uv - parametric_cub_bezier(roots[i],p0,p1,p2,p3);
|
||||
d0 = min(d0,dot(to_curve,to_curve));
|
||||
if(roundEnd)
|
||||
{
|
||||
roots[i] = clamp(roots[i],0.,1.);
|
||||
vec2 to_curve = uv - parametric_cub_bezier(roots[i],p0,p1,p2,p3);
|
||||
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);
|
||||
}
|
||||
|
||||
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 elementBvhRoot = currentOffset[0];
|
||||
|
@ -724,11 +738,11 @@ vec3 drawElement(uint elementIndex, vec2 localUV, inout vec3 debugBVH = vec3(0))
|
|||
{
|
||||
debugBVH.g += 0.5;
|
||||
|
||||
uint styleIndex = bvhChildren[elementBvhRoot + elementBvhIndex].y - elementBvhLength;
|
||||
uint styleIndex = bvhChildren[elementBvhRoot + elementBvhIndex].y;
|
||||
// for(int i = 0; i<200;i++)
|
||||
if (elementData[styleIndex] == 0.) //Ãæ
|
||||
{
|
||||
uint contourIndex = leftChild - elementBvhLength;
|
||||
uint contourIndex = leftChild - 0x80000000;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (num_its % 2 == 1)
|
||||
if (num_its % 2 == 1 && elementColor.a<1)
|
||||
{
|
||||
elementColor = vec4(1);
|
||||
//debugHit = true;
|
||||
hitElement = 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) //Ïß
|
||||
{
|
||||
float strokeWidth = elementData[styleIndex+1];
|
||||
uint lineIndex = leftChild - elementBvhLength;
|
||||
uint lineIndex = leftChild - 0x80000000;
|
||||
uint p0Index = elementIndexs[linesOffset + 4 * lineIndex];
|
||||
uint p1Index = elementIndexs[linesOffset + 4 * lineIndex + 1];
|
||||
uint p2Index = elementIndexs[linesOffset + 4 * lineIndex + 2];
|
||||
|
@ -784,8 +804,22 @@ vec3 drawElement(uint elementIndex, vec2 localUV, inout vec3 debugBVH = vec3(0))
|
|||
vec2 p3 = vec2(elementData[pointsOffset + 2 * p3Index],
|
||||
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);
|
||||
}
|
||||
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;
|
||||
|
@ -807,7 +841,8 @@ vec3 drawElement(uint elementIndex, vec2 localUV, inout vec3 debugBVH = vec3(0))
|
|||
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;
|
||||
|
||||
vec3 debugBVH = vec3(0);
|
||||
bool debugHit = false;
|
||||
//bool debugHit = false;
|
||||
vec4 color = vec4(-1);
|
||||
stack.top = 0;
|
||||
uint index = 0, visitTime = 0;
|
||||
uint bvhLength = paintingOffsets[paintingIndex-1].y;
|
||||
|
@ -844,15 +880,17 @@ void main()
|
|||
vec2 localUV = uv - (bound.xy + bound.zw) / 2;
|
||||
localUV = rotation * localUV;
|
||||
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)
|
||||
debugBVH = vec3(1, 0, 1);
|
||||
uint elementIndex = leftChild - bvhLength;
|
||||
//uint elementIndex = leftChild - bvhLength;
|
||||
debugBVH.bg += 0.5 * (localUV + vec2(1));
|
||||
|
||||
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));
|
||||
else
|
||||
imageStore(gBaseColor, pixelLocation, vec4(debugBVH,1));
|
||||
|
|
|
@ -16,7 +16,8 @@ uniform mat4 view;
|
|||
uniform float farPlane;
|
||||
uniform float shadowCascadePlaneDistances[16];
|
||||
uniform float shadowBiases[16];
|
||||
uniform int shadowCascadeCount;
|
||||
uniform int shadowCascadeCount;
|
||||
uniform float shadowBlendRatio;
|
||||
|
||||
uniform vec3 mainLightDirection;
|
||||
uniform vec3 mainLightRadiance;
|
||||
|
@ -64,29 +65,10 @@ 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)
|
||||
const int pcfRadius = 3;
|
||||
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);
|
||||
// perform perspective divide
|
||||
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
|
||||
|
@ -114,7 +96,39 @@ float ShadowCalculation(vec3 fragPosWorldSpace, vec3 normal, out int layer)
|
|||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue