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

这篇具有很好参考价值的文章主要介绍了Threejs进阶之十五:在Thereejs 使用自定义shader。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最终效果

先看下这次代码最终要实现的效果,
Threejs进阶之十五:在Thereejs 使用自定义shader
效果分析:
要实现上述效果,我们需要两张图片,作为纹理贴图,使其图案产生明暗效果;然后通过定义ShaderMaterial对象通过自定义Shader实现上述效果;后面代码中会进行详细分析;
这里我们先介绍下基础知识

什么是 Shader

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

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

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

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

ShaderMaterial类

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

ShaderMaterial( parameters )

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

常用属性

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

uniforms属性

Uniform变量是着色器中一个全局的变量,其值可以由Three.js中的JavaScript代码设置。ShaderMaterial的uniforms属性通常是一个对象,其中定义了uniform变量的名称、类型和初始值。
用于在顶点着色器和片元着色器之间传递数据,它在着色器中被声明为一个uniform变量,可以包含标量、向量、矩阵等类型。在构造函数中,可以通过设置uniforms属性来传入需要在着色器中使用的数据。

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表示顶点着色器的代码,这里的代码是字符串形式的着色器代码,它负责生成最终的点的位置。

var vertexShaderCode = `
    uniform float time;
    void main() {
    
        // 处理顶点位置
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
`;

fragmentShader属性

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

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及其相关库

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等基础场景文章来源地址https://www.toymoban.com/news/detail-454399.html

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 

到了这里,关于Threejs进阶之十五:在Thereejs 使用自定义shader的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Threejs入门之十四:Threejs中的组(Group)对象

    组其实就是一个集合,将不同的物体添加到一个组中,就形成了一个集合; 比如我们可以创建两个物体,然后将这两个物体使用group.add方法添加到同一个组中 Group的特性 在Threejs的官方文档中介绍Group时说它几乎与Object3D相同,因此,Group的属性和Object3D的相同 .children属性 使用

    2024年02月06日
    浏览(77)
  • 【Unity】 HTFramework框架(四十五)【进阶篇】指令系统-自定义指令

    更新日期:2023年6月19日。 Github源码:[点我获取源码] Gitee源码:[点我获取源码] 指令系统详解:【Unity】 HTFramework框架(四十四)【进阶篇】指令系统。 使用 HTFramework 的 指令系统 ,可以将一段指令代码即时编译并执行。 例如,我需要这样一个功能: 新建一个游戏物体,将

    2024年02月11日
    浏览(75)
  • docker专题系列之十五:卸载docker

    一、准备工作 1.杀死docker有关的容器: 2.删除所有docker容器: 3.删除所有docker镜像: 4.停止 docker 服务: 5.删除docker相关存储目录:(分别进行执行以下四个命令) 6.如果删除不掉,则先umount: 7.然后再重新执行上面那步“删除docker相关存储目录”。 二、卸载工作 经过上面一

    2024年02月11日
    浏览(33)
  • 软件设计模式系列之十五——职责链模式

    职责链模式(Chain of Responsibility Pattern)也称为责任链模式,是一种结构型设计模式,用于构建一条对象处理请求的责任链。在这个模式中,多个对象依次处理请求,直到其中一个对象能够处理该请求为止。职责链模式将请求的发送者和接收者解耦,允许多个对象都有机会处理

    2024年02月08日
    浏览(35)
  • 大语言模型之十五-预训练和监督微调中文LLama-2

    这篇博客是继《大语言模型之十二 SentencePiece扩充LLama2中文词汇》、《大语言模型之十三 LLama2中文推理》和《大语言模型之十四-PEFT的LoRA》 前面博客演示了中文词汇的扩充以及给予LoRA方法的预训练模型参数合并,并没有给出LoRA模型参数是如何训练得出的。 本篇博客将分析

    2024年02月08日
    浏览(41)
  • DPDK系列之十五虚拟化virtio源码分析之vhost-user

    在网络IO的半虚拟中,vhost-user是目前最优秀的解决方案。在DPDK中,同样也采用了这种方式。vhost-user是为了解决内核状态数据操作复杂的情况提出的一种解决方式,通过在用户进程来替代内核进程来实现数据交互的最少化。在vhost-user中,使用Socket进行设备文件间通信(替代了

    2023年04月25日
    浏览(45)
  • Threejs进阶之一:基于vite+vue3+threejs构建三维场景

    前面的章节我们都是通过HTML+JS的方式创建三维场景,从这一章节开始,我们后面将使用vite+vue3+threejs来构建三维场景。 打开vscode的终端管理器,输入如下命令 在弹出的选择框架提醒中,按上下键盘键,选择Vue,然后回车 选择JavaScript,回车 提示项目创建完成, 输入cd vue3-t

    2024年02月12日
    浏览(44)
  • threeJs实现3D地球-旋转-自定义贴图-透明发光

    //---html (angular)---         //---ts--- 效果图:

    2024年04月17日
    浏览(38)
  • 自定义MVC的进阶使用

    通用增删改查、通用分页、XML解析反射建模,包括自定义MVC工作原理与低阶使用等等前面一系列的的文章,其实都是为了这篇博客所作的准备。在本篇博客,会将前面十几篇博客内容串联起来,做出一个简单却不平凡的微项目。 将前面我们所写的通用Servlet——框架打包成J

    2024年02月12日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包