【问题标题】:OpenGL ES 2.0 Shader - 2D Radial Gradient in PolygonOpenGL ES 2.0 着色器 - 多边形中的 2D 径向渐变
【发布时间】:2012-07-25 16:15:30
【问题描述】:

我正在尝试在多边形内绘制径向渐变。我的舞台是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);
}                                       

使用圆形多边形会导致:

【问题讨论】:

    标签: opengl-es glsl fragment-shader


    【解决方案1】:

    好的,我找到了解决方案,现在它的工作原理很明显。我使用相对值而不是绝对值,这导致了拉伸。着色器现在看起来像这样:

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

    【讨论】:

      【解决方案2】:

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

      我在 KickJS GLSL 编辑器中创建了一个着色器示例,您可以看到它运行良好:

      http://goo.gl/viDKB

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

      【讨论】:

      • 问题是如果舞台是二次方的,它会按预期工作。如果舞台是矩形的,渐变也会被拉伸,这在光源下不会发生。如果我全屏显示,也在 KickJS GLSL 编辑器中。
      • 在您的 KickJS 示例中,圆圈边缘有一些奇怪的闪烁。
      【解决方案3】:

      您将半径作为浮点数传递,因此 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 是属性位置(不是灯光位置)* 矩阵通过前一个着色器的变量传递。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多