1、彩色效果图:
1.1彩色图的片元着色器:
const fragment = `
uniform sampler2D texture1;
varying vec2 vUv;
void main(){
gl_FragColor = texture2D(texture1,vUv);
}
`;
2、灰度效果图
2.1灰度图的片元着色器:
//灰度图公式: R*0.299 + G*0.587 + B*0.114
const fragment = `
uniform sampler2D texture1;
varying vec2 vUv;
void main(){
vec4 tColor= texture2D(texture1,vUv);
float gray = tColor.r*0.299 + tColor.g*0.587 + tColor.b*0.114;
gl_FragColor = vec4(gray,gray,gray,1.0);
}
`;
3完整源代码
import { PerspectiveCamera, Scene, ShaderMaterial, Mesh, WebGLRenderer, SphereGeometry, TextureLoader } from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
export class LearnShader {
private scene!: Scene;
private camera!: PerspectiveCamera;
private webGLRenderer!: WebGLRenderer;
constructor() {
this.scene = new Scene();
this.camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 1000);
this.camera.position.set(100, 100, 200);
this.camera.lookAt(this.scene.position);
this.webGLRenderer = new WebGLRenderer({ antialias: true });
this.webGLRenderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(this.webGLRenderer.domElement);
const vertex = `
varying vec2 vUv;
void main(){
vUv = uv;
gl_Position = projectionMatrix*viewMatrix*modelMatrix*vec4(position,1.0);
}
`;
const fragment = `
uniform sampler2D texture1;
varying vec2 vUv;
void main(){
vec4 tColor= texture2D(texture1,vUv);
float gray = tColor.r*0.299 + tColor.g*0.587 + tColor.b*0.114;
gl_FragColor = vec4(gray,gray,gray,1.0);
}
`;
const geometry = new SphereGeometry(40, 40, 40);
const material = new ShaderMaterial({
uniforms: {
texture1: {
value: new TextureLoader().load('../assets/Earth.png')
}
},
vertexShader: vertex,
fragmentShader: fragment
});
const mesh = new Mesh(geometry, material);
this.scene.add(mesh);
new OrbitControls(this.camera, this.webGLRenderer.domElement);
window.addEventListener('resize', () => this.onWindowResize());
this.render();
}
private onWindowResize() {
this.webGLRenderer.setSize(window.innerWidth, window.innerHeight);
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix(); //相机属性发生变化更新投影矩阵
}
private render() {
window.requestAnimationFrame(() => this.render());
this.webGLRenderer.render(this.scene, this.camera);
}
}