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

ThreeJS-3D教学十二:ShaderMaterial

一、首先 Shader 是做什么的
Shader 可以自定义每个顶点、每个片元/像素如何显示,而控制顶点和片元显示是通过设置 vertexShader 顶点着色器和 fragmentShader 片元着色器,这两个着色器用在 ShaderMaterial 和 RawShaderMaterial 材质上。
我们先看一个例子:
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head><title>three.js webgl - raw shader</title><meta charset="utf-8"><meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body>
<div id="container"></div>
<script id="vertexShader" type="x-shader/x-vertex">uniform mat4 modelViewMatrix;uniform mat4 projectionMatrix;attribute vec3 position;void main()	{gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );}
</script><script id="fragmentShader" type="x-shader/x-fragment">void main()	{gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);}</script>
<script type="importmap">{"imports": {"three": "../three-155/build/three.module.js","three/addons/": "../three-155/examples/jsm/"}}
</script><script type="module">import * as THREE from 'three';import Stats from 'three/addons/libs/stats.module.js';import { OrbitControls } from 'three/addons/controls/OrbitControls.js';let container, stats, controls;let camera, scene, renderer;init();animate();initObject();function initObject() {// geometry// 第一个是生成几个三角形 const vertexCount = 2 * 3;const geometry = new THREE.BufferGeometry();const positions = [];const colors = [];for ( let i = 0; i < vertexCount; i ++ ) {// adding x,y,zpositions.push( Math.random() - 0.5 );positions.push( Math.random() - 0.5 );positions.push( Math.random() - 0.5 );// adding r,g,b,acolors.push( Math.random() * 255 );colors.push( Math.random() * 255 );colors.push( Math.random() * 255 );colors.push( Math.random() * 255 );}const positionAttribute = new THREE.Float32BufferAttribute( positions, 3 );const colorAttribute = new THREE.Uint8BufferAttribute( colors, 4 );colorAttribute.normalized = true; // this will map the buffer values to 0.0f - +1.0f in the shadergeometry.setAttribute( 'position', positionAttribute );geometry.setAttribute( 'color', colorAttribute );// materialconst material = new THREE.RawShaderMaterial({uniforms: {time: { value: 1.0 }},vertexShader: document.getElementById( 'vertexShader' ).textContent,fragmentShader: document.getElementById( 'fragmentShader' ).textContent,side: THREE.DoubleSide,transparent: true});const mesh = new THREE.Mesh( geometry, material );scene.add( mesh );}function init() {container = document.getElementById( 'container' );camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 10 );camera.position.z = 2;scene = new THREE.Scene();scene.background = new THREE.Color( 0x101010 );renderer = new THREE.WebGLRenderer();renderer.setPixelRatio( window.devicePixelRatio );renderer.setSize( window.innerWidth, window.innerHeight );container.appendChild( renderer.domElement );controls = new OrbitControls( camera, renderer.domElement );stats = new Stats();container.appendChild( stats.dom );window.addEventListener( 'resize', onWindowResize );}function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize( window.innerWidth, window.innerHeight );}function animate() {requestAnimationFrame( animate );render();controls.update();stats.update();}function render() {const time = performance.now();const object = scene.children[0];if (object) {// object.rotation.y = time * 0.0005;object.material.uniforms.time.value = time * 0.005;}renderer.render( scene, camera );}
</script>
</body>
</html>

以上代码 顶点着色器 我们用的是固定写法计算顶点的位置

gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
或者也可以这样:
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4( position, 1.0 );

而片元着色器我们设置了一个白色
我相信大家会对 scropt 中 x-shader/x-vertex、x-shader/x-fragment 很陌生,没关系咱们学习 Shader 其实大部分就是学这里面怎么写:
它是一种类似C语言的 GLSL 语言——即 OpenGL Shading Language——,
JavaScript、C 等语言通常在 CPU 上执行,而着色器语言通常在 GPU 上执行,由 GPU 分别对每个顶点、每个片元独立执行

shader 程序可以单独写在诸如 vertex.glsl、fragment.glsl 的文件里再导入使用,也可以和示例一样写在script中,或者在 JavaScript 里用字符串格式表示(后面会介绍)

在顶点着色器里需要设置 gl_Position顶点位置,在片元着色器里需要设置 gl_FragColor 片元/像素颜色,两者都在没有返回值的 void main() {} 主函数里设置,并且 main 函数会被自动执行

着色器语言三种变量 attribute、uniform 和 varying

  • 简单总结
    顶点着色器渲染定位顶点位置
    片段着色器为该几何体的每个可见片元(像素)进行着色
    片段着色器在顶点着色器之后执行
    在每个顶点之间会有变化的数据(如顶点的位置)称为attribute,只能在顶点着色器中使用
    顶点之间不变的数据(如网格位置或颜色)称为uniform,可以在顶点着色器和片段着色器中使用
    从顶点着色器发送到片元着色器中的插值计算数据被称为varying

看了上面的内容,我们再来看一个案例,提前说下 在这里我无意将所有 GLSL 语言的方法一一列出,我相信大家也不愿意看,毕竟网上一大堆类似文章,官网上也能看,我只是通过案例,把一些常用的知识点给到大家,能让各位对 编写Shader有个初步的认知:

let vertexShader = `precision mediump float;precision mediump int;uniform mat4 modelViewMatrix;uniform mat4 projectionMatrix;attribute vec3 position;attribute vec4 color;varying vec3 vPosition;varying vec4 vColor;void main()	{vPosition = position;vColor = color;gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );}
`;
let fragmentShader = `precision mediump float;precision mediump int;uniform float time;varying vec3 vPosition;varying vec4 vColor;void main()	{vec4 color = vec4( vColor );color.g += sin( vPosition.x * 10.0 + time ) * 0.5;gl_FragColor = color;}
`;

上面有几点知识点,先从简单的来,
1、通过 varying 可以将vPosition、vColor 从 vertexShader 到 fragmentShader
2、上面的写法是 shader 程序刚才提到的 字符串格式写法
3、precision 一个新的知识点 - 着色器运算精度设置
通过设置着色器数值的精度可以更好的配置资源,可以根据需要,在不太影响渲染效果前提下,可以尽量降低运算精度。
lowp、mediump和highp关键字 分别对应 低、中、高三个精度

1)通过precision关键字可以批量声明一些变量精度。
比如顶点着色器代码设置precision highp float;,表示顶点着色器中所有浮点数精度为高精度。

