আমি কীভাবে নির্ভরযোগ্যভাবে অ্যান্ড্রয়েডে জিপিইউ স্কিনিং প্রয়োগ করতে পারি?


11

আমি অ্যান্ড্রয়েডে ক্যারেক্টার স্কিনিং কাজ করার চেষ্টা করছি।

ধারণাটি বেশ ভ্যানিলা: আমার স্কিনিং ম্যাট্রিক্স রয়েছে এবং প্রতিটি শীর্ষবিন্দু সহ আমি চারটি ম্যাট্রিক্স সূচক এবং চারটি সম্পর্কিত ওজন প্রেরণ করি। আমি তাদেরকে ভার্টেক্স শ্যাডারে সংযুক্ত করে প্রতিটি প্রান্তে এগুলি প্রয়োগ করি।

আমার গেমের আইওএস সংস্করণে আমি ভার্টেক্স শ্যাডারে এটি করছি (নরমালগুলিতে কিছু মনে করবেন না):

attribute vec4 in_pos;
attribute vec4 in_normal;
attribute vec2 in_texture_coords;
attribute vec4 in_bone_index;
attribute vec4 in_bone_weight;

varying vec2 fs_texture_coords;

uniform mat4 world_view_projection;
uniform mat4 bones[@bind_matrix_count];

void main()
{
    // Skinning
    vec4 transformed_pos =
        ((in_pos * bones[int(in_bone_index.x)]) * in_bone_weight.x) +
        ((in_pos * bones[int(in_bone_index.y)]) * in_bone_weight.y) +
        ((in_pos * bones[int(in_bone_index.z)]) * in_bone_weight.z) +
        ((in_pos * bones[int(in_bone_index.w)]) * in_bone_weight.w);

    gl_Position = world_view_projection * transformed_pos;
    fs_texture_coords = in_texture_coords;
}

এবং এটি বেশ ভাল কাজ করে। তবে অ্যান্ড্রয়েডে একই কোড সহ কিছু ডিভাইসে (উল্লেখযোগ্যভাবে Nexus 7 2013), আপনি uniformঅ ধ্রুবক সূচকগুলি দিয়ে অ্যাক্সেস করতে পারবেন না । অন্য পদগুলিতে, আপনি এটি করতে পারবেন না:

bones[int(in_bone_index.w)]

কারণ bones[some_non_constant]সর্বদা হিসাবে মূল্যায়ন করা হয় bones[0], যা মোটেও মজাদার নয়। সবচেয়ে খারাপটি হ'ল শেডার সংকলক আনন্দের সাথে এটি সংকলন করে।

এই লোকটির মনে হয়েছিল ঠিক একই সমস্যা আছে have তিনি ম্যাট্রিকের পরিবর্তে ভেক্টর হিসাবে ইউনিফর্মটি অ্যাক্সেস করে সমাধান করেছেন। আমি একই কাজ করেছি, এবং বাস্তবে এটি কাজ করেছিল!

attribute vec4 in_pos;
attribute vec4 in_normal;
attribute vec2 in_texture_coords;
attribute vec4 in_bone_index;
attribute vec4 in_bone_weight;

varying vec2 fs_texture_coords;

uniform mat4 world_view_projection;
uniform vec4 bones[@bind_matrix_count * 4]; // four vec4's for each matrix

void main()
{
    // Skinning
    mat4 skin_0 = mat4(
        bones[4 * int(in_bone_index.x) + 0],
        bones[4 * int(in_bone_index.x) + 1],
        bones[4 * int(in_bone_index.x) + 2],
        bones[4 * int(in_bone_index.x) + 3]);
    mat4 skin_1 = mat4(
        bones[4 * int(in_bone_index.y) + 0],
        bones[4 * int(in_bone_index.y) + 1],
        bones[4 * int(in_bone_index.y) + 2],
        bones[4 * int(in_bone_index.y) + 3]);
    mat4 skin_2 = mat4(
        bones[4 * int(in_bone_index.z) + 0],
        bones[4 * int(in_bone_index.z) + 1],
        bones[4 * int(in_bone_index.z) + 2],
        bones[4 * int(in_bone_index.z) + 3]);
    mat4 skin_3 = mat4(
        bones[4 * int(in_bone_index.w) + 0],
        bones[4 * int(in_bone_index.w) + 1],
        bones[4 * int(in_bone_index.w) + 2],
        bones[4 * int(in_bone_index.w) + 3]);
    vec4 transformed_pos =
        ((in_pos * skin_0) * in_bone_weight.x) +
        ((in_pos * skin_1) * in_bone_weight.y) +
        ((in_pos * skin_2) * in_bone_weight.z) +
        ((in_pos * skin_3) * in_bone_weight.w);

    gl_Position = world_view_projection * transformed_pos;
    fs_texture_coords = in_texture_coords;
}

তবে আমি মনে করি এটি সুযোগ হিসাবে কাজ করেছে। uniformগুলি এলোমেলোভাবে অ্যাক্সেস করার অর্থ নয়, তাই আমি আশঙ্কা করি যে এই "কৌশল" প্রতিটি ডিভাইসে কাজ করবে না।

এই লোকটি তার ম্যাট্রিকগুলি টেক্সচার হিসাবে পাস করছে, এটি একটি দুর্দান্ত ধারণা। আমি একটি 4x32 OES_texture_float টেক্সচার তৈরি করেছি, যেখানে প্রতিটি টেক্সেল একটি ম্যাট্রিক্স সারি এবং প্রতিটি টেক্সচার সারি একটি সম্পূর্ণ ম্যাট্রিক্স। আমি এটিতে এটি অ্যাক্সেস করি:

attribute vec4 in_pos;
attribute vec4 in_normal;
attribute vec2 in_texture_coords;
attribute vec4 in_bone_index;
attribute vec4 in_bone_weight;

varying vec2 fs_texture_coords;

uniform mat4 world_view_projection; // A texture!
uniform sampler2D bones;

void main()
{
    // Skinning
    mat4 bone0 = mat4(
        texture2D(bones, vec2(0.00, in_bone_index.x / 32.0)),
        texture2D(bones, vec2(0.25, in_bone_index.x / 32.0)),
        texture2D(bones, vec2(0.50, in_bone_index.x / 32.0)),
        texture2D(bones, vec2(0.75, in_bone_index.x / 32.0)));
    mat4 bone1 = mat4(
        texture2D(bones, vec2(0.00, in_bone_index.y / 32.0)),
        texture2D(bones, vec2(0.25, in_bone_index.y / 32.0)),
        texture2D(bones, vec2(0.50, in_bone_index.y / 32.0)),
        texture2D(bones, vec2(0.75, in_bone_index.y / 32.0)));
    mat4 bone2 = mat4(
        texture2D(bones, vec2(0.00, in_bone_index.z / 32.0)),
        texture2D(bones, vec2(0.25, in_bone_index.z / 32.0)),
        texture2D(bones, vec2(0.50, in_bone_index.z / 32.0)),
        texture2D(bones, vec2(0.75, in_bone_index.z / 32.0)));
    mat4 bone3 = mat4(
        texture2D(bones, vec2(0.00, in_bone_index.w / 32.0)),
        texture2D(bones, vec2(0.25, in_bone_index.w / 32.0)),
        texture2D(bones, vec2(0.50, in_bone_index.w / 32.0)),
        texture2D(bones, vec2(0.75, in_bone_index.w / 32.0)));
    vec4 transformed_pos =
        ((in_pos * bone0) * in_bone_weight.x) +
        ((in_pos * bone1) * in_bone_weight.y) +
        ((in_pos * bone2) * in_bone_weight.z) +
        ((in_pos * bone3) * in_bone_weight.w);

    gl_Position = world_view_projection * transformed_pos;
    fs_texture_coords = in_texture_coords;
}

প্রকৃতপক্ষে, এটি বেশ সুন্দর কাজ করেছে ... যতক্ষণ না আমি এটি আমার গ্যালাক্সি নোট 2 এ চেষ্টা করে দেখি এই বার সংকলকটি অভিযোগ করেছে যে আমি texture2Dভার্টেক্স শেডারটিতে ব্যবহার করতে পারছি না !

সুতরাং আমি যা করছি তা যাচাই করা হচ্ছে জিপিইউ ভার্টেক্স শ্যাডারে টেক্সচার অ্যাক্সেসগুলি সমর্থন করে কিনা এবং যদি এটি OES_texture_float সমর্থন করে। যদি এটি হয়, আমি টেক্সচার পদ্ধতির ব্যবহার করছি। যদি এটি না হয় তবে আমি ভেক্টর পদ্ধতির ব্যবহার করছি।

যাইহোক, টেক্সচার পদ্ধতির সমস্ত প্ল্যাটফর্মগুলিতে পাওয়া যায় না এবং ভেক্টর পদ্ধতির সুযোগ অনুযায়ী কাজ করা হয়। আমি জানতে চাই যে আমার ত্বকের ম্যাট্রিক্সগুলি ভার্টেক্স শ্যাডারে পাস করার কোনও উপায় আছে কিনা, যা সমস্ত ডিভাইসে নির্ভরযোগ্যভাবে কাজ করে।

আমার অ্যান্ড্রয়েড ৪.১++ এর মতো ন্যূনতম যুক্তিসঙ্গত ওএস প্রয়োজনীয়তা থাকতে পারে তবে আমি এমন একটি সমাধান পেতে চাই যা সেই সমস্ত ডিভাইসে কাজ করে যা এই প্রয়োজনীয়তাগুলি পূরণ করে।


ঠিক আছে, আমি বিকল্পগুলির কথা ভাবতে পারি না, টিবিএইচ আমি মনে করি যে আপনার সেরা বাজিটি উভয় কৌশলই ব্যবহার করা উচিত যার উপর নির্ভর করে কোনটি উপলভ্য, যদি না হয় কেবল জিপিইউ স্কিনিং ব্যবহার না করে কেবল সিপিইউ ত্বকের বাস্তবায়নে পড়ে (সম্ভবত কম বিস্তৃত মডেল সহ) ?)।
ধারণা 3 ডি

@ ধারণা3 ডি: আমি জানি না, সম্ভবত অ্যান্ড্রয়েড ৪.১++ তে উপস্থিত থাকার গ্যারান্টিযুক্ত এমন কিছু এক্সটেনশান যা এই সমস্যাটি সমাধানের জন্য ডিজাইন করা হয়েছে, বা একই ফলাফলের সাথে ধারণাগতভাবে আলাদা কিছু করছে। আমি প্রচুর বিষয়ের সাধারণ ধারণাগুলিতে নিজেকে বেশ দক্ষ বলে বিবেচনা করি তবে অ্যান্ড্রয়েড প্ল্যাটফর্ম সম্পর্কে আমার জ্ঞান খুব সীমাবদ্ধ এবং আমি ভাবছিলাম যে এই সমস্যার নিখুঁতভাবে প্রযুক্তিগত কাজ হতে পারে।
পান্ডা পাইজামা

সুতরাং সম্ভবত এই কারণেই আমি আমার নেক্সাস on এ কাজ করার জন্য ত্বক পেতে পারি না: / ধন্যবাদ, আপনার প্রশ্নটি আমার চোখ খুলে দিয়েছে!
অ্যাসিঙ্ক

উত্তর:


4

এটি নেক্সাস 7 (অ্যাড্রেনো জিপিইউ) এর অনুসরনকারী নয়। আপনি বলতে "ইউনিফর্ম এলোমেলোভাবে অ্যাক্সেস করা যেতে বোঝানো হয় না", কিন্তু এর পরিশিষ্ট অনুযায়ী বৈশিষ্ট :

ইউনিফর্ম (নমুনা বাদে)

ভার্টেক্স শ্যাডারে অ্যারে ইনডেক্সিংয়ের সমস্ত ফর্মের জন্য সমর্থন বাধ্যতামূলক। খণ্ড শ্যাডারে ইনডেক্সের জন্য সমর্থন কেবল ধ্রুবক-সূচক-এক্সপ্রেশনগুলির জন্য বাধ্যতামূলক।

এটা তোলে আলোচনা থেকে শোনাচ্ছে এখানে যে এই বাগ শুধুমাত্র অভিন্ন ম্যাট্রিক্স অ্যারে ক্ষেত্রে প্রযোজ্য, তাই ভেক্টর ব্যবহার কাজ প্রায় নির্ভরযোগ্যভাবে কাজ করার সম্ভাবনা রয়েছে এবং অন্যান্য জিপিইউ (আমি মালি এবং PowerVR জিপিইউ উপর অন্তত র্যান্ডম অভিন্ন ইন্ডেক্স সব কাজের কথা জানি) এর পোর্টেবল হও।


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