简介
上一节我们了解了着色器材质,这节我们了解如何使用着色器。
着色器变量
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 );
}
`
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 。
|