欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

three.js中物體的燈光與陰影設(shè)置

 更新時間:2023年07月26日 16:03:10   作者:jieyucx  
本文主要介紹了three.js中物體的燈光與陰影設(shè)置,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、.設(shè)置物體陰影的核心步驟

1. 以平面上有一個球體為例,設(shè)置球體的陰影投射到平面上

核心步驟如下:

要讓球體的陰影照射到平面上,需要使用陰影映射技術(shù)。具體步驟如下:

在渲染器中啟用陰影:

renderer.shadowMap.enabled = true;

創(chuàng)建一個平面和一個球體:

// 創(chuàng)建平面
var planeGeometry = new THREE.PlaneGeometry(5, 5);
var planeMaterial = new THREE.MeshStandardMaterial({ color: 0x888888 });
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -Math.PI / 2; // 將平面旋轉(zhuǎn)至水平方向
plane.receiveShadow = true; // 接收陰影
scene.add(plane);
// 創(chuàng)建球體
var sphereGeometry = new THREE.SphereGeometry(1, 32, 32);
var sphereMaterial = new THREE.MeshStandardMaterial({ color: 0xff0000 });
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.y = 1; // 將球體放置在平面上方
sphere.castShadow = true; // 投射陰影
scene.add(sphere);

創(chuàng)建一個聚光燈:

var light = new THREE.SpotLight(0xffffff, 1, 100, Math.PI / 4);
light.position.set(0, 5, 0);
light.target.position.set(0, 0, 0);
light.castShadow = true; // 投射陰影
light.shadow.bias = -0.002; // 減少陰影失真
light.shadow.mapSize.width = 1024;
light.shadow.mapSize.height = 1024;
scene.add(light);

設(shè)置球體和聚光燈的關(guān)系:

sphere.add(light); // 球體作為聚光燈的子元素

現(xiàn)在打開瀏覽器預(yù)覽,就可以看到球體的陰影照射到了平面上。如果想讓陰影更加自然,可以調(diào)整陰影相關(guān)的參數(shù),例如增大陰影貼圖的分辨率、調(diào)整聚光燈的角度、調(diào)整陰影偏差等。

2. 設(shè)置正方體和球體的燈光與陰影:

效果如圖:

核心步驟和案例一一樣,就不在贅述,這里給出完整代碼,如下:

