कुछ दिन पहले मैंने बेजियर वक्र को कुशलतापूर्वक चित्रित करना शुरू कर दिया था, और मैं चार्ल्स लूप और जिम ब्लिंन द्वारा विकसित इस विधि में आया जो बहुत दिलचस्प लग रहा था। कितनी बार, उनके एल्गोरिदम के साथ प्रयोग करने के बाद, मैं बस क्यूबिक घटता प्रस्तुत करने में सक्षम होने के लिए प्रतीत नहीं कर सकता। Quadratics ठीक है, कोई समस्या नहीं है।बेज़ीयर वक्र, लूप और ब्लिंन शैली
केवल संसाधनों मैं पाया है अब तक इस प्रकार हैं:
Resolution Independent Curve Rendering using Programmable Graphics Hardware
परीक्षण को और जल्दी से चलाने के लिए, मैं इस कर रहा हूँ XNA। असल में मैं जीपीयू में अपने शिखर के साथ बनावट निर्देशांक पास कर रहा हूं, एक परिप्रेक्ष्य परिवर्तन लागू करता हूं और अंतिम परिणाम प्रस्तुत करने के लिए पिक्सेल शेडर में सभी लेखों में वर्णित सूत्र का उपयोग करता हूं। कितनी बार, समस्या (मुझे लगता है) यह बताता है कि मैं बनावट निर्देशांक की गणना कैसे करता हूं। इस कोड की जाँच करें:
public void Update()
{
float a1 = Vector3.Dot(p1, Vector3.Cross(p4, p3));
float a2 = Vector3.Dot(p2, Vector3.Cross(p1, p4));
float a3 = Vector3.Dot(p3, Vector3.Cross(p2, p2));
float d1 = a1 - 2 * a2 + 3 * a3;
float d2 = -a2 + 3 * a3;
float d3 = 3 * a3;
float discr = d1 * d1 * (3 * d2 * d2 - 4 * d1 * d3);
if (discr > 0)
{
Type = CurveTypes.Serpentine;
float ls = 3 * d2 - (float)Math.Sqrt(9 * d2 * d2 - 12 * d1 * d3);
float lt = 6 * d1;
float ms = 3 * d2 + (float)Math.Sqrt(9 * d2 * d2 - 12 * d1 * d3);
float mt = 6 * d1;
TexCoord1 = new Vector3(ls * ms, (float)Math.Pow(ls, 3), (float)Math.Pow(ms, 3));
TexCoord2 = new Vector3((3 * ls * ms - ls * mt - lt * ms)/3, ls * ls * (ls - lt), ms * ms * (ms - mt));
TexCoord3 = new Vector3((lt * (mt - 2 * ms) + ls * (3 * ms - 2 * mt))/3, (float)Math.Pow(lt - ls, 2) * ls, (float)Math.Pow(mt - ms, 2) * ms);
TexCoord4 = new Vector3((lt - ls) * (mt - ms), -(float)Math.Pow(lt - ls, 3), -(float)Math.Pow(mt - ms, 3));
}
else if (discr == 0)
{
Type = CurveTypes.Cusp;
}
else if (discr < 0)
{
Type = CurveTypes.Loop;
}
}
कीजिए गड़बड़ है, यह सिर्फ कुछ परीक्षण कोड है। पी 1 ... पी 4 विश्व अंतरिक्ष में नियंत्रण बिंदु हैं, और TexCoord1 ... TexCoord4 इसी बनावट निर्देशांक हैं। यह जीपीयू जेम्स लेख में जो कहा गया है उसका एक प्रतिकृति है।
वहाँ कुछ समस्याओं यहाँ हैं, पहले जब a3 की गणना, हम दोनों मानकों, जो निश्चित रूप से हमेशा एक (0,0,0) वेक्टर में जो परिणाम के लिए p2 का उपयोग करें और इस बात का डॉट उत्पाद लेने और p3 हमेशा होगा हमें 0 दें। यह बहुत बेकार नहीं है, तो वे लेख में क्यों उल्लेख करेंगे?
यह निश्चित रूप से डिस्क को गलत बना देगा, और हम यह निर्धारित करने में भी सक्षम नहीं होंगे कि यह किस प्रकार का वक्र है।
थोड़ी देर के लिए उस कोड के साथ झुकाव के बाद, मैंने इसे ठीक करने की कोशिश करने का फैसला किया कि उन्होंने लूप और ब्लिंन पेपर में क्यों किया। उस से मुझे कुछ ऐसा मिलता है:
public void Update()
{
Matrix m1 = new Matrix(
p4.X, p4.Y, 1, 0,
p3.X, p3.Y, 1, 0,
p2.X, p2.Y, 1, 0,
0, 0, 0, 1);
Matrix m2 = new Matrix(
p4.X, p4.Y, 1, 0,
p3.X, p3.Y, 1, 0,
p1.X, p1.Y, 1, 0,
0, 0, 0, 1);
Matrix m3 = new Matrix(
p4.X, p4.Y, 1, 0,
p2.X, p2.Y, 1, 0,
p1.X, p1.Y, 1, 0,
0, 0, 0, 1);
Matrix m4 = new Matrix(
p3.X, p3.Y, 1, 0,
p2.X, p2.Y, 1, 0,
p1.X, p1.Y, 1, 0,
0, 0, 0, 1);
float det1 = m1.Determinant();
float det2 = -m2.Determinant();
float det3 = m3.Determinant();
float det4 = -m4.Determinant();
float tet1 = det1 * det3 - det2 * det2;
float tet2 = det2 * det3 - det1 * det4;
float tet3 = det2 * det4 - det3 * det3;
float discr = 4 * tet1 * tet3 - tet2 * tet2;
if (discr > 0)
{
Type = CurveTypes.Serpentine;
float ls = 2 * det2;
float lt = det3 + (float)((1/Math.Sqrt(3)) * Math.Sqrt(3 * det3 * det3 - 4 * det2 * det4));
float ms = 2 * det2;
float mt = det3 - (float)((1/Math.Sqrt(3)) * Math.Sqrt(3 * det3 * det3 - 4 * det2 * det4));
TexCoord1 = new Vector3(lt * mt, (float)Math.Pow(lt, 3), (float)Math.Pow(mt, 3));
TexCoord2 = new Vector3(-ms * lt - ls * mt, -3 * ls * lt * lt, -3 * ms * mt * mt);
TexCoord3 = new Vector3(ls * ms, 3 * ls * ls * lt, 3 * ms * ms * mt);
TexCoord4 = new Vector3(0, -ls * ls * ls, -ms * ms * ms);
}
else if (discr == 0)
{
Type = CurveTypes.Cusp;
}
else if (discr < 0)
{
Type = CurveTypes.Loop;
}
}
मान लीजिए कि यह काम नहीं करता है। कितनी बार, डिस्कर कम से कम थोड़ा और सही प्रतीत होता है। कम से कम इसका सही संकेत है, और यह शून्य है जब नियंत्रण बिंदु को एक कुंड बनाने के लिए व्यवस्थित किया जाता है। हालांकि मुझे वही दृश्य परिणाम मिलता है, हालांकि वक्र को थोड़ी देर के लिए यादृच्छिक रूप से गायब हो जाता है (पिक्सेल शेडर फॉर्मूला हमेशा शून्य से अधिक होता है) और नियंत्रण बिंदु को वापस एक वर्ग आकार में ले जाने के बाद लौटाता है। यहां पिक्सेल शेडर कोड है:
PixelToFrame PixelShader(VertexToPixel PSIn)
{
PixelToFrame Output = (PixelToFrame)0;
if(pow(PSIn.TexCoords.x, 3) - PSIn.TexCoords.y * PSIn.TexCoords.z > 0)
{
Output.Color = float4(0,0,0,0.1);
}
else
{
Output.Color = float4(0,1,0,1);
}
return Output;
}
यह सभी उपयोगी जानकारी है जो मैं अभी सोच सकता हूं। क्या किसी को पता है कि क्या हो रहा है? क्योंकि मैं उनमें से बाहर चला रहा हूँ।
मैं अपने आप को इस पद्धति को लागू करने शुरू कर दिया और जब मैं कुछ काम कर रहे है वापस पोस्ट करेंगे। बस आप को पता है कि इस सवाल का नहीं छोड़ा है चाहता था :) – Ani
@ananthonline भयानक! कृपया कीजिए! – Roliga
मुझे इसके साथ भी समस्याएं हैं। क्या आप इसे काम करने के लिए मिला? क्या तुम मेरे सवाल का जवाब दे सकते हो? http://stackoverflow.com/questions/15519142/resolution-independent-cubic-bezier-drawing-on-gpu-blinn-loop – scippie