mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-15 13:14:17 +01:00
Fix float imprecision on blend weights
This commit is contained in:
parent
46a111d152
commit
7553b5da8a
1 changed files with 21 additions and 1 deletions
|
|
@ -138,7 +138,27 @@ public class VertexAttribute
|
||||||
|
|
||||||
return new VertexAttribute(
|
return new VertexAttribute(
|
||||||
element,
|
element,
|
||||||
index => BuildNByte4(values[index])
|
index => {
|
||||||
|
// Blend weights are _very_ sensitive to float imprecision - a vertex sum being off
|
||||||
|
// by one, such as 256, is enough to cause a visible defect. To avoid this, we tweak
|
||||||
|
// the converted values to have the expected sum, preferencing values with minimal differences.
|
||||||
|
var originalValues = values[index];
|
||||||
|
var byteValues = BuildNByte4(originalValues);
|
||||||
|
|
||||||
|
var adjustment = 255 - byteValues.Select(value => (int)value).Sum();
|
||||||
|
while (adjustment != 0)
|
||||||
|
{
|
||||||
|
var convertedValues = byteValues.Select(value => value * (1f / 255f)).ToArray();
|
||||||
|
var closestIndex = Enumerable.Range(0, 4)
|
||||||
|
.Select(index => (index, delta: Math.Abs(originalValues[index] - convertedValues[index])))
|
||||||
|
.MinBy(x => x.delta)
|
||||||
|
.index;
|
||||||
|
byteValues[closestIndex] = (byte)(byteValues[closestIndex] + Math.CopySign(1, adjustment));
|
||||||
|
adjustment = 255 - byteValues.Select(value => (int)value).Sum();
|
||||||
|
}
|
||||||
|
|
||||||
|
return byteValues;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue