ThreeJs基础代码段(五)飘扬的旗帜

本文介绍了如何使用Three.js通过自定义着色器实现3D国旗的飘扬效果。通过ShaderMaterial结合顶点着色器和片段着色器,调整材质和时间参数,模拟旗帜随风摆动的视觉效果。同时,添加阴影增强真实感,并通过不断更新时间参数来实现动态变化。
摘要由CSDN通过智能技术生成

        先看效果:

        想要做到旗帜飘扬的效果,仅仅依靠标准的几何体与材质是不够的,还需要对之加以“改装”。

        通常制作一面国旗用简单的立方体贴上纹理,效果如下,比较生硬死板,整体感官一般。

        那么如何制作一面飘扬的旗帜呢? 

        在threejs中可以通过更改材质的方式和编写着色器的方式来达到我们想要的效果。但是MeshStandardMaterial材质非常复杂,涉及较多的代码与计算,且性能开销比较大,所以编写自己的着色器无疑是最简单的方式。

        首先需要创建一个特定的材质,这里我们选择ShaderMaterial,因为此材质可以将一些代码自动添加到着色器代码中,这里我们提供顶点着色器和片段着色器,并在uniforms中提供三个参数,频率、时间和纹理,频率控制方向的位移,时间控制旗帜的活跃程度:

const material = new THREE.ShaderMaterial({
    vertexShader: testVertexShader,
    fragmentShader: testFragmentShader,
    uniforms:
    {
        uFrequency: { value: new THREE.Vector2(10, 5) },
        uTime: { value: 0 },
        uColor: { value: new THREE.Color('orange') },
        uTexture: { value: flagTexture }
    }
})

        顶点着色器代码:

uniform vec2 uFrequency;
uniform float uTime;

varying vec2 vUv;
varying float vElevation;

void main()
{
    vec4 modelPosition = modelMatrix * vec4(position, 1.0);

    float elevation = sin(modelPosition.x * uFrequency.x - uTime) * 0.1;
    elevation += sin(modelPosition.y * uFrequency.y - uTime) * 0.1;

    modelPosition.z += elevation;

    vec4 viewPosition = viewMatrix * modelPosition;
    vec4 projectedPosition = projectionMatrix * viewPosition;

    gl_Position = projectedPosition;

    vUv = uv;
    vElevation = elevation;
}

        片段着色器代码:

uniform vec3 uColor;
uniform sampler2D uTexture;

varying vec2 vUv;
varying float vElevation;

void main()
{
    vec4 textureColor = texture2D(uTexture, vUv);
    textureColor.rgb *= vElevation * 2.0 + 0.65;
    gl_FragColor = textureColor;
    // gl_FragColor = vec4(vUv, 1.0, 1.0);
}

       在旗帜飘扬的过程中,还增加了阴影,过程如下:

//在顶点着色器中,我们将风高程存储在一个变量中
void main()
{
    // ...

    float elevation = sin(modelPosition.x * uFrequency.x - uTime) * 0.1;
    elevation += sin(modelPosition.y * uFrequency.y - uTime) * 0.1;
    
    modelPosition.z += elevation;

    // ...
}
//变量将提升发送到片段
// ...
varying float vElevation;

void main()
{
    // ...

    vElevation = elevation;
}
检索片段着色器中的变量
// ...
varying float vElevation;

void main()
{
    vec4 textureColor = texture2D(uTexture, vUv);
    textureColor.rgb *= vElevation * 2.0 + 0.5;
    gl_FragColor = textureColor;
}

        更新材质:

    const elapsedTime = clock.getElapsedTime()

    // Update material
    material.uniforms.uTime.value = elapsedTime
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值