Three.js: r112の新しいMeshStandardMaterialには、一部のGPUにバンディングアーティファクトがあります

作成日 2019年12月30日  ·  18コメント  ·  ソース: mrdoob/three.js

r112の時点で、デフォルトのMeshStandardMaterial(この場合は特にglTFファイルのロード時に使用されますが、おそらく他のシナリオでも使用されます)は、一部のGPUでバンディングアーティファクトを示しています。 具体的には、Pixelbookとすべての世代のPixelスマートフォンでこの問題が発生しています。 この問題は、私が試したNvidiaデスクトップGPUでも、OculusGoやOculusQuestでも発生しません。

また、マテリアルの新しいシェーダーが、レンダリングアーティファクトを示さないものも含め、さまざまなモバイルデバイスでの特定のアプリケーションで、r111と比較して顕著なパフォーマンスの低下を被ったことにも注意してください。

アーティファクトは次のようになります(PixelbookでThree.js r112を使用してレンダリング)

Screenshot 2019-12-29 at 9 15 19 PM

期待される出力は次のようになります(同じPixelbookでThree.js r111を使用してレンダリング)

Screenshot 2019-12-29 at 9 24 31 PM

現在r112を使用しているライブリンク: https ://xrdinosaurs.com

そのページのすべての恐竜が問題を示していますが、フラットまたは滑らかな色の大きな領域を持つ恐竜(TRexの腹のような)はより目立つ傾向があります。

スクリーンショットのマテリアル(以下に完全に貼り付けられています)は、glTF拡張機能「KHR_materials_pbrSpecularGlossiness」を使用しており、拡散、法線、および鏡面/光沢のテクスチャがあります。

    {
      "doubleSided": true,
      "emissiveFactor": [
        0,
        0,
        0
      ],
      "extensions": {
        "KHR_materials_pbrSpecularGlossiness": {
          "diffuseFactor": [
            0.46512957319999998,
            0.46512957319999998,
            0.46512957319999998,
            1
          ],
          "diffuseTexture": {
            "index": 4,
            "texCoord": 0
          },
          "glossinessFactor": 0.27610518290000002,
          "specularFactor": [
            0.92244664629999995,
            0.92244664629999995,
            0.92244664629999995
          ],
          "specularGlossinessTexture": {
            "index": 6,
            "texCoord": 0
          }
        }
      },
      "name": "TRex",
      "normalTexture": {
        "index": 5,
        "scale": 1,
        "texCoord": 0
      }
    }
Bug Device Issue

最も参考になるコメント

@elalish複数の例でいくつかのテストを実行した後、これらのアーティファクトの実際の原因を特定することができました。 以前の投稿で述べたこととは異なり、問題の根本的な原因は、誤った座標サンプリングとは関係ありませんが、 PMREMGeneratordevicePixelRatio処理する方法と関係があります。

名目上の浮動小数点pixelRatioを持つデバイスでは、生成されたテクスチャで「悪い」ミップマップ座標を取得しています。 そのため、小さなギャップと重複する領域があります。 また、例をローカル(0.899 ..)で表示するかオンライン(1)で表示するかによって、マシンのdevicePixelRatios異なることもわかりました。そのため、これらのアーティファクトはローカルでしか発生しませんでした。

setPixelRatioを無効にして簡単なテストを設定しましたが、問題は解決したようです。他の人がそうであれば、 PMREMGeneratorが処理する方法をリファクタリングするのが最善です。

@toji @ plut0nistこれらのアーティファクトを提示したデバイスで次の例をチェックすることを気にしますか?

DEVの例
テスト例

全てのコメント18件

Pixel(1)でグリッチを確認できます。 ただし、アーティファクトはKHR_materials_pbrSpecularGlossinessが使用されている場合にのみ発生するようです。

18042は、幾何学的アンチエイリアシングを導入しました。 ただし、 GLTFLoaderは、 lights_physical_fragmentシェーダーチャンクのコードを次のように置き換えます。

https://github.com/mrdoob/three.js/blob/3ba0553208cfc9113152f5f39b4036a448cf3f25/examples/js/loaders/GLTFLoader.js#L683 -L688

