更新MaterialStyle::decoded
parent
5013538e16
commit
38336aa944
|
@ -625,7 +625,7 @@ int solve_quartic(vec4 coeffs, inout vec4 s)
|
|||
|
||||
return num;
|
||||
}
|
||||
float cubic_bezier_dis(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3, bool roundEnd)
|
||||
float cubic_bezier_dis(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3, bool roundEnd, out float t)
|
||||
{
|
||||
|
||||
// switch points when near to end point to minimize numerical error
|
||||
|
@ -862,7 +862,13 @@ float cubic_bezier_dis(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3, bool roundEn
|
|||
{
|
||||
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));
|
||||
float d = dot(to_curve, to_curve);
|
||||
if (d < d0)
|
||||
{
|
||||
d0 = d;
|
||||
t = roots[i];
|
||||
}
|
||||
// d0 = min(d0, dot(to_curve, to_curve));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -959,6 +965,37 @@ bool angleLargeThanPi(vec2 a, vec2 b)
|
|||
return a.x * b.y - b.x * a.y < 0;
|
||||
}
|
||||
|
||||
float getLocalWidth(float t, vec2 lengthRate, float originWidth, uint widthMapSize, uint widthMapIndex)
|
||||
{
|
||||
if (widthMapSize == 0)
|
||||
return originWidth;
|
||||
float width;
|
||||
vec2 lastData = unpackUnorm2x16(floatBitsToUint(elementData[widthMapIndex]));
|
||||
float lastLevel = 0;
|
||||
float lastWidth = lastData.y;
|
||||
float currentLengthRate = mix(lengthRate.x, lengthRate.y, t);
|
||||
bool found = false;
|
||||
for (uint i = 0; i < widthMapSize; i++)
|
||||
{
|
||||
vec2 data = unpackUnorm2x16(floatBitsToUint(elementData[widthMapIndex + i]));
|
||||
float level = data.x;
|
||||
float currentWidth = data.y;
|
||||
if (currentLengthRate <= level)
|
||||
{
|
||||
float a = (currentLengthRate - lastLevel) / (level - lastLevel);
|
||||
a = smoothstep(0, 1, a);
|
||||
width = mix(lastWidth, currentWidth, a);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
lastWidth = currentWidth;
|
||||
lastLevel = level;
|
||||
}
|
||||
if (!found)
|
||||
width = lastWidth;
|
||||
return width * originWidth;
|
||||
}
|
||||
|
||||
void drawLine(in float d, uint styleHeadIndex, out vec4 elementColor, out vec2 metallicRoughness)
|
||||
{
|
||||
elementColor = vec4(1);
|
||||
|
@ -1156,11 +1193,11 @@ vec2 getLineTangentEnd(uint contourIterator, uint linesOffset, uint pointsOffset
|
|||
return normalize(p[3] - p[1]);
|
||||
}
|
||||
|
||||
mat4x2 getPointsByContourIterator(uint contourIterator, uint linesOffset, uint pointsOffset)
|
||||
mat4x2 getPointsByContourIterator(uint contourIterator, uint linesOffset, uint pointsOffset, out vec2 lengthRate)
|
||||
{
|
||||
uint lineIndex = elementIndexs[contourIterator];
|
||||
uint pLocation = linesOffset + 3 * lineIndex;
|
||||
vec2 percent = unpackUnorm2x16(elementIndexs[pLocation + 2]);
|
||||
lengthRate = unpackUnorm2x16(elementIndexs[pLocation + 2]);
|
||||
uvec4 pxIndex =
|
||||
uvec4(pointsOffset) + 2 * uvec4(elementIndexs[pLocation] >> 16, elementIndexs[pLocation] & 0xFFFF,
|
||||
elementIndexs[pLocation + 1] >> 16, elementIndexs[pLocation + 1] & 0xFFFF);
|
||||
|
@ -1186,6 +1223,7 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
|
|||
float minDistance = 1e38;
|
||||
uint lineCount = elementIndexs[contourIndex];
|
||||
uint widthMapSize = floatBitsToUint(elementData[styleIndex + 1]);
|
||||
uint widthMapIndex = styleIndex + 2;
|
||||
styleIndex += widthMapSize + 2;
|
||||
vec4 styleHead = unpackUnorm4x8(floatBitsToUint(elementData[styleIndex]));
|
||||
float lineType = floor(styleHead.b * 10);
|
||||
|
@ -1202,7 +1240,8 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
|
|||
for (uint contourIterator_ = contourIndex + 1; contourIterator_ < contourIndex + 1 + lineCount; contourIterator_++)
|
||||
{
|
||||
uint contourIterator = contourIterator_;
|
||||
mat4x2 p = getPointsByContourIterator(contourIterator, linesOffset, pointsOffset);
|
||||
vec2 lengthRate;
|
||||
mat4x2 p = getPointsByContourIterator(contourIterator, linesOffset, pointsOffset, lengthRate);
|
||||
|
||||
if ((contourIterator == contourIndex + 1))
|
||||
{
|
||||
|
@ -1235,7 +1274,8 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
|
|||
vec2 tangentBeginNext = vec2(0);
|
||||
if (contourIterator + 1 < contourIndex + 1 + lineCount)
|
||||
{
|
||||
mat4x2 pNext = getPointsByContourIterator(contourIterator + 1, linesOffset, pointsOffset);
|
||||
vec2 lengthRate;
|
||||
mat4x2 pNext = getPointsByContourIterator(contourIterator + 1, linesOffset, pointsOffset, lengthRate);
|
||||
|
||||
if (pNext[0] == p[3])
|
||||
{
|
||||
|
@ -1267,13 +1307,15 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
|
|||
onVeryEnd = true;
|
||||
}
|
||||
|
||||
float d = cubic_bezier_dis(localUV, p[0], p[1], p[2], p[3], true);
|
||||
if (d <= strokeWidth)
|
||||
float t;
|
||||
float d = cubic_bezier_dis(localUV, p[0], p[1], p[2], p[3], true, t);
|
||||
float localWidth = getLocalWidth(t, lengthRate, strokeWidth, widthMapSize, widthMapIndex);
|
||||
if (d <= localWidth)
|
||||
{
|
||||
bool hit = d < minDistance;
|
||||
hit = hit &&
|
||||
shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, tangentEndLast, strokeWidth);
|
||||
hit = hit && shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd, tangentBeginNext, strokeWidth);
|
||||
shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, tangentEndLast, localWidth);
|
||||
hit = hit && shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd, tangentBeginNext, localWidth);
|
||||
if (hit)
|
||||
{
|
||||
bool reverse = p[3].y - p[0].y < 0.;
|
||||
|
@ -1289,7 +1331,7 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
|
|||
{
|
||||
minDistance = min(minDistance, d);
|
||||
hitElement = true;
|
||||
drawLine(minDistance / strokeWidth, styleIndex, elementColor, metallicRoughness);
|
||||
drawLine(minDistance / localWidth, styleIndex, elementColor, metallicRoughness);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,13 @@ std::unique_ptr<MaterialStyle> Renderer::MaterialStyle::decoded(const std::vecto
|
|||
else /// MaterialStyleStroke
|
||||
{
|
||||
std::unique_ptr<MaterialStroke> materialStroke;
|
||||
std::map<float, float> widthMap;
|
||||
uint widthMapSize = floatBitsToUint(encoded[1]);
|
||||
for (int i = 0; i < widthMapSize; i++)
|
||||
{
|
||||
glm::vec2 v = glm::unpackUnorm2x16(glm::floatBitsToUint(encoded[2 + i]));
|
||||
widthMap.emplace(v.x, v.y);
|
||||
}
|
||||
uint headIndex = widthMapSize + 2;
|
||||
if (encoded[1] < 0)
|
||||
headIndex = 1; /// 쇗휭앉경긍쯤
|
||||
|
@ -96,6 +102,6 @@ std::unique_ptr<MaterialStyle> Renderer::MaterialStyle::decoded(const std::vecto
|
|||
break;
|
||||
}
|
||||
}
|
||||
return std::make_unique<MaterialStyleStroke>(encoded[0], strokeType, endType, std::move(materialStroke));
|
||||
return std::make_unique<MaterialStyleStroke>(encoded[0], strokeType, endType, std::move(materialStroke), widthMap);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ std::vector<glm::vec2> generatePathBuffer(const QPainterPath& path)
|
|||
pathBuffer.emplace_back(element.x, element.y);
|
||||
lastPoint = glm::vec2(element.x, element.y);
|
||||
j++;
|
||||
k = 0;
|
||||
break;
|
||||
case QPainterPath::LineToElement:
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue