ওপেনজিএলে একটি রেট্রো-স্টাইলের প্যালেট অদলবদল তৈরি করা


37

আমি একটি মেগামান- মতো খেলায় কাজ করছি যেখানে রানটাইমের সময় আমাকে নির্দিষ্ট পিক্সেলের রঙ পরিবর্তন করতে হবে। রেফারেন্সের জন্য : মেগামানে আপনি যখন আপনার নির্বাচিত অস্ত্রটি পরিবর্তন করেন তারপরে নির্বাচিত অস্ত্রকে প্রতিফলিত করার জন্য প্রধান চরিত্রের প্যালেট পরিবর্তন হয়। স্প্রাইটের সমস্ত রঙ পরিবর্তন হয় না, কেবলমাত্র কিছু নির্দিষ্টরকমই করে

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

আমার সমস্ত টেক্সচার 32-বিট এবং প্যালেটগুলি ব্যবহার করবেন না।

আমি চাই যে প্রভাবটি অর্জন করতে পারি তার দুটি উপায় আছে, তবে এই প্রভাবটি সহজেই অর্জন করার আরও ভাল উপায় থাকলে আমি আগ্রহী। আমি যে দুটি বিকল্প সম্পর্কে জানি তা হ'ল:

  1. "প্যালেট অদলবদল" আচরণ সম্পাদন করতে একটি শেডার ব্যবহার করুন এবং কিছু জিএলএসএল লিখুন।
  2. যদি শেডারগুলি উপলভ্য না থাকে (বলুন, কারণ গ্রাফিক্স কার্ড তাদের সমর্থন করে না) তবে "মূল" টেক্সচারগুলি ক্লোন করা এবং প্রাক-প্রয়োগযুক্ত রঙ পরিবর্তন সহ বিভিন্ন সংস্করণ উত্পন্ন করা সম্ভব।

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

সম্পাদনা করুন : আমি গৃহীত উত্তরের কৌশলটি ব্যবহার করে শেষ করেছি এবং এখানে আমার রেফারেন্সের শেডার।

uniform sampler2D texture;
uniform sampler2D colorTable;
uniform float paletteIndex;

void main()
{
        vec2 pos = gl_TexCoord[0].xy;
        vec4 color = texture2D(texture, pos);
        vec2 index = vec2(color.r + paletteIndex, 0);
        vec4 indexedColor = texture2D(colorTable, index);
        gl_FragColor = indexedColor;      
}

উভয় টেক্সচার 32-বিট, এক টেক্সচারটি বিভিন্ন প্যালেট সমেত লুপ লুক টেবিল হিসাবে ব্যবহৃত হয় যা সমস্ত একই আকার (আমার ক্ষেত্রে 6 টি রঙ)। আমি রঙ টেবিলের সূচক হিসাবে উত্স পিক্সেলের লাল চ্যানেলটি ব্যবহার করি। এটি মেগামানের মতো প্যালেট অদলবদল করার জন্য কব্জির মতো কাজ করেছে!

উত্তর:


41

আমি কয়েকটি চরিত্রের টেক্সচারের জন্য ভিআরএএম নষ্ট করার বিষয়ে চিন্তা করব না।

আপনার কাছে আপনার বিকল্পটি ২ ব্যবহার করতে ( আমার কাছে বিভিন্ন টেক্সচার বা বিভিন্ন ইউভি অফসেটের সাথে যদি এটি ফিট হয়) হ'ল উপায়: আরও নমনীয়, ডেটা-চালিত, কোডের উপর কম প্রভাব, কম বাগ, কম উদ্বেগ।


এটি একপাশে রেখে দেওয়া, যদি আপনি স্মৃতিতে টন স্প্রিট অ্যানিমেশন সহ কয়েকটি টন অক্ষর সংগ্রহ করতে শুরু করেন, তবে আপনি ওপেনজিএল দ্বারা প্রস্তাবিত যা ব্যবহার শুরু করতে পারেন , তা নিজে করুন প্যালেটগুলি:

প্যালেটেড টেক্সচার

প্রাক্তন জিএল বিক্রেতাদের দ্বারা EXT_paletted_texture সম্প্রসারণের জন্য সমর্থন বাদ দেওয়া হয়েছে। আপনার যদি নতুন হার্ডওয়ারে সত্যই প্যালেটযুক্ত টেক্সচারের প্রয়োজন হয় তবে আপনি সেই প্রভাবটি অর্জন করতে শেডার ব্যবহার করতে পারেন।

শেডার উদাহরণ:

//Fragment shader
#version 110
uniform sampler2D ColorTable;     //256 x 1 pixels
uniform sampler2D MyIndexTexture;
varying vec2 TexCoord0;

