着色器glsl基础
shader中的各种数据类型
RawShaderMaterial 和 ShaderMaterial
shader是什么?
shader是一个用GLSL编写的小程序,也就是着色器语言,我们可以通过shader来编写顶点着色器和片元着色器,在WEBGL编程一书中 25-26页有详细说明。
threejs提供了关于shader的材质 RawShaderMaterial 和 ShaderMaterial 两种编写shader的材质。
RawShaderMaterial:不内置uniforms和attributes
ShaderMaterial:内置一些需要的参数,后期的使用都为此材质
这里的教程使用的教程为ShaderMaterial
?浏览器的渲染图
顶点着色器代码运行在GPU的顶点着色器单元,片元着色器代码运行在片元着色器单元。
欧拉角
欧拉角分为以x、y、z方向做旋转,其中分为外中内三个方向,外面的方向旋转,里面的方向会跟着旋转,但是x、y、z各自方向独立,会造成万向节死锁。
四元数
WebGL和canvas渲染方式
三者的关系是 JavaScript -> WebGL -> OpenGL ->… -> 显卡 并把最终渲染出来图形 呈现到Canvas。
所以,能使用WebGL的前提是浏览器支持WebGL,且显卡支持OpenGL ES2.0才可以。
canvas是一个H5标签,作用是在网页上画图,但是只支持2D,不支持3D。WebGL是一种3D绘图标准,WebGL支持3D,且性能优于canvas。所以现在能用WebGL的都用WebGL,有些项目用canvas是因为部分手机不支持WebGL。
OpenGL是 底层的驱动级的图形接口(是显卡有直接关系的) 类似于 DirectX
但是这种底层的OpenGL是 寄生于浏览器的JavaScript无法涉及的
但是为了让Web拥有更强大的 图形处理能力 2010年时候WebGL被推出来
WebGL允许工程师使用JS去调用部分封装过的 OpenGL ES2.0标准接口去 提供硬件级别的3D图形加速功能。
使用three.js里的各种光源
PointLight 点光源 常用
聚光灯 距离越远,光越弱
DirectionalLight(方向光源) 类似太阳光则不会这样
旋转平移放到
// 几何体xyz三个方向都放大2倍
// geometry.scale(2, 2, 2);
// 几何体沿着x轴平移50
// geometry.translate(50, 0, 0);
// 几何体绕着x轴旋转45度
// geometry.rotateX(Math.PI / 4);
// 居中:偏移的几何体居中
// geometry.center();
-----------
// 网格模型xyz方向分别缩放0.5,1.5,2倍
// mesh.scale.set(0.5, 1.5, 2)
// 直接设置网格模型的位置
// mesh.position.set(100, 100, 100)
// 网格模型沿着x轴方向平移100
// mesh.translateX(100);
//沿着axis轴表示方向平移100
// mesh.translateOnAxis(axis, 100);
// 绕着Y轴旋转90度
// mesh.rotateY(Math.PI / 2);
// 绕axis轴旋转90度
// mesh.rotateOnAxis ( axis, Math.PI / 2 )
// console.log(mesh.rotation);//控制台查看:旋转方法,改变了rotation属性
面法线跟顶点法线的区别
一般情况下,面的法向量和顶点的法向量是相同的。
三角形的顶点计算,面的法向量
假设一个三角形由顶点 po、p1 和 p2 组成,我们需要计算每个顶点 n0、n1 和 n2 的顶点法线。
首先计算位于三角形上的两个向量:
p1 - p0 = a
p2 - p0 = b
求得面法线:
n = a * b (* 是叉乘运算)
// 所以同一个顶点可以有不同的法线
面法线跟顶点法线的区别
three.js(3):点、线、面(颜色插值,几何体三种渲染方式)
face 法向量,颜色两种设置设置
三个点的法向量如何求出面的法向量
Three.js几何体顶点颜色和材质颜色区别
设置模型的几何体顶点颜色时候,
对于Geometry几何体,如果是点Points或线Line模型,可以直接设置几何体对象的.colors属性,
如果是网格模型Mesh,需要通过三角形属性.faces来设置顶点颜色,Face3.color或Face3.vertexColors。
对于BufferGeometry几何体而言,直接设置attributes.color属性就可以,一般加载的外部模型都是BufferGeometry几何体。
--------
// 定点设置颜色的时候不需要关心material的颜色,这里有参数看选择材质渲染还是定点颜色渲染
var material = new THREE.MeshBasicMaterial({
// 使用顶点颜色数据渲染模型,不需要再定义color属性
// color: 0xff0000,
vertexColors: THREE.VertexColors, //以顶点颜色为准
// vertexColors:THREE.FaceColors
});
// Mesh
光照,法向量,Material的颜色
clone 和 copy方法
mesh clone方法 复制所有属性
mesh copy 方法 复制mesh的位置、旋转、矩阵等属性(不包含geometry和material属性)
Vector3 clone方法 返回一个新的对象
Vector3 copy 向量p1三个分量xyz的值覆盖向量p2三个分量
texture
// uv两个方向纹理重复数量
texture.repeat.set(4, 2);
// 不设置重复 偏移范围-1~1
texture.offset = new THREE.Vector2(0.3, 0.1)
// 设置纹理旋转角度
texture.rotation = Math.PI/4;
// 设置纹理的旋转中心,默认(0,0)
texture.center.set(0.5,0.5);
geometry和buffergeometry有啥区别
和geometry一样,BufferGeometry存储顶点、面索引、法线、颜色、纹理坐标和自定义的一些几何体数据
BufferGeometry更高效的秘密:将数据放在一块连续的内存空间中
连续的存储空间能够节省传递数据到cpu的时间(把数据放到显卡GPU中的时间)
一 旋转动画,requestAnimationFrame周期性渲染
// 渲染函数
function render() {
renderer.render(scene,camera);//执行渲染操作
mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
requestAnimationFrame(render);//请求再次执行渲染函数render,渲染下一帧
}
render();
旋转缩放
// 渲染函数
function render() {
renderer.render(scene, camera); //执行渲染操作
}
render();
//创建控件对象 相机对象camera作为参数 控件可以监听鼠标的变化,改变相机对象的属性
var controls = new THREE.OrbitControls(camera);
//监听鼠标事件,触发渲染函数,更新canvas画布渲染效果
controls.addEventListener('change', render);
多个几何体
/**
* 创建网格模型
*/
//长方体 参数:长,宽,高
// var geometry = new THREE.BoxGeometry(100, 100, 100);
// 球体 参数:半径60 经纬度细分数40,40
// var geometry = new THREE.SphereGeometry(60, 40, 40);
// 圆柱 参数:圆柱面顶部、底部直径50,50 高度100 圆周分段数
// var geometry = new THREE.CylinderGeometry( 50, 50, 100, 25 );
// 正八面体
// var geometry = new THREE.OctahedronGeometry(50);
// 正十二面体
// var geometry = new THREE.DodecahedronGeometry(50);
// 正二十面体
var geometry = new THREE.IcosahedronGeometry(50);
多个几何体的偏移
mesh2.translateY(120); //球体网格模型沿Y轴正方向平移120
// mesh3.translateX(120); //球体网格模型沿Y轴正方向平移120
mesh3.position.set(120,0,0);//设置mesh3模型对象的xyz坐标为120,0,0
辅助坐标系
var axisHelper = new THREE.AxisHelper(250);
scene.add(axisHelper);
不同材质
//基础网格材质对象 不受光照影响 没有棱角感
// var material = new THREE.MeshBasicMaterial({
// color: 0x0000ff,
// wireframe:true,//线条模式渲染
// });
// 与光照计算 漫反射 产生棱角感
// var material = new THREE.MeshLambertMaterial({
// color: 0x00ff00,
// });
// 与光照计算 高光效果(镜面反射) 产生棱角感
var material = new THREE.MeshPhongMaterial({
color: 0xff0000,
specular:0x444444, // 高光部分的颜色
shininess:30, // 高光部分的亮度,默认30
emissive: 30 // 这是该材质的发射的颜色。它其实并不像一个光源,只是一种纯粹的、不受其它光照影响的颜色。默认值为黑色
wireframe:true
});
半透明
var material1 = new THREE.MeshLambertMaterial({
color: 0x0000ff,//材质颜色
transparent:true,//开启透明度
opacity:0.5,//设置透明度具体值
}); //材质对象Material
点光源与位置设置
//点光源
var point = new THREE.PointLight(0xffffff);
point.position.set(400, 200, 300); //点光源位置
scene.add(point); //点光源添加到场景中
// 点光源2 位置和point关于原点对称
var point2 = new THREE.PointLight(0xffffff);
point2.position.set(-400, -200, -300); //点光源位置
scene.add(point2); //点光源添加到场景中
//环境光 环境光颜色与网格模型的颜色进行RGB进行乘法运算
var ambient = new THREE.AmbientLight(0x444444);
scene.add(ambient);