سؤال

أقوم بتنفيذ عارض برنامج جافا سكريبت (للأغراض الأكاديمية).يتعامل مع تمثيل كائن ثلاثي الأبعاد على شكل مثلثات، ويتعامل مع الإسقاط المنظوري من مساحة ثلاثية الأبعاد إلى مساحة ثنائية الأبعاد.

حتى الآن، استخدمت lineTo و fillRect لتمثيل القمم والخطوط على الشاشة.لقد استخدمت حتى lineTo للقيام بملء مثلث خط المسح.(يمكنك الاطلاع على المشروع هنا)

حتى الآن كان FPS جيدًا جدًا.لكن الجزء الأخير من المهمة هو تنفيذ z-Buffering :P.على حد علمي، الطريقة الوحيدة للقيام بذلك هي التوقف عن ملء مثلثاتي باستخدام lineTo واملأها إما بمصفوفة من الخطوط بحجم 1 بكسل أو بمصفوفة من المربعات بحجم 1 بكسل.(لأنه قبل أن أرسم كل "بكسل"، لا بد لي من التحقق من المخزن المؤقت للعمق ومعرفة ما إذا كان ينبغي علي رسمه بالفعل أم لا.)

المشكلة هي أن ملء المثلثات بمستطيلات أو خطوط صغيرة يكون بطيئًا.يحصل على كل شيء وصولا إلى 2FPS.لذا سؤالي هو، هل هناك أي طريقة لرسم بكسل واحد بدلاً من خط صغير (والذي قد يكون أسرع)؟

وبدلاً من ذلك، ما الذي يمكنني فعله أيضًا لتسريع الأمور؟هدفي هو أن أجعلها تدور بسرعة كافية لعرض المبدأ.(6-10 إطارات في الثانية ستكون كافية)

هتافات.

[تحرير] أثناء انتظار الإجابة، سأشرع في تعديل وظائف تعبئة المثلث الخاصة بي لرسم "بكسلات" بحجم 4 بكسل بدلاً من 1 بكسل.لكن ذلك سيبدو قاسياً..

هل كانت مفيدة؟

المحلول

تحقق من هذا: http://jsfiddle.net/ZXjAM/2/

// points 0,1,2,3 front face
var fAvgZ = (cube.processPoints[0].colorZ + 
    cube.processPoints[1].colorZ + 
    cube.processPoints[2].colorZ + 
    cube.processPoints[3].colorZ) / 4 / 20;

// points 0,2,4,6 top
var tAvgZ = (cube.processPoints[0].colorZ + 
    cube.processPoints[2].colorZ + 
    cube.processPoints[4].colorZ + 
    cube.processPoints[6].colorZ) / 4 / 20;

// points 4,5,6,7 rear
var reAvgZ = (cube.processPoints[4].colorZ + 
    cube.processPoints[5].colorZ + 
    cube.processPoints[6].colorZ + 
    cube.processPoints[7].colorZ) / 4 / 20;

// points 1,3,5,7 bottom
var bAvgZ = (cube.processPoints[1].colorZ + 
    cube.processPoints[3].colorZ + 
    cube.processPoints[5].colorZ + 
    cube.processPoints[7].colorZ) / 4 / 20;

// points 2,3,6,7 right side
var rAvgZ = (cube.processPoints[2].colorZ + 
    cube.processPoints[3].colorZ + 
    cube.processPoints[6].colorZ + 
    cube.processPoints[7].colorZ) / 4 / 20;

// points 0,1,4,5 left side
var lAvgZ = (cube.processPoints[0].colorZ + 
    cube.processPoints[1].colorZ + 
    cube.processPoints[4].colorZ + 
    cube.processPoints[5].colorZ) / 4 / 20;

var layers = [{key:0, val:fAvgZ},
          {key:1, val:fAvgZ},
          {key:2, val:tAvgZ},
          {key:3, val:tAvgZ},
          {key:4, val:reAvgZ},
          {key:5, val:reAvgZ},
          {key:6, val:bAvgZ},
          {key:7, val:bAvgZ},
          {key:8, val:rAvgZ},
          {key:9, val:rAvgZ},
          {key:10, val:lAvgZ},
          {key:11, val:lAvgZ}];

var outLay = layers.sort(function(a,b){
    return (a.val - b.val);
});

for(var i = 0; i < outLay.length; i++)
{
    var k = outLay[i].key;
    ...
}

هذه، بأي حال من الأحوال، هي الطريقة الأكثر فعالية لمتوسط/فرز قيم النقاط، ومن المحتمل أن يتم ذلك باستخدام عدد أقل من أسطر التعليمات البرمجية باستخدام خصائص المكعب الموجودة مسبقًا، ولكن المفهوم الأساسي يظل كما هو.

أجد متوسط ​​مؤشر z وأستخدمه لافتراض ترتيب الطبقات.من الواضح أن هذا لن ينجح في كل شيء على الإطلاق، لكن بالنسبة لمتعددات الوجوه البسيطة، ينبغي أن يكون كافيًا.

يمكن تبسيط ذلك إلى:

var layers = [];
for (var i = 0; i < cube.sides.length; i++){
    var side = cube.sides[i];
    var avg = (cube.processPoints[side.a].colorZ + 
               cube.processPoints[side.b].colorZ + 
               cube.processPoints[side.c].colorZ) / 3 / 20;                   
    layers.push({key:i, val:avg});
}

var outLay = layers.sort(function(a,b){
    return (a.val - b.val);
});

يبدو أن هناك بعض الحالات الهامشية حيث توجد مشكلة في الطلب السريع.

ويبدو أن هذا أكثر دقة: http://jsfiddle.net/ZXjAM/4/

var layers = [];
for (var i = 0; i < 12; ++i){
    var side1 = cube.sides[i];
    var side2 = cube.sides[++i];
    var avg = (cube.processPoints[side1.a].colorZ + 
               cube.processPoints[side1.b].colorZ + 
               cube.processPoints[side1.c].colorZ + 
               cube.processPoints[side2.a].colorZ + 
               cube.processPoints[side2.b].colorZ + 
               cube.processPoints[side2.c].colorZ) / 6;                   
    layers.push({key:i-1, val:avg});
    layers.push({key:i, val:avg});
}

var outLay = layers.sort(function(a,b){
    return (a.val - b.val);
});
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top