当前位置: 首页 > article >正文

从零开始学习three.js(18):一文详解three.js中的着色器Shader

在WebGL和Three.js的3D图形渲染中,着色器(Shader) 是实现复杂视觉效果的核心工具。通过编写自定义的着色器代码,开发者可以直接操作GPU,实现从基础颜色渲染到动态光照、粒子效果等高级图形技术。本文将深入解析Three.js中着色器的核心概念、实现原理及实战应用,并结合代码示例帮助读者全面掌握这一关键技术。

核心特点​​:


一、着色器基础与分类

1.1 顶点着色器(Vertex Shader)

顶点着色器负责处理几何体的每个顶点,主要功能包括:

  • 顶点位置变换:将模型空间坐标转换为屏幕空间坐标(通过 gl_Position 输出)
  • 顶点属性计算:如法线变换、纹理坐标传递等
void main() {gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}

说明projectionMatrix(投影矩阵)、modelViewMatrix(模型视图矩阵)由Three.js自动注入,position是顶点的原始坐标。

1.2 片元着色器(Fragment Shader)

片元着色器决定每个像素的最终颜色,通过 gl_FragColor 输出:

void main() {gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // 红色
}

特性:颜色支持动态计算,如基于光照模型、纹理采样等。

1.3 着色器材质类型

Three.js提供两种自定义着色器材质:

  • ShaderMaterial​:简化版材质,内置常用变量(如modelViewMatrixprojectionMatrix),适合快速开发。

  • RawShaderMaterial​:需手动声明所有变量(如attributeuniform),灵活性更高,适合深度优化。

​示例代码:创建基础着色器材质​

const material = new THREE.ShaderMaterial({  vertexShader: vertexShaderCode,  fragmentShader: fragmentShaderCode,  uniforms: {  time: { value: 0 },  color: { value: new THREE.Color(0xff0000) }  }  
});  

二、着色器变量类型

2.1 Uniforms

  • 全局常量:所有顶点/片元共享同一值(如时间、光源位置)
  • 传递方式:通过 ShaderMaterialuniforms 属性设置
const material = new THREE.ShaderMaterial({uniforms: {uTime: { value: 0 },uTexture: { value: new THREE.TextureLoader().load("texture.png") }}
});

在着色器中声明uniform float uTime;

2.2 Attributes

  • 顶点属性:每个顶点独有的数据(如位置、颜色、法线)
  • 典型应用:动态顶点动画(如波浪效果)
geometry.setAttribute('displacement', new THREE.BufferAttribute(displacementArray, 1));

在顶点着色器中访问attribute float displacement;

2.3 Varyings

  • 插值变量:从顶点着色器向片元着色器传递数据(如UV坐标、颜色插值)
// 顶点着色器
varying vec2 vUv;
void main() {vUv = uv;// ...
}// 片元着色器
varying vec2 vUv;
void main() {vec4 color = texture2D(uTexture, vUv);
}

注意:变量名需在两者中保持一致。


三、矩阵变换与坐标系统

3.1 核心矩阵解析

  • 模型矩阵(modelMatrix) :几何体的旋转、平移、缩放变换
  • 视图矩阵(viewMatrix) :相机的观察变换(等同于相机世界矩阵的逆矩阵)
  • 投影矩阵(projectionMatrix) :3D到2D的投影(如透视投影)

3.2 矩阵乘法顺序

顶点变换遵循 “右乘”顺序,确保坐标正确转换:

gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);

原理:从模型空间→世界空间→相机空间→裁剪空间逐步变换。


四、实战案例:动态波纹效果

4.1 着色器代码实现

顶点着色器(传递UV坐标):

varying vec2 vUv;
void main() {vUv = uv;gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}

片元着色器(动态波纹计算):

uniform float uTime;
varying vec2 vUv;void main() {float ripple = sin(length(vUv - 0.5) * 10.0 - uTime * 2.0);float opacity = smoothstep(0.0, 0.2, abs(ripple));gl_FragColor = vec4(0.2, 0.5, 1.0, opacity);
}

4.2 JavaScript端配置

const material = new THREE.ShaderMaterial({uniforms: {uTime: { value: 0 }},vertexShader: vertexShaderCode,fragmentShader: fragmentShaderCode,transparent: true
});// 动画循环中更新Uniform
function animate() {material.uniforms.uTime.value += 0.01;requestAnimationFrame(animate);
}

效果:实现以中心向外扩散的蓝色波纹。


五、高级技巧与优化

