[Three.js旅程講義ノート]23
19856 ワード
🙌🏻 この文章はThree.js Journeyの講義です.
23 Realistic Render
THREE.NoToneMapping (default) THREE.LinearToneMapping THREE.ReinhardToneMapping THREE.CineonToneMapping THREE.ACESFilmicToneMapping
Toneマッピングの露出を変更することもできます.
ジオメトリのエッジを拡大すると、階段のような画像を別名と呼びます.今ではモデルの詳細が多いので大丈夫ですが、ピクセルスケールが1の画面でエッジを表示するとaliasingが表示されます.ピクセルレンダリングが発生すると、そのピクセルのどのオブジェクトがレンダリングされるかがテストされます.通常、エッジが画面のピクセルの垂直線と水平線に完全に整列していないという問題が発生します.簡単な解決策は、レンダリングの解像度を向上させることです.もちろん、これは簡単な方法ですが、パフォーマンスの問題を引き起こす可能性があります.もう1つの解決策はマルチサンプリングです.レンダリングの解像度は向上しますが、グラフィックのエッジでのみレンダリングできます.次に、画素値を平均し、最終画素値を得る.Three.jsにも多重サンプリングを適用できます!
今やっと前回のレッスンで作ったハンバーガーを応用する時間になりました.
拡大すると表面が熱くなる問題が発生します!これは陰影ニキビと呼ばれています.
23 Realistic Render
前の授業でハンバーガーを3つ食べました.jsにインポートすると、色出力が少しおかしいことがわかります.時々私たちは真実のレンダリングを望んでいます.特に、実際に使用している製品をウェブサイトに表示したい場合や、3 D芸術家として、最高の結果で仕事を表示したい場合は、このようにします.このレッスンでは、レンダリング品質を改善する方法について説明します.
前回のレッスンで作成したハンバーグを使用できますが、様々なテクスチャに適したモデルリポジトリのFlight Helmetで実習します.まず、starter packに球があります.照明を設定します.まずtestSphereのマテリアルをMeshStandardMaterialに変更し、照明を確認します.new THREE.MeshStandardMaterial()
DirectionLightは1つしか使用しません.照明をより多く制御し、シャドウを生成するには、DirectionLightが重要です.const directionalLight = new THREE.DirectionalLight('#ffffff', 1)
directionalLight.position.set(0.25, 3, - 2.25)
scene.add(directionalLight)
Three.js光強度のDefault valueは現実をうまく反映していない.これは重要ではないと思いますが、現実と標準の値を反映できれば、より良い選択になります.より現実的な値を適用するには、webGLReaderの物理CorrectLightsプロパティをtrueに変更する必要があります.renderer.physicallyCorrectLights = true
Model
ライトが設定されているので今からモデルのロードを始めましょうまず、GLTFLADERをインスタンス化します.モデルは圧縮されていないのでDRACoLoaderは不要です.import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
const gltfLoader = new GLTFLoader();
gltfLoader.load("/models/FlightHelmet/glTF/FlightHelmet.gltf", (gltf) => {
gltf.scene.scale.set(10, 10, 10);
gltf.scene.position.set(0, -4, 0);
gltf.scene.rotation.y = Math.PI * 0.5;
scene.add(gltf.scene);
gui
.add(gltf.scene.rotation, "y")
.min(-Math.PI)
.max(Math.PI)
.step(0.001)
.name("rotation");
});
Environment map
弱いDirectionLightが1つしかないので、モデルを正確にチェックすることはできません.照明は環境マップで処理されます.私たちは材料の授業で環境地図を知った.環境地図は周囲を囲む写真のようだ.360度の写真かもしれないし、立方体の形をした6枚の写真かもしれない.環境図を使用して背景とモデルをマッピングします.
Load the environment map
/**
* Environment map
*/
const environmentMap = cubeTextureLoader.load([
'/textures/environmentMaps/0/px.jpg',
'/textures/environmentMaps/0/nx.jpg',
'/textures/environmentMaps/0/py.jpg',
'/textures/environmentMaps/0/ny.jpg',
'/textures/environmentMaps/0/pz.jpg',
'/textures/environmentMaps/0/nz.jpg'
])
Apply the environment map to the background
環境マップをシーンの背景に追加するには、まず巨大な立方体を作成し、中からも立方体の一面が見えるように設定する必要があります.それからテクスチャを適用すればいいです.scene.background = environmentMap
Apply the environment map to the model
リアルレンダリングのコアは、環境を介してモデルをマッピングすることです.EnvMapプロパティを使用して環境マッピングをMeshStandardMaterialに適用する方法を学習しました.問題は,我々のモデルが多くのメッシュから構成されていることである.継承クラス(メソッドやグループ、メッシュなど)を使用することができます.コールバックで処理するのではなく、updateAllMaterials関数を作成します.const updateAllMaterials = () => {
scene.traverse((child) => {
console.log(child);
});
};
子供はコンソールウィンドウで確認できます.実は私たちがやりたいのは子供たちをコンソールに撮るのではなく、環境地図を応用することです.環境地図を照明、カメラ、グループに適用するのは意味がありません.私たちはMeshに環境地図を適用したいだけです.const updateAllMaterials = () => {
scene.traverse((child) => {
if (
child instanceof THREE.Mesh &&
child.material instanceof THREE.MeshStandardMaterial
) {
child.material.envMap = environmentMap;
child.material.envMapIntensity = 5;
}
});
};
Apply the environment map as default
environment mapを適用するより簡単な方法があります.シーンの環境プロパティを使用できます.もちろん、この方法では、シーン内で各マテリアル環境マップの強度を直接変更することはできません.scene.environment = environmentMap
Renderer
色を操作する必要があります.これはWebGLReduserで作業できます.
Output encoding
outputEncoding
プロパティ制御出力レンダリングエンコード.renderer.outputEncoding = THREE.sRGBEncoding
もう一つの可能な価格はTHREE.GammaEncoding
です.ガンマ符号化は、人間の目の感度に応じて、明暗値の記憶方式を最適化することによって色を記憶する方式である.sRGBE符号化を使用することは、一般値2.2のデフォルトガンマ係数を使用してガンマEncodeを行うことに相当する.より多くのものを制御できるので、ガンマ符号化はもっとよく聞こえますが、物理的には理想的ではありません.輝度を管理するには、いくつかのより良い方法があります.
Textures encoding
気づいたかもしれませんが、今は環境地図の色が少しおかしいです.これで満足できますが、まず正しい色を保つ方法を知っておく必要があります.問題は、レンダラー出力符号化がTHREEであることです.sRGBEncodingまた、デフォルトではEnvironment map textureはTHREEです.LinearEncodingです私たちが見えるすべてのテクスチャはTHREEですsRGBEは符号化されています.そうしないと、すべてのもののテクスチャがTHREEになります.LinearEncodeを使用してエンコードされます.environmentMap.encoding = THREE.sRGBEncoding
Tone mapping
ToneマッピングはHDR値をLDR値に変換します.Tone mapping効果でよりリアルな結果が得られます.Toneマッピングを変更するには、WebGLReaderでToneマッピング属性を更新するだけです.可能な価格はいろいろあります.
new THREE.MeshStandardMaterial()
const directionalLight = new THREE.DirectionalLight('#ffffff', 1)
directionalLight.position.set(0.25, 3, - 2.25)
scene.add(directionalLight)
renderer.physicallyCorrectLights = true
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
const gltfLoader = new GLTFLoader();
gltfLoader.load("/models/FlightHelmet/glTF/FlightHelmet.gltf", (gltf) => {
gltf.scene.scale.set(10, 10, 10);
gltf.scene.position.set(0, -4, 0);
gltf.scene.rotation.y = Math.PI * 0.5;
scene.add(gltf.scene);
gui
.add(gltf.scene.rotation, "y")
.min(-Math.PI)
.max(Math.PI)
.step(0.001)
.name("rotation");
});
/**
* Environment map
*/
const environmentMap = cubeTextureLoader.load([
'/textures/environmentMaps/0/px.jpg',
'/textures/environmentMaps/0/nx.jpg',
'/textures/environmentMaps/0/py.jpg',
'/textures/environmentMaps/0/ny.jpg',
'/textures/environmentMaps/0/pz.jpg',
'/textures/environmentMaps/0/nz.jpg'
])
scene.background = environmentMap
const updateAllMaterials = () => {
scene.traverse((child) => {
console.log(child);
});
};
const updateAllMaterials = () => {
scene.traverse((child) => {
if (
child instanceof THREE.Mesh &&
child.material instanceof THREE.MeshStandardMaterial
) {
child.material.envMap = environmentMap;
child.material.envMapIntensity = 5;
}
});
};
scene.environment = environmentMap
renderer.outputEncoding = THREE.sRGBEncoding
environmentMap.encoding = THREE.sRGBEncoding
renderer.toneMapping = THREE.ACESFilmicToneMapping
Toneマッピングの露出を変更することもできます.
renderer.toneMappingExposure = 3
Antialiasing
ジオメトリのエッジを拡大すると、階段のような画像を別名と呼びます.今ではモデルの詳細が多いので大丈夫ですが、ピクセルスケールが1の画面でエッジを表示するとaliasingが表示されます.ピクセルレンダリングが発生すると、そのピクセルのどのオブジェクトがレンダリングされるかがテストされます.通常、エッジが画面のピクセルの垂直線と水平線に完全に整列していないという問題が発生します.簡単な解決策は、レンダリングの解像度を向上させることです.もちろん、これは簡単な方法ですが、パフォーマンスの問題を引き起こす可能性があります.もう1つの解決策はマルチサンプリングです.レンダリングの解像度は向上しますが、グラフィックのエッジでのみレンダリングできます.次に、画素値を平均し、最終画素値を得る.Three.jsにも多重サンプリングを適用できます!
const renderer = new THREE.WebGLRenderer({
canvas: canvas,
antialias: true
})
反転を使用すると、リソースが消費されます.理想的には、ピクセルスケールが2未満の画面でのみアクティブにします.Shadows
renderer.shadowMap.enabled = true
renderer.shadowMap.type = THREE.PCFSoftShadowMap
directionalLight.castShadow = true
directionalLight.shadow.camera.far = 15
directionalLight.shadow.mapSize.set(1024, 1024)
child.castShadow = true
child.receiveShadow = true
Final tweaks
Hamburger
今やっと前回のレッスンで作ったハンバーガーを応用する時間になりました.
gltfLoader.load(
'/models/hamburger.glb',
(gltf) =>
{
gltf.scene.scale.set(0.3, 0.3, 0.3)
gltf.scene.position.set(0, - 1, 0)
scene.add(gltf.scene)
updateAllMaterials()
}
)
拡大すると表面が熱くなる問題が発生します!これは陰影ニキビと呼ばれています.
directionalLight.shadow.normalBias = 0.05
Reference
この問題について([Three.js旅程講義ノート]23), 我々は、より多くの情報をここで見つけました https://velog.io/@9rganizedchaos/Three.js-journey-강의노트-23テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol