如何使用着色器制作平滑区域

时间:2015-06-23 13:52:37

标签: opengl shader

我想用着色器对着色器进行编码,但是看起来不好,它的边缘不平滑,这里是代码:

vert file:

varying vec3 normal;
void main()
{
    gl_TexCoord[0] = gl_MultiTexCoord0; 
    normal = gl_NormalMatrix*gl_Normal;
    gl_Position = ftransform();
} 

frag file:

varying vec3 normal;
uniform sampler2D tex;
uniform sampler2D tex1;
void main()
{

    vec4 clr = texture2D(tex, gl_TexCoord[0].st);

    float s = gl_TexCoord[0].s - 0.5;

    float t = gl_TexCoord[0].t - 0.5;

    if ( s<0.0 )
        s = 0.0 - s;
    if ( t < 0.0 )
        t = 0.0 -t;
    if ( s*s + t*t >0.5*0.5 )
        clr = vec4(0.0, 0.0, 0.0, 0.0);     
    gl_FragColor = clr; 
}

Image

1 个答案:

答案 0 :(得分:0)

您应该在中间区域混合两种颜色,在两个区域之间进行小的混合。

varying vec3 normal;
uniform sampler2D tex;
uniform sampler2D tex1;
void main()
{

    vec4 insideColor = texture2D(tex, gl_TexCoord[0].st);
    vec4 outsideColor = vec4(0.0, 0.0, 0.0, 0.0);

    float s = gl_TexCoord[0].s - 0.5;

    float t = gl_TexCoord[0].t - 0.5;

    if ( s<0.0 )
        s = 0.0 - s;
    if ( t < 0.0 )
        t = 0.0 -t;

    const float radius = 0.5;

    // scale represents the pixel width of the image.
    // I used an arbitrary value of 128px but you should set this to
    // the actual width.
    // The smaller this value, the larger the blending zone will be.
    const float scale = 128;

    float mixFactor = clamp(scale * (s*s + t*t - radius*radius), 0, 1);
    gl_FragColor = mix(insideColor, outsideColor, mixFactor);
}

另外,在编写着色器时请尽量不要使用分支语句,并使用向量微积分而不是多个浮点运算。此着色器的更高效(但仍可以改进)版本将是:

varying vec3 normal;
uniform sampler2D tex;
uniform sampler2D tex1;
void main()
{

    vec4 insideColor = texture2D(tex, gl_TexCoord[0].st);
    vec4 outsideColor = vec4(0.0, 0.0, 0.0, 0.0);

    vec2 coord = gl_TexCoord[0].st - vec2(0.5, 0.5);
    coord = abs(coord);

    const float radius = 0.5;

    // scale represents the pixel width of the image.
    // I used an arbitrary value of 128px but you should set this to
    // the actual width.
    // The smaller this value, the larger the blending zone will be.
    const float scale = 128;

    float mixFactor = clamp(scale * (length(coord) - radius), 0, 1);
    gl_FragColor = mix(insideColor, outsideColor, mixFactor);
}