• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

wzkun

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

three 遮罩层

three 实现遮罩模型的效果,主要使用mesh 的material,构建shader来完成,通过可以是一个特定的图片,也可以是canvas绘制2D图形,之后转图片,来实现

1.shader代码

this.vertex = ShaderLib.standard.vertexShader.replace(
      `void main() {`,
      `
      varying vec2 maskUV; // 遮罩UV
      uniform vec2 maxBound; // 最大边界
      uniform vec2 minBound;  // 最小边界
  
      void main() {
        vec4 p=modelMatrix*vec4(position,1.0); // 将顶点位置转换到世界坐标系中
        // 计算出顶点遮罩UV坐标  /w 齐次坐标
        maskUV=(vec2(p.x/p.w,p.z/p.w)-minBound)/(maxBound-minBound);
      `
    );

    this.fragment = ShaderLib.standard.fragmentShader.replace(
      `void main() {`,
      `
      uniform sampler2D maskTexture; // 遮罩贴图
      varying vec2 maskUV;  // 遮罩UV坐标  顶点着色器传过来的
      uniform int state; // 裁剪状态  0 不裁剪  1 显示裁剪贴图  2 裁剪模型
      void main() {
        // 采样遮罩贴图
        vec4 c = texture(maskTexture,maskUV);

        if(state!=0){
          if(state==1){
            gl_FragColor=c;
            return;
          }else{
            // 因为 遮罩贴图是红绿图 红色通道>0.5 表示超出裁剪范围 需要剔除
            if(c.x>0.5)
            {
              discard;
            }
          }
        }
      `

构建一个遮罩的shader,根据图像的区域来分割

      tiles.group.traverse((x) => {
        if (x instanceof Mesh && x.material instanceof Material) {

          x.material.onBeforeCompile = (shader: Shader) => {
            console.log(tiles.group.rotation)
            shader.uniforms.maxBound = maxBound;
            shader.uniforms.minBound = minBound;
            // shader.uniforms.state = { value: 1 };
            shader.uniforms.state = { value: tiles.group.userData.state }
            let texture =  (tiles.group as any).texture;
            texture.value.rotation = 10*Math.random()
            shader.uniforms.maskTexture = texture;

            // shader.uniforms.maskTexture.value.rotation = 10*Math.random()
            // shader.uniforms.maskTexture = maskTexture;
            shader.vertexShader = vertex;
            shader.fragmentShader = fragment;
          };
        }
      });

  这段js是遍历group 给group里面的mesh赋值、使得动态绘制遮罩层

TRANSLATE with x
English
Arabic Hebrew Polish
Bulgarian Hindi Portuguese
Catalan Hmong Daw Romanian
Chinese Simplified Hungarian Russian
Chinese Traditional Indonesian Slovak
Czech Italian Slovenian
Danish Japanese Spanish
Dutch Klingon Swedish
English Korean Thai
Estonian Latvian Turkish
Finnish Lithuanian Ukrainian
French Malay Urdu
German Maltese Vietnamese
Greek Norwegian Welsh
Haitian Creole Persian  
 
TRANSLATE with
COPY THE URL BELOW
Back
EMBED THE SNIPPET BELOW IN YOUR SITE
Enable collaborative features and customize widget: Bing Webmaster Portal
Back

posted on 2022-08-08 22:11  菜鸡坤  阅读(507)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3