当前位置: 首页 > news >正文

第五部分-后期特效与着色器——27. 高级着色器

27. 高级着色器

1. 概述

高级着色器技术包括噪声函数、光照模型、后处理特效等。通过自定义着色器可以实现复杂视觉效果,如火焰、水波、溶解等。

┌─────────────────────────────────────────────────────────────┐ │ 高级着色器技术 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 噪声函数 │ │ ├── 正弦波噪声 │ │ ├── Simplex 噪声 │ │ ├── Perlin 噪声 │ │ └── 细胞噪声 │ │ │ │ 光照模型 │ │ ├── 漫反射光照 │ │ ├── 高光光照 │ │ ├── 环境光照 │ │ └── 法线贴图 │ │ │ │ 特效 │ │ ├── 溶解效果 │ │ ├── 边缘发光 │ │ ├── 扫描效果 │ │ └── 热浪扭曲 │ │ │ └─────────────────────────────────────────────────────────────┘

2. 噪声函数

2.1 正弦波噪声

// 简单的正弦波噪声 float wave = sin(position.x * 3.0 + uTime) * cos(position.z * 3.0 + uTime);

2.2 随机噪声

// 随机函数 float random(vec2 st) { return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.5453123); } // 使用随机噪声 float noise = random(vUv);

2.3 平滑噪声

// 平滑插值 float smoothNoise(vec2 st) { vec2 i = floor(st); vec2 f = fract(st); float a = random(i); float b = random(i + vec2(1.0, 0.0)); float c = random(i + vec2(0.0, 1.0)); float d = random(i + vec2(1.0, 1.0)); vec2 u = f * f * (3.0 - 2.0 * f); return mix(mix(a, b, u.x), mix(c, d, u.x), u.y); }

3. 光照模型

3.1 简单漫反射

// 漫反射光照 uniform vec3 uLightDir; uniform vec3 uLightColor; void main() { vec3 normal = normalize(vNormal); vec3 lightDir = normalize(uLightDir); float diff = max(dot(normal, lightDir), 0.0); vec3 diffuse = diff * uLightColor; gl_FragColor = vec4(diffuse, 1.0); }

3.2 完整光照模型

// 环境光 + 漫反射 + 高光 uniform vec3 uAmbientColor; uniform vec3 uLightDir; uniform vec3 uLightColor; uniform vec3 uViewPosition; uniform float uShininess; void main() { vec3 normal = normalize(vNormal); vec3 lightDir = normalize(uLightDir); vec3 viewDir = normalize(uViewPosition - vPosition); vec3 reflectDir = reflect(-lightDir, normal); // 环境光 vec3 ambient = uAmbientColor; // 漫反射 float diff = max(dot(normal, lightDir), 0.0); vec3 diffuse = diff * uLightColor; // 高光 float spec = pow(max(dot(viewDir, reflectDir), 0.0), uShininess); vec3 specular = spec * uLightColor; vec3 result = ambient + diffuse + specular; gl_FragColor = vec4(result, 1.0); }

4. 溶解效果

