three.js实现建筑物纹理流动效果

在实现建筑模型蓝色科技线框效果后,进阶制作的表面纹理流动效果。初始思路是建筑物基础材质用MeshLambertMaterial,后面替换ShaderMaterial材质使用pngt贴图,透明区域填充底色,制作流动动画。目前来看色值有偏差。(ps:blender贴图展开投影即可,ShaderMaterial需要对照uv坐标实现贴图定位)

首先基础材质替换。

node.material = new THREE.MeshLambertMaterial({
                                color: 0x0440A3,
                                transparent: true,
                                opacity: 0.5,
                            })
                  // 模型边线设置
                  const edges = new THREE.EdgesGeometry(node.geometry,30)                             
                            const edgesMaterial = new THREE.LineBasicMaterial({
                                color: 0x0440A3 ,
                                linewidth:0.5,
                                transparent: true,
                                opacity: 0.5,
                                depthWrite: false,
                              side: THREE.DoubleSide,

                            })
                            const line = new THREE.LineSegments(
                                edges,
                                edgesMaterial
                            ) 
                           node.add(line)    

这是蓝色科技线框效果,EdgesGeometry的第二个参数是可以减少模型内部三角面的效果参数。

然后是选中需要的模型做ShaderMaterial材质替换。在这个过程中加载贴图需要属性定义(在blender里贴图属性为重复的参数),所以要写在外面重新定义赋值。

 const texture1 = new THREE.TextureLoader().load('textures/62.png');

// 设置纹理的包裹模式为重复
texture1.wrapS = THREE.RepeatWrapping; // 水平方向重复
texture1.wrapT = THREE.RepeatWrapping; // 垂直方向重复

// 设置纹理重复次数
texture1.repeat.set(3, 3); // 在X轴和Y轴上各重复2次

然后设置 ShaderMaterial材质。

 const vertexShader = `
varying vec2 vUv;

void main() {
    vUv = uv;
      vUv.x = uv.x * 3.3;  // 缩放UV坐标,使纹理在X轴上重复
    vUv.y = uv.y * 3.3;  // 缩放UV坐标,使纹理在Y轴上重复
     vUv += vec2(-0.2, 0);  // 如果需要平移UV坐标 xy 
     //float angle = 0.5; // 如果需要旋转UV坐标

      

    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;

const fragmentShader = `
uniform sampler2D texture1;
 uniform vec3 fillColor;
 uniform float fillOpacity;
uniform float time;
uniform float speed;
uniform vec2 uvRepeat; 
uniform vec2 uvScale;
varying vec2 vUv;
uniform float intensity;
 uniform float transitionProgress;
//uniform vec3 emissiveColor;
void main() {
    //vec2 uv = vUv;
   //缩放暂时没用
   //vec2 uv = vUv * uvScale;
    // Example: a simple wave effect
    //左右来回移动
    //uv.y += sin(uv.x * 10.0 + time) * 0.1;

 vec2 uv = vUv + vec2(0.0, time * speed);
    vec4 color = texture2D(texture1, uv);

 vec3 finalColor = color.rgb * intensity;

   // 从上到下的过渡效果
            float alpha = smoothstep(transitionProgress - 0.1, transitionProgress + 0.1, vUv.x);

   // 如果透明区域,使用填充颜色和透明度
            if (color.a < 0.1) {
                gl_FragColor = vec4(fillColor, fillOpacity * alpha);
            } else {
                gl_FragColor = vec4(finalColor, color.a * alpha); // 输出颜色
            }
        
    
    //gl_FragColor = color;
}
`;

首先是顶点着色器和片段着色器单独写出,需要赋值的定义过多,主要是uv的设置和blender里对应,我在blender里对uv位置做出调整,所以需要在顶点着色器里对uv矫正。在片端着色器中主要传递图片到模型uv上,做啦一个条件判断,透明度值是透明时使用底色,不透明区域使用贴图的显示色。 vec2 uv = vUv + vec2(0.0, time * speed);是贴图流动设置,后面在animate要更新其值。alpha这个参数是做动画从左到右过渡效果的参数。

后面是重复执行调用代码animate

 /* fresnelMat.uniforms.time.value += 0.05; */
        
        progress += 0.01;
        fresnelMat.uniforms.transitionProgress.value = Math.min(progress, 4.3);

注释的是图片流动速度

做啦区间值,4.3是测试过透明度隐藏最大值,最小值是0。

大致是实现两个效果,图片流动和过渡效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值