void main()
{
  //What color do we want to index?
  vec4 myindex = texture2D(MyIndexTexture, TexCoord0);
  //Do a dependency texture read
  vec4 texel = texture2D(ColorTable, myindex.xy);
  gl_FragColor = texel;   //Output the color
}

এটি কেবল ColorTable(আরজিবিএ MyIndexTexture8-এর একটি প্যালেট) নমুনা দিচ্ছে (ইনডেক্সড রঙগুলিতে একটি 8 বিট বর্গক্ষেত্র ) using রেট্রো স্টাইলের প্যালেটগুলি যেভাবে কাজ করে তা কেবল পুনরুত্পাদন করে।


উপরের-উদ্ধৃত উদাহরণটি দুটি ব্যবহার করে sampler2D, যেখানে এটি আসলে একটি sampler1D+ একটি ব্যবহার করতে পারে sampler2D। আমি সন্দেহ করি এটি সামঞ্জস্যতার কারণে ( ওপেনগিএল ইএস-তে কোনও এক-মাত্রিক টেক্সচার নেই ) ... তবে কিছুই নয়, ডেস্কটপ ওপেনজিএলের জন্য এটিকে সহজ করা যেতে পারে:

uniform sampler1D Palette;             // A palette of 256 colors
uniform sampler2D IndexedColorTexture; // A texture using indexed color
varying vec2 TexCoord0;                // UVs

void main()
{
    // Pick up a color index
    vec4 index = texture2D(IndexedColorTexture, TexCoord0);
    // Retrieve the actual color from the palette
    vec4 texel = texture1D(Palette, index.x);
    gl_FragColor = texel;   //Output the color
}

Palette"আসল" রঙগুলির এক-মাত্রিক টেক্সচার (উদাহরণস্বরূপ GL_RGBA8), এবং সূচিযুক্ত রঙগুলিরIndexedColorTexture একটি দ্বিমাত্রিক টেক্সচার (সাধারণত , যা আপনাকে 256 সূচক দেয়)। সেই তৈরি করতে হলে, আছে বিভিন্ন রচনার সরঞ্জাম এবং ইমেজ ফাইল ফরম্যাটের যে সমর্থন ইমেজ paletted আউট, এটা এক তোমার চাহিদা পূরণ এটি করা সম্ভব হওয়া উচিত।GL_R8


2
ঠিক উত্তর আমি দিতে হবে, শুধুমাত্র আরও বিশদ। আমি পারলে +2 করতাম।
ইলমারি করোনেন

আমার জন্য এটি কাজ করতে আমার কিছুটা সমস্যা হচ্ছে, বেশিরভাগ কারণেই আমি বুঝতে পারি না যে রঙের সূচকটি কীভাবে নির্ধারিত হয় - আপনি সম্ভবত আরও কিছুটা প্রসারিত করতে পারেন?
জ্যাক দ্য হিউম্যান

আপনার সম্ভবত সূচিযুক্ত রঙগুলি পড়া উচিত । আপনার টেক্সচার সূচকগুলির 2D অ্যারে হয়ে যায়, প্যালেটের রঙগুলির সাথে সম্পর্কিত সূচকগুলি (সাধারণত একটি দ্বিমাত্রিক টেক্সচার)। ওপেনজিএল ওয়েবসাইটের দেওয়া উদাহরণটি সহজ করার জন্য আমি আমার উত্তর সম্পাদনা করব।
লরেন্ট কুইভিডু

আমি দুঃখিত, আমি আমার মূল মন্তব্যে পরিষ্কার ছিলাম না। আমি সূচিযুক্ত রঙগুলির সাথে এবং সেগুলি কীভাবে কাজ করে তা সম্পর্কে আমি পরিচিত, তবে তারা কীভাবে শেডার বা 32-বিট টেক্সচারের প্রসঙ্গে (যেগুলি সূচিযুক্ত নয় - ডান?) ঠিক সেভাবেই আমি স্পষ্ট নই।
জ্যাক দ্য হিউম্যান

ভাল, জিনিসটি এখানে আপনার কাছে একটি 32-বিট প্যালেট রয়েছে 256 রঙের এবং 8-বিট সূচকগুলির একটি গঠন (0 থেকে 255 পর্যন্ত চলছে)। আমার সম্পাদনা দেখুন;)
লরেন্ট কুইভিডু

10

এটি করার জন্য আমি ভাবতে পারি এমন 2 টি উপায় রয়েছে।

উপায় # 1: GL_MODULATE

