আমার টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো শ্যাডারে এই শর্তযুক্ত কেন এত ধীর?


19

আমি ওয়েবজিএলে কিছু এফপিএস-পরিমাপের কোড স্থাপন করেছি ( এই এসও উত্তরের উপর ভিত্তি করে ) এবং আমার খণ্ডের শেডারটির কার্যকারিতা সহ কিছু বিজোড়তা আবিষ্কার করেছি। কোডটি 1024x1024 ক্যানভাসের উপরে কেবল একটি একক কোয়াড (বা দুটি ত্রিভুজ) উপস্থাপন করে, যাতে সমস্ত ম্যাজিকটি খণ্ড শ্যাডারে ঘটে।

এই সাধারণ শেডারটি বিবেচনা করুন (জিএলএসএল; ভার্টেক্স শ্যাডারটি কেবল একটি পাস-থ্রো):

// some definitions

void main() {
    float seed = uSeed;
    float x = vPos.x;
    float y = vPos.y;

    float value = 1.0;

    // Nothing to see here...

    gl_FragColor = vec4(value, value, value, 1.0);
}

সুতরাং এটি কেবল একটি সাদা ক্যানভাস সরবরাহ করে। এটি আমার মেশিনে গড়ে প্রায় 30 fps হয়।

এবার আসুন ক্র্যাঞ্চিংয়ের সংখ্যাটি র‌্যাম্প আপ করুন এবং অবস্থান-নির্ভর গোলমালের কয়েকটি অষ্টভের উপর ভিত্তি করে প্রতিটি খণ্ডটি গণনা করুন:

void main() {
    float seed = uSeed;
    float x = vPos.x;
    float y = vPos.y;

    float value = 1.0;

      float noise;
      for ( int j=0; j<10; ++j)
      {
        noise = 0.0;
        for ( int i=4; i>0; i-- )
        {
            float oct = pow(2.0,float(i));
            noise += snoise(vec2(mod(seed,13.0)+x*oct,mod(seed*seed,11.0)+y*oct))/oct*4.0;
        }
      }

      value = noise/2.0+0.5;

    gl_FragColor = vec4(value, value, value, 1.0);
}

আপনি যদি উপরের কোডটি চালাতে চান তবে আমি এই প্রয়োগটিsnoise ব্যবহার করছি ।

এটি ps-এর মতো কিছুতে fps নামিয়ে আনে।

এখন অদ্ভুত অংশ ... আসুন শর্ত হিসাবে প্রতি 16 টুকরাগুলির মধ্যে একটির গুন করি এবং অন্যটিকে শ্বেত করে ছেড়ে দেওয়া যাক, নিম্নোক্ত শর্তের সাথে শব্দের গণনাটি গুটিয়ে রেখে:

if (int(mod(x*512.0,4.0)) == 0 && int(mod(y*512.0,4.0)) == 0)) {
    // same noise computation
}

আপনি এটি আরও দ্রুত হবে আশা করতেন, তবে এটি এখনও মাত্র 7 fps।

আরও একটি পরীক্ষার জন্য, এর পরিবর্তে নিম্নলিখিত শর্তসাপেক্ষে পিক্সেলগুলি ফিল্টার করুন:

if (x > 0.5 && y > 0.5) {
    // same noise computation
}

এটি আগের মতো শব্দ পিক্সেলের ঠিক একই সংখ্যা দেয় তবে এখন আমরা প্রায় 30 পিপিএসে ফিরে এসেছি।

এখানে কি হচ্ছে? 16 পিক্সেলের 16 তম ফিল্টার করার দুটি উপায় চক্রের সঠিক সংখ্যাটি দেওয়া উচিত নয়? আর ধীরে ধীরে কেন সমস্ত পিক্সেলকে গোলমাল হিসাবে রেন্ডার করার মতো ধীর ?

বোনাস প্রশ্ন: আমি এই সম্পর্কে কি করতে পারি? আমি যদি কেবল কয়েকটি ব্যয়বহুল টুকরোগুলি দিয়ে আমার ক্যানভাসকে ঝাঁকুনি দিতে চাই তবে কি ভয়াবহ পারফরম্যান্সের আশেপাশে কাজ করার কোনও উপায় আছে ?

(কেবলমাত্র নিশ্চিত হয়েই, আমি নিশ্চিত হয়েছি যে সাদা রঙের পরিবর্তে প্রতি 16 ম পিক্সেল কালো রেন্ডার করে সত্যিকারের মডুলো গণনা ফ্রেম হারকে মোটেই প্রভাবিত করে না))

উত্তর:


22

পিক্সেলগুলি ছোট স্কোয়ারে গ্রুপযুক্ত হয়ে যায় (হার্ডওয়্যারের উপর নির্ভর করে কত বড়) এবং একক সিমড পাইপলাইনে একসাথে গণনা করা হয় । (অ্যারে সিমডের ধরণের কাঠামো)

এই পাইপলাইন (যা বিক্রেতার উপর নির্ভর করে বিভিন্ন নাম রয়েছে: ওয়ার্পস, ওয়েভফ্রন্টস) লকস্টেপে প্রতিটি পিক্সেল / খণ্ডের জন্য ক্রিয়াকলাপ চালাবে। এর অর্থ হ'ল যদি 1 পিক্সেলটির একটি গণনা করা দরকার হয় তবে সমস্ত পিক্সেল এটি গণনা করবে এবং ফলাফলগুলির প্রয়োজন নেই এমনগুলি এটিকে ফেলে দেবে।

যদি সমস্ত খণ্ডগুলি শেডার দিয়ে একই পথ অনুসরণ করে তবে অন্যান্য শাখাগুলি কার্যকর করা হবে না।

এর অর্থ হ'ল প্রতি 16 তম পিক্সেলের কম্পিউটিংয়ের আপনার প্রথম পদ্ধতিটি সবচেয়ে খারাপ কেস ব্রাঞ্চিং হবে।

আপনি যদি এখনও নিজের ইমেজটি ডাউন আকারে রাখতে চান তবে কেবল একটি ছোট টেক্সচারে রেন্ডার করুন এবং তারপরে এটি উপরে উঠান।


5
একটি ছোট টেক্সচার এবং আপস্যাম্পলিংয়ে রেন্ডারিং করা এটি করার একটি ভাল উপায়। তবে যদি কোনও কারণে আপনাকে বড় টেক্সচারের প্রতি 16 ম পিক্সেলটিতে লিখতে হয় তবে রেন্ডার টার্গেটের মধ্যে লেখাগুলি ছড়িয়ে দেওয়ার জন্য প্রতি 16 ম পিক্সেলের সাথে ইমেজ লোড / স্টোরের জন্য একটি অনুরোধের সাথে একটি কম্পিউট শেডার ব্যবহার করা ভাল বিকল্প হতে পারে।
নাথান রিড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.