Fix: painting.comp bug

dev-LayerStyle
wuyize 2023-03-15 11:23:21 +08:00
parent c6a4d79888
commit 57d6de47f8
2 changed files with 78 additions and 33 deletions

View File

@ -1150,11 +1150,6 @@ void main()
else else
tangentEnd = normalize(p[3] - p[1]); tangentEnd = normalize(p[3] - p[1]);
// if (onBegin ? shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin,
// tangentEndLast)
// : (onEnd ? shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd,
// tangentBeginNext)
// : d < minDistance))
bool hit = d < minDistance; bool hit = d < minDistance;
if (onBegin) if (onBegin)
hit = hit && hit = hit &&

View File

@ -1023,14 +1023,14 @@ void drawLine(in float d, in uint styleIndex, out vec4 elementColor, out vec2 me
} }
} }
bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p3, vec2 tangentBegin, vec2 tangentEndLast) bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p0, vec2 tangentBegin, vec2 tangentEndLast)
{ {
vec2 normal; vec2 normal;
if (onVeryBegin) if (onVeryBegin)
{ {
if (endType == 0) if (endType % 2 == 0)
return true; return true;
else if (endType == 1) else if (endType % 2 == 1)
normal = normalize(mat2(0, 1, -1, 0) * (-tangentBegin)); normal = normalize(mat2(0, 1, -1, 0) * (-tangentBegin));
} }
else else
@ -1039,17 +1039,26 @@ bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p3, ve
vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBegin)); vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBegin));
normal = normalLast + normalNow; normal = normalLast + normalNow;
} }
return angleLargeThanPi(normal, localUV - p3); return angleLargeThanPi(normal, localUV - p0);
} }
bool shouldFillEndCap(vec2 localUV, int endType, vec2 p0, vec2 tangentEnd) bool shouldFillEndCap(vec2 localUV, bool onVeryEnd, int endType, vec2 p3, vec2 tangentEnd, vec2 tangentBeginNext)
{ {
vec2 normal; vec2 normal;
if (endType == 0) if (onVeryEnd)
{
if ((endType / 2) % 2 == 0)
return true; return true;
else if (endType == 1) else if ((endType / 2) % 2 == 1)
normal = normalize(mat2(0, 1, -1, 0) * tangentEnd); normal = normalize(mat2(0, 1, -1, 0) * tangentEnd);
return angleLargeThanPi(localUV - p0, normal); }
else
{
vec2 normalLast = normalize(mat2(0, 1, -1, 0) * tangentEnd);
vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBeginNext));
normal = normalLast + normalNow;
}
return angleLargeThanPi(localUV - p3, normal);
} }
bool fillElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsOffset, uint styleIndex, bool fillElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsOffset, uint styleIndex,
@ -1100,8 +1109,8 @@ bool fillElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsO
return hitElement; return hitElement;
} }
bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsOffset, uint styleIndex, float widthHeightRatio, bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsOffset, uint styleIndex,
inout vec4 elementColor, inout vec2 metallicRoughness) float widthHeightRatio, inout vec4 elementColor, inout vec2 metallicRoughness)
{ {
bool hitElement = false; bool hitElement = false;
float strokeWidth = elementData[styleIndex]; float strokeWidth = elementData[styleIndex];
@ -1135,12 +1144,44 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
mat4x2 p = mat4x2 p =
mat4x2(elementData[pxIndex[0]], elementData[pyIndex[0]], elementData[pxIndex[1]], elementData[pyIndex[1]], mat4x2(elementData[pxIndex[0]], elementData[pyIndex[0]], elementData[pxIndex[1]], elementData[pyIndex[1]],
elementData[pxIndex[2]], elementData[pyIndex[2]], elementData[pxIndex[3]], elementData[pyIndex[3]]); elementData[pxIndex[2]], elementData[pyIndex[2]], elementData[pxIndex[3]], elementData[pyIndex[3]]);
p[0] *= ratio; p[0] *= ratio;
p[1] *= ratio; p[1] *= ratio;
p[2] *= ratio; p[2] *= ratio;
p[3] *= ratio; p[3] *= ratio;
vec2 tangentBeginNext;
if (contourIterator + 1 < contourIndex + 1 + lineCount)
{
uint lineIndex = elementIndexs[contourIterator + 1];
uint pLocation = linesOffset + 3 * lineIndex;
//vec2 percent = unpackUnorm2x16(elementIndexs[pLocation + 2]);
uvec4 pxIndex = uvec4(pointsOffset) +
2 * uvec4(elementIndexs[pLocation] >> 16, elementIndexs[pLocation] & 0xFFFF,
elementIndexs[pLocation + 1] >> 16, elementIndexs[pLocation + 1] & 0xFFFF);
uvec4 pyIndex = uvec4(1) + pxIndex;
mat4x2 pNext = mat4x2(elementData[pxIndex[0]], elementData[pyIndex[0]], elementData[pxIndex[1]],
elementData[pyIndex[1]], elementData[pxIndex[2]], elementData[pyIndex[2]],
elementData[pxIndex[3]], elementData[pyIndex[3]]);
pNext[0] *= ratio;
pNext[1] *= ratio;
pNext[2] *= ratio;
pNext[3] *= ratio;
if (pNext[0] == pNext[1] && pNext[2] == pNext[3])
{
pNext[1] = (pNext[0] + pNext[3]) / 2;
pNext[2] = pNext[1];
}
//if(pNext[0]!=p[3])
// break;
if (pNext[0] != pNext[1])
tangentBeginNext = normalize(pNext[0] - pNext[1]);
else
tangentBeginNext = normalize(pNext[0] - pNext[2]);
}
if (p[0] == p[1] && p[2] == p[3]) if (p[0] == p[1] && p[2] == p[3])
{ {
p[1] = (p[0] + p[3]) / 2; p[1] = (p[0] + p[3]) / 2;
@ -1158,7 +1199,10 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
float d = cubic_bezier_dis(localUV, p[0], p[1], p[2], p[3], true); float d = cubic_bezier_dis(localUV, p[0], p[1], p[2], p[3], true);
if (d <= strokeWidth) if (d <= strokeWidth)
{ {
bool onBegin = distance(localUV, p[0]) <= strokeWidth && ( p3Last == p[0] || contourIterator==contourIndex + 1); bool onBegin =
distance(localUV, p[0]) <= strokeWidth; //&& (p3Last == p[0] || contourIterator == contourIndex + 1);
bool onEnd = distance(localUV, p[3]) <= strokeWidth;
vec2 tangentBegin; vec2 tangentBegin;
vec2 tangentEnd; vec2 tangentEnd;
if (p[0] != p[1]) if (p[0] != p[1])
@ -1170,30 +1214,36 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
else else
tangentEnd = normalize(p[3] - p[1]); tangentEnd = normalize(p[3] - p[1]);
if (onBegin ? shouldFillBeginCap(localUV, percent[0]<1e-5, endType, p[0], tangentBegin, p3Last - p2Last) bool hit = d < minDistance;
: d < minDistance) if (onBegin)
hit =
hit && shouldFillBeginCap(localUV, percent[0] < 1e-5, endType, p[0], tangentBegin, p3Last - p2Last);
if (onEnd)
hit = hit &&
shouldFillEndCap(localUV, percent[1] > 1 - 1e-5, endType, p[3], tangentEnd, tangentBeginNext);
if (hit)
{ {
minDistance = min(minDistance, d);
bool reverse = p[3].y - p[0].y < 0.; bool reverse = p[3].y - p[0].y < 0.;
if (tangentBegin.y == 0.) // if (tangentBegin.y == 0.)
tangentBegin.y = reverse ? eps : -eps; // tangentBegin.y = reverse ? eps : -eps;
if (tangentEnd.y == 0.) // if (tangentEnd.y == 0.)
tangentEnd.y = reverse ? -eps : eps; // tangentEnd.y = reverse ? -eps : eps;
int intTest = cubic_bezier_int_test2(localUV, p[0], p[1], p[2], p[3], reverse) + int intTest = cubic_bezier_int_test2(localUV, p[0], p[1], p[2], p[3], reverse) +
ray_int_test(localUV, p[0], tangentBegin, reverse) + ray_int_test(localUV, p[0], tangentBegin, reverse) +
ray_int_test(localUV, p[3], tangentEnd, reverse); ray_int_test(localUV, p[3], tangentEnd, reverse);
if (lineType == 2 || (intTest % 2 == int(lineType))) if (lineType == 2 || (intTest % 2 == int(lineType)))
{ {
minDistance = min(minDistance, d);
hitElement = true; hitElement = true;
// elementColor = vec4(1, 1, 0, 1); // elementColor = vec4(1, 1, 0, 1);
vec2 metallicRoughness; vec2 metallicRoughness;
drawLine(minDistance / strokeWidth, styleIndex, elementColor, metallicRoughness); drawLine(minDistance / strokeWidth, styleIndex, elementColor, metallicRoughness);
} }
else if (p3Last == p[0]) // else if (p3Last == p[0])
hitElement = false; // hitElement = false;
} }
tangentEndLast = tangentEnd; tangentEndLast = tangentEnd;
} }
@ -1202,7 +1252,7 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
} }
if (hitElement && distance(localUV, p3Last) <= strokeWidth) if (hitElement && distance(localUV, p3Last) <= strokeWidth)
{ {
hitElement = shouldFillEndCap(localUV, endType, p3Last, tangentEndLast); // hitElement = shouldFillEndCap(localUV, percent[1] > 1 - 1e-5, endType, p3Last, tangentEndLast, vec2(0));
} }
// if (minDistance <= 0.001) // if (minDistance <= 0.001)
@ -1261,8 +1311,8 @@ bool drawElement(uint elementIndex, vec2 localUV, vec2 scale, out vec3 color, ou
} }
else // Ïß else // Ïß
{ {
hitElement = strokeElement(localUV, contourIndex, linesOffset, pointsOffset, styleIndex, widthHeightRatio, hitElement = strokeElement(localUV, contourIndex, linesOffset, pointsOffset, styleIndex,
elementColor, metallicRoughness); widthHeightRatio, elementColor, metallicRoughness);
} }
elementBvhIndex = elementBvhLength; elementBvhIndex = elementBvhLength;
@ -1303,7 +1353,7 @@ void main()
vec3 debugBVH = vec3(0); vec3 debugBVH = vec3(0);
// bool debugHit = false; // bool debugHit = false;
vec4 color = vec4(0.76, 0.33, 0.15, -1); vec4 color = vec4(0.76, 0.33, 0.15, -1);
//vec4 color = vec4(1,1,1, -1); // vec4 color = vec4(1,1,1, -1);
vec2 metallicRoughness = vec2(0, 0.8); vec2 metallicRoughness = vec2(0, 0.8);
stack.top = 0; stack.top = 0;
uint index = 0, visitTime = 0; uint index = 0, visitTime = 0;
@ -1373,7 +1423,7 @@ void main()
imageStore(gBaseColor, pixelLocation, vec4(color.rgb, 1)); imageStore(gBaseColor, pixelLocation, vec4(color.rgb, 1));
imageStore(gMetallicRoughness, pixelLocation, vec4(metallicRoughness, 0, 1)); imageStore(gMetallicRoughness, pixelLocation, vec4(metallicRoughness, 0, 1));
return; //return;
if (/*color.a!=-1&&*/ debugBVH == vec3(0)) if (/*color.a!=-1&&*/ debugBVH == vec3(0))
{ {
// imageStore(gBaseColor, pixelLocation, vec4(vec3(1, 1, 0),1)); // imageStore(gBaseColor, pixelLocation, vec4(vec3(1, 1, 0),1));