精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

基于web創建逼真的3D圖形 | CSS技巧

新聞 前端 開發
在成為一名web開發者之前,我從事于視覺設計行業,創造屢獲殊榮,電影和電視節目等高端3D效果,例如 Tron, The Thing, Resident Evil,和 Vikings ,為了能夠創造這些效果,我們需要使用高度復雜的動畫軟件。

在成為一名web開發者之前,我從事于視覺設計行業,創造屢獲殊榮,電影和電視節目等高端3D效果,例如 Tron, The Thing, Resident Evil,和 Vikings 。為了能夠創造這些效果,我們需要使用高度復雜的動畫軟件,例如 Maya , 3Ds Max 或者 Houdini ,包括使用數以百計的機器 渲染機器 來做長時間的離線渲染。正因為我工作以來一直使用這些工具,以至于我對現在的web技術感到很驚訝。我們可以創造和顯示高質量的3D內容在瀏覽器里面,實際上,就是使用webGL和Three.js。

這個項目例子 是使用這些技術創建的。在他們的網站里,你可以發現更多thress.js的項目。 

使用three.js的一些項目

這些由three.js構建的網站表明,3D可視化在商業,零售,娛樂和廣告領域擁有巨大的潛力。

WebGL是比較低級的JavaScript的API,它能夠通過使用GPU,來創造并將3D的內容顯示在瀏覽器里面。不幸地是,既然WebGL是比較低的API,意味著它更加困難被使用。你需要編寫上百行代碼來運行,即使是很簡單的任務。three.js,另一方面來說,是一個開放的JavaScript庫,抽象了WebGL的復雜性,同時允許你以更簡單的方式,創造實時的3D內容。

在本教程中,我將介紹基礎的three.js庫。在介紹一個新的程序庫時,先舉一個簡單的例子來更好地表達基本原理,但我想進一步說明這一點。同時,我還將建立一個場景,更加愉快和逼真。

我們就開始了一個簡單的平面和球面但最終它會看起來像這樣:

See the Pen learning-threejs-final by Engin Arslan ( @enginarslan ) on CodePen .

臨摹是計算機圖形學的頂峰,但是,在你的位置下,實現不一定是進程中必要的因素,而是從你的工具箱中進行智能部署。這里有一些技術,你將會在本教程中學到,它將幫助實現照片寫實。

  • 顏色,凹凸和粗糙度圖。

  • 物理材料

  • 陰影照明

逼真的3D圖像 by Ian Spriggs

您將在這里學習的基本3D原理和技術在任何其他3D內容創建環境中都是相關的,無論是混合機、Unity、瑪雅還是3ds max。

這將是一個漫長的教程。如果您是一個喜歡看視頻的人,或者您想了解更多的關于Three.js,您應該看看我對這個問題培訓的視頻。來自 Lynda.com .

要求

當使用three.js時,如果你在本地工作,它有助于通過本地服務器服務HTML文件,以便加載像外部三維幾何圖形、圖像等應用場景。如果你在尋找一個很容易建立的服務,你可以使用python來運行簡單的HTTP服務器。python在很多操作系統上都有安裝。

您不必擔心設置本地開發服務器來執行本教程。相反,您將依賴于數據URL來加載像圖片這樣的資源,以消除設置服務器的開銷。使用線上代碼編輯器像 CodePen ,你可以很輕松的運行你的Three.js代碼場景。