@toji上記のコードを次のように置き換えて、アプリのGLTFLoaderコピーを変更してください。

var lightPhysicalFragmentChunk = [
    'PhysicalMaterial material;',
    'material.diffuseColor = diffuseColor.rgb;',
    'vec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );',
    'float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );',

    'material.specularRoughness = max( 1.0 - glossinessFactor, 0.0525 );// 0.0525 corresponds to the base mip of a 256 cubemap.',
    'material.specularRoughness += geometryRoughness;',
    'material.specularRoughness = min( material.specularRoughness, 1.0 );',
    'material.specularColor = specularFactor.rgb;',
].join( '\n' );

@elalishこのパッチで問題が解決しない場合でも、いずれにせよ、これをGLTFLoaderに追加する必要があります。

@ Mugen87はい、確かに。 Pixel3でも再現できるかどうかを確認します。

@toji Pixel3すべてのPixelではありません...

ドライバーのバグ? しかし、どの行がそれをトリガーしているのかわかりません。 幾何学的なアンチエイリアシングの有無は、とにかくそのタイプのアーティファクトにはなりません、私はかなり確信しています。

@toji私はまた、専用のくだらないテスター電話(Targetから約30ドルのアルカテル)を試しました。 空が黒いことに気づきましたが、バンディングのアーティファクトは得られません。 パフォーマンスに関しては、それは正確にはバターではありませんが、悪くはありません。 正直なところ、その3Dビューは、この電話の2DキーボードUIよりも応答性が高くなっています。 図に行きます。

うーん、黒い空は実際にはPMREMの生成が完全に失敗したことを意味します。これは、httpsです。 これをr112に入れるつもりだったのですが、すり抜けてしまいました。 ただし、OPのバグとは無関係の可能性があります。

ChromeとFirefoxの両方のOnePlus5TでOPのエラーを再現しました。

ありがとう! パッチをGLTFLoaderし、バンディングアーティファクトが減少したが、除去されなかったことを確認しました。

パッチ前:

Screenshot 2019-12-30 at 12 11 36 PM

パッチ後:

Screenshot 2019-12-30 at 12 10 35 PM

基本的に、バンドの1つを修正したように見えます。 :)(Pixelbookで撮影されたスクリーンショットですが、Pixel 4 XLでも観察されています。現時点では他のテストデバイスはありません。)

テストしたい他の変更にパッチを当ててください。ローカルでテストしたい場合は、 ください。 (サーバーコンポーネントは必要ありません。)

パフォーマンスに関しては、それは正確にはバターではありませんが、悪くはありません。

ありがとうございました。 😁パフォーマンスに一生懸命取り組んでいます。 この場合、r112への更新中に、パフォーマンスの低下に気づき、@ mrdoobにそれについて尋ねました。 彼は、それが新しい、より正確な標準シェーダーである可能性があることを示唆し、検証のためにいくつかのマテリアルをMeshLambertMaterialと交換することを提案しました。 環境モデルはとにかく適切に構成されたPBRマテリアルを持っていなかったので、ランバートに強制してそのままにしました。これにより、パフォーマンスの回帰が返され、その後いくつかが返されました(ビューポートの大部分を占めるため)。それらは「ヒーロー」資産であるため、標準的な素材です。

補足:レンダラーがMeshStandardMaterialチェックするため、 GLTFLoaderが鏡面反射/光沢マテリアルを使用してメッシュをロードする場合、 Scene.environmentは現在機能しません。

https://github.com/mrdoob/three.js/blob/dd81aad5513d66e35e51f3a3b42555bc8aef5cbc/src/renderers/WebGLRenderer.js#L1633

ただし、 GLTFLoaderは、鏡面反射/光沢マテリアルごとにShaderMaterialを作成します。 T-Rexモデルでテストするときにこれを今日実現しました^^。 さて、最終的に#14099を完了するもう1つの理由。

環境マップを使用しないと、バンディングアーティファクトを再現できません。 アンビエントライトやポイントライトのようなシンプルな照明設定を備えたPixel(1)では、すべてが見栄えがします。

ええと、環境マップを使用した物理的なマテリアルにはもっと問題があるようです。 次の例がPixel1、Android10でどのように表示されるかを確認してください。