uniform sampler2D uTexture; uniform sampler2D uNoiseTexture; uniform float uProgress; uniform vec3 uEdgeColor; void main() { vec4 noise = texture2D(uNoiseTexture, vUv); float dissolve = noise.r; if (dissolve < uProgress) { discard; } vec4 color = texture2D(uTexture, vUv); // 边缘发光 float edge = smoothstep(uProgress, uProgress + 0.1, dissolve); vec3 finalColor = mix(uEdgeColor, color.rgb, edge); gl_FragColor = vec4(finalColor, 1.0); }

5. 完整示例

import*asTHREEfrom'three';import{OrbitControls}from'three/examples/jsm/controls/OrbitControls.js';constscene=newTHREE.Scene();scene.background=newTHREE.Color(0x111122);constcamera=newTHREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);camera.position.set(3,2,4);camera.lookAt(0,0,0);constrenderer=newTHREE.WebGLRenderer({antialias:true});renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(renderer.domElement);constcontrols=newOrbitControls(camera,renderer.domElement);controls.enableDamping=true;// 创建噪声纹理constcanvas=document.createElement('canvas');canvas.width=512;canvas.height=512;constctx=canvas.getContext('2d');constimageData=ctx.createImageData(canvas.width,canvas.height);for(leti=0;i<imageData.data.length;i+=4){constval=Math.random()*255;imageData.data[i]=val;imageData.data[i+1]=val;imageData.data[i+2]=val;imageData.data[i+3]=255;}ctx.putImageData(imageData,0,0);constnoiseTexture=newTHREE.CanvasTexture(canvas);noiseTexture.wrapS=THREE.RepeatWrapping;noiseTexture.wrapT=THREE.RepeatWrapping;// 顶点着色器constvertexShader=`varying vec2 vUv; varying vec3 vPosition; varying vec3 vNormal; void main() { vUv = uv; vNormal = normalize(normalMatrix * normal); vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); vPosition = mvPosition.xyz; gl_PointSize = 1.0; gl_Position = projectionMatrix * mvPosition; }`;// 片元着色器constfragmentShader=`uniform float uTime; uniform sampler2D uNoiseTexture; uniform vec3 uColorA; uniform vec3 uColorB; uniform float uProgress; varying vec2 vUv; varying vec3 vPosition; varying vec3 vNormal; // 随机函数 float random(vec2 st) { return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.5453123); } // 平滑噪声 float smoothNoise(vec2 st) { vec2 i = floor(st); vec2 f = fract(st); float a = random(i); float b = random(i + vec2(1.0, 0.0)); float c = random(i + vec2(0.0, 1.0)); float d = random(i + vec2(1.0, 1.0)); vec2 u = f * f * (3.0 - 2.0 * f); return mix(mix(a, b, u.x), mix(c, d, u.x), u.y); } void main() { // 噪声值 vec2 noiseCoord = vUv * 4.0 + uTime * 0.1; float noise = smoothNoise(noiseCoord); // 溶解效果 vec4 noiseTex = texture2D(uNoiseTexture, vUv); float dissolve = noiseTex.r; if (dissolve < uProgress) { discard; } // 颜色渐变 vec3 color = mix(uColorA, uColorB, vUv.x + noise * 0.3); // 简单的光照 vec3 lightDir = normalize(vec3(1.0, 2.0, 1.0)); float diff = max(dot(vNormal, lightDir), 0.2); color *= diff; // 边缘发光 float edge = smoothstep(uProgress, uProgress + 0.1, dissolve); color = mix(vec3(1.0, 0.5, 0.0), color, edge); // 动态颜色 color += vec3(sin(uTime) * 0.2, cos(uTime * 0.7) * 0.2, sin(uTime * 0.5) * 0.2); gl_FragColor = vec4(color, 1.0); }`;constuniforms={uTime:{value:0},uNoiseTexture:{value:noiseTexture},uColorA:{value:newTHREE.Color(0x44aa88)},uColorB:{value:newTHREE.Color(0xff6633)},uProgress:{value:0}};constmaterial=newTHREE.ShaderMaterial({uniforms:uniforms,vertexShader:vertexShader,fragmentShader:fragmentShader,side:THREE.DoubleSide});constgeometry=newTHREE.SphereGeometry(1,128,128);constsphere=newTHREE.Mesh(geometry,material);scene.add(sphere);// GUI 控制importGUIfrom'lil-gui';constgui=newGUI();gui.add(uniforms.uProgress,'value',0,1).name('溶解进度');gui.addColor(uniforms.uColorA,'value').name('颜色 A');gui.addColor(uniforms.uColorB,'value').name('颜色 B');// 动画lettime=0;functionanimate(){requestAnimationFrame(animate);time+=0.01;uniforms.uTime.value=time;sphere.rotation.y=time*0.2;sphere.rotation.x=Math.sin(time*0.3)*0.2;controls.update();renderer.render(scene,camera);}animate();window.addEventListener('resize',onWindowResize,false);functiononWindowResize(){camera.aspect=window.innerWidth/window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth,window.innerHeight);}

