জিএলএসএল শেডার - হিউ / স্যাচুরেশন / ব্রাইটনেস পরিবর্তন করুন


14

আমি একটি জিএলএসএল ফ্রেগমেন্ট শ্যাডার ব্যবহার করে একটি চিত্রের বর্ণ পরিবর্তন করার চেষ্টা করছি। আমি ফটোশপের হিউ / স্যাচুরেশন অ্যাডজাস্টমেন্ট স্তরটির অনুরূপ কিছু অর্জন করতে চাই।

নিম্নলিখিত ছবিতে আপনি দেখতে পেয়েছি এখন পর্যন্ত আমি কী পেয়েছি। আমি সবুজ বর্গক্ষেত্রের বর্ণটি পরিবর্তন করতে চাই যাতে ডানদিকে লাল বর্গক্ষেত্রের মতো লাগে তবে এই শেডারটি দিয়ে আমি অর্ধেক লাল অর্ধেক গোলাপী বর্গক্ষেত্রটি (মাঝখানে বর্গাকার) পাই get
এখানে চিত্র বর্ণনা লিখুন

আমি খণ্ড শ্যাডারে যা করছি তা টেক্সচারের রঙটিকে এইচএসভিতে রূপান্তরিত করছে, তারপরে আমি এইচএসভি রঙটি যুক্ত করব যা আমি ভার্টেক্স শেডার থেকে এতে পেয়েছি এবং আমি রঙটি আরজিবিতে রূপান্তর করি।
আমি কি ভুল করছি?

খণ্ড শ্যাডার:

precision mediump float;
varying vec2 vTextureCoord;
varying vec3 vHSV;
uniform sampler2D sTexture;

vec3 convertRGBtoHSV(vec3 rgbColor) {
    float r = rgbColor[0];
    float g = rgbColor[1];
    float b = rgbColor[2];
    float colorMax = max(max(r,g), b);
    float colorMin = min(min(r,g), b);
    float delta = colorMax - colorMin;
    float h = 0.0;
    float s = 0.0;
    float v = colorMax;
    vec3 hsv = vec3(0.0);
    if (colorMax != 0.0) {
      s = (colorMax - colorMin ) / colorMax;
    }
    if (delta != 0.0) {
        if (r == colorMax) {
            h = (g - b) / delta;
        } else if (g == colorMax) {        
            h = 2.0 + (b - r) / delta;
        } else {    
            h = 4.0 + (r - g) / delta;
        }
        h *= 60.0;
        if (h < 0.0) {
            h += 360.0;
        }
    }
    hsv[0] = h;
    hsv[1] = s;
    hsv[2] = v;
    return hsv;
}
vec3 convertHSVtoRGB(vec3 hsvColor) {
    float h = hsvColor.x;
    float s = hsvColor.y;
    float v = hsvColor.z;
    if (s == 0.0) {
        return vec3(v, v, v);
    }
    if (h == 360.0) {
        h = 0.0;
    }
    int hi = int(h);
    float f = h - float(hi);
    float p = v * (1.0 - s);
    float q = v * (1.0 - (s * f));
    float t = v * (1.0 - (s * (1.0 - f)));
    vec3 rgb;
    if (hi == 0) {
        rgb = vec3(v, t, p);
    } else if (hi == 1) {
        rgb = vec3(q, v, p);
    } else if (hi == 2) {
        rgb = vec3(p, v, t);
    } if(hi == 3) {
        rgb = vec3(p, q, v);
    } else if (hi == 4) {
        rgb = vec3(t, p, v);
    } else {
        rgb = vec3(v, p, q);
    }
    return rgb;
}
void main() {
    vec4 textureColor = texture2D(sTexture, vTextureCoord);
    vec3 fragRGB = textureColor.rgb;
    vec3 fragHSV = convertRGBtoHSV(fragRGB);
    fragHSV += vHSV;
    fragHSV.x = mod(fragHSV.x, 360.0);
    fragHSV.y = mod(fragHSV.y, 1.0);
    fragHSV.z = mod(fragHSV.z, 1.0);
    fragRGB = convertHSVtoRGB(fragHSV);
    gl_FragColor = vec4(convertHSVtoRGB(fragHSV), textureColor.w);
}

সম্পাদনা: স্যাম হোসেভার তার উত্তরে প্রদত্ত ফাংশনগুলি ব্যবহার করে গোলাপী ব্যান্ডগুলির সাথে সমস্যাটি সমাধান হয়েছে তবে আমি কেবল বর্ণ বর্ণের অর্ধেক পর্যন্ত পৌঁছতে পারি। আমি রঙটি লাল থেকে সবুজতে পরিবর্তন করতে পারি তবে আমি এটিকে নীল বা গোলাপী রঙে পরিবর্তন করতে পারি না। এখানে চিত্র বর্ণনা লিখুন

খণ্ড শ্যাডারে, আমি এখন এটি করছি:

