第五部分-后期特效与着色器——26. 着色器基础
26. 着色器基础1. 概述着色器Shader是在 GPU 上运行的小程序用于控制顶点位置和像素颜色。Three.js 允许通过 ShaderMaterial 编写自定义着色器实现高级视觉效果。┌─────────────────────────────────────────────────────────────┐ │ 着色器工作流程 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 顶点数据 ──► 顶点着色器 ──► 片元着色器 ──► 像素颜色 │ │ (Vertex) (Fragment) │ │ │ │ 顶点着色器处理顶点位置、法线、UV 等 │ │ 片元着色器处理每个像素的颜色、光照、纹理等 │ │ │ └─────────────────────────────────────────────────────────────┘2. 着色器类型2.1 顶点着色器Vertex Shader顶点着色器处理每个顶点的位置和属性。// 基础顶点着色器 void main() { // 计算顶点位置 vec4 mvPosition modelViewMatrix * vec4(position, 1.0); gl_PointSize 1.0; gl_Position projectionMatrix * mvPosition; }2.2 片元着色器Fragment Shader片元着色器处理每个像素的颜色。// 基础片元着色器 uniform vec3 color; void main() { gl_FragColor vec4(color, 1.0); }3. ShaderMaterial3.1 基本用法constvertexShadervarying vec2 vUv; void main() { vUv uv; vec4 mvPosition modelViewMatrix * vec4(position, 1.0); gl_PointSize 1.0; gl_Position projectionMatrix * mvPosition; };constfragmentShaderuniform vec3 uColor; varying vec2 vUv; void main() { gl_FragColor vec4(uColor, 1.0); };constmaterialnewTHREE.ShaderMaterial({uniforms:{uColor:{value:newTHREE.Color(0xff6600)}},vertexShader:vertexShader,fragmentShader:fragmentShader});3.2 ShaderMaterial 属性属性说明uniforms全局变量如时间、颜色vertexShader顶点着色器代码fragmentShader片元着色器代码transparent是否透明side渲染面wireframe线框模式4. UniformsUniforms 是着色器的全局变量可以在 JavaScript 中更新。constuniforms{uTime:{value:0},uColor:{value:newTHREE.Color(0xff6600)},uTexture:{value:texture},uResolution:{value:newTHREE.Vector2(800,600)}};// 更新 uniformfunctionanimate(){uniforms.uTime.value0.01;requestAnimationFrame(animate);}5. 内置变量5.1 顶点着色器内置变量变量类型说明positionvec3顶点位置局部坐标normalvec3顶点法线uvvec2UV 坐标modelViewMatrixmat4模型视图矩阵projectionMatrixmat4投影矩阵5.2 片元着色器内置变量变量类型说明gl_FragColorvec4输出颜色gl_FragCoordvec4片元屏幕坐标varying自定义从顶点着色器传递的数据6. Varying 变量Varying 变量用于在顶点着色器和片元着色器之间传递数据。// 顶点着色器 varying vec2 vUv; void main() { vUv uv; gl_Position projectionMatrix * modelViewMatrix * vec4(position, 1.0); } // 片元着色器 varying vec2 vUv; void main() { gl_FragColor vec4(vUv.x, vUv.y, 0.5, 1.0); }7. 完整示例import*asTHREEfromthree;import{OrbitControls}fromthree/examples/jsm/controls/OrbitControls.js;constscenenewTHREE.Scene();scene.backgroundnewTHREE.Color(0x000000);constcameranewTHREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);camera.position.set(2,2,3);camera.lookAt(0,0,0);constrenderernewTHREE.WebGLRenderer({antialias:true});renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(renderer.domElement);constcontrolsnewOrbitControls(camera,renderer.domElement);controls.enableDampingtrue;// 创建纹理constcanvasdocument.createElement(canvas);canvas.width512;canvas.height512;constctxcanvas.getContext(2d);ctx.fillStyle#ff6600;ctx.fillRect(0,0,canvas.width,canvas.height);ctx.fillStyle#ffffff;ctx.fontBold 40px Arial;ctx.fillText(Three.js,canvas.width/2-100,canvas.height/2);consttexturenewTHREE.CanvasTexture(canvas);// 顶点着色器constvertexShadervarying vec2 vUv; varying vec3 vPosition; void main() { vUv uv; vec4 mvPosition modelViewMatrix * vec4(position, 1.0); vPosition mvPosition.xyz; gl_PointSize 1.0; gl_Position projectionMatrix * mvPosition; };// 片元着色器constfragmentShaderuniform float uTime; uniform vec3 uColor; uniform sampler2D uTexture; varying vec2 vUv; varying vec3 vPosition; void main() { // 波浪效果 float wave sin(vUv.x * 20.0 uTime) * cos(vUv.y * 20.0 uTime) * 0.5 0.5; // 纹理采样 vec4 texColor texture2D(uTexture, vUv); // 渐变效果 vec3 gradient vec3(vUv.x, vUv.y, 0.5); // 颜色混合 vec3 finalColor mix(uColor, texColor.rgb, 0.5); finalColor mix(finalColor, gradient, 0.3); finalColor vec3(wave * 0.3); // 边缘暗角 float vignette 1.0 - length(vUv - 0.5) * 0.8; finalColor * vignette; gl_FragColor vec4(finalColor, 1.0); };// 创建材质constuniforms{uTime:{value:0},uColor:{value:newTHREE.Color(0xff6600)},uTexture:{value:texture}};constmaterialnewTHREE.ShaderMaterial({uniforms:uniforms,vertexShader:vertexShader,fragmentShader:fragmentShader,side:THREE.DoubleSide});// 创建几何体constgeometrynewTHREE.SphereGeometry(1,64,64);constmeshnewTHREE.Mesh(geometry,material);scene.add(mesh);// GUI 控制importGUIfromlil-gui;constguinewGUI();gui.add(uniforms.uColor.value,r,0,1).name(红色).onChange(()uniforms.uColor.value.setHSL(uniforms.uColor.value.r,1,0.5));gui.add(uniforms.uColor.value,g,0,1).name(绿色);gui.add(uniforms.uColor.value,b,0,1).name(蓝色);// 动画functionanimate(){requestAnimationFrame(animate);uniforms.uTime.value0.01;mesh.rotation.y0.005;controls.update();renderer.render(scene,camera);}animate();window.addEventListener(resize,onWindowResize,false);functiononWindowResize(){camera.aspectwindow.innerWidth/window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth,window.innerHeight);}8. 常见效果示例8.1 波浪效果float wave sin(position.y * 5.0 uTime) * 0.1; vec3 newPosition position vec3(0.0, wave, 0.0);8.2 颜色渐变vec3 color1 vec3(1.0, 0.0, 0.0); vec3 color2 vec3(0.0, 0.0, 1.0); vec3 finalColor mix(color1, color2, vUv.x);8.3 溶解效果float dissolve texture2D(uNoiseTexture, vUv).r; if (dissolve uProgress) discard;9. 总结类型用途顶点着色器处理顶点位置片元着色器处理像素颜色Uniforms全局变量Varying顶点→片元传递ShaderMaterial自定义材质内置变量说明position顶点位置uvUV 坐标normal法线modelViewMatrix模型视图矩阵projectionMatrix投影矩阵
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2579968.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!