本教程假設對前端JavaScript以及對前端Web開發的知識有一些了解。如果您不習慣使用JavaScript,但希望輕松上手,您可能需要查看課程/書籍。 ["Coding for Visual Learners: Learning JavaScript with p5.js"( http://www.codingforvisuallearners.com/ ). (免責聲明:我是作者)

讓我們開始在Web上建立3D圖形!

入門

我已經準備了 prepared a Pen 你可以跟隨本教程進行操作。

您將使用的HTML代碼將是超級簡單的。它只需要有一個div元素來承載正在顯示3D圖形的畫布。它從CDN上加載Three.js庫(版本86)。

<div id="webgl"></div>
``<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/86/three.min.js">``</script>

為了您的方便,CodeOpen隱藏了HTML結構。如果您在其它在線編輯器或本地站點上構建此場景,那么您的HTML將需要類似于下面代碼的內容,其中 main.js 將是保存JavaScript代碼的文件。

<!DOCTYPE html>
<html>
<head>
    <title>Three.js</title>
    <style type="text/css">
        html, body {
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>
    <div id="webgl"></div>
    ``<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/86/three.min.js">``</script>
    ``<script src="./main.js">``</script>
</body>
</html>

請注意html中的簡單CSS聲明。這就是你在CodePen里的CSS標簽:

html, body {
  margin: 0;
  padding: 0;
  overflow: hidden;
}

這是為了確保沒有任何的margin和padding值,可以通過您的瀏覽器應用,不會出現滾動條,因此可以有圖形填充整個屏幕。這就是我們開始構建3D圖形需要的一切。

***部分 - Three.js 基本場景

當我們平常用three.js和3D來工作時,這里有幾個您需要掌握的對象。它們是 場景 , 相機 以及 渲染 。

首先,您需要創造一個場景。您可以把一個場景對象看作是您要處理的每一個3D對象的容器。它代表了您將要創造的3D世界。您可以像這樣來創造場景對象:

var scene = new THREE.Scene();`

另外一件事就是當你使用3D工作時,你需要相機。想象相機就像眼睛一樣,你會看到這個3D世界。當使用2D可視化時,相機的概念通常是不存在的。你看到什么就是什么。但是在3D的世界,你需要一個相機來定義你的觀點,因為你可以從一個場景中看到很多的位置和角度。相機不僅定義了位置,而且還定義了其他的信息,如視野或縱橫比。

var camera = new THREE.PerspectiveCamera(
    45, // field of view
    window.innerWidth / window.innerHeight, // aspect ratio
    1, // near clipping plane (beyond which nothing is visible)
    1000 // far clipping plane (beyond which nothing is visible)
);

相機捕捉場景以顯示目的,但我們實際上可以看到任何東西,3D數據需要轉換為2D圖像。這個過程稱為 正在渲染 ,同時你需要用 渲染器 在three.js的場景中來進行渲染。你可以初始化渲染像這樣的:

var renderer = new THREE.WebGLRenderer();`

之后設置渲染器的大小。這將決定輸出圖像的大小。

renderer.setSize(window.innerWidth, window.innerHeight);`

為了能夠顯示你渲染的結果,你需要將渲染器的 domelement 屬性追加到HTML內容里面。你會使用空的div元素,為此來創造id為 WebGL 的元素。

document.getElementById('webgl').appendChild(renderer.domElement);`

當做完這一切,你可以視在渲染器上 渲染 的這種方法,是提供場景和相機作為參數對象。

renderer.render(
    scene,
    camera
);

為了讓代碼更簡潔,在函數 init 里面進行調用和執行功能。

init();`

也許你現在什么也看不見...除了黑屏。別急,這是正常的。這個場景是正常工作的,但是你沒有包含任何的對象再場景里面,你所看到的基本上是空的空間,接下來,你會使用3D對象填充這個場景。

看 the Pen learning-threejs-01 by Engin Arslan ( @enginarslan ) on CodePen .

向場景中添加對象

three.js里面的幾何對象是由兩部分組成的。一個幾何對象決定了一個對象的形狀和一個材料決定了其表面質量,一個對象的外形,兩者的結合組成了three.js里面的網格,形成3D對象。

Three.js允許你創建一些簡單的形狀,如立方體、球體在一個簡單的方式。您可以通過創建一個簡單的球體的半徑值。

var geo = new THREE.SphereGeometry(1);`

這里有各種材料可以在幾何中使用。材料決定了一個對象對光場景的反應。我們可以用一切材料使物體反光,粗糙,透明等。默認的材料,像由 MeshBasicMaterial . MeshBasicMaterial 創造的three.js對象一點不受光場景的影響。這意味著即使你的場景中沒有燈光,你的幾何圖形也將可見。你可以用一個顏色屬性,可以為對象設置你想要的顏色 meshbasicmaterial hex值傳遞一個對象,您現在將使用此材料,但稍后更新它將使您的對象受到場景燈光的影響。你沒有任何照明的場景,現在 meshbasicmaterial 應該是一個好的選擇。

var material = new THREE.MeshBasicMaterial({
        color: 0x00ff00
});

你可以結合幾何和材料創建一個網格,這將形成三維物體。

var mesh = new THREE.Mesh(geometry, material);`

創建一個函數來封裝創建球體的代碼。在本教程中,您不會創建多個球體,但保持整體整潔還是不錯的。

function getSphere(radius) {
    var geometry = new THREE.SphereGeometry(radius);
    var material = new THREE.MeshBasicMaterial({
        color: 0x00ff00
    });
    var sphere = new THREE.Mesh(geometry, material);
    return sphere;
}

var sphere = getSphere(1);

然后,您需要將這個新創建的對象添加到場景中以使其可見。

scene.add(sphere);`

讓我們再次檢查這個場景,你還會看到這個黑屏。

看代碼 learning-threejs-02 by Engin Arslan ( @enginarslan ) on CodePen .

無論何時你往three.js里面添加場景對象,對象被放置在場景的中心,在x、y和z的坐標為0, 0, 0,就是你什么都看不到的原因,這就意味著你目前的相機和球體處于同一位置。你應該改變他們中的任何一個的位置,以便能夠開始看東西。

3D協調

讓我們把照相機20個單位移到z軸上。這是通過在攝像機上設置 * 位置的屬性來實現的。3D對象有 position , rotation 和 scale 屬性,可以允許你在3D空間里面任意旋轉它們。

camera.position.z = 20;`

你可以移動攝像機以及其他軸。

camera.position.x = 0;
camera.position.y = 5;
camera.position.z = 20;

相機現在位置更高了,但是球體不再在框架的中心位置了。你需要把相機指向它。為了能夠做到這樣,你可以調用相機的一個方法稱為 lookAt 。通過相機上的 lookAt 方法確定哪些點是相機指向的。在三維空間中的點表示的是向量。所以,你可以通過一個新的 Vector3 對象,這 lookAt 方法能在0, 0, 0相機坐標看。

camera.lookAt(new THREE.Vector3(0, 0, 0));`

球對象現在看起來不是很圓。究其原因,是 spheregeometry 函數實際上接受兩個額外的參數,寬度和高度細分,影響 resolution 表面。增加這些值,平滑的曲面會出現。我將此值設置為24的寬度和高度細分。

var geo = new THREE.SphereGeometry(radius, 24, 24);`

See the Pen learning-threejs-03 by Engin Arslan ( @enginarslan ) on CodePen .

現在,您將創建一個簡單的平面幾何的球體。 PlaneGeometry 函數要求有 width 和 height 參數。在3D中,2D對象沒有默認的兩個側面,所以你需要將一個 side 屬性傳遞給材質,使平面幾何體的兩邊呈現。

function getPlane(w, h) {
  var geo = new THREE.PlaneGeometry(w, h);
  var material = new THREE.MeshBasicMaterial({
    color: 0x00ff00,
    side: THREE.DoubleSide,
  });
  var mesh = new THREE.Mesh(geo, material);

  return mesh;
}

現在你可以往這個平面對象里添加場景。你會注意到,平面幾何的初始旋轉是平行于y軸,但你可能需要它是水平的,因為它作為一個接地平面,你需要記住一件重要的事,那就是three.js里的旋轉。它們用 radians 為單位,不用 degrees ?;《刃D90度相當于 π/ 2 數學。

var plane = getPlane(50, 50);
scene.add(plane);
plane.rotation.x = Math.PI/2;

當你創造一個球對象,它用它的中心點定位。如果你想把它移動到地面上,那么你可以只增加它的'位置' Y值的當前半徑的數量。但這不會是一個綱領性的做事方式。如果你想讓球體停留在平面上,不管它的半徑值是多少,你都應該利用半徑值來定位。

sphere.position.y = sphere.geometry.parameters.radius;`

看 the Pen learning-threejs-04 by Engin Arslan ( @enginarslan ) on CodePen .

動畫

你幾乎完成了本教程的***部分。但在我們把它整合起來之前,我想說明一下如何用three.js來做動畫。three.js動畫中使用的 requestanimationframe 方法對 窗口 對象反復執行一個給定的函數。它有點像一個 setInterval 函數,但它是繪制瀏覽器運行性能。

創造一個 update 函數,通過渲染,場景,和相機在那里執行渲染方法,在函數內進行渲染。你將會在內部聲明 requestAnimationFrame 函數,并將 更新 函數,通過對 requestanimationframe 函數遞歸進行回調,這樣說明代碼比寫出來更好。

function update(renderer, scene, camera) {
  renderer.render(scene, camera);

  requestAnimationFrame(function() {
    update(renderer, scene, camera);
  });
}

在這一點上一切看起來都一樣,但核心的區別是, requestanimationframe 函數是使場景渲染每秒約60幀遞歸調用的 更新 函數。這意味著如果你正在 update 函數里面執行語句,該語句將以每秒60次的速度執行。讓我們添加一個縮放動畫球對象。為了從 update 函數中選擇球體對象,您可以將它作為參數傳遞,但我們將使用不同的技術。首先,在球對象上設置一個 name 屬性,并給它取一個你喜歡的名字。

sphere.name = 'sphere';`

在update函數內部,你可以使用它的名字,并且使用 getObjectByName 方法在其父對象上,找到該對象,這個場景。

var sphere = scene.getObjectByName('sphere');
sphere.scale.x += 0.01;
sphere.scale.z += 0.01;

通過這段代碼,這個球的X和Z軸在縮放。盡管我們的意圖不是創造一個縮放的球。我們正在設置 update 函數,以便我們以后可以使用不同的動畫。現在你已經看到了它是如何工作的,你可以刪除這個縮放動畫。

看代碼 learning-threejs-05 by Engin Arslan ( @enginarslan ) on CodePen .

第二部分 - 在場景中添加現實

目前,我們正在使用 MeshBasicMaterial ,即使在場景中沒有燈光時,它也會顯示出給定的顏色,這會導致一個非常扁平的外觀。盡管真實世界的材料不會以這種方式進行工作。真實世界可見的表面,取決于從表面反射回我們眼睛的光有多少。three.js有幾個不同的材料,提供更好的接近實際表面的行為,其中一個是 meshstandardmaterial 。 meshstandardmaterial 是一個基于物理的渲染材料,可以幫助你達到逼真的效果。這是現代游戲引擎的一種材料,如 Unreal or Unity,是游戲和視覺效果的行業標準。

讓我們開始在我們對象中使用 MeshStandardMaterial ,改變其顏色變為白色。

var material = new THREE.MeshStandardMaterial({
  color: 0xffffff,
});

你將會在這個點上再次得到黑色渲染。這是正常的。對象在場景中需要光才能顯示。這對于 meshbasicmaterial 不是必須的,因為它是一個簡單的材料,在所有條件下,顯示給定的顏色,但其他材料需要與光的相互作用才可見。讓我們創造一個 SpotLight 函數,你將會用這個函數創造兩個聚光燈。

function getSpotLight(color, intensity) {
  var light = new THREE.SpotLight(color, intensity);

  return light;
}

var spotLight_01 = getSpotlight(0xffffff, 1);
scene.add(spotLight_01);

你也許在這個點上可以看到些事情。為了更好的取景和陰影,光線和相機的位置有點不同。同時創造一個輔助光。

var spotLight_02 = getSpotlight(0xffffff, 1);
scene.add(spotLight_02);

camera.position.x = 0;
camera.position.y = 6;
camera.position.z = 6;

spotLight_01.position.x = 6;
spotLight_01.position.y = 8;
spotLight_01.position.z = -20;

spotLight_02.position.x = -12;
spotLight_02.position.y = 6;
spotLight_02.position.z = -10;

做完這些,你場景中將有兩個光源,從兩個不同的位置照射球體。燈光有助于了解場景的維度。但在這一點上,事情仍然非常不真實,因為照明缺少一個關鍵的組成部分:陰影!

不幸地是,在three.js中渲染陰影不是很簡單。這是因為陰影計算上很費成本,我們需要在多個地方激活陰影渲染。首先,你需要告訴渲染器開始渲染陰影:

var renderer = new THREE.WebGLRenderer();
renderer.shadowMap.enabled = true;

然后,你需要告訴光線投射陰影。在 getSpotLight 函數里面進行。

light.castShadow = true;`

你應該告訴對象投射或者接收陰影。在這種情況下,你將會讓球體投射陰影并且用這個平面來接收陰影。

mesh.castShadow = true;
mesh.receiveShadow = true;

在設置了這些之后,我們應該開始看場景中的陰影。首先,他們可能效果不是很好。您可以通過設置光影貼圖大小來提高陰影的分辨率。

light.shadow.mapSize.x = 4096;
light.shadow.mapSize.y = 4096;

MeshStandardMaterial 有很多屬性,例如 roughness 和 metalness 控制表面與光的相互作用。這些屬性取值在0到1之間,它們控制著相應的表面行為。增加平面材料的粗糙度值到1,使表面看起來更像一個橡膠,作為反射而使其變得模糊。

// material adjustments
var planeMaterial = plane.material;
planeMaterial.roughness = 1;

盡管如此,在本教程中我們不會將其值設為 1 。您可以自由試驗值,但可以將其設置為0.65,用于粗糙度和0.75的金屬。

planeMaterial.roughness = 0.65;
planeMaterial.metalness = 0.75;

盡管現在的場景看起來更有希望,但仍然很難稱之為現實。事實是,在不使用紋理貼圖的情況下,很難在三維中建立光致主義。

看代碼 learning-threejs-06 by Engin Arslan ( @enginarslan ) on CodePen .

紋理映射

材質貼圖是二維圖像,可以在材質上進行映射,以提供表面細節。到目前為止,你只能在表面上得到純色,但使用紋理貼圖,你可以在一個表面上繪制任何你想要的圖像。紋理貼圖不僅被用來操縱表面的顏色信息,而且還可以用來操縱表面的其他特性,如反射性、亮度、粗糙度等。

紋理可以從照片來源獲得,也可以從草稿中繪制。對于一個在3D環境中有用的紋理,它應該以某種方式被捕獲。圖像中有反射或陰影,或圖像過于扭曲的圖像,不會產生很好的紋理貼圖。有幾個專門的網站在網上尋找紋理。其中一個是 textures.com ,它有一個很好的存檔。他們有一些免費的下載選項,但你需要注冊才能做到這一點。另一個3D材質的網站是 Megascans ,它的高分辨率,高質量的環境掃描,高質量的產品質量。

我使用了一個名為 mb3d.co.uk 的網站上的例子。這個網站提供了無縫的、免費的紋理。無縫紋理意味著一種紋理,可以在表面上多次重復,而不會在邊緣遇到任何不連續性的情況下發生. 這是鏈接 我用的紋理文件。我已經將圖片文件的大小縮小到512px,并使用一個名為 ezgif 的在線服務將圖像文件轉換為數據URI,以將其作為JavaScript代碼的一部分,而不是將其作為單獨的資產加載。(提示:如果要使用該服務,不要將標記包含在數據中)

創建一個函數,返回我們生成的數據URI,這樣我們就不必在代碼的中間放置一個大的字符串。

function getTexture() {
    var data = 'data:image/jpeg;base64,/...'; // paste your data URI inside the quotation marks.
    return data
}

接下來,你需要加載紋理并將其應用到平面上。為此您將使用three.js。在加載紋理之后,你會將紋理加載到所需材質的地圖屬性中,將其作為一種顏色地圖在表面上。

var textureLoader = new THREE.TextureLoader();
var texture = textureLoader.load(getTexture());
planeMaterial.map = texture;

現在的東西看起來很難看,因為表面的紋理像素化了。這張圖片拉伸得太大了,無法覆蓋整個表面。你可以做的是讓圖像重復,而不是縮放,這樣就不會像素化了。為此,您需要設置 wrapSand wrapT 屬性為 THREE.RepeatWrapping 。重復包裝并指定重復值。因為你也會為其他類型的地圖做這個(比如凹凸或粗糙貼圖),***是為它創建一個循環:

var repetition = 6;
var textures = ['map']// we will add 'bumpMap' and 'roughnessMap'
textures.forEach((mapName) => {
  planeMaterial[mapName].wrapS = THREE.RepeatWrapping;
  planeMaterial[mapName].wrapT = THREE.RepeatWrapping;
  planeMaterial[mapName].repeat.set(repetition, repetition);
});

這看起來應該更好。因為你所使用的紋理是無縫的,你不會注意到有重復發生的邊緣的任何不連接。

紋理的加載實際上是一個異步操作。這意味著您的3D場景是在加載圖像文件之前生成的。但是由于您一直在使用 requestAnimationFrame 不斷地呈現場景,因此在本例中不會造成任何問題。如果不這樣做,則需要使用回調或其他異步方法來管理加載順序。

看代碼 learning-threejs-07 by Engin Arslan ( @enginarslan ) on CodePen .

其他紋理地圖

正如上一章所提到的,紋理不僅被用來定義表面的顏色,而且還用來定義它的其他性質。貼圖的另一種方式是 凹凸貼圖 。當被用作凹凸貼圖時,紋理的亮度值會模擬一個高度的效果。

planeMaterial.bumpMap = texture;`

凹凸貼圖也應該使用與顏色貼圖相同的重復配置,所以在 textures 數組中包含它。

var textures = ['map', 'bumpMap'];`

使用凹凸貼圖,加亮一個像素的值,相應的表面看起來會更高。但是凹凸貼圖并沒有改變表面,它只是在操縱光與表面的相互作用產生一種不均勻拓撲的錯覺?,F在的碰撞量看起來有點太大了。凹凸貼圖在使用時效果很好。因此,讓我們將 bumpScale 參數更改為更低的值,以獲得更細微的效果。

planeMaterial.bumpScale = 0.01;`

注意,這種紋理在外觀上有很大的不同。反射不再***了,但卻被***地分割了,就像現實生活中那樣。另一種可用于標準材料的 StandardMaterial 是 roughness map 。紋理貼圖是一個粗糙的貼圖,你可以使用給定圖像的亮度值來控制反射的銳度。

planeMaterial.roughnessMap = texture;
var textures = ['map', 'bumpMap', 'roughnessMap'];

根據這three.js文檔,當與 environment map 一起使用時,標準材料的工作效果***。環境圖模擬了一個遙遠的環境,反映了場景中的反射面。當你試圖模擬物體的反射率時,這真的很有幫助。在三個環境地圖。js以 立方體地圖 的形式出現。多維數據集映射是一個在多維數據集內映射的場景的全景視圖。一個立方體地圖由6個獨立的圖像組成,這些圖像對應一個立方體的每個面。由于在一個在線編輯器中加載6個模式圖像將會有太多的工作,所以在本例中不會實際使用環境映射。但是為了使這個球面對象更加有趣,也可以添加一個粗糙度圖。你會使用這個 紋理 ,但是是320px*320px數據URI。

創建一個名為 getMetalTexture 紋理的新函數。

function getMetalTexture() {
    var data = 'data:image/jpeg;base64,/...'; // paste your data URI inside the quotation marks.
    return data
}

把它應用在球面上,比如 bumpMap 和 roughnessMap :

var sphereMaterial = sphere.material;
var metalTexture = textureLoader.load(getMetalTexture());

sphereMaterial.bumpMap = metalTexture;
sphereMaterial.roughnessMap = metalTexture;
sphereMaterial.bumpScale = 0.01;
sphereMaterial.roughness = 0.75;
sphereMaterial.metalness = 0.25;

看代碼 learning-threejs-08 by Engin Arslan ( @enginarslan ) on CodePen .

封裝起來

你幾乎完成了!在這里,你只需要做一些小小的調整??梢钥吹竭@個場景文件的最終版本 in this Pen .

給燈光提供一種非白色的顏色。注意,如何實際使用CSS顏色值作為字符串來指定顏色:

var spotLight_01 = getSpotlight('rgb(145, 200, 255)', 1);
var spotLight_02 = getSpotlight('rgb(255, 220, 180)', 1);

然后在燈光中添加一些微妙的隨機動畫,為場景添加一些生命。首先,將名稱屬性分配給燈光,這樣您就可以使用 getObjectByName 方法在 update 函數中找到它們。

spotLight_01.name = 'spotLight_01';
spotLight_02.name = 'spotLight_02';

之后,在 update 函數里面,使用 Math.random() 函數創造動畫,

var spotLight_01 = scene.getObjectByName('spotLight_01');
spotLight_01.intensity += (Math.random() - 0.5) * 0.15;
spotLight_01.intensity = Math.abs(spotLight_01.intensity);

var spotLight_02 = scene.getObjectByName('spotLight_02');
spotLight_02.intensity += (Math.random() - 0.5) * 0.05;
spotLight_02.intensity = Math.abs(spotLight_02.intensity);

作為一個額外的獎勵,在場景文件中,我已經包含了 OrbitControls 腳本。three.js攝像機,這意味著你可以把你的鼠標拖到場景上與攝像頭互動!我也這樣做了,這樣場景就會隨著窗口大小的變化而調整。為了方便起見,我使用外部腳本實現了這一點。

看代碼 learning-threejs-final by Engin Arslan ( @enginarslan ) on CodePen .

現在,這個場景有點接近現實主義了。盡管如此,仍有許多缺失的部分。由于缺少反射和周圍的光線,球體球太暗了。地面平面在看的角度看得太平了。球體的輪廓太***了——它是CG(計算機圖形)***的。照明實際上并不像它所能的那樣真實;它不會隨著源的距離而衰減(失去強度)。你還應該添加粒子效果,相機動畫,以及后期處理濾鏡,如果你想要這樣做的話。但這仍然是一個很好的例子來說明three.js的力量。以及你可以在瀏覽器中創建的圖形質量。有關可以實現使用這個神奇的庫的更多信息,你應該看看我的新課程 Lynda.com 的項目!

謝謝你閱讀到這里!希望你喜歡這篇文章,如果有任何問題,你可以在Twitter上 @inspiratory或在我 網站 上, 隨時聯系我。

責任編輯:張燕妮 來源: 眾成翻譯
相關推薦

2021-01-03 17:30:10

3D人像ARVR

2013-01-30 16:15:40

adobeHTML5css3

2022-06-29 10:21:33

3d打印輔助工具

2010-02-14 15:27:25

2017-03-22 11:57:57

3D XPoint存儲英特爾

2022-08-03 13:52:22

AI建筑師

2024-07-03 14:29:38

2021-11-08 06:02:17

CSS 技巧代碼重構

2023-12-01 09:00:00

NeRF技術人工智能

2012-05-10 10:55:03

CSS

2021-06-18 05:59:37

Css前端CSS 特效

2017-07-11 15:00:04

前端CSS3D視角

2021-08-30 06:20:39

CSS 技巧3D 效果

2009-03-10 18:16:49

2022-12-15 21:59:56

AIVR場景

2023-12-09 14:29:32

AI算法

2013-11-18 17:33:48

微軟Windows 8.1應用

2013-07-25 09:32:26

OpenGL ESAndroid4.3

2009-08-27 18:10:58

PHP繪制3D圖形

2009-03-26 09:00:12

Mozilla瀏覽器3D圖形加速
點贊
收藏

51CTO技術棧公眾號

亚洲 欧美 日韩 国产综合 在线| 国产精品18毛片一区二区| 国产精品av久久久久久无| 国产成年精品| 欧美日韩国产精品一区二区三区四区| 日本一区二区精品视频| 国产模特av私拍大尺度| 99精品热视频只有精品10| 一区二区av在线| 免费黄色a级片| 91tv亚洲精品香蕉国产一区| 国产精品美女久久久久久久久久久 | 国内爆初菊对白视频| 欧美亚洲一区| 不卡中文字幕av| 艳妇乳肉亭妇荡乳av| 欧美一级在线| 欧美日韩国产综合新一区| 亚洲一区二区精品在线观看| 人妻一区二区三区四区| 久久99久久精品| 国产91|九色| 美女福利视频在线观看| 成人亚洲一区二区| 日韩精品一区二区三区第95| 看看黄色一级片| 美女福利一区二区 | 日韩成人高清视频| 午夜激情久久| 一区二区欧美在线| 欧洲一级黄色片| 嫩呦国产一区二区三区av | www.色呦呦| 奇米在线7777在线精品| 91精品国产成人www| 极品盗摄国产盗摄合集| 久久在线视频| 在线丨暗呦小u女国产精品| 波多野结衣一二三区| 日韩在线亚洲| 欧美一区国产二区| 欧美成人福利在线观看| 免费观看一级欧美片| 亚洲一区二区三区精品在线| 法国空姐在线观看免费| 国产二区视频在线观看| av亚洲精华国产精华精| 国产综合视频在线观看| 中文字幕人妻一区二区在线视频| 日韩中文字幕亚洲一区二区va在线| 97欧美精品一区二区三区| 欧美成人一二三区| 欧美日韩少妇| 色综合久综合久久综合久鬼88| 天天鲁一鲁摸一摸爽一爽| 视频在线不卡免费观看| 日韩午夜在线视频| 欧美老熟妇一区二区三区| 久久久久国产| 免费91在线视频| 免费毛片在线播放免费| 国产综合婷婷| 久久久久成人精品| xxxx.国产| 天堂av在线一区| 国产成人一区二区在线| 国产美女www爽爽爽| 蜜臀精品久久久久久蜜臀| 国产精品日韩av| 国产又粗又猛又爽又黄的视频一| 激情综合亚洲精品| 99久久一区三区四区免费| 国产91免费在线观看| av一二三不卡影片| 日产中文字幕在线精品一区| 国产51人人成人人人人爽色哟哟| 欧美经典一区二区三区| 91手机视频在线| 日本中文字幕中出在线| 午夜精品福利视频网站| 久久久久久久中文| 日本精品在线中文字幕| 在线不卡a资源高清| 日本中文字幕影院| www.丝袜精品| 亚洲色图校园春色| 91香蕉一区二区三区在线观看| 一区在线免费观看| 国产成人精品综合久久久| 国产精品毛片一区二区在线看舒淇 | 亚洲欧美日韩久久| 国产乱子伦农村叉叉叉| 日韩精品第二页| 亚洲福利视频久久| 1024在线看片| 亚洲久久视频| 成人美女免费网站视频| 污污网站免费在线观看| 国产精品麻豆99久久久久久| av免费看网址| 婷婷久久免费视频| 日韩精品视频在线免费观看| 欧美88888| 在线午夜精品| 成人淫片在线看| 欧美挠脚心网站| 一区二区三区四区在线免费观看 | 7777kkk亚洲综合欧美网站| 91精品91久久久中77777| 在线观看免费视频污| 丝袜美腿综合| 欧美高清视频免费观看| 中文字幕第三页| 成人精品国产免费网站| 亚洲一区二区免费视频软件合集| freexxx性亚洲精品| 欧美精品丝袜中出| 人人人妻人人澡人人爽欧美一区| 欧美日韩亚洲一区三区| 国产欧美精品在线| 欧美日韩免费做爰大片| 夜夜嗨av一区二区三区中文字幕 | 中文字幕日韩精品一区二区| 亚洲啊v在线| 欧美成人精品高清在线播放| 久久午夜精品视频| 久久久久久黄| 久久riav| 国产探花视频在线观看| 678五月天丁香亚洲综合网| 免费黄色片网站| 9色精品在线| 99一区二区| 哥也色在线视频| 欧美日韩三级视频| 欧美aaa级片| 男女精品网站| 欧美国产二区| 51精品视频| 精品人伦一区二区色婷婷| 国产精品免费人成网站酒店 | 99久久99热这里只有精品| 国产成一区二区| 国产中文字幕在线观看| 日韩欧美中文在线| aa一级黄色片| 日日夜夜精品视频天天综合网| 欧美大陆一区二区| 不卡一二三区| 国产午夜精品视频| 国产亚洲久一区二区| 中文字幕 久热精品 视频在线| 国产一级不卡毛片| 日韩高清欧美| 成人午夜在线观看| 在线观看wwwxxxx| 欧美成人午夜电影| 日韩精品一区二区在线播放 | 久久亚洲高清| 日韩电影av| 中文字幕9999| 国产情侣在线播放| 一区二区三区日韩| 中文字幕精品久久久| 久久激情中文| 在线观看欧美亚洲| 日韩精品三级| 91精品国产高清久久久久久久久| 四虎影院在线播放| 精品视频在线免费看| 天天色天天综合| 高清国产一区二区| 鲁一鲁一鲁一鲁一澡| 国产欧美日韩免费观看| 成人精品一区二区三区| 欧洲成人综合网| 亚洲免费av网址| 在线免费av片| 洋洋av久久久久久久一区| 手机在线看片日韩| 蜜乳av一区二区| 屁屁影院ccyy国产第一页| 亚洲最大在线| 成人免费直播live| 蜜桃视频m3u8在线观看| 日韩小视频在线观看| 国产成人三级在线观看视频| 日本精品视频一区二区| 九九热这里有精品视频| 久久久亚洲国产美女国产盗摄| gai在线观看免费高清| 亚洲天堂久久| 亚洲砖区区免费| 久久精品福利| 国产综合在线观看视频| 久草在线资源站手机版| 日韩在线观看精品| 四虎影视精品成人| 日韩亚洲欧美成人一区| 日韩手机在线视频| 亚洲一区二区偷拍精品| 内射毛片内射国产夫妻| av在线免费不卡| 久久久精品高清| 午夜在线精品| 国产高清不卡无码视频| av伊人久久| 精品国产乱码久久久久| 电影一区中文字幕| 国产精品国模在线| 一二三四视频在线中文| 欧美乱人伦中文字幕在线| 69视频在线观看| 日韩高清av在线| 亚洲第一大网站| 欧美精品99久久久**| 无码人妻丰满熟妇精品区| 亚洲一区日韩精品中文字幕| 国产一区第一页| 国产日韩欧美综合一区| 精品国产av色一区二区深夜久久| 国产一区二区三区黄视频 | 狠狠久久伊人中文字幕| 91av视频在线观看| 成人av影院在线观看| 欧美另类交人妖| 激情成人四房播| 日韩视频亚洲视频| www.中文字幕久久久| 亚洲美女激情视频| 亚州男人的天堂| 亚洲第一福利网| 人妻一区二区三区免费| 亚洲福利在线看| 肥臀熟女一区二区三区| 日韩片之四级片| 国产黄色免费大片| 日韩欧美在线网站| 国产av无码专区亚洲av麻豆| 欧美一区日韩一区| av网站在线观看免费| 51精品久久久久久久蜜臀| 在线播放精品视频| 欧美人狂配大交3d怪物一区| 国产一区二区网站| 这里只有精品99re| 精品久久久免费视频| 日韩精品一区二区三区在线播放 | 中文字幕亚洲欧美一区二区三区| 深夜福利视频一区| 亚洲毛片在线看| 狠狠色伊人亚洲综合网站l| 亚洲日本欧美中文幕| 国产高清免费av在线| 中文字幕欧美国内| 免费a级在线播放| 久青草国产97香蕉在线视频| 在线观看av免费| 91精品国产成人www| 国产高清不卡| 国产精品亚洲欧美导航| 精品一区二区三区四区五区 | 在线观看免费的av| 国产精品亚洲午夜一区二区三区| 特种兵之深入敌后| 99re这里只有精品首页| av电影网站在线观看| 国产精品久久久久久久久免费樱桃| 乱老熟女一区二区三区| 一区二区欧美国产| 中文字幕在线观看免费视频| 一本大道久久a久久综合| 成人黄色三级视频| 538在线一区二区精品国产| 国产成人av免费看| 精品无人区乱码1区2区3区在线| 国产午夜在线观看| 欧美大成色www永久网站婷| 91精品国产黑色瑜伽裤| 国产精品成人免费电影| 精品视频在线播放一区二区三区| 国产精品视频入口| 欧美中文一区二区| 成人免费a级片| 天堂va蜜桃一区二区三区 | 青青艹在线观看| 日韩视频中午一区| 免费在线毛片| 久久综合亚洲社区| 黑人巨大亚洲一区二区久 | 97精品视频在线播放| 亚洲不卡系列| 国产精品日韩一区二区免费视频| 欧美自拍偷拍| 国精产品一区一区三区视频| 免费看欧美女人艹b| 日韩免费高清一区二区| 国产精品久久久久久久久免费桃花 | 少妇一级淫片免费看| 丝袜美腿亚洲一区二区| 中文字幕在线视频久| 99re6在线| 日韩电影在线视频| 337p粉嫩大胆噜噜噜鲁| 精品一区二区三区av| 成人h动漫精品一区| 一区二区三区日韩精品| 一本大道伊人av久久综合| 精品呦交小u女在线| 秋霞在线视频| 成人国产在线视频| 国产成人精品一区二区免费看京 | 久久青青草原一区二区| 一区二区不卡| 欧美成人福利在线观看| 国产午夜亚洲精品午夜鲁丝片| 欧美成人aaaaⅴ片在线看| 91精品国产综合久久国产大片| 岛国在线视频| 欧美在线性视频| 激情小说亚洲色图| 2022中文字幕| 国产在线日韩欧美| 蜜桃av免费在线观看| 在线影视一区二区三区| 亚洲欧美日韩动漫| 国语自产偷拍精品视频偷| 伊人www22综合色| 综合视频免费看| 美女www一区二区| 丁香激情五月少妇| 91高清视频在线| 黄色av网站在线免费观看| 欧美一级在线播放| 欧美综合自拍| 人妻熟妇乱又伦精品视频| 成人美女视频在线看| 久久综合久久鬼| 亚洲第一区在线| av手机在线观看| 国精产品99永久一区一区| 亚洲青涩在线| 黄色a一级视频| 色综合中文综合网| 男生女生差差差的视频在线观看| 88xx成人精品| 九九亚洲视频| 免费午夜视频在线观看| 久久久久国产成人精品亚洲午夜| 日本高清不卡码| 亚洲人精品午夜在线观看| 日韩影片中文字幕| 天堂资源在线亚洲视频| 蜜桃av一区二区| 久久爱一区二区| 日韩午夜中文字幕| 9999在线视频| 免费日韩电影在线观看| 日韩高清不卡在线| 亚洲一区电影在线观看| 欧美一区二区三区喷汁尤物| 污污视频在线| 国产一区高清视频| 久久久久久夜| 久久久99999| 精品国产区一区| 日韩影片中文字幕| 波多野结衣三级在线| 不卡av免费在线观看| 精品人妻一区二区色欲产成人| 一区二区日韩精品| **日韩最新| 男女啪啪免费视频网站| 国产性做久久久久久| 国产模特av私拍大尺度| 午夜精品久久久久久久久久久久久 | 国产亚洲一区二区手机在线观看| 国产高清精品软男同| 成人一区在线看| 欧美一区二区三区久久久| 理论片在线不卡免费观看| 精品久久ai| 91欧美视频在线| 亚洲v精品v日韩v欧美v专区| 大地资源中文在线观看免费版| 91亚洲va在线va天堂va国 | 手机亚洲第一页| 亚洲a级在线观看| 久久精品女人天堂| 国产女人被狂躁到高潮小说| 亚洲欧美视频在线| 亚洲午夜免费| 欧美伦理视频在线观看| 亚洲综合男人的天堂| 成人一区二区不卡免费| 俄罗斯精品一区二区三区| 青青草国产成人av片免费| 日韩激情在线播放| 久久亚洲国产精品| 国产精品美女久久久久久不卡|