更新MaterialStyle::decoded
parent
5013538e16
commit
38336aa944
|
@ -625,7 +625,7 @@ int solve_quartic(vec4 coeffs, inout vec4 s)
|
||||||
|
|
||||||
return num;
|
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
|
// 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.);
|
roots[i] = clamp(roots[i], 0., 1.);
|
||||||
vec2 to_curve = uv - parametric_cub_bezier(roots[i], p0, p1, p2, p3);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -959,6 +965,37 @@ bool angleLargeThanPi(vec2 a, vec2 b)
|
||||||
return a.x * b.y - b.x * a.y < 0;
|
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)
|
void drawLine(in float d, uint styleHeadIndex, out vec4 elementColor, out vec2 metallicRoughness)
|
||||||
{
|
{
|
||||||
elementColor = vec4(1);
|
elementColor = vec4(1);
|
||||||
|
@ -1156,11 +1193,11 @@ 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)
|
mat4x2 getPointsByContourIterator(uint contourIterator, uint linesOffset, uint pointsOffset, out vec2 lengthRate)
|
||||||
{
|
{
|
||||||
uint lineIndex = elementIndexs[contourIterator];
|
uint lineIndex = elementIndexs[contourIterator];
|
||||||
uint pLocation = linesOffset + 3 * lineIndex;
|
uint pLocation = linesOffset + 3 * lineIndex;
|
||||||
vec2 percent = unpackUnorm2x16(elementIndexs[pLocation + 2]);
|
lengthRate = unpackUnorm2x16(elementIndexs[pLocation + 2]);
|
||||||
uvec4 pxIndex =
|
uvec4 pxIndex =
|
||||||
uvec4(pointsOffset) + 2 * uvec4(elementIndexs[pLocation] >> 16, elementIndexs[pLocation] & 0xFFFF,
|
uvec4(pointsOffset) + 2 * uvec4(elementIndexs[pLocation] >> 16, elementIndexs[pLocation] & 0xFFFF,
|
||||||
elementIndexs[pLocation + 1] >> 16, elementIndexs[pLocation + 1] & 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;
|
float minDistance = 1e38;
|
||||||
uint lineCount = elementIndexs[contourIndex];
|
uint lineCount = elementIndexs[contourIndex];
|
||||||
uint widthMapSize = floatBitsToUint(elementData[styleIndex + 1]);
|
uint widthMapSize = floatBitsToUint(elementData[styleIndex + 1]);
|
||||||
|
uint widthMapIndex = styleIndex + 2;
|
||||||
styleIndex += widthMapSize + 2;
|
styleIndex += widthMapSize + 2;
|
||||||
vec4 styleHead = unpackUnorm4x8(floatBitsToUint(elementData[styleIndex]));
|
vec4 styleHead = unpackUnorm4x8(floatBitsToUint(elementData[styleIndex]));
|
||||||
float lineType = floor(styleHead.b * 10);
|
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_++)
|
for (uint contourIterator_ = contourIndex + 1; contourIterator_ < contourIndex + 1 + lineCount; contourIterator_++)
|
||||||
{
|
{
|
||||||
uint contourIterator = contourIterator_;
|
uint contourIterator = contourIterator_;
|
||||||
mat4x2 p = getPointsByContourIterator(contourIterator, linesOffset, pointsOffset);
|
vec2 lengthRate;
|
||||||
|
mat4x2 p = getPointsByContourIterator(contourIterator, linesOffset, pointsOffset, lengthRate);
|
||||||
|
|
||||||
if ((contourIterator == contourIndex + 1))
|
if ((contourIterator == contourIndex + 1))
|
||||||
{
|
{
|
||||||
|
@ -1235,7 +1274,8 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
|
||||||
vec2 tangentBeginNext = vec2(0);
|
vec2 tangentBeginNext = vec2(0);
|
||||||
if (contourIterator + 1 < contourIndex + 1 + lineCount)
|
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])
|
if (pNext[0] == p[3])
|
||||||
{
|
{
|
||||||
|
@ -1267,13 +1307,15 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
|
||||||
onVeryEnd = true;
|
onVeryEnd = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
float d = cubic_bezier_dis(localUV, p[0], p[1], p[2], p[3], true);
|
float t;
|
||||||
if (d <= strokeWidth)
|
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;
|
bool hit = d < minDistance;
|
||||||
hit = hit &&
|
hit = hit &&
|
||||||
shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, tangentEndLast, strokeWidth);
|
shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, tangentEndLast, localWidth);
|
||||||
hit = hit && shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd, tangentBeginNext, strokeWidth);
|
hit = hit && shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd, tangentBeginNext, localWidth);
|
||||||
if (hit)
|
if (hit)
|
||||||
{
|
{
|
||||||
bool reverse = p[3].y - p[0].y < 0.;
|
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);
|
minDistance = min(minDistance, d);
|
||||||
hitElement = true;
|
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
|
else /// MaterialStyleStroke
|
||||||
{
|
{
|
||||||
std::unique_ptr<MaterialStroke> materialStroke;
|
std::unique_ptr<MaterialStroke> materialStroke;
|
||||||
|
std::map<float, float> widthMap;
|
||||||
uint widthMapSize = floatBitsToUint(encoded[1]);
|
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;
|
uint headIndex = widthMapSize + 2;
|
||||||
if (encoded[1] < 0)
|
if (encoded[1] < 0)
|
||||||
headIndex = 1; /// 쇗휭앉경긍쯤
|
headIndex = 1; /// 쇗휭앉경긍쯤
|
||||||
|
@ -96,6 +102,6 @@ std::unique_ptr<MaterialStyle> Renderer::MaterialStyle::decoded(const std::vecto
|
||||||
break;
|
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);
|
pathBuffer.emplace_back(element.x, element.y);
|
||||||
lastPoint = glm::vec2(element.x, element.y);
|
lastPoint = glm::vec2(element.x, element.y);
|
||||||
j++;
|
j++;
|
||||||
|
k = 0;
|
||||||
break;
|
break;
|
||||||
case QPainterPath::LineToElement:
|
case QPainterPath::LineToElement:
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue