2012-05-17 116 views
4

我需要一個簡單聚光燈着色器的幫助。 錐體內的所有頂點都應爲黃色,錐體外的所有頂點應爲黑色。 我只是不能得到它的工作。我認爲它與從世界到眼座標的轉變有關。簡單GLSL聚光燈着色器

頂點着色器:

uniform vec4 lightPositionOC; // in object coordinates 
uniform vec3 spotDirectionOC; // in object coordinates 
uniform float spotCutoff;  // in degrees 

void main(void) 
{ 
    vec3 lightPosition; 
    vec3 spotDirection; 
    vec3 lightDirection; 
    float angle; 

    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 

    // Transforms light position and direction into eye coordinates 
    lightPosition = (lightPositionOC * gl_ModelViewMatrix).xyz; 
    spotDirection = normalize(spotDirectionOC * gl_NormalMatrix); 

    // Calculates the light vector (vector from light position to vertex) 
    vec4 vertex = gl_ModelViewMatrix * gl_Vertex; 
    lightDirection = normalize(vertex.xyz - lightPosition.xyz); 

    // Calculates the angle between the spot light direction vector and the light vector 
    angle = dot(normalize(spotDirection), 
       -normalize(lightDirection)); 
    angle = max(angle,0); 

    // Test whether vertex is located in the cone 
    if(angle > radians(spotCutoff)) 
     gl_FrontColor = vec4(1,1,0,1); // lit (yellow) 
    else 
     gl_FrontColor = vec4(0,0,0,1); // unlit(black) 
} 

片段着色器:

void main(void) 
{ 
    gl_FragColor = gl_Color; 
} 

編輯:
蒂姆是正確的。這

if(angle > radians(spotCutoff)) 

應該是:

if(acos(angle) < radians(spotCutoff)) 

新問題:
的光似乎並沒有留在現場的固定位置,而似乎是相對於移動當我向前或向後移動時,作爲錐體的相機變得更小或更大。

+0

哪裏是你的'#version'指令? – genpfault

+0

而不是設置gl_FrontColor我只是將一個顏色值作爲變量傳遞給片段着色器。再次,當我寫GLSL 1.20時,通常只是爲了向後兼容GLSL 3.30+着色器,並且我以同樣的方式做事。我仍然認爲它與gl_FrontColor有關,但看看這個問題:http://stackoverflow.com/questions/6430154/what-is-the-relationship-between-gl-color-and-gl-frontcolor-in-both -vertex-and -f –

回答

5

(讓spotDirection是向量A,以及lightDirection是矢量B)

要分配;

angle = dot(A,B)

不應式是:

cos(angle) = dot(A,B)

angle = arccos(dot(A,B))

http://en.wikipedia.org/wiki/Dot_product#Geometric_interpretation

+0

謝謝你的努力!你能幫我解答我的第二個問題嗎? – Basti

+2

@Basti爲了將來的參考,如果你有其他問題,你應該考慮發佈一個單獨的問題。這個問題被標記爲已解決,並且很可能不會引起您在帖子底部的修改。話雖如此,我沒有足夠的信息來知道答案。如果你真的在對象座標中定義光照位置,而不是移動對象,那麼我不希望看到光照有變化,所以可能有錯誤的地方沒有在上面顯示。嘗試製作一個新帖子,其中包含指向描述問題的圖片的鏈接 – Tim

1

我ñ我的舊着色器我用代碼:

float spotEffect = dot(normalize(gl_LightSource[0].spotDirection.xyz), 
         normalize(-light)); 
if (spotEffect < gl_LightSource[0].spotCosCutoff) 
{ 
    spotEffect = smoothstep(gl_LightSource[0].spotCosCutoff-0.002,  
          gl_LightSource[0].spotCosCutoff, spotEffect); 
} 
else spotEffect = 1.0; 

而不是發送角度着色器最好是發送這些角度

1

要回答你的問題,這裏有一個鏈接到一個類似的問題:GLSL point light shader moving with camera。 解決的辦法是刪除gl_NormalMatrix和gl_ModelViewMatrix。

spotDirection = normalize(spotDirectionOC * gl_NormalMatrix); 

將成爲:

spotDirection = normalize(spotDirectionOC);