前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Threejs进阶之十五:在Thereejs 使用自定义shader

Threejs进阶之十五:在Thereejs 使用自定义shader

作者头像
九仞山
发布2023-10-14 09:00:09
7080
发布2023-10-14 09:00:09
举报
文章被收录于专栏:前端漫步前端漫步

最终效果

先看下这次代码最终要实现的效果,

效果分析:

要实现上述效果,我们需要两张图片,作为纹理贴图,使其图案产生明暗效果;然后通过定义ShaderMaterial对象通过自定义Shader实现上述效果;后面代码中会进行详细分析;

这里我们先介绍下基础知识

什么是 Shader

Shader(着色器)是一种在图形处理单元(GPU)上执行的程序,它定义了如何根据输入数据(例如顶点位置,纹理坐标等)计算出各个像素的颜色。shader 主要包含两种类型,分别为顶点着色器(Vertex Shader)和片元着色器(Fragment Shader)。

顶点着色器处理顶点数据,例如坐标、法线、纹理坐标等,并对每个顶点进行分析、转换和计算。然后将这些处理过的数据传递给片元着色器进行下一步的计算。

片元着色器则处理每个像素的数据,包括颜色、深度和透明度等,并根据计算结果为像素上色。最终渲染出多个像素点。片元也可以理解为 “像素片段”,因为它们不能完全匹配显示设备上的物理像素,而是在设备上渲染为多个物理像素。

在Three.js中,可以使用ShaderMaterial来创建自定义的着色器材质,以实现更加复杂的渲染效果。

ShaderMaterial类

ShaderMaterial是Three.js中用来定义着色器材质的一个类,其构造函数的基本语法如下:

代码语言:javascript
复制
ShaderMaterial( parameters )

其中,parameters是一个对象,包含了所有需要设置的属性和方法

常用属性

  • uniforms:一个对象,用来传递顶点着色器和片元着色器之间需要共享的数据,例如光照、纹理等。
  • vertexShader:字符串类型,表示顶点着色器的代码。
  • fragmentShader:字符串类型,表示片元着色器的代码。
  • clipping:定义此材质是否支持剪裁; 如果渲染器传递clippingPlanes uniform,则为true。默认值为false。
uniforms属性

Uniform变量是着色器中一个全局的变量,其值可以由Three.js中的JavaScript代码设置。ShaderMaterial的uniforms属性通常是一个对象,其中定义了uniform变量的名称、类型和初始值。

用于在顶点着色器和片元着色器之间传递数据,它在着色器中被声明为一个uniform变量,可以包含标量、向量、矩阵等类型。在构造函数中,可以通过设置uniforms属性来传入需要在着色器中使用的数据。

代码语言:javascript
复制
var material = new THREE.ShaderMaterial({
   
    uniforms: {
   
        time: {
    value: 1.0 }, // 一个浮点数型的uniform变量
        resolution: {
    value: new THREE.Vector2() }, // 一个向量型的uniform变量
        texture: {
    value: new THREE.Texture() } //一个纹理类型的uniform变量
    },
    vertexShader: vertexShaderCode,
    fragmentShader: fragmentShaderCode
});

uniform变量的常见属性:

  • value 为uniform的初始值。
  • type 用于定义uniform变量的类型。支持的类型包括:float、vec2、vec3、vec4、int、ivec2、ivec3、ivec4、bool、bvec2、bvec3、bvec4、mat4 和 sampler2D。
  • needsUpdate 指示uniform是否需要在下一帧中更新。

可以在自定义的着色器代码中通过直接使用uniform变量的名称来引用它们。在JavaScript代码中,可以通过设置ShaderMaterial中uniforms属性中的变量值来对着色器进行控制并动态地更新外观和行为。

vertexShader属性

vertexShader表示顶点着色器的代码,这里的代码是字符串形式的着色器代码,它负责生成最终的点的位置。

代码语言:javascript
复制
var vertexShaderCode = `
    uniform float time;
    void main() {
    
        // 处理顶点位置
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
`;
fragmentShader属性

fragmentShader表示片元着色器的代码,这里的代码是字符串形式的着色器代码,它用于给模型添加材质、纹理、光照等效果的代码

代码语言:javascript
复制
var fragmentShaderCode = `
    uniform vec2 resolution;
    uniform float time;
    uniform sampler2D texture;
    void main() {
    
        // 处理纹理采样、光照计算等
        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
    }
`;

代码实现

代码实现环境为:vite+vue3+threejs,还不知道如何通过vite+vue3+threejs构建三维场景的小伙伴可以看我以前的博客:Threejs进阶之一:基于vite+vue3+threejs构建三维场景,这里不在赘述

新建ShaderView.vue文件并引入Threejs

在Vue项目的components中新建ShaderView.vue,引入Threejs及其相关库

代码语言:javascript
复制
import * as THREE from 'three' 
import {
    OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import {
    onMounted } from 'vue';
import {
    EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'
import {
    BloomPass } from 'three/examples/jsm/postprocessing/BloomPass'
import {
    FilmPass } from 'three/examples/jsm/postprocessing/FilmPass';
import {
    RenderPass } from 'three/examples/jsm/postprocessing/RenderPass';

定义初始化函数

在onMounted函数中定义init()函数,构建scene,camera,renderer等基础场景

代码语言:javascript
复制
let camera,scene,renderer,material
let controls,uniforms,clock,mesh,composer
onMounted(() => {
   
  init()
})
function init() {
   
  initScene()
  initCamera()
  initMesh() 
  initRenderer()
  initEffect()
  initControls()
  animate()
  window.addEventListener('resize',onWindowResize)
}
function initScene() {
   
  scene = new THREE.Scene() 
}
function initCamera() {
   
  camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
  // 设置相机位置
  camera.position.z = 5;
  camera.lookAt(0,0,0)
}
function initMesh() {
    
}
function initRenderer() {
   
  clock = new THREE.Clock();
  renderer = new THREE.WebGL
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 最终效果
  • 什么是 Shader
  • ShaderMaterial类
    • 常用属性
      • uniforms属性
      • vertexShader属性
      • fragmentShader属性
  • 代码实现
    • 新建ShaderView.vue文件并引入Threejs
      • 定义初始化函数
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档