简介
上一节我们了解了着色器材质,这节我们了解如何使用着色器。
着色器变量
- 着色器中有三种变量:
Uniforms
全局变量。可以传入顶点着色器,也可以传入片元着色器,在整个渲染过程中保持不变的变量。Varyings
是从顶点着色器传递到片元着色器的变量。我们需要确保在两个着色器中变量的类型和命名完全一致。Attributes
与每个顶点关联的变量。例如,顶点位置,法线和顶点颜色都是存储在attributes
中的数据。它只能在顶点着色器获取。
绘制一个只有4/1变色的圆
- 基础模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>学习</title>
</head>
<body>
<canvas id="c2d" class="c2d" width="1000" height="500"></canvas>
<script type="module">
import * as THREE from './file/three.js-dev/build/three.module.js'
import { OrbitControls } from './file/three.js-dev/examples/jsm/controls/OrbitControls.js'
const canvas = document.querySelector('#c2d')
// 渲染器
const renderer = new THREE.WebGLRenderer({ canvas })
const fov = 40 // 视野范围
const aspect = 2 // 相机默认值 画布的宽高比
const near = 0.1 // 近平面
const far = 10000 // 远平面
// 透视投影相机
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far)
camera.position.set(0, 100, 0)
camera.lookAt(0, 0, 0)
// 控制相机
const controls = new OrbitControls(camera, canvas)
controls.update()
// 场景
const scene = new THREE.Scene()
// 渲染
function render() {
renderer.render(scene, camera)
requestAnimationFrame(render)
}
requestAnimationFrame(render)
</script>
</body>
</html>
- 创建着色器。
// 顶点着色器代码
const vertexShader = `
varying vec3 vPosition;// 创建变量 在片元着色器 中使用
void main() {
vPosition = position;// 赋值 顶点坐标
// projectionMatrix 是投影变换矩阵 modelViewMatrix 是相机坐标系的变换矩阵 position 顶点坐标
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
`
// mod(x,y)返回x – y * floor (x/y),即求模计算%
// 片元着色器代码
const fragmentShader = `
varying vec3 vPosition;// 获取顶点着色器 设置的变量
uniform float time;// 获取传入的 全局变量
void main() {
float time = mod(time, 3.0);
if(vPosition.x > 0.0 && vPosition.y > 0.0){
if(time < 1.0){
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
} else if(time >= 1.0 && time < 2.0){
gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
}else{
gl_FragColor = vec4(1.0, 0.7, 0.0, 1.0);
}
}else{
gl_FragColor=vec4(0.2, 0.2, 0.2, 1.0);
}
}
`
three.js
在顶点着色器中定义好了一下关于顶点信息的变量,如position、modelViewMatrix
等。- 创建
vPosition
变量把顶点信息传入片元着色器。 - 在片元着色器中获取
time
全局变量,用于在不同时间修改颜色。 - 根据顶点坐标来判断几何体要修改颜色的位置。
- 创建全局变量。
const uniforms = {
time: {
type: 'f',
value: 0.0
}
}
type
定义数据类型。
- 创建球几何体,使用着色器材质。
const geometry = new THREE.SphereGeometry(15, 32, 16)
const mate = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: vertexShader,
fragmentShader: fragmentShader
})
const mesh = new THREE.Mesh(geometry, mate)
scene.add(mesh)
- 修改渲染函数。
// 渲染
function render() {
uniforms.time.value += 0.1
renderer.render(scene, camera)
requestAnimationFrame(render)
}
- 通过渲染函数修改全局变量大小。
- 每一次执行渲染,着色器会重新执行,获取最新的
uniforms
。