实现任意曲线围成封闭图形的渲染
parent
781ec614bc
commit
38bd57c4c9
|
@ -140,13 +140,31 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GLuint bvhChildren[] = {7/*数组长度*/,0/*与显存对齐*/,
|
GLuint bvhChildren[] = {7/*rootBVH长度*/,0/*与显存对齐*/,
|
||||||
|
//root
|
||||||
1,2,
|
1,2,
|
||||||
3,4, 5,6,
|
3,4, 5,6,
|
||||||
7,0, 7,30./360* 4294967296 , 8,0, 7,0};
|
7,0, 7,30./360* 4294967296 /*右儿子用来表示旋转角度*/, 8,0, 7,0,
|
||||||
QVector4D bvhBound[] = { QVector4D(-1,-1,1,1) ,
|
//elememt0
|
||||||
|
1,2,
|
||||||
|
5+28/*contour索引,由于contour不定长,这里需要给到contour在elementIndex中位置*/,5+12/*style索引,在elementData中位置*/, 3,4,
|
||||||
|
5+36,5+12, 5+32,5+12,
|
||||||
|
//elememt1
|
||||||
|
1+0/*line索引,element中第几条*/,1 + 25
|
||||||
|
|
||||||
|
};
|
||||||
|
QVector4D bvhBound[] = {
|
||||||
|
//root
|
||||||
|
QVector4D(-1,-1,1,1),
|
||||||
QVector4D(-0.9,-0.9,-0.1,0.9), QVector4D(0.1, -0.9,0.9,0.9),
|
QVector4D(-0.9,-0.9,-0.1,0.9), QVector4D(0.1, -0.9,0.9,0.9),
|
||||||
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
|
||||||
|
QVector4D(-1,-1,1,1),
|
||||||
|
QVector4D(-1,-0.5,1,1), QVector4D(-1,-1,1,0.5),
|
||||||
|
QVector4D(-1,-1,1,-0.5), QVector4D(-1,-0.5,1,0.5),
|
||||||
|
//elememt1
|
||||||
|
QVector4D(-1,0,1,1),
|
||||||
|
};
|
||||||
glFunc->glGenBuffers(1, &m_mesh->bvhSSBO);
|
glFunc->glGenBuffers(1, &m_mesh->bvhSSBO);
|
||||||
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_mesh->bvhSSBO);
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_mesh->bvhSSBO);
|
||||||
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER,sizeof(bvhChildren), bvhChildren, GL_DYNAMIC_DRAW);
|
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER,sizeof(bvhChildren), bvhChildren, GL_DYNAMIC_DRAW);
|
||||||
|
@ -157,9 +175,41 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
|
||||||
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(bvhBound), bvhBound, GL_DYNAMIC_DRAW);
|
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(bvhBound), bvhBound, GL_DYNAMIC_DRAW);
|
||||||
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||||
|
|
||||||
GLuint elementIndex[] = { 1/*数组长度*/,
|
GLuint elementOffset[] = {
|
||||||
0,0,14,14,14,14,
|
//element0
|
||||||
14,14,21,21,21,21
|
7, //elementBvhRoot
|
||||||
|
5, //elementBvhLength
|
||||||
|
0, //pointsOffset
|
||||||
|
0, //linesOffset
|
||||||
|
//element1
|
||||||
|
12, //elementBvhRoot
|
||||||
|
1, //elementBvhLength
|
||||||
|
19, //pointsOffset
|
||||||
|
40, //linesOffset
|
||||||
|
};
|
||||||
|
glFunc->glGenBuffers(1, &m_mesh->elementOffsetSSBO);
|
||||||
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_mesh->elementOffsetSSBO);
|
||||||
|
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(elementOffset), elementOffset, GL_DYNAMIC_DRAW);
|
||||||
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||||
|
|
||||||
|
GLuint elementIndex[] = {
|
||||||
|
//element0
|
||||||
|
//lines, 全部当作三阶贝塞尔, 每条线四个点索引
|
||||||
|
4,2,2,0,
|
||||||
|
0,0,1,1,
|
||||||
|
1,1,4,4,
|
||||||
|
1,1,5,5,
|
||||||
|
4,4,5,5,
|
||||||
|
1,1,3,3,
|
||||||
|
3,3,5,5,
|
||||||
|
//contours, 第一个元素指明轮廓段数,后面为lines索引
|
||||||
|
3, 0,1,2,
|
||||||
|
3, 2,3,4,
|
||||||
|
3, 3,5,6,
|
||||||
|
|
||||||
|
//element2
|
||||||
|
//lines
|
||||||
|
0,1,2
|
||||||
};
|
};
|
||||||
glFunc->glGenBuffers(1, &m_mesh->elementIndexSSBO);
|
glFunc->glGenBuffers(1, &m_mesh->elementIndexSSBO);
|
||||||
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_mesh->elementIndexSSBO);
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_mesh->elementIndexSSBO);
|
||||||
|
@ -168,12 +218,34 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
|
||||||
|
|
||||||
|
|
||||||
GLfloat elementData[] = {
|
GLfloat elementData[] = {
|
||||||
1,0, 0,1, -1,0, 1,
|
//element0
|
||||||
-1,0, 0,-1, 1,0, 0,
|
//points
|
||||||
1,0, 0,1, -1,0, 2,
|
-1,0.5, -1,-0.5, 0,1, 0,-1, 1,0.5, 1,-0.5,
|
||||||
|
//fillStyle
|
||||||
|
//fill
|
||||||
|
0,
|
||||||
|
//fillType
|
||||||
|
0, //单色
|
||||||
|
//fillColorMetallicRoughness
|
||||||
|
1,1,0, 0,0.8,
|
||||||
|
|
||||||
|
//element1
|
||||||
|
//points
|
||||||
|
-1,0.5, 0,1, 1,0.5,
|
||||||
|
//strokeStyle
|
||||||
|
//stroke
|
||||||
|
1,
|
||||||
|
//strokeWidth
|
||||||
|
0.02,
|
||||||
|
//strokeEndType
|
||||||
|
0, //圆角
|
||||||
|
//strokeFillType
|
||||||
|
0, //单色
|
||||||
|
//strokeFillColorMetallicRoughness
|
||||||
|
0,1,0, 0,0.8
|
||||||
};
|
};
|
||||||
glFunc->glGenBuffers(1, &m_mesh->elementSSBO);
|
glFunc->glGenBuffers(1, &m_mesh->elementDataSSBO);
|
||||||
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_mesh->elementSSBO);
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_mesh->elementDataSSBO);
|
||||||
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(elementData), elementData, GL_DYNAMIC_DRAW);
|
glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(elementData), elementData, GL_DYNAMIC_DRAW);
|
||||||
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,9 @@ void PaintingMesh::draw()
|
||||||
|
|
||||||
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, bvhSSBO);
|
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, bvhSSBO);
|
||||||
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, bvhBoundSSBO);
|
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, bvhBoundSSBO);
|
||||||
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, elementIndexSSBO);
|
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, elementOffsetSSBO);
|
||||||
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, elementSSBO);
|
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, elementIndexSSBO);
|
||||||
|
glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, elementDataSSBO);
|
||||||
|
|
||||||
glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
|
glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
|
||||||
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||||
|
|
|
@ -42,7 +42,7 @@ public:
|
||||||
QOpenGLFunctions_4_5_Compatibility* glFunc; //opengl函数入口
|
QOpenGLFunctions_4_5_Compatibility* glFunc; //opengl函数入口
|
||||||
QOpenGLShaderProgram* shaderProgram; //着色器程序
|
QOpenGLShaderProgram* shaderProgram; //着色器程序
|
||||||
|
|
||||||
GLuint bvhSSBO, bvhBoundSSBO, elementIndexSSBO, elementSSBO;
|
GLuint bvhSSBO, bvhBoundSSBO, elementOffsetSSBO, elementIndexSSBO, elementDataSSBO;
|
||||||
|
|
||||||
/* 函数 */
|
/* 函数 */
|
||||||
PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model);
|
PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model);
|
||||||
|
|
|
@ -3,11 +3,13 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <QScreen>
|
||||||
|
#include <QGuiApplication>
|
||||||
|
|
||||||
RendererWidget::RendererWidget(QWidget* parent)
|
RendererWidget::RendererWidget(QWidget* parent)
|
||||||
: QOpenGLWidget(parent), camera(QVector3D(0.0f, 100.0f, 0.0f))
|
: QOpenGLWidget(parent), camera(QVector3D(0.0f, 100.0f, 0.0f))
|
||||||
{
|
{
|
||||||
startTimer(1000 / 120);
|
startTimer(1000 / QGuiApplication::primaryScreen()->refreshRate());
|
||||||
lastFrame = std::clock();
|
lastFrame = std::clock();
|
||||||
setFocusPolicy(Qt::StrongFocus);
|
setFocusPolicy(Qt::StrongFocus);
|
||||||
}
|
}
|
||||||
|
@ -177,7 +179,7 @@ void RendererWidget::resizeGL(int width, int height)
|
||||||
void RendererWidget::timerEvent(QTimerEvent* event)
|
void RendererWidget::timerEvent(QTimerEvent* event)
|
||||||
{
|
{
|
||||||
clock_t currentFrame = std::clock();
|
clock_t currentFrame = std::clock();
|
||||||
deltaTime = (float)(std::clock() - lastFrame) / CLOCKS_PER_SEC;
|
deltaTime = (float)(currentFrame - lastFrame) / CLOCKS_PER_SEC;
|
||||||
lastFrame = currentFrame;
|
lastFrame = currentFrame;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,97 +20,128 @@ layout(std430, binding = 2) buffer bvhBoundBuffer
|
||||||
};
|
};
|
||||||
layout(std430, binding = 3) buffer elementOffsetBuffer
|
layout(std430, binding = 3) buffer elementOffsetBuffer
|
||||||
{
|
{
|
||||||
int elementCount;
|
/**********************
|
||||||
uint elementOffset[][6];
|
** @x elementBvhRoot
|
||||||
|
** @y elementBvhLength
|
||||||
|
** @z pointsOffset
|
||||||
|
** @w linesOffset
|
||||||
|
**********************/
|
||||||
|
uvec4 elementOffset[];
|
||||||
};
|
};
|
||||||
layout(std430, binding = 4) buffer elementBuffer
|
layout(std430, binding = 4) buffer elementIndexBuffer
|
||||||
{
|
{
|
||||||
float elementData[];
|
uint elementIndexs[]; //ÏߺÍÃæ
|
||||||
|
};
|
||||||
|
layout(std430, binding = 5) buffer elementDataBuffer
|
||||||
|
{
|
||||||
|
float elementData[]; //µãºÍStyle
|
||||||
};
|
};
|
||||||
|
|
||||||
const float PI = 3.14159265359;
|
const float PI = 3.14159265358979;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
float border = 0;
|
float border = 0;
|
||||||
|
|
||||||
mat2 inv(mat2 m){
|
mat2 inv(mat2 m)
|
||||||
|
{
|
||||||
return mat2(m[1][1], -m[0][1], -m[1][0], m[0][0]) / (m[0][0] * m[1][1] - m[1][0] * m[0][1]);
|
return mat2(m[1][1], -m[0][1], -m[1][0], m[0][0]) / (m[0][0] * m[1][1] - m[1][0] * m[0][1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
float abs_min(float a, float b){
|
float abs_min(float a, float b)
|
||||||
if(abs(a)<abs(b)){
|
{
|
||||||
|
if (abs(a) < abs(b))
|
||||||
|
{
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int i_mod(int a, int m){
|
int i_mod(int a, int m)
|
||||||
|
{
|
||||||
return int(mod(float(a), float(m)));
|
return int(mod(float(a), float(m)));
|
||||||
}
|
}
|
||||||
|
|
||||||
float line_dist(vec2 uv, const vec2 p0, vec2 p1){
|
float line_dist(vec2 uv, const vec2 p0, vec2 p1)
|
||||||
|
{
|
||||||
vec2 tang = p1 - p0;
|
vec2 tang = p1 - p0;
|
||||||
vec2 nor = normalize(vec2(tang.y, -tang.x));
|
vec2 nor = normalize(vec2(tang.y, -tang.x));
|
||||||
|
|
||||||
if(dot(tang,uv)<dot(tang,p0)){
|
if (dot(tang, uv) < dot(tang, p0))
|
||||||
|
{
|
||||||
return distance(p0, uv);
|
return distance(p0, uv);
|
||||||
}
|
}
|
||||||
else if(dot(tang,uv)>dot(tang,p1)){
|
else if (dot(tang, uv) > dot(tang, p1))
|
||||||
|
{
|
||||||
return distance(p1, uv);
|
return distance(p1, uv);
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
return dot(nor, uv) - dot(nor, p0);
|
return dot(nor, uv) - dot(nor, p0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool int_test(vec2 uv, vec2 last_point, vec2 p0, vec2 p1){
|
bool int_test(vec2 uv, vec2 last_point, vec2 p0, vec2 p1)
|
||||||
|
{
|
||||||
last_point -= uv;
|
last_point -= uv;
|
||||||
p0 -= uv;
|
p0 -= uv;
|
||||||
p1 -= uv;
|
p1 -= uv;
|
||||||
|
|
||||||
bool ret;
|
bool ret;
|
||||||
if(p0.y==0.){
|
if (p0.y == 0.)
|
||||||
|
{
|
||||||
ret = (p0.x >= 0. && p1.y * last_point.y < 0.);
|
ret = (p0.x >= 0. && p1.y * last_point.y < 0.);
|
||||||
}
|
}
|
||||||
else if(p1.y==0.){
|
else if (p1.y == 0.)
|
||||||
|
{
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
else if(p0.y*p1.y<0.){
|
else if (p0.y * p1.y < 0.)
|
||||||
if(p0.x>=0. && p1.x>=0.){
|
{
|
||||||
|
if (p0.x >= 0. && p1.x >= 0.)
|
||||||
|
{
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
else if (p0.x<0. && p1.x<0.){
|
else if (p0.x < 0. && p1.x < 0.)
|
||||||
|
{
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
vec2 nor;
|
vec2 nor;
|
||||||
if(p0.y>p1.y){
|
if (p0.y > p1.y)
|
||||||
|
{
|
||||||
nor = p0 - p1;
|
nor = p0 - p1;
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
nor = p1 - p0;
|
nor = p1 - p0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nor = vec2(nor.y, -nor.x);
|
nor = vec2(nor.y, -nor.x);
|
||||||
if(dot(nor,p0)<0.){
|
if (dot(nor, p0) < 0.)
|
||||||
|
{
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tri_test(vec2 uv, vec2 p0, vec2 p1, vec2 p2, bool inside){
|
bool tri_test(vec2 uv, vec2 p0, vec2 p1, vec2 p2, bool inside)
|
||||||
|
{
|
||||||
vec2 nor1 = normalize(p0 - p1);
|
vec2 nor1 = normalize(p0 - p1);
|
||||||
nor1 = vec2(nor1.y, -nor1.x);
|
nor1 = vec2(nor1.y, -nor1.x);
|
||||||
vec2 nor2 = normalize(p1 - p2);
|
vec2 nor2 = normalize(p1 - p2);
|
||||||
|
@ -118,29 +149,37 @@ bool tri_test(vec2 uv, vec2 p0, vec2 p1, vec2 p2, bool inside){
|
||||||
vec2 tan3 = normalize(p2 - p0);
|
vec2 tan3 = normalize(p2 - p0);
|
||||||
vec2 nor3 = vec2(tan3.y, -tan3.x);
|
vec2 nor3 = vec2(tan3.y, -tan3.x);
|
||||||
|
|
||||||
if(inside){
|
if (inside)
|
||||||
if(dot(tan3,p0)>=dot(tan3,uv) || dot(tan3,p2)<=dot(tan3,uv)){
|
{
|
||||||
|
if (dot(tan3, p0) >= dot(tan3, uv) || dot(tan3, p2) <= dot(tan3, uv))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float brd = max(dot(nor3, nor1), dot(nor3, nor2)) * border;
|
float brd = max(dot(nor3, nor1), dot(nor3, nor2)) * border;
|
||||||
return (dot(uv,nor1)>=dot(p0,nor1) && dot(uv,nor2)>=dot(p1,nor2) && dot(uv,nor3)>=dot(p2,nor3)+brd) ||
|
return (dot(uv, nor1) >= dot(p0, nor1) && dot(uv, nor2) >= dot(p1, nor2) &&
|
||||||
(dot(uv,nor1)<=dot(p0,nor1) && dot(uv,nor2)<=dot(p1,nor2) && dot(uv,nor3)<=dot(p2,nor3)-brd);
|
dot(uv, nor3) >= dot(p2, nor3) + brd) ||
|
||||||
|
(dot(uv, nor1) <= dot(p0, nor1) && dot(uv, nor2) <= dot(p1, nor2) &&
|
||||||
|
dot(uv, nor3) <= dot(p2, nor3) - brd);
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
float brd1 = dot(nor1, tan3) * border;
|
float brd1 = dot(nor1, tan3) * border;
|
||||||
float brd2 = dot(nor2, tan3) * border;
|
float brd2 = dot(nor2, tan3) * border;
|
||||||
|
|
||||||
if(dot(tan3,p0)>=dot(tan3,uv)-brd1 || dot(tan3,p2)<=dot(tan3,uv)-brd2){
|
if (dot(tan3, p0) >= dot(tan3, uv) - brd1 || dot(tan3, p2) <= dot(tan3, uv) - brd2)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (dot(uv,nor1)>=dot(p0,nor1)-border && dot(uv,nor2)>=dot(p1,nor2)-border && dot(uv,nor3)>=dot(p2,nor3)) ||
|
return (dot(uv, nor1) >= dot(p0, nor1) - border && dot(uv, nor2) >= dot(p1, nor2) - border &&
|
||||||
(dot(uv,nor1)<=dot(p0,nor1)+border && dot(uv,nor2)<=dot(p1,nor2)+border && dot(uv,nor3)<=dot(p2,nor3));
|
dot(uv, nor3) >= dot(p2, nor3)) ||
|
||||||
|
(dot(uv, nor1) <= dot(p0, nor1) + border && dot(uv, nor2) <= dot(p1, nor2) + border &&
|
||||||
|
dot(uv, nor3) <= dot(p2, nor3));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
float bezier_sd(vec2 uv, vec2 p0, vec2 p1, vec2 p2)
|
||||||
|
{
|
||||||
float bezier_sd(vec2 uv, vec2 p0, vec2 p1, vec2 p2){
|
|
||||||
|
|
||||||
const mat2 trf1 = mat2(-1, 2, 1, 2);
|
const mat2 trf1 = mat2(-1, 2, 1, 2);
|
||||||
mat2 trf2 = inv(mat2(p0 - p1, p2 - p1));
|
mat2 trf2 = inv(mat2(p0 - p1, p2 - p1));
|
||||||
|
@ -157,294 +196,341 @@ float bezier_sd(vec2 uv, vec2 p0, vec2 p1, vec2 p2){
|
||||||
return (xy.x * xy.x - xy.y) / length(gradient);
|
return (xy.x * xy.x - xy.y) / length(gradient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
// Modified from http://tog.acm.org/resources/GraphicsGems/gems/Roots3And4.c
|
||||||
|
// Credits to Doublefresh for hinting there
|
||||||
|
int solve_quadric(vec2 coeffs, inout vec2 roots)
|
||||||
|
{
|
||||||
|
|
||||||
|
// normal form: x^2 + px + q = 0
|
||||||
|
float p = coeffs[1] / 2.;
|
||||||
|
float q = coeffs[0];
|
||||||
|
|
||||||
|
float D = p * p - q;
|
||||||
|
|
||||||
float render_serif(vec2 uv){
|
if (D < 0.)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
roots[0] = -sqrt(D) - p;
|
||||||
|
roots[1] = sqrt(D) - p;
|
||||||
|
|
||||||
uv.y-=.5;
|
return 2;
|
||||||
uv*=1.8;
|
|
||||||
border*=1.8;
|
|
||||||
uv.y+=.5;
|
|
||||||
|
|
||||||
uv.x+=.1;
|
|
||||||
|
|
||||||
float d = 1e38;
|
|
||||||
float poly_d = 1e38;
|
|
||||||
float d1 = 1e38;
|
|
||||||
|
|
||||||
vec2 p0,p1,p2;
|
|
||||||
|
|
||||||
if(all(lessThan(abs(uv-vec2(-0.905207605282,0.43943531671)),vec2(0.131571631799,0.146321237064)+vec2(border)))){
|
|
||||||
p0=vec2(-0.980652472562,0.432256320122);p1=vec2(-0.980652472562,0.376129514241);p2=vec2(-0.959444621888,0.347459653556);
|
|
||||||
if(tri_test(uv, p0, p1, p2, true)){
|
|
||||||
d=min(d,-bezier_sd(uv, p0, p1, p2));
|
|
||||||
}
|
|
||||||
p0=vec2(-0.959444621888,0.347459653556);p1=vec2(-0.938361593128,0.318958533541);p2=vec2(-0.897114929876,0.318958533541);
|
|
||||||
if(tri_test(uv, p0, p1, p2, true)){
|
|
||||||
d=min(d,-bezier_sd(uv, p0, p1, p2));
|
|
||||||
}
|
|
||||||
p0=vec2(-0.897114929876,0.318958533541);p1=vec2(-0.865527286983,0.318958533541);p2=vec2(-0.845437632053,0.335419078254);
|
|
||||||
if(tri_test(uv, p0, p1, p2, true)){
|
|
||||||
d=min(d,-bezier_sd(uv, p0, p1, p2));
|
|
||||||
}
|
|
||||||
p0=vec2(-0.845437632053,0.335419078254);p1=vec2(-0.825063806547,0.352112459345);p2=vec2(-0.81697111046,0.384744318419);
|
|
||||||
if(tri_test(uv, p0, p1, p2, true)){
|
|
||||||
d=min(d,-bezier_sd(uv, p0, p1, p2));
|
|
||||||
}
|
|
||||||
p0=vec2(-0.778334987661,0.384744318419);p1=vec2(-0.789821407019,0.339059715715);p2=vec2(-0.82088690046,0.316086918361);
|
|
||||||
if(tri_test(uv, p0, p1, p2, false)){
|
|
||||||
d=min(d,bezier_sd(uv, p0, p1, p2));
|
|
||||||
}
|
|
||||||
p0=vec2(-0.82088690046,0.316086918361);p1=vec2(-0.851691401898,0.293114079646);p2=vec2(-0.902074977419,0.293114079646);
|
|
||||||
if(tri_test(uv, p0, p1, p2, false)){
|
|
||||||
d=min(d,bezier_sd(uv, p0, p1, p2));
|
|
||||||
}
|
|
||||||
p0=vec2(-0.902074977419,0.293114079646);p1=vec2(-0.962900714754,0.293114079646);p2=vec2(-0.999970513281,0.333055493352);
|
|
||||||
if(tri_test(uv, p0, p1, p2, false)){
|
|
||||||
d=min(d,bezier_sd(uv, p0, p1, p2));
|
|
||||||
}
|
|
||||||
p0=vec2(-0.999970513281,0.333055493352);p1=vec2(-1.03677923708,0.373257899062);p2=vec2(-1.03677923708,0.439565833392);
|
|
||||||
if(tri_test(uv, p0, p1, p2, false)){
|
|
||||||
d=min(d,bezier_sd(uv, p0, p1, p2));
|
|
||||||
}
|
|
||||||
p0=vec2(-1.03677923708,0.439565833392);p1=vec2(-1.03677923708,0.505351659632);p2=vec2(-1.00049262137,0.545554106703);
|
|
||||||
if(tri_test(uv, p0, p1, p2, false)){
|
|
||||||
d=min(d,bezier_sd(uv, p0, p1, p2));
|
|
||||||
}
|
|
||||||
p0=vec2(-1.00049262137,0.545554106703);p1=vec2(-0.964206005662,0.585756553774);p2=vec2(-0.905207625963,0.585756553774);
|
|
||||||
if(tri_test(uv, p0, p1, p2, false)){
|
|
||||||
d=min(d,bezier_sd(uv, p0, p1, p2));
|
|
||||||
}
|
|
||||||
p0=vec2(-0.905207625963,0.585756553774);p1=vec2(-0.842293414903,0.585756553774);p2=vec2(-0.808617339647,0.546859356249);
|
|
||||||
if(tri_test(uv, p0, p1, p2, false)){
|
|
||||||
d=min(d,bezier_sd(uv, p0, p1, p2));
|
|
||||||
}
|
|
||||||
p0=vec2(-0.808617339647,0.546859356249);p1=vec2(-0.774941264391,0.508223274812);p2=vec2(-0.773635973483,0.434344752485);
|
|
||||||
if(tri_test(uv, p0, p1, p2, false)){
|
|
||||||
d=min(d,bezier_sd(uv, p0, p1, p2));
|
|
||||||
}
|
|
||||||
p0=vec2(-0.830284887455,0.462016564017);p1=vec2(-0.831851211727,0.510572740539);p2=vec2(-0.850763015272,0.535223303252);
|
|
||||||
if(tri_test(uv, p0, p1, p2, true)){
|
|
||||||
d=min(d,-bezier_sd(uv, p0, p1, p2));
|
|
||||||
}
|
|
||||||
p0=vec2(-0.850763015272,0.535223303252);p1=vec2(-0.869704151709,0.559912099879);p2=vec2(-0.905207625963,0.559912099879);
|
|
||||||
if(tri_test(uv, p0, p1, p2, true)){
|
|
||||||
d=min(d,-bezier_sd(uv, p0, p1, p2));
|
|
||||||
}
|
|
||||||
p0=vec2(-0.905207625963,0.559912099879);p1=vec2(-0.938361593128,0.559912099879);p2=vec2(-0.957418587479,0.535111893535);
|
|
||||||
if(tri_test(uv, p0, p1, p2, true)){
|
|
||||||
d=min(d,-bezier_sd(uv, p0, p1, p2));
|
|
||||||
}
|
|
||||||
p0=vec2(-0.957418587479,0.535111893535);p1=vec2(-0.976475566475,0.510311707175);p2=vec2(-0.980652472562,0.462016564017);
|
|
||||||
if(tri_test(uv, p0, p1, p2, true)){
|
|
||||||
d=min(d,-bezier_sd(uv, p0, p1, p2));
|
|
||||||
}
|
|
||||||
|
|
||||||
d1=1e38;
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.966462321887,0.559912099879),vec2(-0.841030169481,0.559912099879)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.905207625963,0.585756553774),vec2(-0.966462321887,0.559912099879)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.841030169481,0.559912099879),vec2(-0.905207625963,0.585756553774)));
|
|
||||||
|
|
||||||
if(d1<=0.){
|
|
||||||
return d1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
poly_d=min(d1,poly_d);
|
|
||||||
}
|
|
||||||
|
|
||||||
d1=1e38;
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.82088690046,0.316086918361),vec2(-0.81910715467,0.318958533541)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.81910715467,0.318958533541),vec2(-0.965419171536,0.318958533541)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.965419171536,0.318958533541),vec2(-0.902074977419,0.293114079646)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.902074977419,0.293114079646),vec2(-0.82088690046,0.316086918361)));
|
|
||||||
|
|
||||||
if(d1<=0.){
|
|
||||||
return d1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
poly_d=min(d1,poly_d);
|
|
||||||
}
|
|
||||||
|
|
||||||
d1=1e38;
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.773817587078,0.434928897242),vec2(-0.808617339647,0.546859356249)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.808617339647,0.546859356249),vec2(-0.882523641701,0.576621645388)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.882523641701,0.576621645388),vec2(-0.773817587078,0.434928897242)));
|
|
||||||
|
|
||||||
if(d1<=0.){
|
|
||||||
return d1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
poly_d=min(d1,poly_d);
|
|
||||||
}
|
|
||||||
|
|
||||||
d1=1e38;
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.81697111046,0.384744318419),vec2(-0.834987634664,0.312096998846)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.834987634664,0.312096998846),vec2(-0.82088690046,0.316086918361)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.82088690046,0.316086918361),vec2(-0.778334987661,0.384744318419)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.778334987661,0.384744318419),vec2(-0.81697111046,0.384744318419)));
|
|
||||||
|
|
||||||
if(d1<=0.){
|
|
||||||
return d1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
poly_d=min(d1,poly_d);
|
|
||||||
}
|
|
||||||
|
|
||||||
d1=1e38;
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.82088690046,0.316086918361),vec2(-0.778334987661,0.384744318419)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.778334987661,0.384744318419),vec2(-0.785237494603,0.384744318419)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.785237494603,0.384744318419),vec2(-0.894429408392,0.295277456717)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.894429408392,0.295277456717),vec2(-0.82088690046,0.316086918361)));
|
|
||||||
|
|
||||||
if(d1<=0.){
|
|
||||||
return d1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
poly_d=min(d1,poly_d);
|
|
||||||
}
|
|
||||||
|
|
||||||
d1=1e38;
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.829392250654,0.434344752485),vec2(-0.773635973483,0.434344752485)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.833342939816,0.556816429474),vec2(-0.829392250654,0.434344752485)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.808617339647,0.546859356249),vec2(-0.833342939816,0.556816429474)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.773635973483,0.434344752485),vec2(-0.808617339647,0.546859356249)));
|
|
||||||
|
|
||||||
if(d1<=0.){
|
|
||||||
return d1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
poly_d=min(d1,poly_d);
|
|
||||||
}
|
|
||||||
|
|
||||||
d1=1e38;
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-1.00049262137,0.545554106703),vec2(-1.03677923708,0.439565833392)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-1.03677923708,0.439565833392),vec2(-1.03493619641,0.434232780007)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-1.03493619641,0.434232780007),vec2(-0.924880247944,0.577456322027)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.924880247944,0.577456322027),vec2(-1.00049262137,0.545554106703)));
|
|
||||||
|
|
||||||
if(d1<=0.){
|
|
||||||
return d1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
poly_d=min(d1,poly_d);
|
|
||||||
}
|
|
||||||
|
|
||||||
d1=1e38;
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-1.033868039,0.448069047365),vec2(-1.03677923708,0.439565833392)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-1.03677923708,0.439565833392),vec2(-0.999970513281,0.333055493352)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.999970513281,0.333055493352),vec2(-0.926665359012,0.303146964146)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.926665359012,0.303146964146),vec2(-1.033868039,0.448069047365)));
|
|
||||||
|
|
||||||
if(d1<=0.){
|
|
||||||
return d1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
poly_d=min(d1,poly_d);
|
|
||||||
}
|
|
||||||
|
|
||||||
d1=1e38;
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-1.02909290529,0.462016564017),vec2(-1.03677923708,0.439565833392)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-1.03677923708,0.439565833392),vec2(-1.03497489278,0.434344752485)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-1.03497489278,0.434344752485),vec2(-0.773635973483,0.434344752485)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.773635973483,0.434344752485),vec2(-0.782239281314,0.462016564017)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.782239281314,0.462016564017),vec2(-1.02909290529,0.462016564017)));
|
|
||||||
|
|
||||||
if(d1<=0.){
|
|
||||||
return d1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
poly_d=min(d1,poly_d);
|
|
||||||
}
|
|
||||||
|
|
||||||
d1=1e38;
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.972402534183,0.557405817862),vec2(-1.00049262137,0.545554106703)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-1.00049262137,0.545554106703),vec2(-1.03677923708,0.439565833392)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-1.03677923708,0.439565833392),vec2(-0.999970513281,0.333055493352)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.999970513281,0.333055493352),vec2(-0.992084221177,0.329837883348)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.992084221177,0.329837883348),vec2(-0.972402534183,0.557405817862)));
|
|
||||||
|
|
||||||
if(d1<=0.){
|
|
||||||
return d1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
poly_d=min(d1,poly_d);
|
|
||||||
}
|
|
||||||
|
|
||||||
d1=1e38;
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.980652472562,0.553925021021),vec2(-1.00049262137,0.545554106703)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-1.00049262137,0.545554106703),vec2(-1.03677923708,0.439565833392)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-1.03677923708,0.439565833392),vec2(-0.999970513281,0.333055493352)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.999970513281,0.333055493352),vec2(-0.980652472562,0.325173725818)));
|
|
||||||
d1=abs_min(d1,line_dist(uv,vec2(-0.980652472562,0.325173725818),vec2(-0.980652472562,0.553925021021)));
|
|
||||||
|
|
||||||
if(d1<=0.){
|
|
||||||
return d1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
poly_d=min(d1,poly_d);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// From Trisomie21
|
||||||
|
// But instead of his cancellation fix i'm using a newton iteration
|
||||||
|
int solve_cubic(vec3 coeffs, inout vec3 r)
|
||||||
|
{
|
||||||
|
|
||||||
d=min(poly_d,d);
|
float a = coeffs[2];
|
||||||
|
float b = coeffs[1];
|
||||||
|
float c = coeffs[0];
|
||||||
|
|
||||||
return d;
|
float p = b - a * a / 3.0;
|
||||||
|
float q = a * (2.0 * a * a - 9.0 * b) / 27.0 + c;
|
||||||
|
float p3 = p * p * p;
|
||||||
|
float d = q * q + 4.0 * p3 / 27.0;
|
||||||
|
float offset = -a / 3.0;
|
||||||
|
if (d >= 0.0)
|
||||||
|
{ // Single solution
|
||||||
|
float z = sqrt(d);
|
||||||
|
float u = (-q + z) / 2.0;
|
||||||
|
float v = (-q - z) / 2.0;
|
||||||
|
u = sign(u) * pow(abs(u), 1.0 / 3.0);
|
||||||
|
v = sign(v) * pow(abs(v), 1.0 / 3.0);
|
||||||
|
r[0] = offset + u + v;
|
||||||
|
|
||||||
|
// Single newton iteration to account for cancellation
|
||||||
|
float f = ((r[0] + a) * r[0] + b) * r[0] + c;
|
||||||
|
float f1 = (3. * r[0] + 2. * a) * r[0] + b;
|
||||||
|
|
||||||
|
r[0] -= f / f1;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
float u = sqrt(-p / 3.0);
|
||||||
|
float v = acos(-sqrt(-27.0 / p3) * q / 2.0) / 3.0;
|
||||||
|
float m = cos(v), n = sin(v) * 1.732050808;
|
||||||
|
|
||||||
|
// Single newton iteration to account for cancellation
|
||||||
|
//(once for every root)
|
||||||
|
r[0] = offset + u * (m + m);
|
||||||
|
r[1] = offset - u * (n + m);
|
||||||
|
r[2] = offset + u * (n - m);
|
||||||
|
|
||||||
|
vec3 f = ((r + a) * r + b) * r + c;
|
||||||
|
vec3 f1 = (3. * r + 2. * a) * r + b;
|
||||||
|
|
||||||
|
r -= f / f1;
|
||||||
|
|
||||||
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float cubic_bezier_normal_iteration(float t, vec2 a0, vec2 a1, vec2 a2, vec2 a3)
|
||||||
|
{
|
||||||
|
// horner's method
|
||||||
|
vec2 a_2 = a2 + t * a3;
|
||||||
|
vec2 a_1 = a1 + t * a_2;
|
||||||
|
vec2 b_2 = a_2 + t * a3;
|
||||||
|
|
||||||
void mainImage( out vec4 fragColor, in vec2 fragCoord ){
|
vec2 uv_to_p = a0 + t * a_1;
|
||||||
|
vec2 tang = a_1 + t * b_2;
|
||||||
|
|
||||||
|
float l_tang = dot(tang, tang);
|
||||||
|
return t - dot(tang, uv_to_p) / l_tang;
|
||||||
|
}
|
||||||
|
|
||||||
|
float cubic_bezier_dis_approx_sq(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3)
|
||||||
|
{
|
||||||
|
vec2 a3 = (-p0 + 3. * p1 - 3. * p2 + p3);
|
||||||
|
vec2 a2 = (3. * p0 - 6. * p1 + 3. * p2);
|
||||||
|
vec2 a1 = (-3. * p0 + 3. * p1);
|
||||||
|
vec2 a0 = p0 - uv;
|
||||||
|
|
||||||
|
float d0 = 1e38;
|
||||||
|
|
||||||
|
float t;
|
||||||
|
vec3 params = vec3(0, .5, 1);
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
t = params[i];
|
||||||
|
for (int j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
t = cubic_bezier_normal_iteration(t, a0, a1, a2, a3);
|
||||||
|
}
|
||||||
|
t = clamp(t, 0., 1.);
|
||||||
|
vec2 uv_to_p = ((a3 * t + a2) * t + a1) * t + a0;
|
||||||
|
d0 = min(d0, dot(uv_to_p, uv_to_p));
|
||||||
|
}
|
||||||
|
|
||||||
|
return d0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// segment_dis_sq by iq
|
||||||
|
float length2(vec2 v)
|
||||||
|
{
|
||||||
|
return dot(v, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
float segment_dis_sq(vec2 p, vec2 a, vec2 b)
|
||||||
|
{
|
||||||
|
vec2 pa = p - a, ba = b - a;
|
||||||
|
float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
|
||||||
|
return length2(pa - ba * h);
|
||||||
|
}
|
||||||
|
|
||||||
|
int segment_int_test(vec2 uv, vec2 p0, vec2 p1)
|
||||||
|
{
|
||||||
|
p0 -= uv;
|
||||||
|
p1 -= uv;
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (p0.y * p1.y < 0.)
|
||||||
|
{
|
||||||
|
vec2 nor = p0 - p1;
|
||||||
|
nor = vec2(nor.y, -nor.x);
|
||||||
|
|
||||||
|
float sgn;
|
||||||
|
|
||||||
|
if (p0.y > p1.y)
|
||||||
|
{
|
||||||
|
sgn = 1.;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sgn = -1.;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dot(nor, p0) * sgn < 0.)
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cubic_bezier_int_test(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3)
|
||||||
|
{
|
||||||
|
|
||||||
|
float cu = (-p0.y + 3. * p1.y - 3. * p2.y + p3.y);
|
||||||
|
float qu = (3. * p0.y - 6. * p1.y + 3. * p2.y);
|
||||||
|
float li = (-3. * p0.y + 3. * p1.y);
|
||||||
|
float co = p0.y - uv.y;
|
||||||
|
|
||||||
|
vec3 roots = vec3(1e38);
|
||||||
|
int n_roots;
|
||||||
|
|
||||||
|
int n_ints = 0;
|
||||||
|
|
||||||
|
if (uv.x < min(min(p0.x, p1.x), min(p2.x, p3.x)))
|
||||||
|
{
|
||||||
|
if (uv.y >= min(p0.y, p3.y) && uv.y <= max(p0.y, p3.y))
|
||||||
|
{
|
||||||
|
n_ints = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
if (abs(cu) < .0001)
|
||||||
|
{
|
||||||
|
n_roots = solve_quadric(vec2(co / qu, li / qu), roots.xy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
n_roots = solve_cubic(vec3(co / cu, li / cu, qu / cu), roots);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < n_roots; i++)
|
||||||
|
{
|
||||||
|
if (roots[i] >= 0. && roots[i] <= 1.)
|
||||||
|
{
|
||||||
|
float x_pos = -p0.x + 3. * p1.x - 3. * p2.x + p3.x;
|
||||||
|
x_pos = x_pos * roots[i] + 3. * p0.x - 6. * p1.x + 3. * p2.x;
|
||||||
|
x_pos = x_pos * roots[i] + -3. * p0.x + 3. * p1.x;
|
||||||
|
x_pos = x_pos * roots[i] + p0.x;
|
||||||
|
|
||||||
|
if (x_pos > uv.x)
|
||||||
|
{
|
||||||
|
n_ints++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return n_ints;
|
||||||
|
}
|
||||||
|
|
||||||
|
float path2_dis_sq(vec2 uv)
|
||||||
|
{
|
||||||
|
float dis_sq = 1e38;
|
||||||
|
|
||||||
|
int num_its = 0;
|
||||||
|
|
||||||
|
vec2[45] p = vec2[](vec2(-0.124919, 0.0496896), vec2(-0.127105, 0.0391554), vec2(-0.127105, 0.0405467),
|
||||||
|
vec2(-0.127105, 0.0463107), vec2(-0.131876, 0.0506833), vec2(-0.143205, 0.0506833),
|
||||||
|
vec2(-0.177789, 0.0506833), vec2(-0.194286, 0.00795032), vec2(-0.194286, -0.018882),
|
||||||
|
vec2(-0.194286, -0.0425342), vec2(-0.181366, -0.0508821), vec2(-0.167851, -0.0508821),
|
||||||
|
vec2(-0.153739, -0.0508821), vec2(-0.144397, -0.0417392), vec2(-0.138236, -0.0325963),
|
||||||
|
vec2(-0.137043, -0.0445217), vec2(-0.129888, -0.0508821), vec2(-0.118758, -0.0508821),
|
||||||
|
vec2(-0.108025, -0.0508821), vec2(-0.0901364, -0.0465093), vec2(-0.0788071, -0.0141118),
|
||||||
|
vec2(-0.087155, -0.0141118), vec2(-0.0901364, -0.0240497), vec2(-0.0955028, -0.0327951),
|
||||||
|
vec2(-0.103254, -0.0327951), vec2(-0.10882, -0.0327951), vec2(-0.111403, -0.0298137),
|
||||||
|
vec2(-0.111403, -0.0242485), vec2(-0.111403, -0.0224597), vec2(-0.111205, -0.0204721),
|
||||||
|
vec2(-0.110609, -0.0178882), vec2(-0.0962985, 0.0496896), vec2(-0.137043, 0.0383603),
|
||||||
|
vec2(-0.130683, 0.0383603), vec2(-0.128894, 0.0331926), vec2(-0.128894, 0.0308075),
|
||||||
|
vec2(-0.138435, -0.0141118), vec2(-0.14082, -0.0256398), vec2(-0.149168, -0.0316026),
|
||||||
|
vec2(-0.154931, -0.0316026), vec2(-0.158509, -0.0316026), vec2(-0.164869, -0.0314042),
|
||||||
|
vec2(-0.164869, -0.0160994), vec2(-0.164869, 0.00258385), vec2(-0.153938, 0.0383603));
|
||||||
|
|
||||||
|
ivec2[6] seg = ivec2[](ivec2(0, 1), ivec2(1, 2), ivec2(20, 21), ivec2(30, 31), ivec2(31, 0), ivec2(35, 36));
|
||||||
|
|
||||||
|
ivec4[13] c_bez =
|
||||||
|
ivec4[](ivec4(2, 3, 4, 5), ivec4(5, 6, 7, 8), ivec4(8, 9, 10, 11), ivec4(11, 12, 13, 14), ivec4(14, 15, 16, 17),
|
||||||
|
ivec4(17, 18, 19, 20), ivec4(21, 22, 23, 24), ivec4(24, 25, 26, 27), ivec4(27, 28, 29, 30),
|
||||||
|
ivec4(32, 33, 34, 35), ivec4(36, 37, 38, 39), ivec4(39, 40, 41, 42), ivec4(42, 43, 44, 32));
|
||||||
|
|
||||||
|
if (all(lessThan(uv, vec2(-0.0788071, 0.0506833) + border)) &&
|
||||||
|
all(greaterThan(uv, vec2(-0.194286, -0.0508821) - border)))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
dis_sq = min(dis_sq, segment_dis_sq(uv, p[seg[i][0]], p[seg[i][1]]));
|
||||||
|
num_its += segment_int_test(uv, p[seg[i][0]], p[seg[i][1]]);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 13; i++)
|
||||||
|
{
|
||||||
|
dis_sq = min(
|
||||||
|
dis_sq, cubic_bezier_dis_approx_sq(uv, p[c_bez[i][0]], p[c_bez[i][1]], p[c_bez[i][2]], p[c_bez[i][3]]));
|
||||||
|
num_its += cubic_bezier_int_test(uv, p[c_bez[i][0]], p[c_bez[i][1]], p[c_bez[i][2]], p[c_bez[i][3]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float sgn = 1.;
|
||||||
|
|
||||||
|
if (num_its % 2 == 1)
|
||||||
|
{
|
||||||
|
sgn = -1.;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sgn * dis_sq;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mainImage(out vec3 fragColor, in vec2 fragCoord)
|
||||||
|
{
|
||||||
border = 0.01;
|
border = 0.01;
|
||||||
|
vec2 uv = fragCoord;
|
||||||
|
uv -= .5;
|
||||||
|
|
||||||
vec2 uv = fragCoord.xy;
|
float dis_sq = 1e38;
|
||||||
|
|
||||||
uv.x-=1;
|
if (all(lessThan(uv, vec2(0.4, 0.0993791) + border)) && all(greaterThan(uv, vec2(-0.4, -0.0993791) - border)))
|
||||||
//uv/=10;
|
{
|
||||||
float d = 1e38;
|
dis_sq = min(dis_sq, path2_dis_sq(uv));
|
||||||
|
|
||||||
if(all(lessThan(abs(uv-vec2(0.0873228569516,0.500000020681)),vec2(1.58799651081,0.206885941035)+vec2(border))))
|
|
||||||
d=min(d,render_serif(uv));
|
|
||||||
|
|
||||||
|
|
||||||
//fragColor=vec4(smoothstep(0., border, d));
|
|
||||||
fragColor=vec4(vec3(d*10),1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float dis = sign(dis_sq) * sqrt(abs(dis_sq));
|
||||||
|
|
||||||
|
fragColor = vec3(smoothstep(0., border, dis));
|
||||||
|
if (dis > 0 && dis <= border)
|
||||||
|
fragColor = vec3(1, 1, 0);
|
||||||
|
}
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
const uint STACK_SIZE = 10;
|
const uint STACK_SIZE = 10;
|
||||||
struct Stack {
|
|
||||||
|
struct Stack
|
||||||
|
{
|
||||||
uint top;
|
uint top;
|
||||||
uint data[STACK_SIZE];
|
uint data[STACK_SIZE];
|
||||||
|
|
||||||
bool empty() {
|
bool empty()
|
||||||
|
{
|
||||||
return top == 0;
|
return top == 0;
|
||||||
}
|
}
|
||||||
bool full() {
|
bool full()
|
||||||
|
{
|
||||||
return top == STACK_SIZE;
|
return top == STACK_SIZE;
|
||||||
}
|
}
|
||||||
bool getTop(out uint x) {
|
bool getTop(out uint x)
|
||||||
|
{
|
||||||
if (empty())
|
if (empty())
|
||||||
return false;
|
return false;
|
||||||
x = data[top - 1];
|
x = data[top - 1];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool pop() {
|
bool pop()
|
||||||
|
{
|
||||||
if (empty())
|
if (empty())
|
||||||
return false;
|
return false;
|
||||||
top--;
|
top--;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool push(in uint x) {
|
bool push(in uint x)
|
||||||
|
{
|
||||||
if (full())
|
if (full())
|
||||||
return false;
|
return false;
|
||||||
data[top] = x;
|
data[top] = x;
|
||||||
top++;
|
top++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} stack;
|
} stack, elementStack;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
@ -473,28 +559,129 @@ void main()
|
||||||
if (all(lessThan(vec2(-1), localUV)) && all(lessThan(localUV, vec2(1))))
|
if (all(lessThan(vec2(-1), localUV)) && all(lessThan(localUV, vec2(1))))
|
||||||
{
|
{
|
||||||
uint elementIndex = leftChild - bvhLength;
|
uint elementIndex = leftChild - bvhLength;
|
||||||
debugBVH.bg+=0.5*(localUV+vec2(1));
|
//debugBVH.bg += 0.5 * (localUV + vec2(1));
|
||||||
for(uint i=elementOffset[elementIndex][1];i<elementOffset[elementIndex][2];i+=7)
|
debugBVH = vec3(0);
|
||||||
|
////////////////////////////ͼԪÄÚBVH/////////////////////////////////
|
||||||
|
|
||||||
|
uvec4 currentOffset = elementOffset[elementIndex];
|
||||||
|
uint elementBvhRoot = currentOffset.x;
|
||||||
|
uint elementBvhLength = currentOffset.y;
|
||||||
|
uint pointsOffset = currentOffset.z;
|
||||||
|
uint linesOffset = currentOffset.w;
|
||||||
|
|
||||||
|
elementStack.top = 0;
|
||||||
|
uint elementBvhIndex = 0;
|
||||||
|
while (elementBvhIndex < elementBvhLength || !elementStack.empty())
|
||||||
{
|
{
|
||||||
if(tri_test(localUV, vec2(elementData[i],elementData[i+1]), vec2(elementData[i+2],elementData[i+3]), vec2(elementData[i+4],elementData[i+5]), true))
|
|
||||||
|
while (elementBvhIndex < elementBvhLength)
|
||||||
{
|
{
|
||||||
if(elementData[i+6]==0)
|
vec4 bound = bvhBound[elementBvhRoot + elementBvhIndex];
|
||||||
|
uint leftChild = bvhChildren[elementBvhRoot + elementBvhIndex].x;
|
||||||
|
|
||||||
|
if (all(lessThan(bound.xy, localUV)) && all(lessThan(localUV, bound.zw)))
|
||||||
{
|
{
|
||||||
debugHit=true;
|
if (leftChild >= elementBvhLength )
|
||||||
}
|
{
|
||||||
else if(elementData[i+6]==1)
|
debugBVH.g += 0.5;
|
||||||
{
|
|
||||||
if(-bezier_sd(localUV, vec2(elementData[i],elementData[i+1]), vec2(elementData[i+2],elementData[i+3]), vec2(elementData[i+4],elementData[i+5]))>0)
|
|
||||||
debugHit=true;
|
uint styleIndex = bvhChildren[elementBvhRoot + elementBvhIndex].y-elementBvhLength;
|
||||||
|
|
||||||
|
if(elementData[styleIndex]==0. )//Ãæ
|
||||||
|
{
|
||||||
|
|
||||||
|
uint lineCount = elementIndexs[leftChild-elementBvhLength];
|
||||||
|
uint num_its = 0;
|
||||||
|
for(uint contourIterator = leftChild-elementBvhLength+1; contourIterator<=leftChild-elementBvhLength+lineCount; contourIterator++ )
|
||||||
|
{
|
||||||
|
uint lineIndex = elementIndexs[contourIterator];
|
||||||
|
uint p0Index = elementIndexs[linesOffset+4*lineIndex];
|
||||||
|
uint p1Index = elementIndexs[linesOffset+4*lineIndex+1];
|
||||||
|
uint p2Index = elementIndexs[linesOffset+4*lineIndex+2];
|
||||||
|
uint p3Index = elementIndexs[linesOffset+4*lineIndex+3];
|
||||||
|
|
||||||
|
vec2 p0 = vec2(elementData[pointsOffset+2*p0Index], elementData[pointsOffset+2*p0Index+1]);
|
||||||
|
vec2 p1 = vec2(elementData[pointsOffset+2*p1Index], elementData[pointsOffset+2*p1Index+1]);
|
||||||
|
vec2 p2 = vec2(elementData[pointsOffset+2*p2Index], elementData[pointsOffset+2*p2Index+1]);
|
||||||
|
vec2 p3 = vec2(elementData[pointsOffset+2*p3Index], elementData[pointsOffset+2*p3Index+1]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(p0==p1 && p2==p3)
|
||||||
|
{
|
||||||
|
num_its += segment_int_test(localUV, p0, p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
num_its += cubic_bezier_int_test(localUV, p0, p1, p2, p3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (num_its % 2 == 1)
|
||||||
{
|
{
|
||||||
if(bezier_sd(localUV, vec2(elementData[i],elementData[i+1]), vec2(elementData[i+2],elementData[i+3]), vec2(elementData[i+4],elementData[i+5]))>0)
|
|
||||||
debugHit = true;
|
debugHit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(elementData[styleIndex]==1)//Ïß
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
elementBvhIndex = elementBvhLength;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//debugBVH.b += 0.2;
|
||||||
|
elementStack.push(elementBvhIndex);
|
||||||
|
elementBvhIndex = leftChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
elementBvhIndex = elementBvhLength;
|
||||||
|
}
|
||||||
|
if (!elementStack.empty())
|
||||||
|
{
|
||||||
|
elementStack.getTop(elementBvhIndex);
|
||||||
|
elementStack.pop();
|
||||||
|
elementBvhIndex = bvhChildren[elementBvhRoot + elementBvhIndex].y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
// mainImage(debugBVH,localUV);
|
||||||
|
|
||||||
|
// for(uint i=elementOffset[elementIndex][1];i<elementOffset[elementIndex][2];i+=7)
|
||||||
|
// {
|
||||||
|
// if(tri_test(localUV, vec2(elementData[i],elementData[i+1]),
|
||||||
|
//vec2(elementData[i+2],elementData[i+3]), vec2(elementData[i+4],elementData[i+5]), true))
|
||||||
|
// {
|
||||||
|
// if(elementData[i+6]==0)
|
||||||
|
// {
|
||||||
|
// debugHit=true;
|
||||||
|
// }
|
||||||
|
// else if(elementData[i+6]==1)
|
||||||
|
// {
|
||||||
|
// if(-bezier_sd(localUV, vec2(elementData[i],elementData[i+1]),
|
||||||
|
//vec2(elementData[i+2],elementData[i+3]), vec2(elementData[i+4],elementData[i+5]))>0)
|
||||||
|
// debugHit=true;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// if(bezier_sd(localUV, vec2(elementData[i],elementData[i+1]),
|
||||||
|
//vec2(elementData[i+2],elementData[i+3]), vec2(elementData[i+4],elementData[i+5]))>0)
|
||||||
|
// debugHit=true;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
index = bvhLength;
|
index = bvhLength;
|
||||||
|
@ -508,7 +695,8 @@ void main()
|
||||||
else
|
else
|
||||||
index = bvhLength;
|
index = bvhLength;
|
||||||
}
|
}
|
||||||
if (!stack.empty()) {
|
if (!stack.empty())
|
||||||
|
{
|
||||||
stack.getTop(index);
|
stack.getTop(index);
|
||||||
stack.pop();
|
stack.pop();
|
||||||
index = bvhChildren[index].y;
|
index = bvhChildren[index].y;
|
||||||
|
|
Loading…
Reference in New Issue