gpt4 book ai didi

opengl - 如何使用 GLSL 更改纹理的色调?

转载 作者:行者123 更新时间:2023-12-03 10:40:54 27 4
gpt4 key购买 nike

有没有办法使用 GLSL(片段着色器)有效地改变 2D OpenGL 纹理的色调?

有人有一些代码吗?

更新: 这是来自 user1118321 建议的代码:

uniform sampler2DRect texture;
const mat3 rgb2yiq = mat3(0.299, 0.587, 0.114, 0.595716, -0.274453, -0.321263, 0.211456, -0.522591, 0.311135);
const mat3 yiq2rgb = mat3(1.0, 0.9563, 0.6210, 1.0, -0.2721, -0.6474, 1.0, -1.1070, 1.7046);
uniform float hue;

void main() {

vec3 yColor = rgb2yiq * texture2DRect(texture, gl_TexCoord[0].st).rgb;

float originalHue = atan(yColor.b, yColor.g);
float finalHue = originalHue + hue;

float chroma = sqrt(yColor.b*yColor.b+yColor.g*yColor.g);

vec3 yFinalColor = vec3(yColor.r, chroma * cos(finalHue), chroma * sin(finalHue));
gl_FragColor = vec4(yiq2rgb*yFinalColor, 1.0);
}

这是与引用比较的结果:

enter image description here

我试图在 atan 内用 Q 切换 I 但结果即使在 0° 左右也是错误的

你有什么提示吗?

如果需要比较,这是原始未修改的图像:
enter image description here

最佳答案

虽然@awoodland 所说的是正确的,但我相信这种方法可能会导致亮度变化问题。

由于多种原因,HSV 和 HLS 颜色系统存在问题。我最近与一位色彩科学家讨论过这个问题,他的建议是转换为 YIQ 或 YCbCr 空间并相应地调整色度 channel (I&Q,或 Cb&Cr)。 (你可以学习如何做 herehere 。)

一旦进入这些空间之一,您就可以通过执行 hue = atan(cr/cb) 从色度 channel 形成的角度获得色调。 (注意 cb == 0)。这为您提供了弧度值。只需通过添加色调旋转量来旋转它。完成后,您可以使用 chroma = sqrt(cr*cr+cb*cb) 计算色度的大小。 .要返回 RGB,请使用 Cr = chroma * sin (hue) 计算新的 Cb 和 Cr(或 I & Q) , Cb = chroma * cos (hue) .然后按照上述网页中的说明转换回 RGB。

编辑:这是我测试过的解决方案,似乎给我的结果与您的引用相同。您可能可以将一些点积折叠为矩阵乘法:

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;
}

关于opengl - 如何使用 GLSL 更改纹理的色调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9234724/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com