Opengl es OpenGL ES 2.0着色器-多边形中的二维径向渐变

Opengl es OpenGL ES 2.0着色器-多边形中的二维径向渐变,opengl-es,glsl,fragment-shader,Opengl Es,Glsl,Fragment Shader,我试图在多边形内部绘制一个径向渐变。我的舞台是600x320。我能画渐变,但它“扭曲/拉伸”。目标是像灯光一样产生梯度 u_lightPosition作为相对值传递:{0.5,0.5} 当前未使用的lightPositionAbsolute作为绝对值{300.0,160.0}传入 我的片段着色器当前看起来如下所示: #ifdef GL_ES precision lowp float; #endif

我试图在多边形内部绘制一个径向渐变。我的舞台是
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);
}                                       
对于圆形多边形,这将导致:


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

我在KickJS GLSL编辑器中创建了一个着色器示例,您可以看到它工作得很好:


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

好的,我找到了解决方案,现在它可以正常工作了。我使用的是相对值,而不是绝对值,这导致了拉伸。着色器现在看起来如下所示:

#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);
}                                       

你通过的半径是浮动的,所以x和y是相同的,但它们不应该是相同的

屏幕:1280x800,半径300={300.0/1280.0300.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是属性位置(而不是灯光位置)*通过前一个着色器的变量传递的矩阵。

问题在于,如果舞台是二次的,它会按预期工作。如果舞台是矩形的,梯度也会被拉伸,这在光源下是不会发生的。同样在KickJS GLSL编辑器中,如果我全屏显示的话。在KickJS示例中,圆圈边缘有一些奇怪的闪烁。