Threejs Shader 围墙练习

在这里插入图片描述
代码

<template>
  <div class="circle" ref="circle"></div>
</template>

<script setup>
import {onMounted, ref} from "vue";
import * as THREE from 'three';
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'

let scene, camera, renderer, controls, circle = ref(null);
let timeValue = {value: 0.0}

function init() {
  let width = circle.value.clientWidth;
  let height = circle.value.clientHeight
  scene = new THREE.Scene();
  renderer = new THREE.WebGLRenderer({
    antialias: true, //开启锯齿
  });
  renderer.setSize(width, height)
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
  renderer.setClearColor(new THREE.Color('#32373E'), 1);
  camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000)
  camera.position.set(500, 500, 500)
  controls = new OrbitControls(camera, renderer.domElement);
  let light = new THREE.AmbientLight(0xadadad, 0.8); // soft white light
  scene.add(light)
  let light_2 = new THREE.HemisphereLight(0x00AAFF, 0xFFAA00, 0.8)
  scene.add(light_2)
  scene.add(new THREE.AxesHelper(500))

  let vertexShader = `
    // uniform mat4 modelMatrix;//不需要声明
    varying vec3 v_position;
    varying vec2 vUv;
    void main(){
      // 模型矩阵modelMatrix对顶点位置坐标进行模型变换
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
      v_position = position;
      vUv = uv;
  }`

  let fragmentShader = `
    varying vec3 v_position;
    uniform float v_time;
    varying vec2 vUv;
    // 底部颜色
    uniform vec3 wall_color;
    // 移动的光带颜色
    uniform vec3 v_color;
    float size = 1.0/10.0;

    void main() {
       float v = v_time;
       float percent = vUv.y / 1.0;
       if (mod(vUv.y-v,size) >0.001 && mod(vUv.y-v,size) < 0.005) {
           gl_FragColor = vec4(v_color, (1.0-percent)*0.6);
       } else  {
          gl_FragColor = vec4(wall_color, (1.0-percent)*0.6);
       }
    }
  `

  let material2 = new THREE.ShaderMaterial({
    vertexShader,
    fragmentShader,
    side: THREE.DoubleSide,
    transparent: true,
    uniforms: {
      v_time: timeValue,
      v_color: {
        value: new THREE.Color('#FFFFFF')
      },
      wall_color: {
        value: new THREE.Color('#FF4127')
      }
    }
  })

  let c = [0, 0, 100, 0, 100, 100, 0, 100, 0, 0];
  let posArr = [];
  let uvrr = [];
  let h = 250; //围墙拉伸高度
  for (let i = 0; i < c.length - 2; i += 2) {
    // 围墙多边形上两个点构成一个直线扫描出来一个高度为h的矩形
    // 矩形的三角形1
    posArr.push(c[i], c[i + 1], 0, c[i + 2], c[i + 3], 0, c[i + 2], c[i + 3], h);
    // 矩形的三角形2
    posArr.push(c[i], c[i + 1], 0, c[i + 2], c[i + 3], h, c[i], c[i + 1], h);

    // 注意顺序问题,和顶点位置坐标对应
    uvrr.push(0, 0, 1, 0, 1, 1);
    uvrr.push(0, 0, 1, 1, 0, 1);
  }
  let geometry = new THREE.BufferGeometry(); //声明一个空几何体对象
  // 设置几何体attributes属性的位置position属性
  geometry.attributes.position = new THREE.BufferAttribute(new Float32Array(posArr), 3);
  // 设置几何体attributes属性的位置uv属性
  geometry.attributes.uv = new THREE.BufferAttribute(new Float32Array(uvrr), 2);
  geometry.computeVertexNormals()

  let mesh = new THREE.Mesh(geometry, material2); //网格模型对象Mesh
  scene.add(mesh);
  mesh.rotateX(-Math.PI/2)

}

function animal() {
  renderer.render(scene, camera);
  timeValue.value += 0.005
  if (timeValue.value >= 1.0) {
    timeValue.value = 0.0;
  }
  requestAnimationFrame(animal)
}

onMounted(() => {
  init();
  circle.value.appendChild(renderer.domElement)
  animal();
})
</script>

<style scoped lang="less">
.circle {
  height: 100%;
}
</style>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值