各位道友,欢迎回到三维修仙界!上集我们开辟了三维虚空,今日将修炼操纵物质法则的终极仙术——编写着色器天书,并召唤上古神兽(加载3D模型)助阵!(๑•̀ᄇ•́)و ✧
章前虚空词典(中)
🔍 元婴境术语表:
- GLSL:Graphics Library Shading Language(虚空法则书写术)
- Vertex Shader:控制时空扭曲的基因编辑器
- Fragment Shader:决定物质显色的造化炉
- 骨骼动画:驱动神兽行动的经脉系统
- 法线贴图:用平面伪装凹凸的障眼法
第一转:GLSL天书入门
着色器语法精要
1. 变量类型(灵力容器)
// 标量(单灵根)
float pi = 3.14159; // 浮点数
int counter = 42; // 整数
bool isOpen = true; // 布尔
// 向量(多灵根聚合)
vec2 coord = vec2(0.5, 0.5); // 二维
vec3 color = vec3(1.0, 0.0, 0.5); // 三维(RGB颜色)
vec4 position = vec4(coord, 0.0, 1.0); // 四维(齐次坐标)
// 矩阵(空间变换阵)
mat4 transform = mat4(1.0); // 4x4单位矩阵
2. 数据传递通道
// 输入属性(从凡间接收数据)
attribute vec3 position; // 顶点坐标
attribute vec2 uv; // 纹理坐标
// 统一变量(仙界全局参数)
uniform mat4 projectionMatrix; // 投影矩阵
uniform float time; // 时间流逝
// 输出传递(着色器间传讯)
varying vec2 vUv; // 向片元着色器传递UV
3. 常用函数库(仙界法则)
// 坐标变换
vec4 worldPosition = modelMatrix * vec4(position, 1.0);
// 颜色空间转换
float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
// 噪声生成
float noise = fract(sin(dot(uv, vec2(12.9898,78.233))) * 43758.5453);
第二转:自定义材质炼丹术
编写赛博朋克风格着色器
1. 顶点着色器(时空扭曲)
varying vec2 vUv;
varying vec3 vPosition;
void main() {
vUv = uv;
vPosition = position;
// 添加正弦波动
vec3 pos = position;
pos.z += sin(position.x * 10.0 + time) * 0.2;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}
2. 片元着色器(赛博显色)
uniform float time;
varying vec2 vUv;
varying vec3 vPosition;
void main() {
// 生成流光条纹
float stripe = step(0.8, fract(vUv.y * 50.0 + time));
// 计算扫描线
float scanLine = sin(vUv.y * 800.0) * 0.1 + 0.9;
// 边缘辉光
float glow = pow(1.0 - length(vUv - 0.5), 4.0);
// 最终颜色合成
vec3 color = vec3(0.0, 0.5, 1.0); // 基色
color = mix(color, vec3(1.0, 0.0, 0.5), stripe);
color *= scanLine;
color += glow * vec3(0.8, 0.2, 1.0);
gl_FragColor = vec4(color, 1.0);
}
3. Three.js整合
const cyberMaterial = new THREE.ShaderMaterial({
uniforms: {
time: { value: 0 },
// 可添加更多uniform...
},
vertexShader: document.querySelector('#vertexShader').textContent,
fragmentShader: document.querySelector('#fragmentShader').textContent
});
// 在动画循环中更新
function animate() {
cyberMaterial.uniforms.time.value = performance.now() / 1000;
// ...
}
第三转:神兽召唤仪式
加载glTF上古神兽
1. 准备祭坛(初始化加载器)
const loader = new THREE.GLTFLoader();
const dracoLoader = new THREE.DRACOLoader();
dracoLoader.setDecoderPath('https://www.gstatic.com/draco/v1/decoders/');
loader.setDRACOLoader(dracoLoader);
// 添加进度条反馈
const progressBar = document.createElement('div');
progressBar.style.cssText = `/* 样式代码省略 */`;
document.body.appendChild(progressBar);
2. 召唤神兽(模型加载)
loader.load(
'models/ancient_dragon.glb',
(gltf) => {
const model = gltf.scene;
// 调整神兽体型
model.scale.set(0.5, 0.5, 0.5);
model.position.y = -1;
// 添加神兽阴影
model.traverse(child => {
if (child.isMesh) {
child.castShadow = true;
child.receiveShadow = true;
}
});
scene.add(model);
progressBar.remove();
},
(xhr) => {
const percent = (xhr.loaded / xhr.total * 100).toFixed(2);
progressBar.style.width = `${percent}%`;
},
(error) => {
console.error('召唤失败:', error);
}
);
3. 激活经脉(骨骼动画)
let mixer;
loader.load('models/dragon_animated.glb', (gltf) => {
const animations = gltf.animations;
mixer = new THREE.AnimationMixer(gltf.scene);
// 获取动作招式
const actions = {
idle: mixer.clipAction(animations[0]),
fly: mixer.clipAction(animations[1]),
attack: mixer.clipAction(animations[2])
};
// 播放待机动作
actions.idle.play();
// 绑定键盘控制
document.addEventListener('keydown', (e) => {
if (e.key === '1') actions.fly.play();
if (e.key === '2') actions.attack.play();
});
});
// 在动画循环中更新
const clock = new THREE.Clock();
function animate() {
if (mixer) mixer.update(clock.getDelta());
// ...
}
第四转:仙器锻造法
法线贴图与PBR材质
const textureLoader = new THREE.TextureLoader();
// 加载PBR纹理套装
const pbrTextures = {
normal: textureLoader.load('textures/iron_normal.jpg'),
roughness: textureLoader.load('textures/iron_roughness.jpg'),
metalness: textureLoader.load('textures/iron_metalness.jpg'),
ao: textureLoader.load('textures/iron_ao.jpg')
};
// 锻造仙器材质
const swordMaterial = new THREE.MeshStandardMaterial({
metalness: 0.9,
roughness: 0.1,
normalMap: pbrTextures.normal,
aoMap: pbrTextures.ao,
envMap: scene.background // 需要设置环境贴图
});
// 应用环境光遮蔽
swordMaterial.aoMapIntensity = 1.0;
// 创建剑刃
const swordGeometry = new THREE.BoxGeometry(2, 0.2, 0.05);
const sword = new THREE.Mesh(swordGeometry, swordMaterial);
scene.add(sword);
渡劫实验室
实操作业:神兽武装计划
- 为召唤的龙模型添加火焰粒子特效
- 使用自定义着色器实现鳞片动态光泽
- 制作神兽的翅膀振动动画
(参考解法将在下集通过「虚空传音」公布,道友可先行参悟)
元婴境(中)毕业标准:
✅ 能编写基础GLSL着色器
✅ 掌握glTF模型加载流程
✅ 了解骨骼动画控制原理
✅ 会使用PBR材质系统
👉 下集预告:《元婴境(下)·虚空幻境与法则融合》,将揭秘:
- 后处理特效链
- 光线追踪伪实现
- 物理引擎整合
- 跨维度粒子系统
虚空浩瀚,道法无涯,我们下集再会! 🐉✨