Three.js利用webgl着色器控制顶点位置打造波浪形状

在这里插入图片描述

<script setup>
import * as THREE from 'three'
import gsap from 'gsap'
//导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
// 导入 dat.gui
import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; 
import * as CANNON from 'cannon-es'

// const gui = new GUI();
//1.创建场景
const scene = new THREE.Scene()
//2.创建相机 角度  宽高比  近端  远端
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 30)
// 设置相机位置  x y z 
camera.position.set(0, 0, 20)
// 把相机添加到场景中
scene.add(camera)

// 创建纹理加载器对象
const textureLoader = new THREE.TextureLoader()
const texture = textureLoader.load('c4965b97abab46118cb221b818bc74a5.png')

// import basicVertexShader from './shader/basic/vertex.glsl'
// import basicFragmentShader from './shader/basic/fragment.glsl'
import basicVertexShader from './shader/raw/vertex.glsl'
import basicFragmentShader from './shader/raw/fragment.glsl'

// 自定义着色器材质
// const shaderMaterial = new THREE.ShaderMaterial({
//   vertexShader: basicVertexShader,
//   fragmentShader: basicFragmentShader
// })
const rawShaderMaterial = new THREE.RawShaderMaterial({
  vertexShader: basicVertexShader,
  fragmentShader: basicFragmentShader,
  // wireframe: true // 线框
  side: THREE.DoubleSide,
  uniforms: {
    uTime: {
      value: 0
    },
    uTexture:{
      value: texture
    }
  }
})

// const material = new THREE.MeshBasicMaterial({color: '#00FF00'})
// 创建平面
const floor = new THREE.Mesh(
  new THREE.PlaneGeometry(1, 1, 64, 64),
  rawShaderMaterial,
  // material
)
scene.add(floor)

// 初始化渲染器
const renderer = new THREE.WebGLRenderer()
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight)
// 开启场景中的阴影贴图
renderer.shadowMap.enabled = true
// 将webgel渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement)

// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement)
// 设置控制器的阻尼 更真实 惯性
controls.enableDamping = true

// 添加坐标轴辅助器
const axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)

// 设置时钟
const clock = new THREE.Clock()
function render() {
  let elapsedTime = clock.getElapsedTime()
  rawShaderMaterial.uniforms.uTime.value = elapsedTime
  // 使用渲染器,通过相机将场景渲染进来
  renderer.render(scene, camera);
  // 渲染下一帧的时候 调用 render函数
  requestAnimationFrame(render)
}
render()

// 监听窗口尺寸变化,更新渲染画面
window.addEventListener("resize", () => {
  // 更新摄像头
  camera.aspect = window.innerWidth / window.innerHeight
  // 更新摄像机的投影矩阵
  camera.updateProjectionMatrix()

  // 更新渲染器
  renderer.setSize(window.innerWidth, window.innerHeight)
  // 设置渲染器的像素比
  renderer.setPixelRatio(window.devicePixelRatio)
})

</script>

vertex.glsl

attribute vec3 position;
attribute vec2 uv;

uniform mat4 projectionMatrix;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform float uTime;

varying vec2 vUv;
varying float vElevation;

void main(){
  vUv = uv;
  vec4 modelPosition = modelMatrix * vec4(position, 1);
  // modelPosition.x += 1.0;
  // modelPosition.z += 1.0;
  // modelPosition.z += modelPosition.x;
  modelPosition.z = sin((modelPosition.x + uTime) * 10.0) * 0.1;
  modelPosition.z += sin((modelPosition.y + uTime) * 10.0) * 0.1;
  vElevation = modelPosition.z;

  gl_Position = projectionMatrix * viewMatrix * modelPosition;
}

fragment.glsl

    // highp -2^16 - 2^16
    // mediump -2^10 - 2^10
    // lowp -2^8 - 2^8
    precision mediump float;
    varying vec2 vUv;
    varying float vElevation;

    uniform sampler2D uTexture;

    void main(){
      // gl_FragColor = vec4(vUv, 0.0, 1.0);
      float height = vElevation + 0.05 * 10.0;
      // gl_FragColor = vec4(1.0 * height, 0.0, 0.0, 1.0);
      
      // 根据UV取出对应的颜色
      vec4 textureColor = texture2D(uTexture, vUv);
      textureColor.rgb *= height;
      gl_FragColor = textureColor;
    }
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值