用DX11中的贝塞尔曲线绘制直线



我想通过镶嵌阶段输入控制点,并将它们输出为弯曲线。我在几何体着色器中将这些线展开为带夹板的四边形。现在我输入了一堆控制点号为4的随机顶点。我假设弯曲是在域着色器中完成的,所以我使用该阶段唯一的uv坐标之一作为bezier函数的t值,该函数接受4个世界位置坐标。

然而,这些线仍然是直的。我不知道我错过了什么。

我的代码如下:

域着色器:

float3 bezier( float3 p0, float3 p1, float3 p2, float3 p3, float u)
{
float B0 = (1. - u) * (1. - u) * (1. - u);
float B1 = 3. * u * (1. - u) * (1. - u);
float B2 = 3. * u * u * (1. - u);
float B3 = u * u * u;
float3 p = B0 * p0 + B1 * p1 + B2 * p2 + B3 * p3;
return p;
}
float t = uv.x;
float3 pos = bezier(inp[0].worldPos, inp[1].worldPos, inp[2].worldPos, inp[3].worldPos, t);

问题可能是我输入的顶点没有形成曲线吗?现在我只取一个网格,比如一个平面,然后从那里取顶点。

外壳着色器中的细节因子为16。密度因子随距离变化。

我不知道还有什么是相关的。如果你需要更多信息,请告诉我。我希望我把这个问题说清楚了,我已经在谷歌上搜索过了,但似乎在我自己的代码中找不到错误。

请参阅SimpleBezier示例:

float4 BernsteinBasis(float t)
{
float invT = 1.0f - t;
return float4(invT * invT * invT,
3.0f * t * invT * invT,
3.0f * t * t * invT,
t * t * t);
}
float4 dBernsteinBasis(float t)
{
float invT = 1.0f - t;
return float4(-3 * invT * invT,
3 * invT * invT - 6 * t * invT,
6 * t * invT - 3 * t * t,
3 * t * t);
}
float3 EvaluateBezier(const OutputPatch< HS_OUTPUT, OUTPUT_PATCH_SIZE > BezPatch,
float4 BasisU,
float4 BasisV)
{
float3 value = float3(0, 0, 0);
value = BasisV.x * (BezPatch[0].pos * BasisU.x + BezPatch[1].pos * BasisU.y + BezPatch[2].pos * BasisU.z + BezPatch[3].pos * BasisU.w);
value += BasisV.y * (BezPatch[4].pos * BasisU.x + BezPatch[5].pos * BasisU.y + BezPatch[6].pos * BasisU.z + BezPatch[7].pos * BasisU.w);
value += BasisV.z * (BezPatch[8].pos * BasisU.x + BezPatch[9].pos * BasisU.y + BezPatch[10].pos * BasisU.z + BezPatch[11].pos * BasisU.w);
value += BasisV.w * (BezPatch[12].pos * BasisU.x + BezPatch[13].pos * BasisU.y + BezPatch[14].pos * BasisU.z + BezPatch[15].pos * BasisU.w);
return value;
}
[domain("quad")]
DS_OUTPUT BezierDS(HS_CONSTANT_DATA_OUTPUT input,
float2 UV : SV_DomainLocation,
const OutputPatch< HS_OUTPUT, OUTPUT_PATCH_SIZE > BezPatch)
{
float4 BasisU = BernsteinBasis(UV.x);
float4 BasisV = BernsteinBasis(UV.y);
float4 dBasisU = dBernsteinBasis(UV.x);
float4 dBasisV = dBernsteinBasis(UV.y);
float3 worldPos = EvaluateBezier(BezPatch, BasisU, BasisV);
float3 tangent = EvaluateBezier(BezPatch, dBasisU, BasisV);
float3 biTangent = EvaluateBezier(BezPatch, BasisU, dBasisV);
float3 normal = normalize(cross(tangent, biTangent));
DS_OUTPUT output;
output.pos = mul(float4(worldPos, 1), g_mViewProjection);
output.worldPos = worldPos;
output.normal = normal;
return output;
}

https://github.com/microsoft/Xbox-ATG-Samples/tree/master/PCSamples/IntroGraphics/SimpleBezierPC

https://github.com/microsoft/Xbox-ATG-Samples/tree/master/PCSamples/IntroGraphics/SimpleBezierPC12


最新更新