আপনি ধূসর রঙের শেডগুলিতে স্প্রিট তৈরি করতে পারেন এবং GL_MODULATEএটি যখন কোনও একক কঠিন রঙের সাথে আঁকা হয়।

উদাহরণ স্বরূপ,

এখানে চিত্র বর্ণনা লিখুন

এখানে চিত্র বর্ণনা লিখুন

এটি আপনাকে খুব বেশি নমনীয়তা দেয় না, মূলত আপনি একই হালকা হালকা এবং আরও গা dark় হতে পারেন।

উপায় # 2: ifবিবৃতি (পারফরম্যান্সের জন্য খারাপ)

আর আপনি যা করতে পারেন তা হল আপনার টেক্সচারগুলিকে কিছু মূল মানগুলির সাথে আর, জি এবং বি অন্তর্ভুক্ত করা উচিত উদাহরণস্বরূপ, প্রথম রঙটি (1,0,0), ২ য় বর্ণটি (0,1,0), তৃতীয় রঙ (0,0,1)।

আপনি বেশ কয়েকটি ইউনিফর্ম ঘোষণা করেন

uniform float4 color1 ;
uniform float4 color2 ;
uniform float4 color3 ;

তারপরে শেডারে চূড়ান্ত পিক্সেলের রঙটি কিছু একটা

float4 pixelColor = texel.r*color1 + texel.g*color2 + texel.b*color3 ;

color1, color2, color3, ইউনিফর্ম, তাই তারা shader রানে আগে নির্ধারণ করা যাবে (কি হবে "মামলা" Megaman উপর নির্ভর করে হয়), তারপর shader কেবল বাকি আছে।

আপনার ifআরও রঙের প্রয়োজন হলে আপনি বিবৃতিও ব্যবহার করতে পারেন, তবে আপনাকে সমতা চেকগুলি সঠিকভাবে কাজ করতে হবে (টেক্সচার R8G8B8ফাইলে প্রতিটি টেক্সচার সাধারণত 0 থেকে 255 এর মধ্যে থাকে তবে শেডারে আপনার আরজিবা ভাসমান থাকে)

উপায় # 3: কেবলমাত্র অপ্রয়োজনীয়ভাবে স্প্রাইট মানচিত্রে বিভিন্ন বর্ণের চিত্রগুলি সঞ্চয় করুন

এখানে চিত্র বর্ণনা লিখুন

আপনি যদি স্মৃতি সংরক্ষণের জন্য উন্মত্তভাবে চেষ্টা না করেন তবে এটি সবচেয়ে সহজ উপায় হতে পারে


2
# 1 ঝরঝরে হতে পারে তবে # 2 এবং # 3 হ'ল ভয়ঙ্করভাবে পরামর্শের খারাপ টুকরো। জিপিইউ মানচিত্রগুলি থেকে ইনডেক্স করতে সক্ষম (যার মধ্যে মূলত একটি প্যালেটটি রয়েছে) এবং এই উভয় পরামর্শের চেয়ে এত ভাল করে।
Skrylar

6

আমি ছায়াময় ব্যবহার করব আপনি যদি সেগুলি ব্যবহার করতে না চান (বা না করতে পারেন) তবে আমি প্রতি রঙে একটি টেক্সচার (বা কোনও টেক্সচারের অংশ) নিয়ে যাব এবং কেবল পরিষ্কার সাদা ব্যবহার করব। এটি আপনাকে glColor()রঙগুলির জন্য অতিরিক্ত টেক্সচার তৈরি করার বিষয়ে চিন্তা না করেই টেক্সচারটি (উদাহরণস্বরূপ ) রঙিন করার অনুমতি দেবে । আপনি অতিরিক্ত টেক্সচারের কাজ ছাড়াই রানে রঙগুলিও অদলবদল করতে পারেন।


এটি একটি দুর্দান্ত ধারণা। আমি আসলে এটি কিছুক্ষণ আগে ভেবেছিলাম কিন্তু আমি যখন এই প্রশ্নটি পোস্ট করি তখন মনে আসে না। এর সাথে কিছু অতিরিক্ত জটিলতা রয়েছে যেহেতু যে কোনও স্প্রাইট যা এই ধরণের সংমিশ্রণ-টেক্সচার ব্যবহার করে তার জন্য আরও জটিল অঙ্কনের যুক্তি প্রয়োজন। এই দুর্দান্ত পরামর্শের জন্য ধন্যবাদ!
জ্যাক দ্য হিউম্যান

