【问题标题】:Antialiasing in Fragment Shader Three js片段着色器三js中的抗锯齿
【发布时间】:2017-10-01 10:35:32
【问题描述】:

我正在编写一个在 Three.js 中生成锥形渐变的小着色器。 一切都很好,我通过添加一点噪音消除了条带,所以总的来说渐变看起来不错。我只有一个问题,即在 2 个渐变色的边缘,我得到了丑陋的锯齿。看图

然后我尝试在我的片段着色器中平滑边缘,效果很好,但不是在渐变的最内侧。

我知道我可以以更高的分辨率渲染场景并将其缩小或应用后期效果,但我想知道是否有更好的方法。

总的来说,我不是着色器编写或 three.js 方面的专家,所以也许你有一些意见可以用一种优雅的方式解决这个问题。

感谢您的帮助,这是小提琴和片段着色器代码。

JS Fiddle sample

<script id="fragmentShader" type="x-shader/x-fragment">
        uniform vec4 colour1;
        uniform vec4 colour2;
        uniform sampler2D texture;
        varying vec3 vUv;

        void main() {
            precision highp float;

            //get Angle for textureCoordinate
            float angleDeg = atan(vUv.y - 0.5,vUv.x - 0.5) * 180.0 / 3.147;
            if (angleDeg < 0.0){
                angleDeg = angleDeg+360.0 ;
            }

            //Generate Gradient
            float lerpValue = angleDeg/360.0;
            vec4 colour = mix(colour1,colour2,lerpValue);

            //My approach to smooth the edge works well on the outside but
            //not on the inside
            if(lerpValue>0.9995){
                float smoot = 1.0-lerpValue;
                smoot = smoot*2000.00;
                vec4 lerpColor = mix(colour1,colour2,0.9995);
                colour = mix(colour1,lerpColor,smoot);

            }
            ///done with gradient 

            //apply noise from noise texture to eliminate banding
            vec2 textureCoord = vUv.xy;
            vec4 noise = texture2D(texture,textureCoord.xy);
            colour.xyz += mix(-0.05, 0.05, noise.x);
            gl_FragColor = colour;

        }
    </script>

【问题讨论】:

标签: three.js webgl shader fragment-shader


【解决方案1】:

首先,您需要一种更准确的方法来计算抗锯齿。支持lerpLimit 任意值的方程(你的魔法值 0.9995)

    //Generate Gradient
    float lerpValue = angleDeg/360.0;

    float lerpLimit = 0.9995;
    float invDiff = lerpLimit/(1.0-lerpLimit);

    if(lerpValue>lerpLimit){
      lerpValue = invDiff - lerpValue*invDiff;
    }

    vec4 colour = mix(colour1,colour2,lerpValue);

    //My approach to smooth the edge works well on the outside but
    //not on the inside
    // ....

现在您可以根据像素/中心的距离调制lerpLimit,以获得恒定厚度的抗锯齿渐变

    //Generate Gradient
    float lerpValue = angleDeg/360.0;

    // the constant thickness of the antialias gradient
    // along the seam
    float limit = .02;

    float lerpLimit = 1.0 - limit / (6.283185*length(vUv.xy - 0.5));

    // avoid negative limit at the center 
    lerpLimit = max( lerpLimit, 0.0 );

    float invDiff = lerpLimit/(1.0-lerpLimit);

    if(lerpValue>lerpLimit){
      lerpValue = invDiff - lerpValue*invDiff;
            }

    vec4 colour = mix(colour1,colour2,lerpValue);

    //My approach to smooth the edge works well on the outside but

【讨论】:

  • 嘿,pleup,非常好的解决方案。我正在努力使用长度,但我从来没有得到正确的结果。感谢您的解决方案和很好的解释!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-27
  • 2013-02-09
  • 1970-01-01
  • 2014-02-18
  • 1970-01-01
  • 2017-01-30
相关资源
最近更新 更多