2012-07-25 94 views
2

我想繪製多邊形內的徑向漸變。我的舞臺是600x320。我可以繪製一個漸變,但它'扭曲/拉伸'。目標是像光線會產生的漸變。OpenGL ES 2.0着色器 - 多邊形中的二維徑向漸變

u_lightPosition通過爲相對值{0.5, 0.5}
目前未使用的lightPositionAbsolute作爲被傳入絕對值{300.0, 160.0}

我的片段着色器目前看起來是這樣的:

#ifdef GL_ES        
precision lowp float;     
#endif         
varying vec4 v_fragmentColor; 

uniform vec2 u_lightPosition; 
uniform vec2 u_lightPositionAbsolute; 
uniform vec4 u_outerColor; 
uniform vec4 u_innerColor; 
uniform float u_radius; 

void main()        
{ 
    vec2 resolution = vec2(600,320); 
    vec2 position = (gl_FragCoord.xy/resolution.xy); 

    float distanceFromLight = length(position - u_lightPosition); 

    gl_FragColor = mix(u_outerColor, u_innerColor, distanceFromLight); 
}          

用圓圈多邊形這導致:

enter image description here

回答

1

我相信你的着色器是蠻好的,你的問題是最可能在幾何體中(或在頂點着色器中)。

我已經創造了KickJS GLSL編輯器,在這裏你可以看到你的着色器的例子非常有效:

http://goo.gl/viDKB

您可以在設置中更改網格的類型。

+1

問題是,如果舞臺是二次的,它就會按預期工作。如果舞臺是長方形的,那麼漸變也會被拉伸,這對於光源不會發生。同樣在KickJS GLSL編輯器中,如果我去全屏。 – Alex 2012-07-26 15:28:27

+1

KickJS示例中的圓圈邊緣有一些奇怪的閃爍現象。 – drewish 2014-08-17 21:18:08

2

好吧,我發現現在它的工作原理是安靜的。我用相對的價值觀來反對絕對的價值觀,這導致了拉伸。着色器現在看起來是這樣的:

#ifdef GL_ES        
precision lowp float;     
#endif         
uniform vec2 u_lightPosition; 
uniform float u_radius; 

void main()        
{ 
    float distance = length(u_lightPosition - gl_FragCoord.xy); 
    float intensity = 1.0 - min(distance, u_radius)/u_radius; 

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

編輯:改變的「光」的衰減:

#ifdef GL_ES        
precision lowp float;     
#endif         
uniform vec2 u_lightPosition; 
uniform float u_radius; 

void main()        
{ 
    float distance = length(u_lightPosition - gl_FragCoord.xy); 

    float maxDistance = pow(u_radius, 0.23); 
    float quadDistance = pow(distance, 0.23); 

    float quadIntensity = 1.0 - min(quadDistance, maxDistance)/maxDistance; 

    gl_FragColor = vec4(quadIntensity, quadIntensity, quadIntensity, 1.0); 
}          
0

你逝去的半徑爲float所以X & y是相同的,但他們不應該是。

即。屏幕:1280 * 800,半徑300 = {300.0/1280.0,300.0/800.0}

"float u_radiusX = (100.0/1280.0);\n"+ 
"float u_radiusY = (100.0/800.0);\n"+ 
"float distanceFromLightX = length(v_lightPos.x - v_Pos.x);\n"+ 
"float distanceFromLightY = length(v_lightPos.y - v_Pos.y);\n"+ 
"float quadIntensityX = (1.0-min(distanceFromLightX,u_radiusX)/u_radiusX);\n"+ 
"float quadIntensityY = (1.0-min(distanceFromLightY,u_radiusY)/u_radiusY);\n"+ 
//finally 
"float quadIntensity = quadIntensityX*quadIntensityY;\n"+ 
"gl_FragColor = vec4(color.r*quadIntensity, color.g*quadIntensity, color.b*quadIntensity, 1.0);\n" 

我這這種方式工作了。其中v_Pos是通過來自之前着色器的變量傳遞的屬性位置(不是光位置)*矩陣。