需求:
1.城市建筑物渐变
2.中心光圈扩散
3.水平面横扫直线
4.抛物线聚合
先看效果
在上代码
/* * @Author: marui * @Date: 2023-03-09 09:42:21 * @LastEditTime: 2023-03-14 10:17:43 * @Description: file content */ import * as THREE from "three"; import gsap from "gsap"; export default function modifyCityMaterial(mesh) { mesh.material.onBeforeCompile = (shader) => { shader.fragmentShader = shader.fragmentShader.replace( "#include <dithering_fragment>", ` #include <dithering_fragment> //#end# ` ); addGradColor(mesh, shader); addSpread(shader) addLightLine(shader) addToTopLine(shader) }; } // 建筑物渐变 function addGradColor(mesh, shader) { // 先计算 才能拿到值 mesh.geometry.computeBoundingBox(); // 获取物体的高度差 let { min, max } = mesh.geometry.boundingBox; // 获取物体的高度差 let uHeight = max.y - min.y; shader.uniforms.uTopColor = { value: new THREE.Color("#aaaeff"), }; shader.uniforms.uHeight = { value: uHeight, }; // 不能解构 因为是基本类型 // let { vertexShader, fragmentShader } = shader; shader.vertexShader = shader.vertexShader.replace( "#include <common>", ` #include <common> varying vec3 vPosition; ` ); shader.vertexShader = shader.vertexShader.replace( "#include <begin_vertex>", ` #include <begin_vertex> vPosition = position; ` ); shader.fragmentShader = shader.fragmentShader.replace( "#include <common>", ` #include <common> uniform vec3 uTopColor; uniform float uHeight; varying vec3 vPosition; ` ); shader.fragmentShader = shader.fragmentShader.replace( "//#end#", ` vec4 distGradColor = gl_FragColor; // 设置混合的百分比 // float gradMix =(vPosition.y+uHeight/2.0)/uHeight; float gradMix =vPosition.y/uHeight/5.0; // 计算出混合颜色 vec3 gradMixColor = mix(distGradColor.xyz,uTopColor,gradMix); gl_FragColor = vec4(gradMixColor,1.0); //#end# ` ); } // 扩散圆环 function addSpread(shader){ // 设置扩散的中心点 shader.uniforms.uSpreadCenter = { value:new THREE.Vector2(0,0) } // 设置扩散的时间 shader.uniforms.uSpreadTime = { value:0 } // 设置条带的宽度 shader.uniforms.uSpreadWidth = { value:10 } shader.fragmentShader = shader.fragmentShader.replace( "#include <common>", ` #include <common> uniform vec2 uSpreadCenter; uniform float uSpreadTime; uniform float uSpreadWidth; ` ); shader.fragmentShader = shader.fragmentShader.replace( "//#end#", ` float spreadRadius = distance(vPosition.xz,uSpreadCenter); // 扩散范围的函数 float spreadIndex = -(spreadRadius-uSpreadTime)*(spreadRadius-uSpreadTime)+uSpreadWidth; if(spreadIndex>0.0){ gl_FragColor = mix(gl_FragColor,vec4(1,1,1,1),spreadIndex/uSpreadWidth); } //#end# ` ) gsap.to(shader.uniforms.uSpreadTime, { value: 500, duration: 3, ease: "none", repeat: -1, }); } // 水平扫光 export function addLightLine(shader) { // 扩散的时间 shader.uniforms.uLightLineTime = { value: -1500 }; // 设置条带的宽度 shader.uniforms.uLightLineWidth = { value: 10 }; shader.fragmentShader = shader.fragmentShader.replace( "#include <common>", ` #include <common> uniform float uLightLineTime; uniform float uLightLineWidth; ` ); shader.fragmentShader = shader.fragmentShader.replace( "//#end#", ` float LightLineMix = -(vPosition.x+vPosition.z-uLightLineTime)*(vPosition.x+vPosition.z-uLightLineTime)+uLightLineWidth; if(LightLineMix>0.0){ gl_FragColor = mix(gl_FragColor,vec4(0.8,0.5,1.0,1),LightLineMix /uLightLineWidth); } //#end# ` ); gsap.to(shader.uniforms.uLightLineTime, { value: 1500, duration: 5, ease: "none", repeat: -1, }); } // 上下扫光 export function addToTopLine(shader) { // 扩散的时间 shader.uniforms.uToTopTime = { value: 0 }; // 设置条带的宽度 shader.uniforms.uToTopWidth = { value: 10 }; shader.fragmentShader = shader.fragmentShader.replace( "#include <common>", ` #include <common> uniform float uToTopTime; uniform float uToTopWidth; ` ); shader.fragmentShader = shader.fragmentShader.replace( "//#end#", ` float ToTopMix = -(vPosition.y-uToTopTime)*(vPosition.y-uToTopTime)+uToTopWidth; if(ToTopMix>0.0){ gl_FragColor = mix(gl_FragColor,vec4(0.8,0.8,1,1),ToTopMix /uToTopWidth); } //#end# ` ); gsap.to(shader.uniforms.uToTopTime, { value: 500, duration: 3, ease: "none", repeat: -1, }); }
标签:fragmentShader,vPosition,城市,float,shader,value,include,扫光,webgl From: https://www.cnblogs.com/mariomr/p/17213986.html