shader 圆形水波纹效果 threejs vue3

<template>
    <div class="greenhouse" ref="canvasContainerRef"> </div>
</template>

<script setup>
import * as THREE from "three";


import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";


import { ref, onMounted, getCurrentInstance, reactive } from "vue";
const { proxy } = getCurrentInstance();
const renderer = ref(); //渲染器

let scene = new THREE.Scene(); //场景--scene是只读属性
const camera = ref(null); //相机
let orbitControls = null


// 创建波纹材质  步骤一
const rippleMaterial = new THREE.ShaderMaterial({
    uniforms: {
        time: { value: 0 },
        color: { value: new THREE.Color(0x22ffcc) }
    },
    vertexShader: `
        varying vec2 vUv;
        void main() {
            vUv = uv;
            gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        }
    `,
    fragmentShader: `
        uniform float time;
        uniform vec3 color;
        varying vec2 vUv;
        
        void main() {
            vec2 center = vec2(0.5, 0.5);
            float dist = distance(vUv, center);
            float ripple = sin(dist * 50.0 - time * 5.0);
            float fade = smoothstep(0.5, 0.0, dist);
            
            float alpha = ripple * fade;
            gl_FragColor = vec4(color, alpha * 0.9);
        }
    `,
    transparent: true,
    side: THREE.DoubleSide
});
const initThree = () => {
    // width和height用来设置Three.js输出Canvas画布尺寸,同时用来辅助设置相机渲染范围
    camera.value = new THREE.PerspectiveCamera(65, window.innerWidth / window.innerHeight, 1, 20000);
    camera.value.position.set(50, 50, 50);
    scene.add(camera.value);
    // scene.background = new THREE.Color(0xffffff);
    // 创建渲染器
    renderer.value = new THREE.WebGLRenderer({
        antialias: true, //开启抗锯齿(否则加载的模型有锯齿--)
    });
    renderer.value.setSize(window.innerWidth, window.innerHeight);
    renderer.value.setPixelRatio(window.devicePixelRatio); //设置设备像素比率,防止Canvas画布输出模糊。

    const canvasContainerRef = proxy.$refs["canvasContainerRef"];

    //环境光
    var ambient = new THREE.AmbientLight(0xffffff, 1);
    scene.add(ambient);
    canvasContainerRef.appendChild(renderer.value.domElement);
    const axesHelper = new THREE.AxesHelper(150);
    scene.add(axesHelper);
    orbitControls = new OrbitControls(camera.value, renderer.value.domElement); //旋转、放大缩小
    // 初始化加载器

    const loader = new GLTFLoader();

    renderer.value.outputEncoding = THREE.sRGBEncoding; //解决加载gltf格式模型纹理贴图和原图不一样问
    animateRender();


    // 创建波纹平面 步骤二
    const ripplePlane = new THREE.Mesh(
        new THREE.PlaneGeometry(30, 30),
        rippleMaterial
    );
    ripplePlane.rotateX(-Math.PI / 2);
    scene.add(ripplePlane);
};




// 动画循环
const animateRender = () => {
    rippleMaterial.uniforms.time.value += 0.04; //步骤三
    requestAnimationFrame(animateRender);
    renderer.value.render(scene, camera.value)
};

onMounted(() => {
    initThree()
});
</script>

<style scoped lang="scss"></style>

调整 float ripple = sin(dist * 50.0 - time * 5.0);这行代码的数字50调整粗细,

调整 new THREE.PlaneGeometry(30, 30),长方形的长宽调整大小

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值