import * as THREE from "three";
// 導(dǎo)入軌道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
// 目標(biāo):燈光與陰影
// 燈光陰影
// 1、材質(zhì)要滿足能夠?qū)庹沼蟹磻?yīng)
// 2、設(shè)置渲染器開啟陰影的計(jì)算 renderer.shadowMap.enabled = true;
// 3、設(shè)置光照投射陰影 directionalLight.castShadow = true;
// 4、設(shè)置物體投射陰影 sphere.castShadow = true;
// 5、設(shè)置物體接收陰影 plane.receiveShadow = true;
// 1、創(chuàng)建場景
const scene = new THREE.Scene();
// 2、創(chuàng)建相機(jī)
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
// 設(shè)置相機(jī)位置
camera.position.set(0, 0, 10);
scene.add(camera);
// 創(chuàng)建球體
const sphereGeometry = new THREE.SphereBufferGeometry(1, 20, 20); // 參數(shù):半徑、水平分段數(shù)、垂直分段數(shù)
const material = new THREE.MeshStandardMaterial(); // 創(chuàng)建標(biāo)準(zhǔn)材質(zhì)
const sphere = new THREE.Mesh(sphereGeometry, material); // 根據(jù)幾何體和材質(zhì)創(chuàng)建球體
sphere.position.set(1, 0, 0); // 設(shè)置球體位置
// 設(shè)置球體顏色
sphere.material.color = new THREE.Color(0x00ff00);
// 投射陰影
sphere.castShadow = true;
scene.add(sphere);
// 創(chuàng)建立方體
const cubeGeometry = new THREE.BoxBufferGeometry(1, 1, 1); // 參數(shù):長、寬、高
// 創(chuàng)建標(biāo)準(zhǔn)材質(zhì)
const materialcube = new THREE.MeshStandardMaterial();
const cube = new THREE.Mesh(cubeGeometry, materialcube); // 根據(jù)幾何體和材質(zhì)創(chuàng)建立方體
cube.position.set(-1, 0, 2); // 設(shè)置立方體位置
// 設(shè)置立方體顏色
cube.material.color = new THREE.Color(0xff0000);
// 投射陰影
cube.castShadow = true;
scene.add(cube);
// // 創(chuàng)建平面
const planeGeometry = new THREE.PlaneBufferGeometry(10, 10); // 參數(shù):寬度、高度
// 創(chuàng)建標(biāo)準(zhǔn)材質(zhì)
const materialplane = new THREE.MeshStandardMaterial();
const plane = new THREE.Mesh(planeGeometry, materialplane); // 根據(jù)幾何體和材質(zhì)創(chuàng)建平面
plane.position.set(0, -1, 0); // 設(shè)置平面位置
plane.rotation.x = -Math.PI / 2; // 設(shè)置平面旋轉(zhuǎn)
// 接收陰影
plane.receiveShadow = true;
scene.add(plane);
// 燈光
// 環(huán)境光
const light = new THREE.AmbientLight(0xffffff, 0.5); // soft white light
scene.add(light);
//直線光源
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5); // 參數(shù):光源顏色、光源強(qiáng)度
directionalLight.position.set(10, 10, 10); // 設(shè)置光源位置
directionalLight.castShadow = true; // 設(shè)置光照投射陰影
scene.add(directionalLight);
// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 設(shè)置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 開啟場景中的陰影貼圖
renderer.shadowMap.enabled = true;
// 將webgl渲染的canvas內(nèi)容添加到body
document.body.appendChild(renderer.domElement);
// 創(chuàng)建軌道控制器
const controls = new OrbitControls(camera, renderer.domElement);
// 設(shè)置控制器阻尼,讓控制器更有真實(shí)效果,必須在動畫循環(huán)里調(diào)用.update()。
controls.enableDamping = true;
function render() {
  controls.update();
  renderer.render(scene, camera);
  //   渲染下一幀的時候就會調(diào)用render函數(shù)
  requestAnimationFrame(render);
}
render();
// 監(jiān)聽畫面變化,更新渲染畫面
window.addEventListener("resize", () => {
  //   console.log("畫面變化了");
  // 更新攝像頭
  camera.aspect = window.innerWidth / window.innerHeight;
  //   更新攝像機(jī)的投影矩陣
  camera.updateProjectionMatrix();
  //   更新渲染器
  renderer.setSize(window.innerWidth, window.innerHeight);
  //   設(shè)置渲染器的像素比
  renderer.setPixelRatio(window.devicePixelRatio);
});

二、直行光源DirectionalLightShadow的陰影屬性和相機(jī)原理介紹

在three.js中,使用new THREE.DirectionalLight可以創(chuàng)建一個方向光源。這個光源可以通過設(shè)置陰影屬性來讓場景中的對象產(chǎn)生陰影。設(shè)置陰影屬性需要使用DirectionalLight類的shadow屬性,它是一個DirectionalLightShadow對象,可以設(shè)置以下屬性:

  • mapSize:陰影貼圖的大小??梢允褂肨HREE.Vector2或者數(shù)字類型的參數(shù)來設(shè)置。
  • bias:偏移量,用于保持陰影的正確性??梢允褂脭?shù)字類型的參數(shù)來設(shè)置。
  • camera:陰影相機(jī)。使用DirectionalLightShadow.camera屬性可以獲取到DirectionalLightShadow對應(yīng)的Camera對象,從而可以對相機(jī)進(jìn)行設(shè)置。

相機(jī)原理:在three.js中,相機(jī)是場景中的虛擬相機(jī),用于模擬真實(shí)世界中的相機(jī)。相機(jī)的工作原理類似于真實(shí)世界中的相機(jī),它可以控制場景的可見區(qū)域、切換視角、實(shí)現(xiàn)景深等效果。在場景中添加相機(jī)之后,可以通過設(shè)置相機(jī)的各個屬性來控制相機(jī)的位置、旋轉(zhuǎn)、縮放等,從而實(shí)現(xiàn)不同的視角和效果。

相機(jī)相關(guān)屬性設(shè)置:在three.js中,可以通過設(shè)置相機(jī)的各個屬性來控制相機(jī)的行為和效果。以下是一些常用的相機(jī)屬性:

  • position:相機(jī)的位置。
  • near:相機(jī)的近裁剪面距離。
  • far:相機(jī)的遠(yuǎn)裁剪面距離。
  • fov:相機(jī)的視角。

舉例說明:下面是一個用于產(chǎn)生陰影的DirectionalLight對象的創(chuàng)建和設(shè)置陰影屬性的代碼示例