https://threejs.org/examples/webgl_materials_envmaps_exr

Screenshot_20200106-111923

https://threejs.org/examples/webgl_materials_physical_clearcoat

Screenshot_20200106-111856

https://threejs.org/examples/webgl_materials_envmaps_hdr

Screenshot_20200106-111809

これらのアーティファクトをiMacで再現できません。

私のマシンでかなり奇妙なことが起こっています。新しいPMREMGeneratorを利用するすべての例でこれらのアーティファクトを再現することができます。 ただし、ローカルで実行する場合のみ。 それらをオンラインで(threejs.orgページから)表示すると、すべて正しく表示されます。

私はそのような問題を経験したことがなく、何が原因であるかについて完全に迷っています。

私はGeForceGTX 750TIを搭載したWindows10を実行しているので、これはデバイス固有の問題ではないと思います。

ただし、ローカルで実行する場合のみ。 それらをオンラインで(threejs.orgページから)表示すると、すべて正しく表示されます。

devバージョンには、 prodまだ存在しない変更があることに注意してください。 現在のmasterブランチをチェックアウトしてから、ローカルテストを実行してください。

現在のマスターブランチをチェックアウトしてから、ローカルテストを実行してください。

この動作に気付いた後、最初に試したのは同じ結果です。 本当に好奇心が強い。

インコグニートウィンドウでテストしていただけますか? 時々、ものがキャッシュされたり、ブラウザの拡張機能が干渉したりして、本当に混乱する可能性があります

インコグニートで試してみましたが、同じ結果です:(

このバンディングがなぜ起こっているのか私は知っていると思います。
mipの生成中に、ローカル(誤った)バージョンがライブバージョンには存在しないブラックバンドを作成しています。

local
online

これは、より低いミップレベルにも複製されます。

これは、座標サンプリングが正しくないことが原因で発生している可能性があります。異方性フィルタリングを手動で無効にして実験しましたが、問題は解決していません。 何が起こっているのかを正確に特定するのは困難です。特に、同じマシンで2つの異なる動作が発生する理由に頭を悩ませることができないためです。

@elalish複数の例でいくつかのテストを実行した後、これらのアーティファクトの実際の原因を特定することができました。 以前の投稿で述べたこととは異なり、問題の根本的な原因は、誤った座標サンプリングとは関係ありませんが、 PMREMGeneratordevicePixelRatio処理する方法と関係があります。

名目上の浮動小数点pixelRatioを持つデバイスでは、生成されたテクスチャで「悪い」ミップマップ座標を取得しています。 そのため、小さなギャップと重複する領域があります。 また、例をローカル(0.899 ..)で表示するかオンライン(1)で表示するかによって、マシンのdevicePixelRatios異なることもわかりました。そのため、これらのアーティファクトはローカルでしか発生しませんでした。

setPixelRatioを無効にして簡単なテストを設定しましたが、問題は解決したようです。他の人がそうであれば、 PMREMGeneratorが処理する方法をリファクタリングするのが最善です。

@toji @ plut0nistこれらのアーティファクトを提示したデバイスで次の例をチェックすることを気にしますか?

DEVの例
テスト例

@sciecode根本原因を

@sciecode :デバイスで確認済み。 DEVサンプルテストでは、環境マップに非常に明白な黒い線が表示されますが、テストサンプルでは表示されません。 素晴らしいデバッグ、ありがとう!

なぜPMREMGeneratordevicePixelRatioを占める必要があるのか​​非常に興味があったので、掘り下げました。 renderer.setViewport()がDPRを送信する値に自動的に因数分解するためであることが判明しました。これは、デフォルトのフレームバッファー以外のレンダーターゲットでは明らかに間違った動作であるように感じます。これは、正確なピクセル値が割り当てられていないためです。ピクセル比をまったく考慮しません。 ここでの「正しい」動作は、内部的にrendere.setViewport()getTargetPixelRatio()を使用する必要があることです。これは、アクティブなレンダーターゲットがデフォルト以外の場合に1を返します。 しかし、それがどのように後方互換性の問題を引き起こす可能性があるかは確かにわかります。

このページは役に立ちましたか?
0 / 5 - 0 評価