2014-09-20 46 views
0

作爲學習片段着色器/矢量數學的練習,我試圖編寫一個後期處理着色器,基於角度(弧度)爲屏幕上的每個點P着色矢量PC,在P和屏幕C的中心之間。基於角度到屏幕中心的顏色片段GLSL

爲了簡單起見,我將在灰度級上做這件事,但是可以在這裏看到一個很好的例子,我可以看到色調隨角度變化而變化變化和色調形成一個循環。

http://demosthenes.info/assets/images/hsl-color-wheel-trans.png

我已搜索周圍,尋找信息有關查找矢量之間的角度,並從這些例子我已經得到到這裏:

#version 110 

uniform sampler2D tex0; //Color info 

void main() 
{ 
    vec2 ScreenCenter = vec2(0.5 , 0.5); 
    vec2 texCoord = gl_TexCoord[0].st; 
    vec2 deltaTexCoord = (texCoord - ScreenCenter.xy);  
    float angle = dot(deltaTexCoord , vec2(0,-1)); 

    //I've made attempts here to mess with acos as well as angle=pow(angle, somefloat) and 
    //have not gotten desired results 

    gl_FragColor = vec4(angle , angle, angle, 1.0); 
} 

然而這個代碼產生線性梯度而比我想要的效果。

+0

儘管試圖簡化它,色相不是一個數字。色調是一個標準化的3D矢量。飽和度和數值分別是數字,即灰色的角度和距離原點的距離。 – Jessy 2014-09-22 13:59:38

回答

2

最簡單的方法是使用內置的GLSL功能atan()有兩個參數:

float angle = atan(deltaTexCoord.y, deltaTexCoord.x); 

這相當於你可能熟悉的C/C++的atan2 function。與使用acos()相比,其主要優點是可以給出所有角度範圍[-pi,pi],而由acos()產生的角度僅在[0,pi]範圍內,因此對於下半部分不正確的圈子。使用atan(y, x),也不需要對輸入值進行歸一化。

0

你快到了。兩個矢量的內積(也稱爲標量或點積)是矢量之間角度乘以矢量長度乘積的餘弦函數餘弦函數。所以爲了回到角度上,你已經將點積映射到餘弦的倒數,並且首先對矢量進行歸一化(0,1)已經是單位長度了。

float angle = acos(dot(normalize(deltaTexCoord), vec2(0, -1))); 

注意,角弧度的單位,從0到2PI報道。