Mark~
HSV and HLS color systems are problematic for a number of reasons. I talked with a color scientist about this recently, and his recommendation was to convert to YIQ or YCbCr space and adjust the the chroma channels (I&Q, or Cb&Cr) accordingly. (You can learn how to do that here and here.)
Once in one of those spaces, you can get the hue from the angle formed by the chroma channels, by doing hue = atan(cr/cb) (watching for cb == 0). This gives you a value in radians. Simply rotate it by adding the hue rotation amount. Once you've done that, you can calculate the magnitude of the chroma with chroma = sqrt(cr*cr+cb*cb). To get back to RGB, calculate the new Cb and Cr (or I & Q) using Cr = chroma * sin (hue), Cb = chroma * cos (hue). Then convert back to RGB as described on the above web pages.
EDIT: Here's a solution that I've tested and seems to give me the same results as your reference. You can probably collapse some of the dot products into matrix multiplies:
uniform sampler2DRect inputTexture;
uniform float hueAdjust;
void main ()
{
const vec4 kRGBToYPrime = vec4 (0.299, 0.587, 0.114, 0.0);
const vec4 kRGBToI = vec4 (0.596, -0.275, -0.321, 0.0);
const vec4 kRGBToQ = vec4 (0.212, -0.523, 0.311, 0.0);
const vec4 kYIQToR = vec4 (1.0, 0.956, 0.621, 0.0);
const vec4 kYIQToG = vec4 (1.0, -0.272, -0.647, 0.0);
const vec4 kYIQToB = vec4 (1.0, -1.107, 1.704, 0.0);
// Sample the input pixel
vec4 color = texture2DRect (inputTexture, gl_TexCoord [ 0 ].xy);
// Convert to YIQ
float YPrime = dot (color, kRGBToYPrime);
float I = dot (color, kRGBToI);
float Q = dot (color, kRGBToQ);
// Calculate the hue and chroma
float hue = atan (Q, I);
float chroma = sqrt (I * I + Q * Q);
// Make the user's adjustments
hue += hueAdjust;
// Convert back to YIQ
Q = chroma * sin (hue);
I = chroma * cos (hue);
// Convert back to RGB
vec4 yIQ = vec4 (YPrime, I, Q, 0.0);
color.r = dot (yIQ, kYIQToR);
color.g = dot (yIQ, kYIQToG);
color.b = dot (yIQ, kYIQToB);
// Save the result
gl_FragColor = color;
}
引用
http://stackoverflow.com/questions/9234724/how-to-change-hue-of-a-texture-with-glsl
分享到:
相关推荐
本篇文章将深入探讨如何在Cocos2dx 2.x中应用Shader,并通过提供的FKCocos2dxEffectDemo实例进行详细解析。 首先,理解Shader的概念至关重要。Shader是运行在GPU上的小型程序,负责计算物体表面的颜色、光照等视觉...
总结,掌握Cocos2d-x Lua Shader的使用能够极大地提升游戏或应用的视觉表现力。通过编写自定义的GLSL着色器,不仅可以实现图片圆角和文字渐变,还可以创造出更多创新的视觉效果。在实际开发过程中,不断实践和调试...
4.2 光照效果:虽然Cocos2d-x自身不直接支持光照效果,但开发者可以利用颜色混合、透明度和自定义Shader来模拟光照效果。 五、实例分析:effectTest 5.1 "effectTest"可能是一个示例项目,用于演示如何在Cocos2d-x...
在提供的“cocos3d”压缩包中,可能包含了用于演示或学习的Cocos2d-x 3D模型加载和显示的代码示例,通过阅读和理解这些代码,你可以更深入地了解上述知识点的实际应用。在实践中,不断调试和优化代码,将帮助你更好...
《cocos2d-x与Box2D在切水果游戏中的应用》 在移动游戏开发领域,cocos2d-x是一个广泛使用的2D游戏引擎,它以其高效、跨平台的特性深受开发者喜爱。Box2D则是一款强大的开源物理引擎,专为2D游戏设计,能够模拟各种...