2)比如片元着色器代码设置precision lowp int;,表示片元着色器中所有整型数精度为低精度。

3)顶点和片元着色器不同类型数据默认精度
顶点着色器默认精度

数据类型默认精度
int高精度hight
float高度hight
sampler2D低精度lowp
samplerCube低精度lowp

片元着色器默认精度

数据类型默认精度
int中精度mediump
float无默认值,如果片元着色器用到浮点数,注意一定手动设置
sampler2D低精度lowp
samplerCube低精度lowp

4、我们发现有申明 modelViewMatrix、projectionMatrix、position、color变量,这是因为我们使用 RawShaderMaterial材质,这个方法没有默认的内置变量声明,与之对应的我们可以用 ShaderMaterial 材质,此时就可以这样写:

let vertexShader = `precision mediump float;precision mediump int;varying vec3 vPosition;varying vec4 vColor;void main()	{vPosition = position;vColor = color;gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );}
`;

更多的 内置变量请看这里
通过以上案例我们算是简单的了解了 Shader,发现 Shader其实就是改变 顶点位置 和 片元/像素颜色

二、图形构成的基础 三角形
我们将 geometry 换为一个球体来认识一下图形的基础构成

const geometry = new THREE.SphereGeometry( 0.5, 16, 8 );
const material = new THREE.RawShaderMaterial({uniforms: {time: { value: 1.0 }},vertexShader: document.getElementById( 'vertexShader1' ).textContent,fragmentShader: document.getElementById( 'fragmentShader1' ).textContent,side: THREE.DoubleSide,transparent: false,wireframe: true  // 将几何体渲染为线框,默认值为false(即渲染为平面多边形)。});

在这里插入图片描述
通过这个球体 可以很好的理解 图形的构成,其实就是一个个的三角形,三角形越是多,图形效果越好 当然对电脑性能要求越高,

const geometry = new THREE.SphereGeometry( 0.5, 128, 64);

在这里插入图片描述
可以看到 这个球体就很完美了,通过这个案例也能更好的帮大家理解
顶点着色器渲染顶点位置的顶点 是哪些点、从哪来的点
片段着色器为该几何体的每个可见片元(像素)进行着色

相关文章:

ThreeJS-3D教学十二:ShaderMaterial

一、首先 Shader 是做什么的 Shader 可以自定义每个顶点、每个片元/像素如何显示&#xff0c;而控制顶点和片元显示是通过设置 vertexShader 顶点着色器和 fragmentShader 片元着色器&#xff0c;这两个着色器用在 ShaderMaterial 和 RawShaderMaterial 材质上。 我们先看一个例…...

计算机网络面试TCP篇之TCP三次握手与四次挥手

TCP 三次握手与四次挥手面试题 任 TCP 虐我千百遍&#xff0c;我仍待 TCP 如初恋。 巨巨巨巨长的提纲&#xff0c;发车&#xff01;发车&#xff01; PS&#xff1a;本次文章不涉及 TCP 流量控制、拥塞控制、可靠性传输等方面知识&#xff0c;这些知识在这篇&#xff1a; TCP …...

Python-数据分析组合可视化实例图【附完整源码】

数据分析组合可视化实例图 开篇&#xff1a;应女朋友的要求&#xff0c;于是写下了这篇详细的数据可视化代码及完整注释 一&#xff1a;柱状图、折线图横向组合网格布局 本段代码使用了pyecharts库来创建一个包含多个图表&#xff08;柱状图、折线图&#xff09;和网格布局的…...

【JavaEE】Spring Web MVC详解

一.基本概念. 1.什么是Spring Web MVC? 官方链接: https://docs.spring.io/spring-framework/reference/web/webmvc.html Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning…...

docker安装rocketMq5x以上的版本

1.背景 安装RocketMQ 5.x以上的版本主要是因为新版本引入了许多性能优化、新功能以及对已有特性的增强&#xff0c;这些改进可以帮助提升消息队列系统的稳定性和效率。 1.性能提升&#xff1a;RocketMQ 5.x版本通常包括了对消息处理速度、吞吐量和延迟的优化&#xff0c;使得系…...

【Spring】DAO 和 Repository 的区别

DAO 和 Repository 的区别 1.概述2.DAO 模式2.1 User2.2 UserDao2.3 UserDaoImpl 3.Repository 模式3.1 UserRepository3.2 UserRepositoryImpl 4.具有多个 DAO 的 Repository 模式4.1 Tweet4.2 TweetDao 和 TweetDaoImpl4.3 增强 User 域4.4 UserRepositoryImpl 5.比较两种模式…...

高阶面试-秒杀系统的设计

场景 特价商品如茅台&#xff0c;在8月1日22点10分0秒开始秒杀 平台用户量&#xff1a;几千万&#xff0c;预计几十万用户感兴趣 需求 临时性的活动&#xff0c;不要太大技术改动 原则 商品不能超卖下单成功的订单不能丢失服务器和数据库不能崩溃尽量不让机器人抢走商品 …...

四十五、 证券基金业数据出境有无特别规范需要注意?

证券基金业数据合规除应遵守本《实务问答》前述的各项通用规定外&#xff0c;还应注意中国证券监督管理委员会等其他机构发布的相关规范。其中&#xff0c;与数据出境相关的主要包括《证券期货业数据分类分级指引》&#xff08;JR/T 0158—2018&#xff0c;2018年 9月 27日实施…...

02.Linux下安装FFmpeg

目录 一、下载FFmpeg的编译源码 二、编译源码 三、ffmpeg工具结构解析 1、bin目录 2、include库 3、lib库 四、注意事项 五、可能出现的一些问题 1、某些工具未安装/版本过久 2、缺少pkg-config工具 3、缺少ffmplay FFmpeg 是一个开源的跨平台音视频处理工具集&…...

华为RH2288H V2服务器,远程端口安装Linux操作系统

1、管理口 每台服务器的管理口不一样的&#xff0c;假如我的管理IP地址为&#xff1a;192.168.111.201 使用网线&#xff0c;将管理口和自己电脑连接起来&#xff0c;自己ip地址设置成和管理ip同一网段。 使用 ie 浏览器&#xff0c;如果是Edge&#xff0c;必须在Internet Exp…...

JS在线加密简述

JS在线加密&#xff0c;是指&#xff1a;在线进行JS代码混淆加密。通过混淆、压缩、加密等手段&#xff0c;使得JS源代码难以阅读和理解。从而可以有效防止代码被盗用或抄袭&#xff0c;保护开发者的知识产权和劳动成果。常用的JS在线加密网站有&#xff1a;JShaman、JS-Obfusc…...

理想汽车提出3DRealCar:首个大规模3D真实汽车数据集

理想提出3DRealCar&#xff0c;这是第一个大规模 3D 实车数据集&#xff0c;包含 2500 辆在真实场景中拍摄的汽车。我们希望 3DRealCar 可以成为促进汽车相关任务的宝贵资源。 理想汽车提出3DRealCar&#xff1a;首个大规模3D真实汽车数据集! 我们精心策划的高质量3DRealCar数…...

HTML5文旅文化旅游网站模板源码

文章目录 1.设计来源文旅宣传1.1 登录界面演示1.2 注册界面演示1.3 首页界面演示1.4 文旅之行界面演示1.5 文旅之行文章内容界面演示1.6 关于我们界面演示1.7 文旅博客界面演示1.8 文旅博客文章内容界面演示1.9 联系我们界面演示 2.效果和源码2.1 动态效果2.2 源代码2.3 源码目…...

山东大学多核并行2024年回忆版

2024.6.13回忆版 矩阵向量乘不可整除代码 集合通信与点对点通信的区别 块划分、循环划分、循环块划分&#xff08;14个向量&#xff0c;4个进程&#xff09; 按行访问还是按列访问快 SISD系统问题 循环依赖问题 问题&#xff1a;为什么不能对这个循环并行化&#xff0…...

CentOS 7 上搭建 JavaEE 环境

CentOS 7 上搭建 JavaEE 环境 安装 Java 环境 1&#xff09;检查系统中是否已安装 Java java -version如果未安装&#xff0c;将返回提示信息。 2&#xff09;安装 Java 8 sudo yum install java-1.8.0-openjdk3&#xff09;配置 Java 环境变量&#xff0c;编辑 /etc/prof…...

库与表管理的终极指南

数据库的库和表的管理 库的管理1.库的创建2.数据库的查看和使用3.数据库的修改4.数据库的删除 表的管理1.表的创建2.表的修改3.表的删除4.查看一个表 阅读指南&#xff1a; 本文章是数据库教程系列的一部分&#xff0c;专注于数据库的库和表管理。读者可以根据兴趣选择阅读相关…...

等级保护测评在测评中Linux系统怎么改

在等级保护测评中&#xff0c;针对Linux系统的整改主要是为了提高其安全性&#xff0c;使之符合等级保护的基本要求。 以下是一些常见的整改步骤和建议&#xff1a; 1. 身份鉴别&#xff1a; • 强化密码策略&#xff0c;例如设置复杂的密码规则、密码长度、密码复杂度、密码…...

Python项目开发实战:微信跳一跳辅助工具,案例教程编程实例课程详解

一、项目背景与意义 微信跳一跳是微信推出的一款小游戏,玩家需要控制一个小人从一个平台跳到另一个平台上,每成功跳过一个平台,分数就会增加。然而,随着游戏难度的增加,玩家需要更精准的控制和更快的反应速度,这往往让许多玩家感到力不从心。因此,开发一款微信跳一跳的辅…...

STM32 SWD烧写

最小电路 stm32f103x 内部已经集成了振荡电路&#xff0c;可以省略&#xff1b;rst引脚电路&#xff0c;可以省略&#xff0c;boot0,boot1不需要设置 正常烧录 -------------------------------------------------------------------STM32CubeProgrammer v2.9.0 …...

数据库系统概论(第5版教材)

第一章 绪论 1、数据(Data)是描述事物的符号记录&#xff1b; 2、数据库系统的构成&#xff1a;数据库 、数据库管理系统&#xff08;及其开发工具&#xff09; 、应用程序和数据库管理员&#xff1b; 3、数据库是长期存储在计算机内、有组织、可共享的大量数据的集合&…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...

若依登录用户名和密码加密

/*** 获取公钥&#xff1a;前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...

Qt的学习(一)

1.什么是Qt Qt特指用来进行桌面应用开发&#xff08;电脑上写的程序&#xff09;涉及到的一套技术Qt无法开发网页前端&#xff0c;也不能开发移动应用。 客户端开发的重要任务&#xff1a;编写和用户交互的界面。一般来说和用户交互的界面&#xff0c;有两种典型风格&…...

[拓扑优化] 1.概述

常见的拓扑优化方法有&#xff1a;均匀化法、变密度法、渐进结构优化法、水平集法、移动可变形组件法等。 常见的数值计算方法有&#xff1a;有限元法、有限差分法、边界元法、离散元法、无网格法、扩展有限元法、等几何分析等。 将上述数值计算方法与拓扑优化方法结合&#…...

PydanticAI快速入门示例

参考链接&#xff1a;https://ai.pydantic.dev/#why-use-pydanticai 示例代码 from pydantic_ai import Agent from pydantic_ai.models.openai import OpenAIModel from pydantic_ai.providers.openai import OpenAIProvider# 配置使用阿里云通义千问模型 model OpenAIMode…...