需求:
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,
});
}
浙公网安备 33010602011771号