2011-06-02 78 views

回答

10

我假設你有一個簡單的沒有爭議的頂點着色器,因爲它不是真正的問題有關,如:

void main() 
{ 
    gl_Position = modelviewProjectionMatrix * position; 
    texCoordVarying = vec2(textureMatrix * vec4(texCoord0, 0.0, 1.0)); 
} 

所以,做多如果照明被禁用,則與ES 1.x相同,包括幾乎沒有人使用過的紋理矩陣。

我不是Photoshop專家,所以請原諒我對各種工具的看法 - 特別是如果我錯了。

我想我說得對,水平工具有效地拉伸(和剪輯)的亮度直方圖?在這種情況下,例如着色器可以是:

varying mediump vec2 texCoordVarying; 
uniform sampler2D tex2D; 

const mediump mat4 rgbToYuv = mat4(0.257, 0.439, -0.148, 0.06, 
            0.504, -0.368, -0.291, 0.5, 
            0.098, -0.071, 0.439, 0.5, 
            0.0,  0.0,  0.0, 1.0); 

const mediump mat4 yuvToRgb = mat4(1.164, 1.164, 1.164, -0.07884, 
            2.018, -0.391, 0.0, 1.153216, 
             0.0, -0.813, 1.596, 0.53866, 
             0.0, 0.0, 0.0, 1.0); 

uniform mediump float centre, range;  

void main() 
{ 
    lowp vec4 srcPixel = texture2D(tex2D, texCoordVarying); 
    lowp vec4 yuvPixel = rgbToYuv * srcPixel; 

    yuvPixel.r = ((yuvPixel.r - centre) * range) + 0.5; 

    gl_FragColor = yuvToRgb * yuvPixel; 
} 

你會控制,通過設置你想要讓通過範圍的中心(將移動到輸出範圍的中心)和總範圍你想通過(整個範圍爲1.0,範圍的一半爲0.5)等。

有趣的是,我從RGB輸入空間切換到YUV色彩空間進行中間調整。我使用矩陣乘法來做到這一點。然後我調整亮度通道,並應用從YUV變回RGB的另一個矩陣。對我而言,在亮度/色度色彩空間中工作是最有意義的,從那裏我選擇YUV是相當任意的,儘管它對於ES目的是RGB空間的簡單線性變換具有很大的優勢。

我的理解是,曲線工具也可以重新映射亮度,但根據一些函數f(x)= y,它是單調遞增的(所以,只會與任何水平或垂直只相交一次)並且被設置在界面中以某種方式從左下到右上的曲線。

因爲GL ES對於數據結構並不是很好,並且儘可能避免分支,所以我建議最好的方法是上傳一個256x1的亮度紋理,其中'x'的值爲f X)。然後,您可以僅通過二次紋理進行映射,例如,與:

... same as before down to ... 
lowp vec4 yuvPixel = rgbToYuv * srcPixel; 

yuvPixel.r = texture2D(lookupTexture, vec2(yuvPixel.r, 0.0)); 

... and as above to convert back to RGB, etc ... 

您正在使用備用紋理單元有效地索引查找表。在支持ES 2.0的iOS設備上,您至少可以獲得八個紋理單元,因此您希望有一個備用。因爲從RGB到HSV的映射涉及很多條件,但過程基本相同 - 從RGB到HSV的映射,在H和S上執行所需的修改,映射回RGB和輸出。

基於一個快速谷歌搜索,this site提供了一些可下載的代碼,其中包括一些Photoshop的功能(雖然不是曲線或水平,這樣我可以看到),並顯著,功能RGBToHSLHSLToRGB用品示例實現。它適用於桌面GLSL,它具有更多預定義的變量,類型和功能,但您不應該遇到任何重大問題。請記住添加精度修飾符併爲缺失的minmax函數提供您自己的替換。

6

對於曲線photoshop使用雙三次樣條插值。對於給定的一組控制點,您可以預先計算每個通道和主曲線的所有256個值。我發現將結果存儲爲256x1紋理並將其傳遞給着色器,然後更改每個組件的值會更加容易:

uniform sampler2D curvesTexture; 

vec3 RGBCurvesAdjustment(vec3 color) 
{ 
    return vec3(texture2D(curvesTexture, vec2(color.r, 1.0)).r, 
       texture2D(curvesTexture, vec2(color.g, 1.0)).g, 
       texture2D(curvesTexture, vec2(color.b, 1.0)).b); 
}