হ্যাঁ, আপনারও স্প্রাইটে এক্স পাস দরকার হবে যা কিছুটা জটিলতা যোগ করতে পারে। আজকের হার্ডওয়্যারটি সাধারণত কমপক্ষে বেসিক পিক্সেল শেডারগুলিকে সমর্থন করে (এমনকি নেটবুক জিপিইউগুলি), আমি পরিবর্তে এগুলি নিয়ে যাব। আপনি যদি সুনির্দিষ্ট কিছুতে রঙিন করতে চান তবে এটি ঝরঝরে হতে পারে, যেমন স্বাস্থ্য বার বা আইকন।
মারিও

3

"স্প্রাইটের সমস্ত রঙই বদলায় না, কেবল কিছু নির্দিষ্ট লোকই তা করে।"

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

আপনি কোনও পৃথক গ্রেস্কেল মাস্ক টেক্সচার তৈরি করতে পারেন যা আপনি কোন পিক্সেলের রঙ পরিবর্তন করবে তা সিদ্ধান্ত নিতে ব্যবহার করেন। জমিনে সাদা অঞ্চলগুলি সম্পূর্ণ রঙ পরিবর্তন করে এবং কালো অঞ্চলগুলি অপরিবর্তিত থাকে।

শ্যাডার ল্যাঙ্গুয়গে:

vec3 বেসকলার = টেক্সচার (বেসস্যাম্পলার, #_TexCoord) .rgb;
ভাসমান পরিমাণ = টেক্সচার (মাস্কস্যাম্পলার, অ্যাট_পেক্সকর্ড) .r;
vec3 রঙ = মিশ্রণ (বেসরঙ, বেসকলার * মডুলেশন কালার, পরিমাণ);

অথবা আপনি বিভিন্ন টেক্সচার কম্বিনার মোডের সাথে ফিক্সড-ফাংশন মাল্টি-টেক্সচার ব্যবহার করতে পারেন।

আপনি সম্ভবত এটির বিভিন্ন উপায় যেতে পারেন; আপনি প্রতিটি আরজিবি চ্যানেলে বিভিন্ন রঙের জন্য মুখোশ লাগাতে পারেন বা এইচএসভি কালারস্পেসে রঙিন স্থানান্তরিত করে রঙগুলি সংশোধন করতে পারেন।

আরেকটি, সম্ভবত সহজ, বিকল্পটি হ'ল প্রতিটি উপাদানগুলির জন্য পৃথক টেক্সচার ব্যবহার করে স্প্রিট আঁকতে। চুলের জন্য একটি টেক্সচার, একটি আর্মার জন্য, বুটের জন্য একটি ইত্যাদি Each


2

প্রথমত এটিকে সাধারণত সাইক্লিং (প্যালেট সাইক্লিং) হিসাবে উল্লেখ করা হয়, যাতে এটি আপনার গুগল-ফুকে সহায়তা করতে পারে।

এটি আপনি কী প্রভাব ফেলতে চান তার উপর নির্ভর করে এবং যদি আপনি স্থির 2 ডি বিষয়বস্তু বা গতিশীল 3 ডি স্টাফ নিয়ে কাজ করে থাকেন (যেমন আপনি কেবল স্পাইট / টেক্সচারের সাথে ডিল করতে চান, বা একটি সম্পূর্ণ 3D দৃশ্য রেন্ডার করতে চান তবে প্যালেট অদলবদল)। এছাড়াও যদি আপনি নিজেকে অনেকগুলি রঙের মধ্যে সীমাবদ্ধ করছেন বা পুরো রঙ ব্যবহার করছেন।

শেডার ব্যবহার করে আরও একটি সম্পূর্ণ পদ্ধতির প্রকৃতপক্ষে প্যালেট টেক্সচারের সাথে রঙিন সূচিযুক্ত চিত্রগুলি তৈরি করা হবে। একটি টেক্সচার তৈরি করুন তবে রঙগুলি পরিবর্তে রঙ দিন, এটি অনুসন্ধানের জন্য একটি সূচক উপস্থাপন করে তারপরে রঙের অন্য টেক্সচার রয়েছে যা প্লেট। উদাহরণস্বরূপ লাল হতে পারে টেক্সচারের সমন্বয়, এবং সবুজ রঙের স্থানাঙ্ক হতে পারে। অনুসন্ধান করতে একটি শেডার ব্যবহার করুন। এবং সেই প্যালেট জমিনের রঙগুলি অ্যানিমেট / সংশোধন করুন। এটি রেট্রো এফেক্টের খুব কাছাকাছি থাকবে তবে কেবল স্প্রাইটস বা টেক্সচারের মতো স্থির 2D বিষয়বস্তুর জন্য কাজ করবে। আপনি যদি জেনুইন রেট্রো গ্রাফিক্স করে থাকেন তবে আপনি প্রকৃত সূচিযুক্ত রঙের স্প্রাইট তৈরি করতে এবং সেগুলি এবং প্যালেটগুলি আমদানি করতে কিছু লিখতে সক্ষম হতে পারেন।

আপনি যদি 'গ্লোবাল' প্যালেট ব্যবহার করতে চলেছেন তবে আপনি কাজ করতেও চাইবেন। পুরানো হার্ডওয়্যার কীভাবে কাজ করবে, প্যালেটগুলির জন্য কম মেমরির প্রয়োজন যেমন আপনার কেবল শিল্পকর্ম উত্পাদন করা প্রয়োজন তবে আপনাকে সমস্ত চিত্রের মধ্যে প্যালেটটি সিঙ্ক্রোনাইজ করতে হবে) বা প্রতিটি চিত্রের নিজস্ব প্যালেট দিতে হবে give এটি আপনাকে আরও নমনীয়তা দেবে তবে আরও মেমরি ব্যবহার করবে। অবশ্যই আপনি উভয় করতে পারেন, এছাড়াও আপনি কেবল রঙ সাইকেল চালানোর জিনিসগুলির জন্য প্যালেটগুলি ব্যবহার করতে পারেন। এছাড়াও আপনি আপনার রঙগুলিকে কতটা সীমাবদ্ধ রাখতে চান না তা পুরানো গেমগুলি উদাহরণস্বরূপ 256 টি রঙ ব্যবহার করবে। আপনি যদি কোনও টেক্সচার ব্যবহার করছেন তবে আপনি পিক্সেল সংখ্যা পেয়ে যাবেন তাই একটি 256 * 256 আপনাকে দেবে