5.1 性能优化策略

  1. 减少分支语句:GPU不擅长动态分支,可用 mix()step() 替代 if-else
  2. 向量化运算:优先使用 vec3/vec4 代替多个 float 计算
  3. 纹理压缩:使用Mipmap和纹理图集减少采样开销

5.2 常见问题排查

  • 变量未声明:检查Three.js版本是否支持特定语法(如 #version 300 es
  • 精度问题:在移动端明确指定精度(precision mediump float;
  • 矩阵顺序错误:确保模型→视图→投影的乘法顺序正确

六、扩展应用:后期处理通道

通过 EffectComposerShaderPass 实现屏幕后处理:

import { EffectComposer, ShaderPass } from 'three/examples/jsm/postprocessing';const composer = new EffectComposer(renderer);
composer.addPass(new RenderPass(scene, camera));const customPass = new ShaderPass(customShaderMaterial);
composer.addPass(customPass);

典型效果:模糊、Bloom光效、颜色校正等。


结语

Three.js着色器为开发者打开了高性能图形编程的大门。通过深入理解GLSL语法、矩阵变换和变量传递机制,可以创造出从基础颜色变化到复杂物理模拟的全方位视觉效果。建议通过Shadertoy平台进行实时演练,结合Three.js文档探索更多可能性。

相关文章:

从零开始学习three.js(18):一文详解three.js中的着色器Shader

在WebGL和Three.js的3D图形渲染中,着色器(Shader) 是实现复杂视觉效果的核心工具。通过编写自定义的着色器代码,开发者可以直接操作GPU,实现从基础颜色渲染到动态光照、粒子效果等高级图形技术。本文将深入解析Three.j…...

调用百度云API机器翻译

新建Python文件,叫 text_translator.py 输入 import requests import jsonAPI_KEY "glYiYVF2dSc7EQ8n78VDRCpa" # 替换为自己的API Key SECRET_KEY "kUlhze8OQZ7xbVRp" # 替换为自己的Secret Keydef main():# 选择翻译方向while True:di…...

大模型训练计算显存占用

在大模型训练过程中,GPU显存中需要存储多种类型的数据,这些数据的合理管理直接影响训练效率和模型规模。需要放入GPU的关键数据类型如下: 注意: 在计算大模型训练占用的显存时,一般只计算 模型参数、梯度、优化器 的显…...

uni-app学习笔记六-vue3响应式基础

一.使用ref定义响应式变量 在组合式 API 中&#xff0c;推荐使用 ref() 函数来声明响应式状态&#xff0c;ref() 接收参数&#xff0c;并将其包裹在一个带有 .value 属性的 ref 对象中返回 示例代码&#xff1a; <template> <view>{{ num1 }}</view><vi…...

亚远景-ASPICE与ISO 21434在汽车电子系统开发中的应用案例

在汽车电子系统开发中&#xff0c;ASPICE&#xff08;Automotive Software Process Improvement and Capacity Determination&#xff09;与ISO 21434&#xff08;Road vehicles — Cybersecurity engineering&#xff09;是两个关键标准&#xff0c;分别从软件开发流程和网络安…...

『已解决』Python virtualenv_ error_ unrecognized arguments_--wheel-bundle

📣读完这篇文章里你能收获到 🐍 了解 virtualenv 参数错误的原因及解决方案📦 学习如何正确配置 Python 虚拟环境文章目录 前言一、问题描述1.1 错误现象1.2 影响范围二、问题分析2.1 根本原因三、解决方案3.1 兼容处理3.2 完整解决方案四、总结前言 本文详细介绍了在 D…...

详细介绍一下Python连接MySQL数据库的完整步骤

以下是 Python 连接 MySQL 数据库的完整步骤&#xff0c;包含环境准备、连接建立、数据操作、错误处理和性能优化等内容&#xff1a; 一、环境准备 安装 MySQL 服务器 Windows/macOS&#xff1a;下载安装包 MySQL Installer Linux&#xff1a; bash Ubuntu/Debian sudo apt-…...

【Unity 2023 新版InputSystem系统】新版InputSystem 如何进行人物移动(包括配置、代码详细实现过程)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、InputSystem配置二、GameInput 游戏输入脚本1.实现思路2.完整代码三、Player 游戏人物移动脚本1.实现思路2.完整代码四、场景脚本设置1.组件设置五、问题解决1.人物一直下落2.人物跳跃时,…...

单片机-STM32部分:13-1、编码器

飞书文档https://x509p6c8to.feishu.cn/wiki/BpEywhaX9iqbiLkdqdAcmDnwnab EC旋转编码器 在产品开发过程中&#xff0c;需要位置闭环的的产品&#xff0c;类似电机类产品来说&#xff0c;编码器至关重要&#xff0c;它不仅可以使我们对带年纪进行精确的速度闭环&#xff0c;位…...

机器学习第十二讲:特征选择 → 选最重要的考试科目做录取判断

机器学习第十二讲&#xff1a;特征选择 → 选最重要的考试科目做录取判断 资料取自《零基础学机器学习》。 查看总目录&#xff1a;学习大纲 关于DeepSeek本地部署指南可以看下我之前写的文章&#xff1a;DeepSeek R1本地与线上满血版部署&#xff1a;超详细手把手指南 一、学…...

关于我在使用stream().toList()遇到的问题

关于我在使用stream().toList()遇到的问题 问题描述 在测试以上程序的时候抛出了空指针异常 于是我以为是我数据库中存在null字段&#xff0c;但查看后发现并不存在为null的数据 问题排查 起初我以为问题出现在sort排序方法这&#xff0c;事实也确实是&#xff0c;当我把s…...

javascript 编程基础(2)javascript与Node.js

文章目录 一、Node.js 与 JavaScript1、基本概念1.1、JavaScript&#xff1a;动态脚本语言1.2、Node.js&#xff1a;JavaScript 运行时环境 2、核心区别3、执行环境差异3.1、浏览器中的JavaScript3.2、Node.js中的JavaScript 4、共同点5、为什么需要Node.js&#xff1f; 一、No…...

Spring Boot 集成 druid,实现 SQL 监控

文章目录 背景Druid 简介监控统计 StateFilter其它 Filter详细步骤第 1 步:添加依赖第 2 步:添加数据源配置【通用部分】第 3 步:添加监控配置【关键部分】第 3 步:访问 druid 页面参考背景 😂 在 Code Review 过程中发现,经常有开发会忘记给表加索引。这就导致,生产运…...

多卡跑ollama run deepseek-r1

# 设置环境变量并启动模型 export CUDA_VISIBLE_DEVICES0,1,2,3 export OLLAMA_SCHED_SPREAD1 # 启用多卡负载均衡 ollama run deepseek-r1:32b 若 deepseek-r1:32b 的显存需求未超过单卡容量&#xff08;如单卡 24GB&#xff09;&#xff0c;Ollama 不会自动启用多卡 在run…...

HTML向四周扩散背景

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>扩散背景效果</title><style>body {…...

基于Java在高德地图面查询检索中使用WGS84坐标的一种方法-以某商场的POI数据检索为例

前言 随着移动互联网的飞速发展&#xff0c;基于位置的服务&#xff08;LBS&#xff09;需求日益增长&#xff0c;越来越多的应用需要从地图中检索特定区域内的地理信息&#xff0c;例如商业场所、公共服务设施等。商场作为城市商业活动的重要载体&#xff0c;其周边的地理信息…...

使用 Terraform 创建 Azure Databricks

使用 Terraform 创建 Azure Databricks Terraform 是一种基础设施即代码(IaC)工具,允许用户通过声明式配置文件来管理和部署云资源。Azure Databricks 是一个基于 Apache Spark 的分析平台,专为数据工程和数据科学设计。通过 Terraform,可以自动化 Azure Databricks 的创…...

本地部署dify+ragflow+deepseek ,结合小模型实现故障预测,并结合本地知识库和大模型给出维修建议

1.准备工作 使用ollama 拉取deepseek-r1:7b 官网下载ollama ollama run deepseek-r1:7b ollama list Ragflow专注于构建基于检索增强生成&#xff08;RAG&#xff09;的工作流&#xff0c;强调模块化和轻量化&#xff0c;适合处理复杂文档格式和需要高精度检索的场景。Dify…...

SECERN AI提出3D生成方法SVAD!单张图像合成超逼真3D Avatar!

SECERN AI提出的3D生成方法SVAD通过视频扩散生成合成训练数据&#xff0c;利用身份保留和图像恢复模块对其进行增强&#xff0c;并利用这些经过优化的数据来训练3DGS虚拟形象。SVAD在新的姿态和视角下保持身份一致性和精细细节方面优于现有最先进&#xff08;SOTA&#xff09;的…...

深入探索:Core Web Vitals 进阶优化与新兴指标

一、INP&#xff08;Interaction to Next Paint&#xff09;深度解析 INP 与 FID 的核心差异 • 响应范围&#xff1a;FID仅测量首次输入延迟&#xff0c;而INP跟踪页面生命周期中所有关键交互 • 测量维度&#xff1a;INP综合考虑输入延迟、处理时间和下一帧渲染时间 • 评…...

c/c++的opencv开闭操作

OpenCV 中的形态学开运算与闭运算 (C) 在计算机视觉和图像处理领域&#xff0c;形态学操作是用于分析和处理图像形状的一系列非线性操作。OpenCV 作为一个强大的开源计算机视觉库&#xff0c;提供了丰富的形态学转换函数。其中&#xff0c;“开运算”&#xff08;Opening&…...

【物联网】 ubantu20.04 搭建L2TP服务器

部署篇 序言 为了是两个客户端在同一个网络内&#xff0c;需要找一台服务器&#xff0c;搭建一个L2TP服务器&#xff0c;通过L2TP使两个客户端在同一个网络内,为什么要搭建&#xff0c;主要是解决例如员工出差后&#xff0c;还需要连接公司内网资源的问题&#xff0c;本文主要…...

winrar 工具测试 下载 与安装

https://zhuanlan.zhihu.com/p/680852417 https://www.angusj.com/resourcehacker/#download 点击String Table&#xff0c;在展开列表中找到80:2052展开&#xff0c;删除1277行。点击右上方编译按钮&#xff0c;并保存。...

PLC组网的方法、要点及实施全解析

一、PLC组网方法 1.1 基于以太网的组网 - 适用场景&#xff1a;适用于数据传输量大、通信距离长、对实时性要求相对不苛刻的场景&#xff0c;如大型工厂的车间级数据交互、跨区域设备协同控制 。 - 实现方式&#xff1a;利用工业以太网交换机&#xff0c;将支持以太网接口的…...

网络安全深度解析:21种常见网站漏洞及防御指南

一、高危漏洞TOP 10 1. SQL注入(SQLi) 原理:通过构造恶意SQL语句突破系统过滤机制 典型场景: - 联合查询注入: union select 1,version(),3--+ - 布尔盲注:and (select substr(user(),1,1)=r) - 时间盲注:;if(now()=sysdate(),sleep(5),0)/ 防御方案: - 严格参数化查…...

【FAQ】HarmonyOS SDK 闭源开放能力 —Vision Kit (3)

1.问题描述&#xff1a; 通过CardRecognition识别身份证拍照拿到的照片地址&#xff0c;使用该方法获取不到图片文件&#xff0c;请问如何解决&#xff1f; 解决方案&#xff1a; //卡证识别实现页&#xff0c;文件名为CardDemoPage&#xff0c;需被引入至入口页 import { …...

Java大厂面试实战:Spring Boot与微服务场景中的技术点解析

Java大厂面试实战&#xff1a;Spring Boot与微服务场景中的技术点解析 第一轮&#xff1a;基础技术了解 面试官&#xff1a;谢飞机&#xff0c;你好。从简历上看&#xff0c;你熟悉Spring Boot&#xff0c;那我们来聊聊它的核心功能吧。Spring Boot有哪些主要的特性&#xff…...

从零启动 Elasticsearch

elastic 有弹力的 ElaticSearch &#xff08;ES&#xff09;是一个基于 Lucene 的分布式全文检索引擎。可以做到近乎实时地存储、检索数据&#xff0c;并且本身具有良好的扩展性&#xff0c;可以扩展到上百台服务器&#xff0c;处理PB级别&#xff08;1 Petabyte 1024TB&…...

比较两个用于手写体识别的卷积神经网络(CNN)模型

要比较两个用于手写体识别的卷积神经网络(CNN)模型,可以从以下 ‌6个核心维度‌ 进行系统性评估,并直接给出对比结论: ‌一、基础性能对比(核心指标)‌ ‌准确率‌ 直接比较两个模型在 ‌相同测试集‌ 上的分类准确率(如MNIST测试集的错误率是否低于0.5%)若准确率接近…...

Linux利用多线程和线程同步实现一个简单的聊天服务器

1. 概述 本文实现一个基于TCP/IP的简单多人聊天室程序。它包含一个服务器端和一个客户端&#xff1a;服务器能够接收多个客户端的连接&#xff0c;并将任何一个客户端发来的消息广播给所有其他连接的客户端&#xff1b;客户端则可以连接到服务器&#xff0c;发送消息并接收来自…...