这节课给大家讲解 顶点位置插值 position ,然后利用插值的顶点位置数据,逐片元操作,实现一个网格模型Mesh沿着y轴方向进行颜色渐变。
position
上节课给大家讲解过,你通过着色器语言GLSL ES关键字varying声明一个变量vColor,然后main函数中执行 vColor = color; ,就可以对顶点颜色数据 color 进行插值计算,插值后 vColor 的颜色数据量与片元数量一致,也就是说每一个片元都能对应一个顶点颜色插值数据 vColor
vColor = color;
color
vColor
// 顶点着色器代码 const vertexShader = ` // attribute vec3 color;//默认提供不用手写 varying vec3 vColor;// varying关键字声明一个变量表示顶点颜色插值后的结果 void main(){ vColor = color;// 顶点颜色数据进行插值计算 // 投影矩阵 * 模型视图矩阵 * 模型顶点坐标 gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
// 片元着色器代码 const fragmentShader = ` varying vec3 vColor;// 顶点片元化后有多少个片元,顶点颜色插值后就有多少个颜色数据 void main() { // gl_FragColor = vec4(0.0,1.0,1.0,1.0); gl_FragColor = vec4(vColor,1.0);
不仅仅顶点颜色color数据可以通过顶点着色器插值计算,其实所有类型的顶点数据都可以,比如顶点位置数据 position 。
你只需要记住一个规律,任何类型的顶点数据,插值计算后,都会生成和所有片元一一对应的新数据。
// 顶点着色器代码 const vertexShader = ` varying vec3 vPosition;//表示顶点插值后位置数据,与片元数量相同,一一对应 void main(){ vPosition = position;// 顶点位置坐标插值计算 gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
positon
vPosition
根据几何体顶点坐标控制Mesh的颜色,y坐标小于0部分,红色,其他部分绿色。
// 片元着色器代码 const fragmentShader = ` varying vec3 vPosition;//获取顶点着色器插值数据vPosition void main() { // 根据vPosition位置控制片元颜色 if(vPosition.y < 0.0){ gl_FragColor = vec4(1.0,0.0,0.0,1.0); }else{ gl_FragColor = vec4(0.0,0.0,1.0,1.0);
控制Mesh沿着y方向,从底部到顶部进行颜色渐变,底部是绿色,顶部是红色。
下面以Mesh的几何体为准,几何体是一个矩形平面 PlaneGeometry ,底部顶点y坐标-25,顶部顶点y坐标25
PlaneGeometry
const geometry = new THREE.PlaneGeometry(100, 50); // 片元着色器代码 const fragmentShader = ` varying vec3 vPosition; void main() { float per = (vPosition.y + 25.0)/50.0; // 几何体顶点y坐标25,颜色值:1 0 0(红色) // 几何体顶点y坐标-25,颜色值:0 1 0(绿色) gl_FragColor = vec4(per,1.0-per,0.0,1.0);
刚才说话所有类型顶点数据都可以插值,你也可以测试,把顶点数据先用 模型矩阵modelMatrix 进行变换,再插值计算。
这个时候 vPosition 反应就不仅仅是几何体geometry顶点的位置了,也包含mesh自身的旋转、缩放、平移。
// 顶点着色器代码 const vertexShader = ` varying vec3 vPosition; void main(){ // vPosition = position; // 考虑mesh及其父对象旋转、缩放、平移的影响 vPosition = vec3(modelMatrix * vec4( position, 1.0 )); gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
你可以把mesh向上平移 mesh.position.y += 25; 。这时候你想想怎么写片元着色器代码,保证矩形平面底部绿色,顶部红色,然后进行渐变。
mesh.position.y += 25;
// 片元着色器代码 const fragmentShader = ` varying vec3 vPosition; void main() { float per = vPosition.y /50.0; // Mesh y坐标50,颜色值:1 0 0(红色) // Mesh y坐标0,颜色值:0 1 0(绿色) gl_FragColor = vec4(per,1.0-per,0.0,1.0);
8. 顶点颜色varying插值计算 10. 颜色贴图map(顶点UV坐标) → Theme by Vdoing 豫ICP备16004767号-2