Three.js 片段着色器三js中的抗锯齿

Three.js 片段着色器三js中的抗锯齿,three.js,webgl,shader,fragment-shader,Three.js,Webgl,Shader,Fragment Shader,我正在编写一个小着色器,它在Three.js中生成一个锥形渐变。 这一切都很好,我已经消除了带状通过添加一点噪音,所以在一般情况下梯度看起来不错。我唯一的问题是,在2种渐变颜色的边缘,我得到了丑陋的锯齿。见图片 然后,我尝试在我的片段着色器中平滑边缘,这很好,但在渐变的内部效果不佳 我知道我可以用更高的分辨率渲染场景,并将其缩小或应用后期效果,但我想知道是否有更好的方法 总的来说,我不是着色器编写或three.js方面的专家,所以也许您有一些意见可以优雅地解决这个问题 感谢您的帮助,这里是一

我正在编写一个小着色器,它在Three.js中生成一个锥形渐变。 这一切都很好,我已经消除了带状通过添加一点噪音,所以在一般情况下梯度看起来不错。我唯一的问题是,在2种渐变颜色的边缘,我得到了丑陋的锯齿。见图片

然后,我尝试在我的片段着色器中平滑边缘,这很好,但在渐变的内部效果不佳

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

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

感谢您的帮助,这里是一个小提琴和fragement着色器代码


均匀vec4色1;
均匀vec4色2;
二维纹理均匀;
可变vec3 vUv;
void main(){
高精度浮点;
//获取纹理坐标的角度
浮动角度DEG=atan(vUv.y-0.5,vUv.x-0.5)*180.0/3.147;
如果(角度度<0.0){
角度度=角度度+360.0;
}
//生成梯度
浮动lerpValue=角度度/360.0;
vec4颜色=混合(颜色1、颜色2、lerpValue);
//我平滑边缘的方法在外部效果很好,但是
//不在里面
如果(lerpValue>0.9995){
浮动smoot=1.0-lerpValue;
smoot=smoot*2000.00;
vec4 lerpColor=混合(颜色1,颜色2,0.9995);
颜色=混合(颜色1、lerpColor、smoot);
}
///用梯度完成
//从“噪波”纹理应用噪波以消除带状
vec2 textureCoord=vUv.xy;
vec4噪声=纹理2d(纹理,textureCoord.xy);
color.xyz+=混合(-0.05,0.05,noise.x);
gl_FragColor=颜色;
}

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

//生成渐变
浮动lerpValue=角度度/360.0;
浮点数lerpLimit=0.9995;
float invDiff=lerpLimit/(1.0-lerpLimit);
if(lerpValue>lerpLimit){
lerpValue=invDiff-lerpValue*invDiff;
}
vec4颜色=混合(颜色1、颜色2、lerpValue);
//我平滑边缘的方法在外部效果很好,但是
//不在里面
// ....
现在,您可以根据距离像素/中心调整
lerpLimit
,以获得恒定厚度的抗锯齿渐变

//生成渐变
浮动lerpValue=角度度/360.0;
//抗锯齿梯度的恒定厚度
//沿着接缝
浮动限制=.02;
浮点数lerpLimit=1.0-极限/(6.283185*长度(vUv.xy-0.5));
//避免在中心设置负极限
lerpLimit=最大值(lerpLimit,0.0);
float invDiff=lerpLimit/(1.0-lerpLimit);
if(lerpValue>lerpLimit){
lerpValue=invDiff-lerpValue*invDiff;
}
vec4颜色=混合(颜色1、颜色2、lerpValue);
//我平滑边缘的方法在外部效果很好,但是

Cleaned up fiddle:嘿,请大家注意,这是一个非常好的解决方案。我一直在努力使用长度,但始终没有得到正确的结果。谢谢你的解决方案和很好的解释!
<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>