前言
學習three.js最好的方法是通過理解它的核心概念和最常用的組件。
1. 基礎(chǔ)概念
場景(Scene): three.js中所有物體的容器。你可以把它想象成一個舞臺,在這里添加物體、光源等。
var scene = new THREE.Scene();
相機(Camera): 決定了哪部分場景會被渲染。最常用的是透視相機(PerspectiveCamera)。
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.z = 5;
除了透視相機,還有正交相機(OrthographicCamera).
不說八股文,就說在實戰(zhàn)中的體驗:
透視相機,在左右移動時,會變形(會有一種拉扯的感覺);
正交相機不會有拉扯的感覺
渲染器(Renderer): 用于在一個元素上渲染圖像。
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);//renderer.domElement 是three.js的渲染器的HTML元素,document.body是文檔的主體
上面這三句是你在用到渲染器時,必定要寫的,這是將three.js場景渲染到屏幕的一種方式.
幾何體(Geometry): 物體的形狀。比如,BoxGeometry 是一個立方體。
var geometry = new THREE.BoxGeometry(1, 1, 1);
材質(zhì)(Material): 物體的外觀(顏色、紋理)。
var material = new THREE.MeshBasicMaterial(
{
color: 0x00ff00
}
);
網(wǎng)格(Mesh): 幾何體和材質(zhì)的組合,可以添加到場景中。
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
光源(Lights): 照亮場景中的物體。常見的有環(huán)境光(AmbientLight)和點光源(PointLight)。
var light = new THREE.PointLight(0xffffff, 1, 100);
light.position.set(50, 50, 50);
scene.add(light);
動畫循環(huán)(Animation Loop): 用于在每幀更新場景和渲染。
function animate() {
requestAnimationFrame(animate);
// 任何動畫的更新
renderer.render(scene, camera);
}
animate();
2. 著色器(Shaders)
著色器是three.js中較高級的概念,用于自定義物體的渲染方式。著色器寫在GLSL(OpenGL Shading Language)中,分為兩種:
- 頂點著色器(Vertex Shader): 處理每個頂點的邏輯,如位置、顏色等。
- 片元著色器(Fragment Shader): 處理最終像素的顏色和外觀。
使用著色器時,你通常會創(chuàng)建一個ShaderMaterial或RawShaderMaterial,并提供頂點和片元著色器的代碼:
var shaderMaterial = new THREE.ShaderMaterial({
vertexShader: `...`, // GLSL代碼
fragmentShader: `...`, // GLSL代碼
});
3. 其他概念
- 紋理(Textures): 用于給物體添加詳細的外觀,如皮膚、圖片等。
- 加載器(Loaders): 用于加載不同格式的模型和紋理。
- 控制器(Controls): 允許用戶通過鼠標、鍵盤等交互來控制相機的視角。
n. 疑惑
1. 感覺搞不懂"紋理貼圖"與"著色器"的關(guān)系,他們倆可以分開用嗎?還是必須混著用?
答:
紋理貼圖
- 定義: 紋理貼圖是一種圖像,可以被映射(貼)到三維物體的表面,用于給物體增加顏色、細節(jié)、紋理等。
- 用途: 紋理貼圖常用于給物體添加真實感,如木材的紋理、石頭的表面等。
- 應用方式: 通過將紋理貼圖應用到材質(zhì)(Material)上,然后將這個材質(zhì)應用到幾何體(Geometry)上。
著色器
- 定義: 著色器是運行在GPU上的小程序,用于控制頂點(頂點著色器)和像素(片元著色器)的渲染方式。
- 用途: 著色器通常用于創(chuàng)建復雜的視覺效果,如動態(tài)光照、陰影、反射、折射等。
- 應用方式: 通過編寫GLSL代碼來定義著色器的行為,并將其應用到ShaderMaterial或RawShaderMaterial。
頂點著色器也是在Material里面使用
這個uniforms里面的texturetootj就是貼圖,他將在著色器代碼中被加載
關(guān)系和組合使用
- 分開使用: 你可以只使用紋理貼圖來增強物體的外觀,而不涉及自定義著色器的復雜性。同樣,你也可以只使用著色器來創(chuàng)建特定的效果,而不使用任何紋理貼圖。
- 結(jié)合使用: 著色器可以訪問和使用紋理貼圖。例如,在自定義的片元著色器中,你可以使用紋理貼圖來決定物體表面的顏色和紋理。這允許你創(chuàng)建更復雜和動態(tài)的視覺效果。
- 總結(jié):還是結(jié)合起來用比較好:貼圖是肯定要加載的,然后通過uniforms將貼圖傳到著色器代碼中,進行使用!
也就是說,著色器中加載到了貼圖,不僅完成了將貼圖貼到模型上的任務,還在貼好圖之后的模型上,添加了光照、陰影、反射、折射等
要想貼圖貼的好,uv坐標少不了
關(guān)于uv坐標的計算,這段代碼都是固定的,直接用就ok!
const positions = geometry.getAttribute('position').array;
// 找到模型頂點坐標的最小值和最大值
let minX = Number.POSITIVE_INFINITY;
let maxX = Number.NEGATIVE_INFINITY;
let minY = Number.POSITIVE_INFINITY;
let maxY = Number.NEGATIVE_INFINITY;
for (let i = 0; i < positions.length; i += 3) {
const x = positions[i];
const y = positions[i + 1];
minX = Math.min(minX, x);
maxX = Math.max(maxX, x);
minY = Math.min(minY, y);
maxY = Math.max(maxY, y);
}
// 計算頂點坐標范圍
const rangeX = maxX - minX;
const rangeY = maxY - minY;
// 計算 UV 坐標并歸一化到 0 到 1 之間
const uvs = [];
for (let i = 0; i < positions.length; i += 3) {
const x = positions[i];
const y = positions[i + 1];
const u = (x - minX) / rangeX;
const v = (y - minY) / rangeY;
uvs.push(u, v);
}
geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));
- 怎么用?
stlLoader.load('./src/stl/Down/測試123456.stl', geometry => {
const positions = geometry.getAttribute('position').array;
// 找到模型頂點坐標的最小值和最大值
let minX = Number.POSITIVE_INFINITY;
let maxX = Number.NEGATIVE_INFINITY;
let minY = Number.POSITIVE_INFINITY;
let maxY = Number.NEGATIVE_INFINITY;
for (let i = 0; i < positions.length; i += 3) {
const x = positions[i];
const y = positions[i + 1];
minX = Math.min(minX, x);
maxX = Math.max(maxX, x);
minY = Math.min(minY, y);
maxY = Math.max(maxY, y);
}
// 計算頂點坐標范圍
const rangeX = maxX - minX;
const rangeY = maxY - minY;
// 計算 UV 坐標并歸一化到 0 到 1 之間
const uvs = [];
for (let i = 0; i < positions.length; i += 3) {
const x = positions[i];
const y = positions[i + 1];
const u = (x - minX) / rangeX;
const v = (y - minY) / rangeY;
uvs.push(u, v);
}
geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));
//~~~
mesh0 = new THREE.Mesh(geometry, material_tooth_0);
mesh0_ = new THREE.Mesh(geometry, material_tooth_);
mesh0_history = mesh0.clone();
objects.push(mesh0);
scene.add(mesh0);
});
為什么要使用著色器?直接使用three.js內(nèi)置的光照、陰影、反射、折射等內(nèi)置的成員屬性不香嗎?
使用著色器(Shaders)而不是僅依賴three.js的內(nèi)置光照、陰影、反射、折射等功能,主要有以下幾個原因:
-
高度自定義和靈活性: 著色器提供了對渲染過程的底層控制,使得你可以創(chuàng)建獨特和復雜的視覺效果,這些效果可能無法通過three.js的標準材質(zhì)和光源直接實現(xiàn)。例如,你可以創(chuàng)建自定義的波紋效果、獨特的光照模型或高級的粒子效果。
-
性能優(yōu)化: 對于特定的應用,使用自定義著色器可能比使用three.js的高級材質(zhì)更高效。自定義著色器允許你精確地控制GPU執(zhí)行哪些操作,從而優(yōu)化性能,特別是在復雜場景或需要渲染大量對象時。
-
藝術(shù)和創(chuàng)意表達: 著色器允許藝術(shù)家和開發(fā)者通過代碼實現(xiàn)他們的創(chuàng)意視覺,提供了一種新的表達方式。這在藝術(shù)作品、視覺效果和游戲開發(fā)中尤其有價值。
-
實現(xiàn)特定的圖形技術(shù): 某些高級圖形技術(shù),如光線追蹤、體積渲染或特殊的材質(zhì)效果,可能需要使用著色器來實現(xiàn)。
-
學習和探索: 學習著色器編程可以加深你對圖形學的理解,提高你在WebGL和three.js上的技術(shù)水平。
雖然three.js提供了豐富的內(nèi)置功能來處理光照、材質(zhì)等,但這些功能有時可能不足以滿足所有的視覺需求或性能要求。因此,著色器是一個強大的工具,用于在需要時擴展和增強three.js的能力。然而,需要注意的是,編寫和維護著色器代碼通常比使用three.js的標準功能更復雜,需要更深入的圖形學知識和GLSL編程技能。文章來源:http://www.zghlxwxcb.cn/news/detail-798186.html
使用著色器glsl語言,讓你不限于JavaScript,而更像是在開發(fā)opengl的項目!!!并且glsl著色器語言在c++也具有普遍性!!!文章來源地址http://www.zghlxwxcb.cn/news/detail-798186.html
到了這里,關(guān)于如何學習three.js的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!