vrm-c / UniVRM

UniVRM is a gltf-based VRM format implementation for Unity. English is here https://vrm.dev/en/ . 日本語 はこちら https://vrm.dev/
https://vrm.dev/en
MIT License
2.62k stars 423 forks source link

タンジェントがプリプロセッサで自動的生成されている #55

Closed m-sigepon closed 4 years ago

m-sigepon commented 6 years ago

前回立てたIssuesの検証結果です。 UniVRMというよりUniGLTF側の問題かもしれませんが、前回の報告の結果も含めてこちらの方にIssueを立てておきます。

現状、タンジェントが自動生成されてしまっており(RecalculateTangentsが実行されているよう?)VRoid上で出力されているタンジェントと自動生成されたタンジェントで結果がことなってしまうため#46の問題が起きているようでした。 (GLTF_EXPORT_TANGENTS、UNIGLTF_IMPORT_TANGENTS)はデフォルトではオフになっているようですが、これがデフォルトで有効になるように変更していただけないでしょうか。 Unity、UE4向けにノーマルマップの出力をこれまで行ってきましたが、タンジェントが自動生成になっていると正しく読み込めないケースがあり基本的にはMayaのFBXエクスポート時にタンジェントをエクスポートする設定、エンジン側で読み込むという形をとっております。 そのため、UniVRMでもタンジェントは自動生成ではなくオブジェクトが持っているタンジェントを読み込んでいただけるとこのような問題が起きるのを防げます。

そのまま読み込むインポート設定ですと、出力時にエクスポート設定を行えばいいだけですがランタイム読み込み側で自動生成になっているとデータ作成側は対応不能になります。

ご検討よろしくお願いします。

iCyP commented 6 years ago

部外者が不躾で申し訳ないですが、特別なTangentSpaceを要求するノーマルマップの生成方法を、標準的な(Mikk)TangentSpaceを用いてノーマルマップを生成する方法へ変更するべきだと私は思います。失礼しました。

m-sigepon commented 6 years ago

https://www.youtube.com/watch?v=gR3r7Xmhmlk MikkTSpaceのTangentSpaceによるノーマル生成する方法ですが、UE4のDirectX向けノーマルマップを生成する場合ですと仰る通り、UE4ではインポート時に自動計算させるという手法が正しいとなってます。 normalmap

Unityで読み込むOpenGL向けのノーマルマップをベイクする場合は、SubstancePainterではFBXエクスポート時にタンジェントをエクスポートし、SubstancePainter側ではタンジェントの自動計算を行わないで読み込む設定と解説されており、モデルのタンジェントをインポートして整合性が取れるノーマルをベイクする形となっております。 gl opengl2

また、UE4ではDirectX向け設定ではTangentを自動計算で問題ないとされていましたが実際に、あったケースで自動計算で正しくノーマルが表現されず、最終的にUnity向けと同じようにFBXエクスポート時にタンジェントもエクスポートし、インポートすることで正しい結果になるという状況がありました。

その為、それらの経験則からDirectX、GL向けともFBXエクスポート時は基本的に、ノーマルと接戦と重法線をエクスポートしインポート時にモデルと同じタンジェントをインポートするのが確実性が高いという結果になっております。

また、GLTLFの仕様には(GLTF_EXPORT_TANGENTS、UNIGLTF_IMPORT_TANGENTS)とタンジェントをエクスポート、インポートするところまでサポートされております。 そのためタンジェントの自動生成は、「タンジェント生成が必要な法線マップの生成をされていると明確に判断出来たうえで」実行されるべきだと思います。

そこで、VRMの拡張オプションとしてタンジェントの自動計算が必要かどうかのフラグを持てないでしょうか? このタンジェントの自動計算が必要かどうかは、VRMエクスポーター(エディター、ランタイム)のオプションとして持つことで出力時にそのオプションを指定できるようにし、VRMインポーター(エディター、ランタイム)で読み込み時に、タンジェントの自動計算が必要だとフラグが立っていればタンジェントを自動計算し タンジェントの自動計算フラグがオフになっているならば、オブジェクト自身のタンジェントをそのままインポートする。

これにより、ベイク環境による問題が解決するかと思われます。

m-sigepon commented 6 years ago

部外者が不躾で申し訳ないですが、特別なTangentSpaceを要求するノーマルマップの生成方法を、標準的な(Mikk)TangentSpaceを用いてノーマルマップを生成する方法へ変更するべきだと私は思います。失礼しました。

また何故これが必要かというと、ノーマルマップは必ずしもオブジェクトからベイクされたノーマルマップが使用されるとは限らないからです。 写真からノーマルマップを生成する系のツールで生成されたノーマルマップなども存在します。

iCyP commented 6 years ago

 私は、エディタ読み込みの場合、他形式->VRMの際にtangentがimportできるならする(もしくはユーザーに確認する)。書き出し時には、理想を言えばuniVRM側で(MikkTSに合わせた)bakeをしてノーマルマップを出力してくれる(VRM形式としてはtangentを持たない)というのが一番ありがたいと思います。  理由は簡単で、私が使うBlender(2.79)だと知る限りtangentはリードオンリーでMikkTS固定なので、custom tangent依存のノーマルマップを正しく表示できないためです。  VRMは中間フォーマットではないという時点からDCCツールでの表示不整合というのは弱い理由付けかもしれませんが、私からは以上です。

 補足?ですが、

m-sigepon commented 6 years ago

 理由は簡単で、私が使うBlender(2.79)だと知る限りtangentはリードオンリーでMikkTS固定なので、custom tangent依存のノーマルマップを正しく表示できないためです。

MikkTSのみしか扱えない環境があるとなると、理想的なのは仰る通り以下の処理だと思われます。

 書き出し時には、理想を言えばuniVRM側で(MikkTSに合わせた)bakeをしてノーマルマップを出力してくれる(VRM形式としてはtangentを持たない)というのが一番ありがたいと思います。

UniVRMのエクスポート時に、アーティストが用意したタンジェントとノーマルマップを上記のようにMikkTSベースのノーマルマップにベイク(変換)する処理が行われれば、UniVRMのエクスポート元のタンジェントとノーマルマップが適用された見た目が再現できるので、インポート時はMikkTSベースのタンジェントを自動計算する処理で問題無いと思います。 (見た目の再現が実現されることが目的のため)

iCyPさんが提案されている方法の実装を検討頂ければと思います。 ノーマルマップの正規化に相当する機能となると思います。

ousttrue commented 5 years ago

右手系GLTFと左手系Unity間でTangentの変換が必要なのかどうか等よくわかっておらず、MikkTSpaceであることを前提にRecalculateする実装となっております。

書き出し時には、理想を言えばuniVRM側で(MikkTSに合わせた)bakeをしてノーマルマップを出力してくれる(VRM形式としてはtangentを持たない)というのが一番ありがたいと思います。

技術的に難しいので今後の課題にしたいと思います。

hiroj commented 4 years ago

tangentに関しては、1.0と0.xともに保存しない方針になります。 https://github.com/vrm-c/vrm-specification/tree/master/specification/VRMC_vrm-1.0_draft#tangent 仕様に対して要望がある場合はvrm-specのほうにお願いいたします。