যদি আপনি কেবল সস্তার নকল প্রভাব, যেমন প্রবাহিত জল চান, আপনি একটি দ্বিতীয় টেক্সচার তৈরি করতে পারেন যাতে আপনি পরিবর্তন করতে চান এমন অঞ্চলটিতে একটি গ্রেস্কেল মাস্ক থাকে, তবে মুখোশযুক্ত টেক্সচারটি হ'ল / স্যাচুরেশন / উজ্জ্বলিকে সংশোধন করুন এর পরিমাণ অনুসারে গ্রেস্কেল মুখোশ জমিন। আপনি এমনকি অলস হতে পারেন এবং রঙ বর্ণের কোনও রঙের রঙ / উজ্জ্বলতা / স্যাচুরেশন পরিবর্তন করতে পারেন।

আপনার যদি পূর্ণ 3D এর প্রয়োজন হয় তবে আপনি ফ্লাইতে সূচিযুক্ত চিত্র তৈরি করার চেষ্টা করতে পারেন তবে আপনার প্যালেটটি সন্ধান করতে হবে এটি ধীর হবে, আপনি সম্ভবত রঙের পরিসীমাতেও সীমাবদ্ধ থাকবেন।

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

অন্যথায় এগুলি সত্যই জাল করুন, প্রতিটি রাজ্যের জন্য একগুচ্ছ অ্যানিমেটেড টেক্সচার তৈরি করুন।

এইচটিএমএল 5 এ প্যালেট সাইক্লিংয়ের দুর্দান্ত ডেমো রয়েছে


0

আমি বিশ্বাস করি যে রঙগুলি স্থানের জন্য ifs যথেষ্ট দ্রুত [0 ... 1] দুটি ভাগে বিভক্ত:

if (color.r > 0.5) {
   color.r = (color.r-0.5) * uniform_r + uniform_base_r;
} else {
  color.r *=2.0;
} // this could be vectorised for all colors

এইভাবে 0 থেকে 0.5 এর মধ্যে রঙের মানগুলি স্বাভাবিক রঙের মানগুলির জন্য সংরক্ষিত থাকে; এবং 0.5 - 1.0 "মডুলেটেড" মানগুলির জন্য সংরক্ষিত রয়েছে, যেখানে ব্যবহারকারীর দ্বারা নির্বাচিত যে কোনও পরিসরের 0.5..1.0 মানচিত্র রয়েছে।

কেবলমাত্র রঙিন রেজোলিউশন 256 মান থেকে প্রতি পিক্সেল থেকে 128 টি মান কেটে নেওয়া হয়।

সম্ভবত কেউ সম্পূর্ণরূপে (রঙ-0.5f, 0.0f) এর মত অন্তর্নির্মিত ফাংশনগুলি ব্যবহার করতে পারে যদি পুরোপুরি আইফটিগুলি সরিয়ে ফেলতে (এগুলিকে শূন্য বা এক দ্বারা গুণে ট্রেড করে ...)।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.