题目1
实现左黑右白+四宫格棋盘(左下+右上白,左上+右下黑,任意宫格)
效果:
代码:
import * as THREE from 'three'
export default class CheckerBoard extends THREE.Group{
private mesh: THREE.Mesh<THREE.PlaneGeometry, THREE.ShaderMaterial>;
private mesh1: THREE.Mesh<THREE.PlaneGeometry, THREE.ShaderMaterial>;
private mesh2: THREE.Mesh<THREE.PlaneGeometry, THREE.ShaderMaterial>;
private tile:number;
private startTime:number;
// private clock:THREE.Clock;
constructor(){
super()
this.tile=2;
// this.clock = new THREE.Clock();
this.startTime = Date.now();
const geometry = new THREE.PlaneGeometry(2,2);
const material = new THREE.ShaderMaterial({
vertexShader:`
varying vec2 vUv;
void main(){
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}
`,
fragmentShader:`
varying vec2 vUv;
void main(){
float color = floor(2.0 * vUv.x);
gl_FragColor = vec4(vec3(color),1.0);
}
`
});
this.mesh = new THREE.Mesh(geometry,material);
this.mesh.position.set(-4,0,0);
this.add(this.mesh);
const material1 = new THREE.ShaderMaterial({
vertexShader:`
varying vec2 vUv;
void main(){
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}
`,
// fragmentShader:`
// varying vec2 vUv;
// void main(){
// float colorX = floor(2.0 * vUv.x);
// float colorY = floor(2.0 * vUv.y);
// int color = 1 - int(colorX)^int(colorY);
// gl_FragColor = vec4(vec3(color),1.0);
// }
// `
// fragmentShader:`
// varying vec2 vUv;
// void main(){
// vec2 vUv1 = floor(2.0 * vUv);
// int color = 1 - int(vUv1.x)^int(vUv1.y);
// gl_FragColor = vec4(vec3(color),1.0);
// }
// `
fragmentShader:`
varying vec2 vUv;
void main(){
float colorX = floor(2.0 * vUv.x);
float colorY = floor(2.0 * vUv.y);
float color = 1.0 - abs(colorX - colorY);
gl_FragColor = vec4(vec3(color),1.0);
}
`
})
this.mesh1 = new THREE.Mesh(geometry,material1);
this.add(this.mesh1);
const material2 = new THREE.ShaderMaterial({
uniforms:{
tile:{ value:this.tile}
},
vertexShader:`
varying vec2 vUv;
void main(){
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}
`,
fragmentShader:`
uniform float tile;
varying vec2 vUv;
// 使用 mod 函数计算行列值之和的奇偶性,并使用 mix 函数计算黑白颜色
vec4 getColor(float x,float y){
float modValue = mod(x+y,2.0);
return mix(vec4(1.0,1.0,1.0,1.0),vec4(0.0,0.0,0.0,1.0),modValue);
}
void main(){
// 将纹理坐标乘上tile值,得到当前格子的坐标;
vec2 uv = vUv * tile;
// 取整数部分,得到当前格子所在的行列值
float x = floor(uv.x);
float y = floor(uv.y);
gl_FragColor = getColor(x,y);
}
`
});
this.mesh2 = new THREE.Mesh(geometry,material2);
this.mesh2.position.set(4,0,0);
this.add(this.mesh2);
}
public update():void{
const gap = ((Date.now() - this.startTime) / 500) % 1;
// console.log(gap)
// 每1秒变化
if(gap >0.9){
this.startTime = Date.now();
this.tile = (this.tile + 1) % 10;
this.mesh2.material.uniforms.tile.value = this.tile;
}
// const delta = this.clock.getDelta();
// console.log(delta)
// if(delta>=1.0){
// // this.clock.start();
// this.tile = (this.tile + 1) % 10;
// this.mesh2.material.uniforms.tile.value = this.tile;
// }
}
}
题目2
实现如下动态图效果:循环由左至右,由黑变白
代码
// construct
const geometry1 = new THREE.PlaneGeometry(10,2);
const material3 = new THREE.ShaderMaterial({
uniforms:{
progress:{ value: 0}
},
vertexShader:`
varying vec2 vUv;
void main(){
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}
`,
fragmentShader:`
varying vec2 vUv;
uniform float progress;
void main(){
float val = step(vUv.x,progress);
vec4 color = mix(vec4(0.0,0.0,0.0,1.0),vec4(1.0,1.0,1.0,1.0),val);
gl_FragColor = color;
}
`
});
this.mesh3 = new THREE.Mesh(geometry1,material3);
this.add(this.mesh3);
更新函数
public update():void{
const gap = (Date.now() - this.startTime) / 1000;
this.mesh3.material.uniforms.progress.value = gap;
}
题目3
实现任意宽高的plane上,以较短的边作为直径,生成一个渐变的圆,由圆心至圆周率,由黑变白 效果如下
代码
import * as THREE from 'three';
export default class CircleOnPlane extends THREE.Group{
private width: number;
private height: number;
private mesh: THREE.Mesh<THREE.PlaneGeometry,THREE.ShaderMaterial>;
constructor(width:number,height:number){
super();
this.width=width;
this.height=height;
const geometry = new THREE.PlaneGeometry(width,height);
const material = new THREE.ShaderMaterial({
uniforms:{
width: { value: this.width },
height: { value: this.height }
},
vertexShader:`
varying vec2 vUv;
void main(){
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}
`,
fragmentShader:`
varying vec2 vUv;
uniform float width;
uniform float height;
void main(){
vec2 vUv1 = vec2(vUv.x * width - width * .5,vUv.y * height - height * .5);
float r = min(width,height) * 0.5;
float len = length(vUv1);
// float progress = mix(smoothstep(0.0,r,len),1.0,step(r,len));
gl_FragColor = mix(vec4(0.0,0.0,0.0,1.0),vec4(1.0,1.0,1.0,1.0),smoothstep(0.0,r,len));
gl_FragColor = mix(vec4(0.0,0.0,0.0,1.0),vec4(1.0,1.0,1.0,1.0),len/r);
// gl_FragColor = vec4(vec3(length((vUv - .5) * normalize(vec2(width, height))) * 4.),1.0);
gl_FragColor = vec4(vec3(length((vUv - .5) * vec2(width/height, 1.)) * 2.0),1.0);
}
`
});
this.mesh = new THREE.Mesh(geometry,material);
this.add(this.mesh);
}
}