核心代碼

const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(20, 30, -5);
directionalLight.castShadow = true;
directionalLight.shadow.mapSize.width = 1024; // 設(shè)置陰影貼圖的寬度
directionalLight.shadow.mapSize.height = 1024; // 設(shè)置陰影貼圖的高度
directionalLight.shadow.bias = -0.01; // 設(shè)置陰影的偏移量
directionalLight.shadow.camera.near = 1; // 設(shè)置陰影相機(jī)的近裁剪面距離
directionalLight.shadow.camera.far = 100; // 設(shè)置陰影相機(jī)的遠(yuǎn)裁剪面距離
directionalLight.shadow.camera.fov = 45; // 設(shè)置陰影相機(jī)的視角

完整示例效果如上圖所示,完整示例代碼如下:

import * as THREE from "three";
// 導(dǎo)入軌道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
// 導(dǎo)入dat.gui
import * as dat from "dat.gui";
const gui = new dat.GUI();
// 1、創(chuàng)建場景
const scene = new THREE.Scene();
// 2、創(chuàng)建相機(jī)
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
// 設(shè)置相機(jī)位置
camera.position.set(0, 0, 10);
scene.add(camera);
const sphereGeometry = new THREE.SphereBufferGeometry(1, 20, 20);
const material = new THREE.MeshStandardMaterial();
const sphere = new THREE.Mesh(sphereGeometry, material);
// 投射陰影
sphere.castShadow = true;
scene.add(sphere);
// // 創(chuàng)建平面
const planeGeometry = new THREE.PlaneBufferGeometry(10, 10);
const plane = new THREE.Mesh(planeGeometry, material);
plane.position.set(0, -1, 0);
plane.rotation.x = -Math.PI / 2;
// 接收陰影
plane.receiveShadow = true;
scene.add(plane);
// 燈光
// 環(huán)境光
const light = new THREE.AmbientLight(0xffffff, 0.5); // soft white light
scene.add(light);
//直線光源
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLight.position.set(5, 5, 5);
directionalLight.castShadow = true;
// 設(shè)置陰影貼圖模糊度
directionalLight.shadow.radius = 20;
// 設(shè)置陰影貼圖的分辨率
directionalLight.shadow.mapSize.set(4096, 4096);
// 設(shè)置平行光投射相機(jī)的屬性
directionalLight.shadow.camera.near = 0.5;
directionalLight.shadow.camera.far = 500;
directionalLight.shadow.camera.top = 5;
directionalLight.shadow.camera.bottom = -5;
directionalLight.shadow.camera.left = -5;
directionalLight.shadow.camera.right = 5;
scene.add(directionalLight);
gui
  .add(directionalLight.shadow.camera, "near")
  .min(0)
  .max(10)
  .step(0.1)
  .onChange(() => {
    directionalLight.shadow.camera.updateProjectionMatrix();
  });
// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 設(shè)置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 開啟場景中的陰影貼圖
renderer.shadowMap.enabled = true;
// 將webgl渲染的canvas內(nèi)容添加到body
document.body.appendChild(renderer.domElement);
// 創(chuàng)建軌道控制器
const controls = new OrbitControls(camera, renderer.domElement);
// 設(shè)置控制器阻尼,讓控制器更有真實(shí)效果,必須在動畫循環(huán)里調(diào)用.update()。
controls.enableDamping = true;
// 添加坐標(biāo)軸輔助器
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);
// 設(shè)置時鐘
const clock = new THREE.Clock();
function render() {
  controls.update();
  renderer.render(scene, camera);
  //   渲染下一幀的時候就會調(diào)用render函數(shù)
  requestAnimationFrame(render);
}
render();
// 監(jiān)聽畫面變化,更新渲染畫面
window.addEventListener("resize", () => {
  //   console.log("畫面變化了");
  // 更新攝像頭
  camera.aspect = window.innerWidth / window.innerHeight;
  //   更新攝像機(jī)的投影矩陣
  camera.updateProjectionMatrix();
  //   更新渲染器
  renderer.setSize(window.innerWidth, window.innerHeight);
  //   設(shè)置渲染器的像素比
  renderer.setPixelRatio(window.devicePixelRatio);
});

到此這篇關(guān)于three.js中物體的燈光與陰影設(shè)置的文章就介紹到這了,更多相關(guān)three.js 物體燈光與陰影內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論