支持线条方角,调整BVH叶子结点编码方式,级联阴影平滑过渡,添加滑动条便于调整光源
parent
fa112820cc
commit
898b08e023
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
roots[i] = clamp(roots[i],0.,1.);
|
if(roundEnd)
|
||||||
vec2 to_curve = uv - parametric_cub_bezier(roots[i],p0,p1,p2,p3);
|
{
|
||||||
d0 = min(d0,dot(to_curve,to_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));
|
||||||
|
}
|
||||||
|
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,8 +804,22 @@ 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));
|
||||||
|
|
|
@ -16,7 +16,8 @@ uniform mat4 view;
|
||||||
uniform float farPlane;
|
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,29 +65,10 @@ 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
|
float normalBias = 4. /** (1+pcfRadius)*/ * shadowBiases[layer]*max((1.0 - dot(normal, mainLightDirection)), 0.1)/textureSize(gShadowMap, 0).x;
|
||||||
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);
|
vec4 fragPosLightSpace = lightSpaceMatrices[layer] * vec4(fragPosWorldSpace+normal*normalBias, 1.0);
|
||||||
// perform perspective divide
|
// perform perspective divide
|
||||||
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
|
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);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue