i am writing a small shader that generates a conical gradient in Three.js. It all works well I have eliminated banding by adding a little bit noise, so in gerneral the gradient looks nice. I only have the problem that on the edge of the 2 gradientcolors i get ugly Aliasing. See image
I then tried to smooth the edges im my fragment shader, which works well but not on the very inside of the gradient.
I know I can get away with rendering the scene in a higher res and scale it down or to apply a posteffect but I am wondering if there is a for a nicer approach.
In general I am not an expert in shader writing or three.js, so maybe you have some input to fix this problem in an elegant way.
Thanks for your help, here is a fiddle and the fragement shader code.
<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>
First, you need a more accurate way to compute your antialiasing. An equation which support any value of lerpLimit
(your magic value 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
// ....
Now you can modulate the lerpLimit
based on the distance pixel/center, in order to have antialias gradient of constant thickness
//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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.