I am trying to paint a radial gradient inside a Polygon. My Stage is 600x320
. I am able to draw a gradient but it`s 'distorted/streched'. The goal is a gradient like a light would produce.
u_lightPosition
is passed as a relative value: {0.5, 0.5}
.
Currently unused lightPositionAbsolute
is passed in as absolute value {300.0, 160.0}
.
My fragment-shader currently looks like this:
#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);
}
With a circle Polygon this results in:
Ok i found the solution which now that it works is quiet obvious. I worked with relative values opposed to absolute ones which resulted in the stretching. The shader now looks like this:
#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);
}
Edit: Changed the falloff of the 'light':
#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);
}
I believe that your shader is just fine, your problem is most likely in the geometry (or in the vertex shader).
I have created an example of your shader in the KickJS GLSL editor, where you can see it works just fine:
You can change the type of mesh under settings.
You are passing radius as float so x & y are the same but they shouldnt be.
ie. screen : 1280 x 800 , radius 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"
I got this working this way. , where v_Pos is attribute position ( NOT the light position ) * matrix passed via variable from previous shader.
来源:https://stackoverflow.com/questions/11654149/opengl-es-2-0-shader-2d-radial-gradient-in-polygon