Three.js は、ブラウザーで 3D グラフィックスを作成するための人気のある JavaScript ライブラリです。インタラクティブなビジュアライゼーションやゲームの作成によく使用されます。 3D グラフィックスに関する課題の 1 つは、雲や煙などの不透明でないオブジェクトをレンダリングすることです。これらのオブジェクトは光を通過させるため、より柔らかく、よりリアルな外観を作成できます。
この場合の目標は、地球の表現に「雰囲気」効果を追加することです。大気は地球を囲み光を散乱させる半透明のレイヤーとなり、よりリアルな外観を与えます。
この効果を実現するには、各ピクセルの色を計算するフラグメント シェーダーを作成します。大気中の位置と光源の方向に基づいて大気中での位置を特定します。フラグメント シェーダーは、「大気散乱」と呼ばれる手法を使用して、大気中の粒子によって光が散乱する様子をシミュレートします。
フラグメント シェーダー コードは次のとおりです:
#ifdef GL_FRAGMENT_PRECISION_HIGH precision highp float; #else precision mediump float; #endif uniform vec3 lightDirection; uniform sampler2D earthTexture; varying vec2 vUv; varying vec3 vNormal; void main() { // Compute the surface normal at this position vec3 normal = normalize(vNormal); // Compute the direction from this point to the light source vec3 lightDir = normalize(lightDirection); // Compute the amount of light that is scattered in this direction float scattering = dot(normal, lightDir); // Compute the color of the atmosphere at this position vec3 color = texture2D(earthTexture, vUv).rgb * scattering; // Output the color gl_FragColor = vec4(color, 1.0); }
このフラグメントシェーダーはいくつかの入力を受け取ります:
フラグメント シェーダーはまず、現在のピクセルでのサーフェス法線を計算します。次に、現在のピクセルから光源までの方向を計算します。これら 2 つの値は、ピクセルの方向に散乱する光の量を計算するために使用されます。
次に、フラグメント シェーダーは、地球テクスチャの色に次の値を乗算して、現在のピクセルにおける大気の色を計算します。飛散量。結果のカラーはフラグメント カラーとして出力されます。
このフラグメント シェーダーを使用するには、それを使用するマテリアルを作成する必要があります。以下は、大気散乱フラグメント シェーダを使用するマテリアルの例です:
const material = new THREE.ShaderMaterial({ fragmentShader: ` #ifdef GL_FRAGMENT_PRECISION_HIGH precision highp float; #else precision mediump float; #endif uniform vec3 lightDirection; uniform sampler2D earthTexture; varying vec2 vUv; varying vec3 vNormal; void main() { vec3 normal = normalize(vNormal); vec3 lightDir = normalize(lightDirection); float scattering = dot(normal, lightDir); vec3 color = texture2D(earthTexture, vUv).rgb * scattering; gl_FragColor = vec4(color, 1.0); } `, uniforms: { lightDirection: { value: new THREE.Vector3(0, 1, 0) }, earthTexture: { value: new THREE.TextureLoader().load('earth.jpg') } } });
このマテリアルは 2 つのユニフォームを取ります:
マテリアルは、lightDirection ユニフォームを使用して、各方向に散乱する光の量を計算します。 EarthTexture ユニフォームを使用して地球の表面を表現します。
このマテリアルを使用するには、メッシュを作成してマテリアルに割り当てる必要があります。メッシュを作成してマテリアルに割り当てる方法の例を次に示します。
const geometry = new THREE.SphereGeometry(10, 32, 32); const material = new THREE.ShaderMaterial({ fragmentShader: ` #ifdef GL_FRAGMENT_PRECISION_HIGH precision highp float; #else precision mediump float; #endif uniform vec3 lightDirection; uniform sampler2D earthTexture; varying vec2 vUv; varying vec3 vNormal; void main() { vec3 normal = normalize(vNormal); vec3 lightDir = normalize(lightDirection); float scattering = dot(normal, lightDir); vec3 color = texture2D(earthTexture, vUv).rgb * scattering; gl_FragColor = vec4(color, 1.0); } `, uniforms: { lightDirection: { value: new THREE.Vector3(0, 1, 0) }, earthTexture: { value: new THREE.TextureLoader().load('earth.jpg') } } }); const mesh = new THREE.Mesh(geometry, material);
このコードは、半径 10、セグメント 32、リング 32 個の球ジオメトリを作成します。次に、大気散乱フラグメント シェーダを使用するマテリアルを作成します。最後に、メッシュを作成し、マテリアルに割り当てます。
メッシュが作成されたら、シーンに追加できます。シーンにメッシュを追加する方法の例を次に示します。
#ifdef GL_FRAGMENT_PRECISION_HIGH precision highp float; #else precision mediump float; #endif uniform vec3 lightDirection; uniform sampler2D earthTexture; varying vec2 vUv; varying vec3 vNormal; void main() { // Compute the surface normal at this position vec3 normal = normalize(vNormal); // Compute the direction from this point to the light source vec3 lightDir = normalize(lightDirection); // Compute the amount of light that is scattered in this direction float scattering = dot(normal, lightDir); // Compute the color of the atmosphere at this position vec3 color = texture2D(earthTexture, vUv).rgb * scattering; // Output the color gl_FragColor = vec4(color, 1.0); }
このコードは、メッシュをシーンに追加します。メッシュは大気散乱フラグメント シェーダを使用してレンダリングされます。その結果、地球を取り囲む半透明の大気が生まれます。
以上がThree.js とカスタム フラグメント シェーダーを使用して、3D Earth モデルの周囲の現実的な雰囲気をシミュレートするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。