首页 > 其他分享 >webgl 城市扫光

webgl 城市扫光

时间:2023-03-14 10:37:22浏览次数:34  
标签:fragmentShader vPosition 城市 float shader value include 扫光 webgl

需求:

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

相关文章