2017-05-03 15 views
1

Three.jsで円錐勾配を生成する小さなシェーダを作成しています。 それはすべてうまく動作します。少しノイズを加えることでバンディングを排除しました。私は2つのgradientcolorsの端に私は醜いエイリアシングを取得する問題があります。フラグメントシェーダでのアンチエイリアス3つのjs

aliasing problem

私は、縁が勾配の内側に非常にうまく動作しますが、ない私のフラグメントシェーダを、イム滑らかにするためにしようとした画像を参照してください。

better

私は高い解像度でシーンをレンダリングして逃げると、それを縮小またはposteffectを適用することができます知っているが、よりよいアプローチのためにそこにある場合、私は疑問に思って。

一般に私はシェイダーライティングや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> 
+0

を持つために、距離ピクセル/中央に基づいてlerpLimitを調節することができますフィディッシュをクリーンアップ:https://jsfiddle.net/vabz67L5/2/ – WestLangley

答えて

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 
    // .... 

今、あなたは一定の厚さのアンチエイリアス勾配

//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 
+0

ちょっとひどい、本当に素晴らしい解決策。長さを使って作業していましたが、決して正しい結果を得られませんでした。 ソリューションと素晴らしい説明をありがとう! –

関連する問題