概要

React Three Fiber を使用して GLTF モデルを表示した際、テクスチャがぼやけて見える、または荒く表示される問題に遭遇しました。本記事では、その原因と解決策を解説します。

症状

  • GLTF モデルのテクスチャがぼやけて表示される
  • 他の 3D ビューアでは正常に表示される同じモデルが、自作のビューアでは荒く見える
  • dpr(デバイスピクセル比)や antialias を設定しても改善しない

原因

Three.js r152 以降、デフォルトの出力カラースペースが変更されました。

GLTF モデルのテクスチャは通常 sRGB 色空間 で保存されています。しかし、Three.js のデフォルト設定では出力が Linear 色空間 になっているため、以下の問題が発生します:

  1. テクスチャの補間処理が Linear 空間で行われる
  2. ミップマップの生成が正しい色空間で行われない
  3. 結果として、テクスチャがぼやけたり、色がおかしくなる

解決策

Canvas の onCreated コールバックで outputColorSpace を設定します。

Before(問題のあるコード)

i<mC/pacdg<ConaplSarvmr=cntae={evsr{{na{a[es=1a>C{,na{tn2ivp]aao}lssiia}tsi:fornto:rmu[e'5@,}r}e5a,ct5-]t,hrfeoev/:fi5b0er}'};

After(修正後のコード)

ii<mmC/ppacdg}o}<Coonapl}n}Sarrvmr=appttCgcnttae={nrooorlevsr{{tewnne.na{aMiseeeaoes=aaerMMtu>Ca{tlrPaaetas{hivrppdpn.aeepp=uvTpmsDfii{taHoi:renn(CsRsnargg{oEi(twe:El}EtwrinxgoiiuncTplrffonegeHoSrrnd,B:Rs}poo:ouEu)ammwf'Erc[.fh.e=e''5deiA:>@t,ergC=rhv:hE1{er5i-S,Tae,ctpFHceereiRt'5PurlE-;]iefmEt,x,oi.hercSrflmTReoRaoGevannB/:tceCfieMoi5o'alb0,,poeprr}2iS'})np;}ga,ce;

各設定の説明

outputColorSpace: THREE.SRGBColorSpace

最も重要な設定 。出力カラースペースを sRGB に設定することで、テクスチャが正しく表示されます。

toneMapping: THREE.ACESFilmicToneMapping

HDR(High Dynamic Range)から SDR(Standard Dynamic Range)への変換方式を指定します。ACES Filmic は映画業界で使われるトーンマッピングで、自然な見た目になります。

toneMappingExposure: 1

トーンマッピングの露出値。1 がデフォルトで、値を上げると明るく、下げると暗くなります。

preserveDrawingBuffer: true

Canvas の内容を保持します。スクリーンショットを撮る場合などに必要です。

powerPreference: 'high-performance'

GPU の電力設定。‘high-performance’ を指定すると、可能な場合は高性能な GPU を使用します。

補足:Raycast を使った法線取得

3D アノテーションのカメラ制御で、アノテーション位置からモデル表面の法線を取得する方法も実装しました。

f)}u:npsccs}c]lf}i}rcocTooc)o;eofetseHnnei};nnnnnnntrrci}cci}tiinRssnf6seeeeeeaof(oofuoteEttemtwwwwwwc(ynci}cnncrni:E.(elccs(oflss(lno.rmtcsdTTTTTTooatinccncottcofnTVaerhhiHHHHHHsnsns(ooolslsci:HeysaierRRRRRRestitt!nnroemooelnRcchvlseEEEEEEstenecssmssoussodTEtaeed.cEEEEEEtrtrhlttaetdtetsSHEossrpt......Hd.esiolsHewsHeuR.rt:siuiVVVVVViisretsnn.tilatisrES3eensoeeeeeetresceooaHtCrHttfEcrT(shncccccctet=srrpi)edi.Ha.e|H(t(stttttt=o(cstmmptnDtnicVn=Rcacoooooofpt.iHaal{ti.oteeenEhnh=rrrrrrnoslnilly=ernr?NcunEici333333udsettMMrom.otle.lel[((((((lii=ne=aa{調=ranrolwMdod001-00lrtgrtt=mlomre)f),,,1,,;eirtshrrdpa.ra3{Ts;,coaheiiiigolnml,Hh=T0001-tnychtxxses.ea(R[>H,,,0,1i,c>ti.3ttidglE]R,,oastf=(aMtoaE{E1-00nds0[.annoitt.=E)1)0)0sit0dcnocdo(eR.,),),))re&]ieereeno(a[M,,,)r&;s.wm:l.u)ny]e{;.tnaCct;uc;siiaoTlhelwlahnnnrHMinoals)ttcmRattnr;teeeaEt.eede{rrlErdr(Drss<..ii()i(eecMxss.r)cccla)tcs);ttlot.aeuOsonrnnnb<b[seioce(j0e(xre)m0e]s)3m,;o)c.t;(adtfH)lne{sai.iol(ctgzrCme.eemee)dt(ansiN)lth{so;eetr}rsam;),na.clnteMor)arutme{ra)il;xi(zhei(t).;object.matrixWorld);

まとめ

Three.js + React Three Fiber で GLTF モデルを表示する際は、outputColorSpaceTHREE.SRGBColorSpace に設定することを忘れずに。これだけで、テクスチャの品質が大幅に改善されます。

環境

  • Three.js: r152+
  • React Three Fiber: 8.x
  • @react-three/drei: 9.x
  • Next.js: 16.x

参考リンク