Fix: painting.comp渲染错误

main
wuyize 2023-03-26 16:15:26 +08:00
parent 2f776d1fdc
commit edb529e7da
2 changed files with 66 additions and 57 deletions

View File

@ -1110,8 +1110,6 @@ void main()
bool onVeryEnd = false; bool onVeryEnd = false;
vec2 tangentEndLast = vec2(0); vec2 tangentEndLast = vec2(0);
vec2 tangentFirstBegin = vec2(0); vec2 tangentFirstBegin = vec2(0);
uint lastHitIndex = 0;
bool lastHitElement = false;
hitElement = false; hitElement = false;
for (uint pathIndex = 0; pathIndex < pathSize; pathIndex++) for (uint pathIndex = 0; pathIndex < pathSize; pathIndex++)
{ {
@ -1182,9 +1180,6 @@ void main()
float localWidth = strokeWidth; // * mix(lengthRate.x, lengthRate.y, t); float localWidth = strokeWidth; // * mix(lengthRate.x, lengthRate.y, t);
if (d <= localWidth) if (d <= localWidth)
{ {
// bool onBegin = true;
// bool onEnd = true;
bool hit = d < minDistance; bool hit = d < minDistance;
hit = hit && shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, tangentEndLast, hit = hit && shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, tangentEndLast,
localWidth); localWidth);
@ -1205,8 +1200,6 @@ void main()
if (lineType == 2 || (intTest % 2 == int(lineType))) if (lineType == 2 || (intTest % 2 == int(lineType)))
{ {
minDistance = min(minDistance, d); minDistance = min(minDistance, d);
lastHitElement = hitElement;
lastHitIndex = pathIndex;
hitElement = true; hitElement = true;
// elementColor = vec4(1, 1, 0, 1); // elementColor = vec4(1, 1, 0, 1);
vec2 metallicRoughness; vec2 metallicRoughness;

View File

@ -1156,6 +1156,27 @@ vec2 getLineTangentEnd(uint contourIterator, uint linesOffset, uint pointsOffset
return normalize(p[3] - p[1]); return normalize(p[3] - p[1]);
} }
mat4x2 getPointsByContourIterator(uint contourIterator, uint linesOffset, uint pointsOffset)
{
uint lineIndex = elementIndexs[contourIterator];
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 p =
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]]);
if (p[0] == p[1] && p[2] == p[3])
{
p[1] = (p[0] + p[3]) / 2;
p[2] = p[1];
}
return p;
}
bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsOffset, uint styleIndex, bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsOffset, uint styleIndex,
inout vec4 elementColor, inout vec2 metallicRoughness) inout vec4 elementColor, inout vec2 metallicRoughness)
{ {
@ -1177,64 +1198,21 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
bool onVeryBegin = false; bool onVeryBegin = false;
bool onVeryEnd = false; bool onVeryEnd = false;
if (endType != 4 /*StrokeEndType::kClosed*/)
onVeryBegin = true;
for (uint contourIterator_ = contourIndex + 1; contourIterator_ < contourIndex + 1 + lineCount; contourIterator_++) for (uint contourIterator_ = contourIndex + 1; contourIterator_ < contourIndex + 1 + lineCount; contourIterator_++)
{ {
uint contourIterator = contourIterator_; uint contourIterator = contourIterator_;
uint lineIndex = elementIndexs[contourIterator]; mat4x2 p = getPointsByContourIterator(contourIterator, linesOffset, pointsOffset);
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 p = if ((contourIterator == contourIndex + 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]]);
vec2 tangentBeginNext = vec2(0);
if (contourIterator + 1 < contourIndex + 1 + lineCount)
{ {
uint lineIndex = elementIndexs[contourIterator + 1]; if (endType != 4 /*StrokeEndType::kClosed*/)
uint pLocation = linesOffset + 3 * lineIndex; onVeryBegin = true;
// 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]]);
if (pNext[0] == pNext[1] && pNext[2] == pNext[3])
{
pNext[1] = (pNext[0] + pNext[3]) / 2;
pNext[2] = pNext[1];
}
if (pNext[0] != pNext[1])
tangentBeginNext = normalize(pNext[0] - pNext[1]);
else
tangentBeginNext = normalize(pNext[0] - pNext[2]);
} }
else else if (p[0] != p3Last)
{ {
if (endType == 4 /*StrokeEndType::kClosed*/) onVeryBegin = true;
tangentBeginNext = tangentFirstBegin;
else
onVeryEnd = true;
} }
if (p[0] == p[1] && p[2] == p[3])
{
p[1] = (p[0] + p[3]) / 2;
p[2] = p[1];
}
if (distance(localUV, p[0]) <= 0.001) if (distance(localUV, p[0]) <= 0.001)
{ {
if (p3Last == p[0]) if (p3Last == p[0])
@ -1254,6 +1232,41 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
else else
tangentEnd = normalize(p[3] - p[1]); tangentEnd = normalize(p[3] - p[1]);
vec2 tangentBeginNext = vec2(0);
if (contourIterator + 1 < contourIndex + 1 + lineCount)
{
mat4x2 pNext = getPointsByContourIterator(contourIterator + 1, linesOffset, pointsOffset);
if (pNext[0] == p[3])
{
onVeryEnd = false;
if (pNext[0] != pNext[1])
tangentBeginNext = normalize(pNext[0] - pNext[1]);
else
tangentBeginNext = normalize(pNext[0] - pNext[2]);
}
else
{
if (endType == 4 /*StrokeEndType::kClosed*/)
{
onVeryEnd = false;
tangentBeginNext = tangentBegin;
}
else
onVeryEnd = true;
}
}
else
{
if (endType == 4 /*StrokeEndType::kClosed*/)
{
onVeryEnd = false;
tangentBeginNext = tangentFirstBegin;
}
else
onVeryEnd = true;
}
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)
{ {
@ -1263,8 +1276,11 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
hit = hit && shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd, tangentBeginNext, strokeWidth); hit = hit && shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd, tangentBeginNext, strokeWidth);
if (hit) if (hit)
{ {
bool reverse = p[3].y - p[0].y < 0.; bool reverse = p[3].y - p[0].y < 0.;
if (tangentBegin.y == 0.)
tangentBegin.y = reverse ? eps : -eps;
if (tangentEnd.y == 0.)
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);