6. 高级特效

6.1 扫描效果

float scanline = sin(vUv.y * 200.0 - uTime * 20.0); scanline = clamp(scanline, 0.0, 1.0); color *= (0.8 + scanline * 0.3);

6.2 热浪扭曲

vec2 distortedUv = vUv + sin(vUv.yx * 20.0 + uTime) * 0.02; vec4 color = texture2D(uTexture, distortedUv);

7. 总结

技术用途
噪声函数生成随机/自然纹理
光照模型计算表面颜色
溶解效果物体消失过渡
扫描效果科技感扫描线
热浪扭曲空气扭曲效果

8. 第五部分总结

恭喜你完成了第五部分:后期特效与着色器

你已掌握:

  1. ✅ 后期特效基础(EffectComposer、RenderPass)
  2. ✅ 内置特效(泛光、景深、轮廓描边)
  3. ✅ 着色器基础(ShaderMaterial、Uniforms)
  4. ✅ 高级着色器(噪声、光照、溶解)

http://www.jsqmd.com/news/747682/

相关文章:

  • LwIP内存池(memp.c)设计精妙在哪?从‘挖坑占位’到链表操作,一个简化版C程序全讲透
  • Node.js终端光标控制:tiny-cursor库的原理与实践
  • 上海APP开发技术路径深度解析:从架构选型到工程落地
  • 第五部分-后期特效与着色器——25. 内置特效
  • 2026现阶段,浙江企业团建为何首选“包吃包住”?深度解析与高口碑目的地推荐 - 2026年企业推荐榜
  • Sunshine:5分钟搭建个人游戏串流服务器,让任何设备都能畅玩PC游戏
  • Hugging Face lerobot:机器人学习的开源利器与应用实践
  • 2025届毕业生推荐的AI学术方案横评
  • 论文自动转视频技术:Paper2Video框架解析与应用
  • 终极星露谷物语模组合集指南:15个必备SMAPI模组提升游戏体验
  • MOREBENCH:大语言模型道德推理能力评估新基准
  • Java实现Llama 3本地推理:轻量级引擎设计与企业级集成实践
  • 物理引擎如何提升AI舞蹈动作的自然度
  • Tracecat:AI原生安全自动化平台架构解析与实战指南
  • 2026年AI真人剧人才培训**指南:如何选择高通过率的机构 - 2026年企业推荐榜
  • BM25算法解析:信息检索的核心排序技术
  • 别再手动K帧了!Blender 3.6自动关键帧与插值技巧,让你的动画丝滑又高效
  • 网盘直链下载助手LinkSwift:八大网盘免费获取真实下载链接的终极解决方案
  • 别再让电机发烫!STM32 FOC开环标定零电角度的安全操作指南
  • PDPS镜像对象保姆级教程:从单个零件到整站布局,5分钟搞定对称模型
  • 50.YOLOv8 工业级全流程实战(CUDA118):训练 + 推理 + ONNX 导出 + TensorRT 加速 + Flask 部署,全套可复制源码 + 避坑指南
  • 揭秘NBTExplorer:专业级Minecraft数据可视化编辑实战指南
  • 别再让大图拖慢你的网站了!用Docker Compose一键部署imgproxy,给MinIO图片服务加个‘瘦身’插件
  • 大语言模型评估:静态测试与生成式方法对比
  • 当理想撞上现实:我是如何用‘断臂求生’策略,拆分硬件创业团队并重启项目的
  • 2026年现阶段山西塑胶地板优质服务商联系与选择全解析 - 2026年企业推荐榜
  • 本地化AI伴侣Amica:私有部署、角色定制与全流程实战指南
  • 别再只懂console.log了!Node.js process模块的7个实战用法,从环境变量到内存监控
  • 在 Hermes Agent 项目中集成 Taotoken 作为自定义模型源
  • 2026萧山考试提分服务标杆名录:慈溪考试提分、新昌考试提分、杭州市区考试提分、柯桥考试提分、桐乡考试提分、桐庐考试提分选择指南 - 优质品牌商家