저는 어디에서부터 시작해 봅시다; 조각 쉐이더 : 조각에서 베 지어 곡선까지 거리를 얻으십시오
FBO를 통해이 텍스처를 생성하는 프래그먼트 셰이더가 있습니다. 베 지어 커브를 제외하고 내가 원하는 모든 프리미티브가 거의 있습니다.
내 오히려 큰 조각 쉐이더 : 모든 2D 공간에서 곡선은 종종 3 개 이상의 지점을 가지고있는 베 지어def on_draw(self):
if not self.inited:
vert = shader.Shader(shader.texvertex)
frag = shader.Shader(shader.testfrag)
self.TexProgram = shader.Program([vert, frag])
with self.TexProgram:
self.TexProgram["lines[0]"] = (0.25, 0.5, 0.75, 0.5)
self.TexProgram["lines[1]"] = (0.0, 0.0, 1.0, 1.0)
self.TexProgram["circles[0]"] = (0.5, 0.5, 0.1)
self.TexProgram["ellipses[0]"] = (0.75, 0.25, 0.1, 2.0) #x,y, width, multiplicator on height
self.TexProgram["polygons[0]"] = (0.1, 0.9)
self.TexProgram["polygons[1]"] = (0.2, 0.9)
self.TexProgram["polygons[2]"] = (0.2, 1)
self.TexProgram["polygons[3]"] = (0.1, 1)
self.TexProgram["polygons[4]"] = (0,0)
self.TexProgram["polygons[5]"] = (0.1, 0.1)
self.TexProgram["polygons[6]"] = (0.2, 0.1)
self.TexProgram["polygons[7]"] = (0.2, 0.2)
self.TexProgram["polygons[8]"] = (0.1, 0.2)
self.TexProgram["polygons[9]"] = (0,0)
self.TexProgram["polylength"] = 8
self.TexProgram["light"] = 1.05
self.TexProgram["thickness"] = 0.02
self.inited = True
self.clear()
else:
with self.TexProgram:
self.fbo.bind_texture()
self.fbo.clear()
t = (0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0)
x1 = 0
x2 = w
y1 = 0
y2 = h
glColor4d(1,1,1,1)
glEnable (GL_TEXTURE_2D)
glBegin(GL_QUADS)
glTexCoord2d(t[0], t[1]); glVertex2d(x1, y1)
glTexCoord2d(t[2], t[3]); glVertex2d(x2, y1)
glTexCoord2d(t[4], t[5]); glVertex2d(x2, y2)
glTexCoord2d(t[6], t[7]); glVertex2d(x1, y2)
glEnd()
입니다
하십시오 pyglet 환경에서 대략 다음과 같이이라고
testfrag = """//fragment
uniform float thickness; //sets beam thickness
uniform float light; //sets beam intensity
uniform vec4 lines[200]; //pairs of lines; x1, y1, x2, y2
uniform vec3 circles[200]; //circles x,y,radius
uniform vec4 ellipses[200]; //ellipses x,y,width, heightmultiplication
uniform int ellipselength = 1; //amount of ellipses
uniform int linelength = 2; //amount of linepairs
uniform int circlelength = 1; //amount of circles
uniform vec2 polygons[200]; //polygon data, points in x,y. (0,0) points used as end marker
uniform int polylength; //amount of polygons
int i; //for counter variable 1
int i2; //for counter variable 2
float mindistance = 1.0; //distance from fragment to next segment
float P2L(in vec2 p, in vec2 lp1, in vec2 lp2) //distance point to line segment
{
float squared = pow(distance(lp1, lp2), 2); //squared line length
float t = dot(p - lp1, lp2 - lp1)/squared; //relative position in parellel to line
if (t < 0.0) return distance(p, lp1); //before the line, get radius to point
if (t > 1.0) return distance(p, lp2); //after the line, get radius to point
return distance(p, lp1 + t * (lp2 - lp1)); //otherwise, get distance line to point
}
float P2C(in vec2 p, in vec3 circle) //point to circle
{
return abs(distance(p, circle.xy)-circle.z); //euclidian distance - radius
}
float P2E(in vec2 p, in vec4 ellipse) //point to ellipse
{
return abs(sqrt(pow(p.x-ellipse.x,2) + pow((p.y-ellipse.y)/ellipse.w, 2)) -ellipse.z); // similar to circle, with factor on height
}
bool PinPoly(in vec2 p, in int start, in int len) //test if point in polygon
{
int i, j;
bool c = false;
for (i = start, j = len-1+start; i < len+start; j = i++) {
if (((polygons[i].y>p.y) != (polygons[j].y>p.y)) &&
(p.x < (polygons[j].x-polygons[i].x) * (p.y-polygons[i].y)/(polygons[j].y-polygons[i].y) + polygons[i].x))
c = !c;
}
return c;
} //balls if I know how this works
void main()
{
vec2 pos = gl_TexCoord[0].xy; // get position on fbo
for (i = 0; i < linelength; i++) //test lines
{
mindistance = min(mindistance, P2L(pos, lines[i].xy, lines[i].zw));
}
for (i = 0; i < circlelength; i++) //test circles
{
mindistance = min(mindistance, P2C(pos, circles[i]));
}
for (i = 0; i < ellipselength; i++) //test ellipses
{
mindistance = min(mindistance, P2E(pos, ellipses[i]));
}
i = 1;
int first;
while (i < polylength) //test polygons
{
//first for line segments
first = i-1;
while (polygons[i] != (0.0, 0.0))
{
mindistance = min(mindistance, P2L(pos, polygons[i-1], polygons[i]));
i++;
}
mindistance = min(mindistance, P2L(pos, polygons[i-1], polygons[first]));
if (PinPoly(pos, first, i-first)) //then test if it is inside a polygon
{
mindistance = 0.0;
}
i += 2; //jump over the (0,0) vec2
}
gl_FragColor = light*(1.0/thickness)*(thickness-mindistance).xxxx; //set color of fragment
}
"""
. 내가 보는 방법에는이 문제를 해결할 수있는 두 가지 방법이 있습니다.
1 :
Generate points on curve.
get closest curve point.
generate points around curve point.
get closest point of those.
rince and repeat last steps until satisfactory precision is reached.
2 : 해석의 거리를 얻을 수있는 공식/알고리즘으로 올라와. 나는 이것을 시도하고 어떤 수의 베 지어 커브 점에 대해서도 일정한 양에 대해서만 해결책을 찾지 못했습니다.
두 번째 방법에 대한 해결책을 선호합니다. 저는 첫 번째 방법에 대한 해결책을 스스로 고안 할 수 있습니다. 그러나 누군가가 그것을 찾는 모든 자원을 알고 있으므로 어쨌든 시간을 낭비하지 않아도됩니다.