11. shader模仿点材质效果
# shader模仿点材质效果
先复习下前面基础课程,关于点材质PointsMaterial
和点模型 (opens new window)Points
的知识点。
const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array([
0, 0, 0, //顶点1坐标
25, 0, 0, //顶点2坐标
50, 0, 0, //顶点3坐标
75, 0, 0, //顶点4坐标
100, 0, 0, //顶点5坐标
]);
geometry.attributes.position = new THREE.BufferAttribute(vertices, 3);
const material = new THREE.PointsMaterial({
color: 0x00ffff,
size: 10.0 //点渲染大小调节
});
const points = new THREE.Points(geometry, material); //点模型对象
本节课任务就是借助ShaderMaterial
,自定义着色器GLSL ES代码,实现PointsMaterial
的部分渲染效果。
# 内置变量gl_PointSize
gl_PointSize
和gl_Position一样,都是顶点着色器GLSL ES的一个内置变量,gl_PointSize
作用是设置点渲染的像素大小。
// 顶点着色器代码
const vertexShader = `
void main(){
gl_PointSize = 20.0;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
`
测试上面代码效果的时候,模型对象要使用点模型Points
,而不是Mesh
,Mesh表示把几何体geometry
顶点数据渲染为三角形,Line
表示把顶点数据渲染为直线,Points
表示把顶点数据渲染为方形点。
// const mesh = new THREE.Mesh(geometry, material);
const mesh = new THREE.Points(geometry, material);
# 内置变量gl_PointCoord
(Point坐标)
gl_PointCoord
是片元着色器着色器GLSL ES的一个内置变量,与Points
渲染的方形点坐标相关,具体含义如下图:
Points
可以渲染多个方形点,每个方形点的gl_PointCoord
坐标原点都位于自身的左上角,x轴水平向右,y轴水平向下,不管gl_PointSize
多大,Points
方形点右下角gl_PointCoord
坐标都是(1.0,1.0)
。
你可以通过下面代码,进行测试验证。
方形点左边红色,右边蓝色
const fragmentShader = `
void main() {
if(gl_PointCoord.x<0.5){
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}else{
gl_FragColor = vec4(0.0,0.0,1.0,1.0);
}
}
`
方形点上边红色,下边蓝色
const fragmentShader = `
void main() {
if(gl_PointCoord.y<0.5){
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}else{
gl_FragColor = vec4(0.0,0.0,1.0,1.0);
}
}
`
左上角四分之一红色
// 片元着色器代码
const fragmentShader = `
void main() {
if(gl_PointCoord.x<0.5 && gl_PointCoord.y<0.5){
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}else{
gl_FragColor = vec4(0.0,0.0,1.0,1.0);
}
}
`
# 修剪方形点变成圆形点
distance()
是着色器语言GLSL ES内置函数,用来计算两个向量之间的距离。
distance(gl_PointCoord, vec2(0.5, 0.5));
表示方形点里面每个片元的gl_PointCoord
坐标与坐标(0.5,0.5)
的距离r。
以这个距离距离r作为临界值,每个方形点的所有片元凡是距离中心vec2(0.5, 0.5)的距离大于r,都舍弃,就会生成一个圆形的点。
// 片元着色器代码
const fragmentShader = `
void main() {
// vec2(0.5, 0.5)是方形点的圆心
float r = distance(gl_PointCoord, vec2(0.5, 0.5));
if(r < 0.5){
// 方形区域片元距离几何中心半径小于0.5,像素颜色设置红色
gl_FragColor = vec4(0.0,1.0,1.0,1.0);
}else {
// 方形区域距离几何中心半径不小于0.5的片元剪裁舍弃掉:
discard;
}
}
`