OpenGL ES 2.0着色器 - 多边形的2D径向渐变

时间:2012-07-25 16:15:31

标签: opengl-es glsl fragment-shader

我正在尝试在Polygon中绘制径向渐变。我的舞台是600x320。我可以画一个渐变,但它'扭曲/拉伸'。目标是像光一样产生的渐变。

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

3 个答案:

答案 0 :(得分: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);
}                                       

答案 1 :(得分:1)

我相信你的着色器很好,你的问题最有可能出现在几何体中(或者在顶点着色器中)。

我在KickJS GLSL编辑器中创建了一个着色器示例,您可以在其中看到它的工作正常:

http://goo.gl/viDKB

您可以在设置下更改网格类型。

答案 2 :(得分:0)

你将半径作为浮点数传递给x& y是相同的,但他们不应该。

即。屏幕:1280 x 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是属性位置(不是光位置)*矩阵通过变量从前一个着色器传递。