void main() {
    vec4 textureColor = texture2D(sTexture, vTextureCoord);
    vec3 fragRGB = textureColor.rgb;
    vec3 fragHSV = rgb2hsv(fragRGB);
    float h = vHSV.x / 360.0;
    fragHSV.x *= h;
    fragHSV.yz *= vHSV.yz;
    fragHSV.x = mod(fragHSV.x, 1.0);
    fragHSV.y = mod(fragHSV.y, 1.0);
    fragHSV.z = mod(fragHSV.z, 1.0);
    fragRGB = hsv2rgb(fragHSV);
    gl_FragColor = vec4(hsv2rgb(fragHSV), textureColor.w);
}

আপনি কি int hi = int(h/60.0); float f = h/60.0 - float(hi);পরিবর্তে বোঝাতে চাইছেন না int hi = int(h); float f = h - float(hi);? যদিও এটি কারণ সৃষ্টি করছে কিনা তা জানেন না।
কলরাবি

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

@ বেসিক: আমরা প্রশ্নের উত্তর রাখি না। যদি আপনি নিজে থেকে উত্তরটি খুঁজে পান তবে আপনার প্রশ্নের উত্তর পোস্ট করুন।
নিকল বোলাস

উত্তর:


22

এই ফাংশনগুলি খুব খারাপভাবে সম্পাদন করবে। আমি জিপিইউ মাথায় রেখে ফাংশনগুলি ব্যবহার করার পরামর্শ দিচ্ছি। এখানে আমার:

vec3 rgb2hsv(vec3 c)
{
    vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
    vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
    vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));

    float d = q.x - min(q.w, q.y);
    float e = 1.0e-10;
    return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}

vec3 hsv2rgb(vec3 c)
{
    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
    return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}

মনে রাখবেন যে এই ফাংশনগুলির জন্য H[0… 1] এর পরিবর্তে [0… 1] এর ব্যাপ্তি রয়েছে , সুতরাং আপনাকে আপনার ইনপুটটি মানিয়ে নিতে হবে।

সূত্র: http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl


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

1
সত্যিই আকর্ষণীয়! এই ফাংশনগুলি আরও ভাল করে কেন আপনি ব্যাখ্যা করতে পারেন? "জিপিইউ মাথায় রাখা" এর মতো কী?
মার্কো

4
@ মারকো জিপিইউগুলি বড় বড় if()কনস্ট্রাক্ট পরিচালনা করতে খুব ভাল নয় , তবে ভেক্টর অপারেশনগুলিতে ভাল (বেশ কয়েকটি স্কেলারের মানের উপর সমান্তরাল অপারেশন)। উপরের ফাংশনগুলি কখনই ব্যবহার করে না if(), অপারেশনগুলিকে সমান্তরাল করার চেষ্টা করে এবং সাধারণভাবে তারা কম নির্দেশাবলী ব্যবহার করে। এগুলি সাধারণত ভাল সূচক হয় যে তারা দ্রুত হতে চলেছে।
সাম হোচেভার

এই ফাংশনগুলি স্ট্যান্ডার্ড এইচএসভি সূত্রের ঠিক সমান (গোলাকৃতি ত্রুটি উপেক্ষা করে), বা এগুলি একটি আনুমানিক হয়?
স্টেফান মনোভ 21

3

নিকল বোলাস যেমন মূল পোস্টের মন্তব্যে পরামর্শ দিয়েছিলেন, আমি আমার সমস্যার সমাধানটি একটি পৃথক উত্তরে পোস্ট করছি।

প্রথম ইস্যুটি হ'ল মূল পোস্টে প্রদর্শিত ইমেজটি গোলাপী ব্যান্ডগুলির সাথে চিত্রটি সরবরাহ করা হয়েছিল। আমি স্যাম হোসেভার তার উত্তরে প্রদত্ত ফাংশনগুলি ব্যবহার করে এটি ঠিক করেছি ( /gamedev//a/59808/22302 )।

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

আমি এখনই শেডারটি ব্যবহার করছি। এটির সাহায্যে আমি রঙটি 0º থেকে 360ift এ স্থানান্তর করতে পারি, চিত্রটি বিশিষ্ট করতে পারি এবং উজ্জ্বলতা হ্রাস করতে পারি।

void main() {
    vec4 textureColor = texture2D(sTexture, vTextureCoord);
    vec3 fragRGB = textureColor.rgb;
    vec3 fragHSV = rgb2hsv(fragRGB).xyz;
    fragHSV.x += vHSV.x / 360.0;
    fragHSV.yz *= vHSV.yz;
    fragHSV.xyz = mod(fragHSV.xyz, 1.0);
    fragRGB = hsv2rgb(fragHSV);
    gl_FragColor = vec4(fragRGB, textureColor.w);
} 

2
টিপ: আপনি সম্ভবত mod()রঙ করতে চান, কিন্তু clamp()পরিবর্তে আপনি চাইলে পরিপূর্ণতা এবং উজ্জ্বলতা ।
গুস্তাভো ম্যাকিয়েল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.