Use swept Bokusho contact capsules
This commit is contained in:
parent
9888113282
commit
e9caacd781
3 changed files with 20 additions and 18 deletions
|
|
@ -6,10 +6,9 @@ namespace Aquarium.Engine.Render;
|
|||
public static class BokushoBrushSimulation
|
||||
{
|
||||
public const float PageDensityScale = 65535.0f;
|
||||
public const float PagePatchTransferGain = 0.0032f;
|
||||
public const float PagePatchTangentRadiusScale = 0.26f;
|
||||
public const float PagePatchSweepRadiusScale = 0.5f;
|
||||
public const float PagePatchNormalRadiusScale = 0.20f;
|
||||
public const float PagePatchTransferGain = 0.0044f;
|
||||
public const float PagePatchTangentRadiusScale = 0.32f;
|
||||
public const float PagePatchNormalRadiusScale = 0.32f;
|
||||
public const float PagePatchMinimumRadius = 0.001f;
|
||||
public const float PagePatchWorldQuantum = 1.0f / 1024.0f;
|
||||
public const float PagePatchInkQuantum = 1.0f / 2048.0f;
|
||||
|
|
@ -667,9 +666,10 @@ public static class BokushoBrushSimulation
|
|||
var normal = new Vector2(-tangent.Y, tangent.X);
|
||||
var (patchTangentRadius, patchNormalRadius) = PagePatchRadii(tangentRadius, normalRadius, sweepLength);
|
||||
var center = (previousTip + tip) * 0.5f;
|
||||
var halfSweepLength = sweepLength * 0.5f;
|
||||
var extents = new Vector2(
|
||||
MathF.Abs(tangent.X) * patchTangentRadius + MathF.Abs(normal.X) * patchNormalRadius,
|
||||
MathF.Abs(tangent.Y) * patchTangentRadius + MathF.Abs(normal.Y) * patchNormalRadius);
|
||||
MathF.Abs(tangent.X) * (halfSweepLength + patchTangentRadius) + MathF.Abs(normal.X) * patchNormalRadius,
|
||||
MathF.Abs(tangent.Y) * (halfSweepLength + patchTangentRadius) + MathF.Abs(normal.Y) * patchNormalRadius);
|
||||
var minWorld = center - extents;
|
||||
var maxWorld = center + extents;
|
||||
var minPixel = WorldToPixel(minWorld, width, height, viewCenter, viewRadius);
|
||||
|
|
@ -687,7 +687,8 @@ public static class BokushoBrushSimulation
|
|||
var uvX = width <= 1 ? 0.0f : x / (float)(width - 1);
|
||||
var world = viewCenter + (new Vector2(uvX, uvY) * 2.0f - Vector2.One) * viewRadius;
|
||||
var local = world - center;
|
||||
var tangentDistance = Vector2.Dot(local, tangent) / patchTangentRadius;
|
||||
var axialExcess = MathF.Max(MathF.Abs(Vector2.Dot(local, tangent)) - halfSweepLength, 0.0f);
|
||||
var tangentDistance = axialExcess / patchTangentRadius;
|
||||
var normalDistance = Vector2.Dot(local, normal) / patchNormalRadius;
|
||||
var ellipse = MathF.Sqrt(tangentDistance * tangentDistance + normalDistance * normalDistance);
|
||||
var coverage = QuantizePositive(SmoothStep(1.0f, 0.0f, ellipse), PagePatchCoverageQuantum);
|
||||
|
|
@ -791,7 +792,7 @@ public static class BokushoBrushSimulation
|
|||
public static (float TangentRadius, float NormalRadius) PagePatchRadii(float tangentRadius, float normalRadius, float sweepLength)
|
||||
{
|
||||
return (
|
||||
MathF.Max(tangentRadius * PagePatchTangentRadiusScale + sweepLength * PagePatchSweepRadiusScale, PagePatchMinimumRadius),
|
||||
MathF.Max(tangentRadius * PagePatchTangentRadiusScale, PagePatchMinimumRadius),
|
||||
MathF.Max(normalRadius * PagePatchNormalRadiusScale, PagePatchMinimumRadius));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
#include "CultMath/CultMath.hlsl"
|
||||
|
||||
static const float BOKUSHO_PAGE_DENSITY_SCALE = 65535.0;
|
||||
static const float BOKUSHO_PAGE_PATCH_TRANSFER_GAIN = 0.0032;
|
||||
static const float BOKUSHO_PAGE_PATCH_TANGENT_RADIUS_SCALE = 0.26;
|
||||
static const float BOKUSHO_PAGE_PATCH_SWEEP_RADIUS_SCALE = 0.5;
|
||||
static const float BOKUSHO_PAGE_PATCH_NORMAL_RADIUS_SCALE = 0.20;
|
||||
static const float BOKUSHO_PAGE_PATCH_TRANSFER_GAIN = 0.0044;
|
||||
static const float BOKUSHO_PAGE_PATCH_TANGENT_RADIUS_SCALE = 0.32;
|
||||
static const float BOKUSHO_PAGE_PATCH_NORMAL_RADIUS_SCALE = 0.32;
|
||||
static const float BOKUSHO_PAGE_PATCH_MINIMUM_RADIUS = 0.001;
|
||||
static const float BOKUSHO_PAGE_PATCH_WORLD_QUANTUM = 1.0 / 1024.0;
|
||||
static const float BOKUSHO_PAGE_PATCH_INK_QUANTUM = 1.0 / 2048.0;
|
||||
|
|
@ -142,12 +141,13 @@ void DepositSweptPatch(float2 previousTip, float2 tip, float normalRadius, float
|
|||
float sweepLength = length(sweep);
|
||||
float2 tangent = sweepLength > 0.000001 ? sweep / sweepLength : float2(1.0, 0.0);
|
||||
float2 normal = float2(-tangent.y, tangent.x);
|
||||
float patchTangentRadius = max(tangentRadius * BOKUSHO_PAGE_PATCH_TANGENT_RADIUS_SCALE + sweepLength * BOKUSHO_PAGE_PATCH_SWEEP_RADIUS_SCALE, BOKUSHO_PAGE_PATCH_MINIMUM_RADIUS);
|
||||
float patchTangentRadius = max(tangentRadius * BOKUSHO_PAGE_PATCH_TANGENT_RADIUS_SCALE, BOKUSHO_PAGE_PATCH_MINIMUM_RADIUS);
|
||||
float patchNormalRadius = max(normalRadius * BOKUSHO_PAGE_PATCH_NORMAL_RADIUS_SCALE, BOKUSHO_PAGE_PATCH_MINIMUM_RADIUS);
|
||||
float2 center = (previousTip + tip) * 0.5;
|
||||
float halfSweepLength = sweepLength * 0.5;
|
||||
float2 extents = float2(
|
||||
abs(tangent.x) * patchTangentRadius + abs(normal.x) * patchNormalRadius,
|
||||
abs(tangent.y) * patchTangentRadius + abs(normal.y) * patchNormalRadius);
|
||||
abs(tangent.x) * (halfSweepLength + patchTangentRadius) + abs(normal.x) * patchNormalRadius,
|
||||
abs(tangent.y) * (halfSweepLength + patchTangentRadius) + abs(normal.y) * patchNormalRadius);
|
||||
float pageSize = max(pageView.w, 1.0);
|
||||
float2 minUv = (center - extents - pageView.xy) / max(pageView.z, 0.001) * 0.5 + 0.5;
|
||||
float2 maxUv = (center + extents - pageView.xy) / max(pageView.z, 0.001) * 0.5 + 0.5;
|
||||
|
|
@ -166,7 +166,8 @@ void DepositSweptPatch(float2 previousTip, float2 tip, float normalRadius, float
|
|||
float uvX = pageSize <= 1.0 ? 0.0 : (float)x / (pageSize - 1.0);
|
||||
float2 world = pageView.xy + (float2(uvX, uvY) * 2.0 - 1.0) * pageView.z;
|
||||
float2 local = world - center;
|
||||
float tangentDistance = dot(local, tangent) / patchTangentRadius;
|
||||
float axialExcess = max(abs(dot(local, tangent)) - halfSweepLength, 0.0);
|
||||
float tangentDistance = axialExcess / patchTangentRadius;
|
||||
float normalDistance = dot(local, normal) / patchNormalRadius;
|
||||
float ellipse = sqrt(tangentDistance * tangentDistance + normalDistance * normalDistance);
|
||||
float coverage = QuantizePositive(cultmath_smoothstep(1.0, 0.0, ellipse), BOKUSHO_PAGE_PATCH_COVERAGE_QUANTUM);
|
||||
|
|
|
|||
|
|
@ -292,14 +292,14 @@ public sealed class BokushoBrushSimulationTests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void PagePatchRadiiIncludeBristleFootprintAndSweepDistance()
|
||||
public void PagePatchRadiiKeepSweepLengthOutOfBristleFootprint()
|
||||
{
|
||||
var (tangentRadius, normalRadius) = BokushoBrushSimulation.PagePatchRadii(
|
||||
tangentRadius: 0.42f,
|
||||
normalRadius: 0.35f,
|
||||
sweepLength: 0.18f);
|
||||
|
||||
Assert.Equal(0.42f * BokushoBrushSimulation.PagePatchTangentRadiusScale + 0.18f * BokushoBrushSimulation.PagePatchSweepRadiusScale, tangentRadius, precision: 6);
|
||||
Assert.Equal(0.42f * BokushoBrushSimulation.PagePatchTangentRadiusScale, tangentRadius, precision: 6);
|
||||
Assert.Equal(0.35f * BokushoBrushSimulation.PagePatchNormalRadiusScale, normalRadius, precision: 6);
|
||||
|
||||
var tiny = BokushoBrushSimulation.PagePatchRadii(0.0f, 0.0f, 0.0f);
|
||||
|
|
|
|||
Loading…
Reference in a new issue