Three.js - 着色器材质使用变量(二十八)

简介

上一节我们了解了着色器材质,这节我们了解如何使用着色器。

着色器变量

  • 着色器中有三种变量:
  1. Uniforms 全局变量。可以传入顶点着色器,也可以传入片元着色器,在整个渲染过程中保持不变的变量。
  2. Varyings 是从顶点着色器传递到片元着色器的变量。我们需要确保在两个着色器中变量的类型和命名完全一致。
  3. Attributes 与每个顶点关联的变量。例如,顶点位置,法线和顶点颜色都是存储在attributes中的数据。它只能在顶点着色器获取。

绘制一个只有4/1变色的圆

  • 基础模板
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>学习</title>
  </head>
  <body>
    <canvas id="c2d" class="c2d" width="1000" height="500"></canvas>
    <script type="module">
      import * as THREE from './file/three.js-dev/build/three.module.js'
      import { OrbitControls } from './file/three.js-dev/examples/jsm/controls/OrbitControls.js'

      const canvas = document.querySelector('#c2d')
      // 渲染器
      const renderer = new THREE.WebGLRenderer({ canvas })

      const fov = 40 // 视野范围
      const aspect = 2 // 相机默认值 画布的宽高比
      const near = 0.1 // 近平面
      const far = 10000 // 远平面
      // 透视投影相机
      const camera = new THREE.PerspectiveCamera(fov, aspect, near, far)
      camera.position.set(0, 100, 0)
      camera.lookAt(0, 0, 0)
      // 控制相机
      const controls = new OrbitControls(camera, canvas)
      controls.update()

      // 场景
      const scene = new THREE.Scene()

      // 渲染
      function render() {
        renderer.render(scene, camera)
        requestAnimationFrame(render)
      }
      requestAnimationFrame(render)
    </script>
  </body>
</html>
  • 创建着色器。
  // 顶点着色器代码
  const vertexShader = `
  varying vec3 vPosition;// 创建变量 在片元着色器 中使用
  void main() {
      vPosition = position;// 赋值 顶点坐标
      // projectionMatrix 是投影变换矩阵 modelViewMatrix 是相机坐标系的变换矩阵 position 顶点坐标
      gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
  }
  `
  // mod(x,y)返回x – y * floor (x/y),即求模计算%
  // 片元着色器代码
  const fragmentShader = `
  varying vec3 vPosition;// 获取顶点着色器 设置的变量
  uniform float time;// 获取传入的 全局变量
  void main() {
    float time = mod(time, 3.0); 
    if(vPosition.x > 0.0 && vPosition.y > 0.0){
      if(time < 1.0){
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
      } else if(time >= 1.0 && time < 2.0){
        gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
      }else{
        gl_FragColor = vec4(1.0, 0.7, 0.0, 1.0);
      }
    }else{
      gl_FragColor=vec4(0.2, 0.2, 0.2, 1.0);
    }
  }
  `
  1. three.js在顶点着色器中定义好了一下关于顶点信息的变量,如position、modelViewMatrix等。
  2. 创建vPosition变量把顶点信息传入片元着色器。
  3. 在片元着色器中获取time全局变量,用于在不同时间修改颜色。
  4. 根据顶点坐标来判断几何体要修改颜色的位置。
  • 创建全局变量。
  const uniforms = {
    time: {
      type: 'f',
      value: 0.0
    }
  }
  1. type 定义数据类型。
  • 创建球几何体,使用着色器材质。
  const geometry = new THREE.SphereGeometry(15, 32, 16)

  const mate = new THREE.ShaderMaterial({
    uniforms: uniforms,
    vertexShader: vertexShader,
    fragmentShader: fragmentShader
  })
  const mesh = new THREE.Mesh(geometry, mate)
  scene.add(mesh)
  • 修改渲染函数。
  // 渲染
  function render() {
    uniforms.time.value += 0.1

    renderer.render(scene, camera)
    requestAnimationFrame(render)
  }
  1. 通过渲染函数修改全局变量大小。
  2. 每一次执行渲染,着色器会重新执行,获取最新的uniforms

1.gif

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个three.js着色器特效编程案例,注释在代码中: ```javascript // 1. 定义场景 var scene = new THREE.Scene(); // 2. 创建相机 var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); camera.position.z = 5; // 3. 创建渲染器 var renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); // 4. 创建物体 var geometry = new THREE.BoxGeometry( 1, 1, 1 ); var material = new THREE.ShaderMaterial({ uniforms: { time: { value: 0.0 } // 添加一个time变量,用于控制着色器的动画效果 }, vertexShader: ` uniform float time; // 从uniform传入time变量 void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); gl_Position.y += sin(time) * 0.2; // 在y轴上添加sin函数的动画效果 } `, fragmentShader: ` void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // 着色器的基本颜色 } ` }); var cube = new THREE.Mesh( geometry, material ); scene.add( cube ); // 5. 渲染场景 function animate() { requestAnimationFrame( animate ); // 更新着色器中的time变量 material.uniforms.time.value += 0.1; renderer.render( scene, camera ); } animate(); ``` 这个案例中,我们首先定义了场景、相机和渲染器。然后创建了一个立方体物体,并为它定义了一个着色器材质。该着色器材质包含了一个顶点着色器和一个片元着色器。在顶点着色器中,我们通过uniform变量JavaScript中传入了time变量,并在y轴上添加了sin函数的动画效果。在片元着色器中,我们简单地将颜色设置为红色。 最后,我们在animate函数中更新着色器中的time变量,并渲染整个场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值