学习three.js最好的方法是通过理解它的核心概念和最常用的组件。
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.z = 5;
除了透视相机,还有正交相机(OrthographicCamera).
不说八股文,就说在实战中的体验:
透视相机,在左右移动时,会变形(会有一种拉扯的感觉);
正交相机不会有拉扯的感觉
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场景渲染到屏幕的一种方式.
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial(
{
color: 0x00ff00
}
);
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
var light = new THREE.PointLight(0xffffff, 1, 100);
light.position.set(50, 50, 50);
scene.add(light);
function animate() {
requestAnimationFrame(animate);
// 任何动画的更新
renderer.render(scene, camera);
}
animate();
着色器是three.js中较高级的概念,用于自定义物体的渲染方式。着色器写在GLSL(OpenGL Shading Language)中,分为两种:
var shaderMaterial = new THREE.ShaderMaterial({
vertexShader: `...`, // GLSL代码
fragmentShader: `...`, // GLSL代码
});
答:
关于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);
});
使用着色器(Shaders)而不是仅依赖three.js的内置光照、阴影、反射、折射等功能,主要有以下几个原因:
高度自定义和灵活性: 着色器提供了对渲染过程的底层控制,使得你可以创建独特和复杂的视觉效果,这些效果可能无法通过three.js的标准材质和光源直接实现。例如,你可以创建自定义的波纹效果、独特的光照模型或高级的粒子效果。
性能优化: 对于特定的应用,使用自定义着色器可能比使用three.js的高级材质更高效。自定义着色器允许你精确地控制GPU执行哪些操作,从而优化性能,特别是在复杂场景或需要渲染大量对象时。
艺术和创意表达: 着色器允许艺术家和开发者通过代码实现他们的创意视觉,提供了一种新的表达方式。这在艺术作品、视觉效果和游戏开发中尤其有价值。
实现特定的图形技术: 某些高级图形技术,如光线追踪、体积渲染或特殊的材质效果,可能需要使用着色器来实现。
学习和探索: 学习着色器编程可以加深你对图形学的理解,提高你在WebGL和three.js上的技术水平。
虽然three.js提供了丰富的内置功能来处理光照、材质等,但这些功能有时可能不足以满足所有的视觉需求或性能要求。因此,着色器是一个强大的工具,用于在需要时扩展和增强three.js的能力。然而,需要注意的是,编写和维护着色器代码通常比使用three.js的标准功能更复杂,需要更深入的图形学知识和GLSL编程技能。
使用着色器glsl语言,让你不限于JavaScript,而更像是在开发opengl的项目!!!并且glsl着色器语言在c++也具有普遍性!!!