首页 > 其他分享 >three.js shader 入门 红旗飘动效果

three.js shader 入门 红旗飘动效果

时间:2024-09-20 15:52:30浏览次数:3  
标签:const THREE js vec4 shader three new modelPosition renderer

预览效果

在这里插入图片描述

1、懒人直接上代码,全部代码效果

import * as THREE from "https://esm.sh/three";
import {OrbitControls} from "https://esm.sh/three/examples/jsm/controls/OrbitControls";

const textureLoader = new THREE.TextureLoader()

let controls;
let scene: THREE.Scene, camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer;
let clock = new THREE.Clock();
const uniforms = {
  uTime: {value: 0},
  uFrequency: {value: new THREE.Vector4(10, 10, .1, .1)},
  uColor: new THREE.Color(),
  uTexture: {value: textureLoader.load('https://3d-eosin.vercel.app/static/media/flag.8486dd6104d28379fbe9.png')}
}

// 初始化webgl
function init() {
  let w = window.innerWidth;
  let h = window.innerHeight;

  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera(75, w / h, 0.01, 1000);
  camera.position.set(0, 0, 1.5);
  camera.lookAt(new THREE.Vector3());

  renderer = new THREE.WebGLRenderer({
    antialias: true,
    alpha: true,
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(w, h);
  renderer.setClearColor(0xe6fcf5, 1);
  document.getElementById("app").appendChild(renderer.domElement);

  controls = new OrbitControls(camera, renderer.domElement);

  render();
  initShader()
  window.addEventListener("resize", resize);
}

// 初始化shader
function initShader() {
  const vertex = /* GLSL */ `
// uniform mat4 projectionMatrix;
// uniform mat4 viewMatrix;
// uniform mat4 modelMatrix;
// attribute vec3 position;
attribute float aRandom;
varying float vRandom;
uniform float  uTime;
uniform vec4  uFrequency;
// attribute vec2 uv;
varying vec2 vUv;
void main(){
  vUv = uv;
  vec4 modelPosition = modelMatrix * vec4(position, 1.0);
  // modelPosition.y += 1.0;
  modelPosition.z += aRandom * .01;
  modelPosition.z += aRandom * .01;
  modelPosition.z += sin(modelPosition.x * uFrequency.x+uTime) * uFrequency.z*modelPosition.x;
  modelPosition.y += sin(modelPosition.x * uFrequency.x+uTime) * uFrequency.w*modelPosition.x;
  vec4 viewPosition = viewMatrix * modelPosition;
  vec4 projectedPosition = projectionMatrix * viewPosition;
  vRandom = modelPosition.z*5.0;
  gl_Position = projectedPosition;
}
`;
  const fragment = /* GLSL */ `
// precision mediump float;
uniform vec3 uColor;
uniform sampler2D uTexture;
varying vec2 vUv;
varying float vRandom;
  void main() {
    // 红色
    gl_FragColor = vec4(vRandom, 0.6, 0.3, 1.0);
    // vec4 textureColor = texture2D(uTexture, vUv)* vec4(vRandom*10.0, 1, 0.5, 1.0);
    // gl_FragColor = textureColor;
  }
`;
  const geometry = new THREE.PlaneGeometry(1, 1, 32, 32);
  geometry.translate(.5, 0, 0)
  const count = geometry.attributes.position.count
  const randoms = new Float32Array(count)
// 使用随机数填充数组
  for (let i = 0; i < count; i++) {
    randoms[i] = Math.random()
  }
// 添加到几何体的属性中
  geometry.setAttribute('aRandom', new THREE.BufferAttribute(randoms, 1))

// const material = new THREE.MeshBasicMaterial({
//     color: 0x0ca678,
//     // wireframe: true
// });
// const material = new THREE.RawShaderMaterial({
  const material = new THREE.ShaderMaterial({
    vertexShader: vertex,
    fragmentShader: fragment,
    // wireframe: true,
    transparent: true,
    side: 2,
    uniforms,
  });

  const mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);
}

// 渲染
function render() {
  uniforms.uTime.value += .1
  renderer.render(scene, camera);
  requestAnimationFrame(render);
}

// 响应式3d窗口
function resize() {
  const w = window.innerWidth;
  const h = window.innerHeight;
  renderer.setSize(w, h);
  camera.aspect = w / h;
  camera.updateProjectionMatrix();
}

init()

2、第一步初始化基本的three.js 代码结构

1、导入模块初始化变量

import * as THREE from "https://esm.sh/three";
import {OrbitControls} from "https://esm.sh/three/examples/jsm/controls/OrbitControls";

const textureLoader = new THREE.TextureLoader()

let controls;
let scene: THREE.Scene, camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer;
let clock = new THREE.Clock();
const uniforms = {
  uTime: {value: 0},
  uFrequency: {value: new THREE.Vector4(10, 10, .1, .1)},
  uColor: new THREE.Color(),
  uTexture: {value: textureLoader.load('https://3d-eosin.vercel.app/static/media/flag.8486dd6104d28379fbe9.png')}
}

3、第二步初定义three.js基本的方法

// 初始化webgl
function init() {
  let w = window.innerWidth;
  let h = window.innerHeight;

  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera(75, w / h, 0.01, 1000);
  camera.position.set(0, 0, 1.5);
  camera.lookAt(new THREE.Vector3());

  renderer = new THREE.WebGLRenderer({
    antialias: true,
    alpha: true,
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(w, h);
  renderer.setClearColor(0xe6fcf5, 1);
  document.getElementById("app").appendChild(renderer.domElement);

  controls = new OrbitControls(camera, renderer.domElement);

  render();
  initShader()
  window.addEventListener("resize", resize);
}

// 渲染
function render() {
  uniforms.uTime.value += .1
  renderer.render(scene, camera);
  requestAnimationFrame(render);
}

// 响应式3d窗口
function resize() {
  const w = window.innerWidth;
  const h = window.innerHeight;
  renderer.setSize(w, h);
  camera.aspect = w / h;
  camera.updateProjectionMatrix();
}

4、第三步编写shader

// 初始化shader
function initShader() {
  const vertex = /* GLSL */ `
// uniform mat4 projectionMatrix;
// uniform mat4 viewMatrix;
// uniform mat4 modelMatrix;
// attribute vec3 position;
attribute float aRandom;
varying float vRandom;
uniform float  uTime;
uniform vec4  uFrequency;
// attribute vec2 uv;
varying vec2 vUv;
void main(){
  vUv = uv;
  vec4 modelPosition = modelMatrix * vec4(position, 1.0);
  // modelPosition.y += 1.0;
  modelPosition.z += aRandom * .01;
  modelPosition.z += aRandom * .01;
  modelPosition.z += sin(modelPosition.x * uFrequency.x+uTime) * uFrequency.z*modelPosition.x;
  modelPosition.y += sin(modelPosition.x * uFrequency.x+uTime) * uFrequency.w*modelPosition.x;
  vec4 viewPosition = viewMatrix * modelPosition;
  vec4 projectedPosition = projectionMatrix * viewPosition;
  vRandom = modelPosition.z*5.0;
  gl_Position = projectedPosition;
}
`;
  const fragment = /* GLSL */ `
// precision mediump float;
uniform vec3 uColor;
uniform sampler2D uTexture;
varying vec2 vUv;
varying float vRandom;
  void main() {
    // 红色
    gl_FragColor = vec4(vRandom, 0.6, 0.3, 1.0);
    // vec4 textureColor = texture2D(uTexture, vUv)* vec4(vRandom*10.0, 1, 0.5, 1.0);
    // gl_FragColor = textureColor;
  }
`;
  const geometry = new THREE.PlaneGeometry(1, 1, 32, 32);
  geometry.translate(.5, 0, 0)
  const count = geometry.attributes.position.count
  const randoms = new Float32Array(count)
// 使用随机数填充数组
  for (let i = 0; i < count; i++) {
    randoms[i] = Math.random()
  }
// 添加到几何体的属性中
  geometry.setAttribute('aRandom', new THREE.BufferAttribute(randoms, 1))

// const material = new THREE.MeshBasicMaterial({
//     color: 0x0ca678,
//     // wireframe: true
// });
// const material = new THREE.RawShaderMaterial({
  const material = new THREE.ShaderMaterial({
    vertexShader: vertex,
    fragmentShader: fragment,
    // wireframe: true,
    transparent: true,
    side: 2,
    uniforms,
  });

  const mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);
}

5、第四步运行

init()

标签:const,THREE,js,vec4,shader,three,new,modelPosition,renderer
From: https://blog.csdn.net/qq_41579192/article/details/142383325

相关文章

  • 基于nodejs+vue物业管理信息系统[开题+源码+程序+论文]计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容研究背景随着城市化进程的加速和房地产市场的蓬勃发展,物业管理作为现代社区治理的重要组成部分,其复杂性和高效性要求日益凸显。传统的人工管理模式已难以满足当前物......
  • 基于nodejs+vue物业租赁管理系统[开题+源码+程序+论文]计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容研究背景随着城市化进程的加速和房地产市场的蓬勃发展,物业租赁已成为现代都市生活中不可或缺的一部分。传统的物业租赁管理方式往往依赖于纸质文档和人工操作,不仅效......
  • 基于Node.js+vue基于springboot和vue的音乐网站(开题+程序+论文) 计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展,数字音乐已成为人们日常生活中不可或缺的一部分。音乐网站作为数字音乐传播的重要平台,不仅为用户提供了丰富的音乐资源,还通过多样......
  • Python-tkinter界面设计案例---快捷编辑json文件
    前言:为了方便测试员编辑一些json文件信息,我打算提供一个简洁清晰的ui界面来提高工作效率。该ui基于轻量化tkinter实现。大致效果如下图所示:前置环境:python3importtkinterastkfromtkinterimportmessageboximportjsonimportosimport_locale_locale._getdefault......
  • java毕业设计,基于java+SSH+JSP的固定资产管理系统设计与实现(全套源码+配套论文),固定资
    基于java+SSH+JSP的固定资产管理系统设计与实现(全套源码+配套论文)大家好,今天给大家介绍基于java+SSH+JSP的固定资产管理系统设计与实现,更多精选毕业设计项目实例见文末哦。文章目录:基于java+SSH+JSP的固定资产管理系统设计与实现(全套源码+配套论文)1、项目简介2、资源......
  • 基于Node.js+vue基金交易平台(开题+程序+论文) 计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容研究背景在金融市场日益繁荣的今天,基金投资作为一种相对稳健且门槛较低的投资方式,受到了广大投资者的青睐。随着互联网的普及和金融科技的发展,传统基金销售模式正逐......
  • 基于Node.js+vue在线考试及自动评分系统(开题+程序+论文) 计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容研究背景随着信息技术的飞速发展和教育模式的不断创新,传统考试方式逐渐暴露出效率低下、成本高昂、评分主观性强等弊端。特别是在大规模教育考试和在线学习日益普及......
  • 基于Node.js+vue基于SpringBoot的民间遗产中心(开题+程序+论文) 计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容研究背景在全球化与文化多样性的背景下,民间遗产作为民族文化的重要组成部分,承载着丰富的历史记忆与地域特色,是连接过去与未来的重要纽带。然而,随着现代化进程的加速,......
  • 基于Node.js+vue基于SpringBoot的毕业生就业系统(开题+程序+论文) 计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容研究背景随着高等教育的普及,每年有大量毕业生涌入就业市场,而企业与求职者之间的信息不对称问题日益凸显。传统的招聘方式效率低下,难以满足毕业生快速找到合适岗位及......
  • Vue.js与Flask/Django后端配合详细讲解
    ✨博客主页:https://blog.csdn.net/m0_63815035?type=blog......