我目前正在使用此片段着色器在WebGL中应用高光/阴影调整到照片纹理。
着色器本身是直接从优秀的GPUImage库iOS。
uniform sampler2D inputImageTexture;
varying highp vec2 textureCoordinate;
uniform lowp float shadows;
uniform lowp float highlights;
const mediump vec3 luminanceWeighting = vec3(0.3, 0.3, 0.3);
void main()
{
lowp vec4 source = texture2D(inputImageTexture, textureCoordinate);
mediump float luminance = dot(source.rgb, luminanceWeighting);
mediump float shadow = clamp((pow(luminance, 1.0/(shadows+1.0)) + (-0.76)*pow(luminance, 2.0/(shadows+1.0))) - luminance, 0.0, 1.0);
mediump float highlight = clamp((1.0 - (pow(1.0-luminance, 1.0/(2.0-highlights)) + (-0.8)*pow(1.0-luminance, 2.0/(2.0-highlights)))) - luminance, -1.0, 0.0);
lowp vec3 result = vec3(0.0, 0.0, 0.0) + ((luminance + shadow + highlight) - 0.0) * ((source.rgb - vec3(0.0, 0.0, 0.0))/(luminance - 0.0));
gl_FragColor = vec4(result.rgb, source.a);
}此着色器现有,只会减少一个规模的0.0 - 1.0高光。不过,我希望它也能在1.0-2.0的尺度上照亮亮点。
目的是有一个完整的过滤器,以减少图像的高光,当高光均匀是小于1.0,并增加了高光强度时,它是高于1.0。同样的,黑暗的阴影也一样。
亮点:
0.0(duller) ---- 1.0 (default - original pixel values) ----- 2.0 (brighter)我尝试简单地将高光变量的夹子更改为0.0,2.0,虽然这确实增加了当制服高于1.0时高光的亮度,但它也严重扰乱了颜色。
我对图像处理和构建片段着色器的理解是极其薄弱的,因为你,我能分辨。
我只是希望有人能给我指明正确的方向。
编辑:
以下是一些截图示例:-
1.00 (基本上是源图像)

0.00,因为您可以看到高光变得平坦/删除。

clamp以允许1.00之上的值并将突出显示值设置为2.00时会发生什么

我只是希望能提高亮点,使其更明亮/更明确。即与将值设置为0.00相反
发布于 2014-10-23 13:33:39
我并不真正理解阴影和高光方程,但我可以看到,它们被设置为永远不会增强阴影和高光,而是为了消除它们。所以我们需要第二步来加强。
对于亮点,我认为要处理更亮的颜色,你需要混合到白色,而不是添加一些东西,这样你就不会得到色调的变化。我用了一个基本的对比方程来挑选高光,然后把它剪出中间色调和阴影。whiteTarget只是抽出0.02.0范围的上半部分,作为一个乘数来决定亮度效应的强度。
对于阴影,我们将我们的范围从0.0-1.0 (0不变,1被洗掉)更改为0.0-2.0 (其中1不变,2被洗掉)。因此,应该删除shadow方程中的+1.0。然后,对于0.0-1.0范围,我只是复制了我所做的高光,除了混入黑色。也许可以对其进行优化以避免使用mix函数(不确定)。
这是我的非优化版本的着色器,设置好了shadows和highlights都在0.02.0的比例上,1.0是标称。你可能想玩一下我把亮度立方体的线条,还有我用来做对比度的值(目前为1.5),但对我来说,它现在的方式相当好--我调整了它,以避免阴影之间的任何难看的重叠,并在输入参数处于两个极端时突出显示范围。
uniform sampler2D inputImageTexture;
varying highp vec2 textureCoordinate;
uniform lowp float shadows;
uniform lowp float highlights;
const mediump vec3 luminanceWeighting = vec3(0.3, 0.3, 0.3);
void main()
{
lowp vec4 source = texture2D(inputImageTexture, textureCoordinate);
mediump float luminance = dot(source.rgb, luminanceWeighting);
//(shadows+1.0) changed to just shadows:
mediump float shadow = clamp((pow(luminance, 1.0/shadows) + (-0.76)*pow(luminance, 2.0/shadows)) - luminance, 0.0, 1.0);
mediump float highlight = clamp((1.0 - (pow(1.0-luminance, 1.0/(2.0-highlights)) + (-0.8)*pow(1.0-luminance, 2.0/(2.0-highlights)))) - luminance, -1.0, 0.0);
lowp vec3 result = vec3(0.0, 0.0, 0.0) + ((luminance + shadow + highlight) - 0.0) * ((source.rgb - vec3(0.0, 0.0, 0.0))/(luminance - 0.0));
// blend toward white if highlights is more than 1
mediump float contrastedLuminance = ((luminance - 0.5) * 1.5) + 0.5;
mediump float whiteInterp = contrastedLuminance*contrastedLuminance*contrastedLuminance;
mediump float whiteTarget = clamp(highlights, 1.0, 2.0) - 1.0;
result = mix(result, vec3(1.0), whiteInterp*whiteTarget);
// blend toward black if shadows is less than 1
mediump float invContrastedLuminance = 1.0 - contrastedLuminance;
mediump float blackInterp = invContrastedLuminance*invContrastedLuminance*invContrastedLuminance;
mediump float blackTarget = 1.0 - clamp(shadows, 0.0, 1.0);
result = mix(result, vec3(0.0), blackInterp*blackTarget);
gl_FragColor = vec4(result, source.a);
}顺便问一下,你知道为什么原来的result行总是把0添加到所有东西中吗?好像可以简化成
vec3 result = (luminance + shadow + highlight) * source.rgb / luminance;但是,也许在计算中而不是在计算之后将其转换为lowp是一种技巧。只是猜一下。
https://stackoverflow.com/questions/26511037
复制相似问题