着色器
1.使用递归的方式实现数组、对象的深拷贝2.js获取url的参数3.弹框组件el-tree+vue3必坑指南4.在Vue 3中,与Vue 2相比,有一些改进和优化的diff算法。5.浏览器解析html6.浏览器渲染HTML7.Object.entries()8.vue实现虚拟dom转换成真是dom的原理9.全局封装组件处理并发请求不连续的loading10.为什么vue数组下标修改监听不到11.vue里表单验证的v-model.number的坑12.有意思的css13.js原生语音转文字14.js手写一个call15.js手写一个apply16. 手写一个 bind 方法17.js寄生组合式继承18.react中的useState修改状态获取最新状态值19.函数柯里化js20.axios请求中断_下载中断和下载进度21.axios请求重试_核心原理22.axios请求重试_axios-retry插件23.虚拟列表-渲染 10 万条数据24.vue-office 组件25.threejs26.把原生 DOM 标签转换后加入到 3D 场景空间中显示27.three.js 物体要使用光线投射技术,计算是否点击位置与物体有交叉28.threejs基本函数29.二分查找算法30.js判断字符串是否连贯31.世界坐标系和模型坐标系32.设置车模型中每个小物体 castShadow = true33.Vue3 echarts 组件化使用 resizeObserver34.网页验证码的作用 *网页中几种常见验证码35.多个装饰器一起es6装饰器36.flex属性37.移动端兼容问题38.那什么是URL、URI、URN?39.threejs的坐标渲染和着色
40.着色器
41.基于 three.js 加载器分别加载模型42.echarts自适应大屏方案 亲测有用43.有趣的工具44.关于threejs中鼠标左右移动,左动看右边,右动看左边45.有趣的知识点threejs46.uniapp底层跨端原理47.防止XSS(跨站脚本攻击)漏洞48.启动vite和electron项目配置多个主进程49.margin-bottom:-1px无效的问题50.九宫格css51.css伪类选择器52.uniapp关于uni.getUserProfile的使用53.uniapp获取用户信息54.在项目中使用UEditor碰到的几个问题55.一维数组转二位数组56.使用此函数对数组进行分块,并在最后一组添加特定的值57.如果win报错无法加载文件 C:\Users\xx\AppData\Roaming\npm\pnpm.ps1,因为在此系统上禁止运行脚本58.阅读时间缓存(快应用)59.uniapp中OnShow获取缓存60.之前使用抖音的担保支付,后俩转换成通用的交易方式61.width:100%与width:auto区别62.leetcode1047字符串反复去重(栈)63.由于<textarea>在某些平台上会创建一个原生控件,这可能会导致层级问题,尤其是在安卓设备上。在uni-app中,对于这种情况,通常推荐的解决方案是使用<cover-view>组件来覆盖原生组件,但是这种做法通常用于覆盖地图、视频等原生组件,而不是<textarea>64.记录一次uniapp使用scrollview65.微前端(矩阵项目)代码将单个文件合并到指定分支66.推荐一个炫酷爆炸例子67.思维导图推荐包68.自适应高度的过渡69.自定义滚动条边角70.实现下划线动画71.js不同类型比较72.css73.sse74.ECMAScript 语言规范每年都会进行一次更新,而备受期待的 ECMAScript 2024 将于 2024 年 6 月正式亮相。目前,ECMAScript 2024 的候选版本已经发布,为我们带来了一系列实用的新功能。75.前端scale负数表示翻转76.关于小说阅读前端翻页插件推荐turn.js77.数组扁平化78.Vue-Plugin-HiPrint79.好玩的vue组件80.DOMRect对象81.js中关于return和if条件处理82.关于文心一言不能打开F12开发者工具83.js文字处理两端展示中间省略号84.[popover, select] el-popover内有select的时候在选择后会自动关闭85.说一下flex的属性86.vue3中404路由匹配规则87.shape-outside88.createRange表示文档中的一个范围——用于js判断文字添加省略号情况89.uniapp+vue3 使用list触底+下拉90.diff算法vue91.动态修改manifest.json92.记录一下大小写导致的问题93.微信小程序关于小说类使用官方阅读器94.VS Code侧边栏的“资源管理器”丢了95.nestjs中服务引入控制器和模块的作用概念:attribute 用于向顶点着色器,传输几何图形待处理的各种属性,例如:顶点坐标,UV 坐标等等
注意:attribute 只能用于顶点着色器中,值在运行时会从几何图形属性中取值
点击查看代码
function createBasic() {
// 目标:着色器变量 - attribute 使用
// 作用:用于向顶点着色器中传入几何图形待处理的各种属性,例如:顶点坐标,UV 坐标等
// 默认情况下几何图形 attribute 属性和值都被 ShaderMaterial 注入顶点着色器内了
// 需要额外传递其他内容时使用 attribute
// 注意:attribute 只能用于顶点着色器中,用于修饰浮点数向量
const geometry = new THREE.PlaneGeometry(1, 1);
console.log(geometry)
geometry.setAttribute('position2', geometry.attributes.position)
const material = new THREE.ShaderMaterial({
vertexShader: `
attribute vec3 position2;
void main() {
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position2, 1.0);
}
`,
fragmentShader: `
void main() {
gl_FragColor = vec4(0, 1.0, 0, 1.0);
}
`
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
}
使用:
1.材质中传入 uniforms 属性(变量和值)
2.着色器中使用 uniform 定义同名变量接收
3.使用此变量与顶点坐标做效果
注意:uniform 是只读的
点击查看代码
function createBasic() {
// 目标:着色器变量-uniform
// 作用:接收全局参数使用,可在顶点/片元着色器中接收使用
// 注意:uniform 是只读的
// 步骤:
// 1. 着色器材质中传入 uniforms 属性并传入变量和值
// 2. 着色器代码中使用 uniform 定义同名变量接收
// 3. 使用此变量在顶点坐标中
const geometry = new THREE.PlaneGeometry(1, 1);
geometry.setAttribute('position2', geometry.attributes.position)
const material = new THREE.ShaderMaterial({
// 2. 着色器代码中使用 uniform 定义同名变量接收
vertexShader: `
attribute vec3 position2;
uniform float posX;
void main() {
// gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position2, 1.0);
vec4 v = vec4(position2, 1.0);
v.x += posX;
gl_Position = projectionMatrix * viewMatrix * modelMatrix * v;
}
`,
fragmentShader: `
void main() {
gl_FragColor = vec4(0, 1.0, 0, 1.0);
}
`,
// 1. 着色器材质中传入 uniforms 属性并传入变量和值
uniforms: {
posX: {
value: 2.0 // 初始值位移 x 轴 2 个单位
}
}
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
}
使用:借助 UV 坐标实现渐变色
1.顶点着色器中定义 varying 变量,保存 uv 坐标
2.片元着色器定义 varying 变量,自动接收 uv 坐标做颜色使用
点击查看代码
function createBasic() {
// 目标:着色器变量-varying
// 作用:把顶点着色器内变量,传递给片元着色器内使用
// 步骤:
// 1. 顶点着色器中定义 varying 变量,保存 uv 坐标
// 2. 片元着色器中定义 varying 变量,自动接收 uv 坐标值,作为颜色使用
const geometry = new THREE.PlaneGeometry(1, 1);
geometry.setAttribute('position2', geometry.attributes.position)
const material = new THREE.ShaderMaterial({
vertexShader: `
attribute vec3 position2;
uniform float posX;
// 1. 顶点着色器中定义 varying 变量,保存 uv 坐标
varying vec2 myUV;
void main() {
// 几何图形的 uv 坐标赋予保存
myUV = uv;
// gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position2, 1.0);
vec4 v = vec4(position2, 1.0);
v.x += posX;
gl_Position = projectionMatrix * viewMatrix * modelMatrix * v;
}
`,
fragmentShader: `
// 2. 片元着色器中定义 varying 变量,自动接收 uv 坐标值,作为颜色使用
varying vec2 myUV;
void main() {
gl_FragColor = vec4(myUV.x, myUV.y, 0, 1.0);
}
`,
uniforms: {
posX: {
value: 2.0
}
}
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
}
公式:直接用 y 轴坐标作为 rgb 颜色
点击查看代码
function createBasic() {
// 目标:使用:借助 UV 坐标实现渐变色
// 公式:直接用 y 轴坐标作为 rgb 颜色
const geometry = new THREE.PlaneGeometry(1, 1);
geometry.setAttribute('position2', geometry.attributes.position)
const material = new THREE.ShaderMaterial({
vertexShader: `
attribute vec3 position2;
uniform float posX;
varying vec2 myUV;
void main() {
// 几何图形的 uv 坐标赋予保存
myUV = uv;
// gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position2, 1.0);
vec4 v = vec4(position2, 1.0);
v.x += posX;
gl_Position = projectionMatrix * viewMatrix * modelMatrix * v;
}
`,
fragmentShader: `
varying vec2 myUV;
void main() {
// float color = myUV.y; // 上白下黑
float color = 1.0 - myUV.y; // 上黑下白
gl_FragColor = vec4(color, color, color, 1.0);
}
`,
uniforms: {
posX: {
value: 2.0
}
}
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
}
使用:
1.增加几何图形顶点数量
2.顶点着色器控制 z 轴坐标位置
建议:收集公式 / 学习图形学+数学知识
调试:可以在 JS 中带入坐标打印数值观察调试
点击查看代码
function createBasic() {
// 目标:实现波浪效果
// 使用:
// 1. 增加几何图形顶点数量
// 2. 顶点着色器控制 z 轴坐标位置
// 1. 增加几何图形顶点数量
const geometry = new THREE.PlaneGeometry(1, 1, 64, 64);
geometry.setAttribute('position2', geometry.attributes.position)
const material = new THREE.ShaderMaterial({
vertexShader: `
attribute vec3 position2;
uniform float posX;
varying vec2 myUV;
void main() {
myUV = uv;
// gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position2, 1.0);
vec4 v = vec4(position2, 1.0);
v.x += posX;
// 2. 顶点着色器控制 z 轴坐标位置
v.z = sin(v.x * 10.0) * 0.1;
v.z += sin(v.y * 10.0) * 0.1;
gl_Position = projectionMatrix * viewMatrix * modelMatrix * v;
}
`,
fragmentShader: `
varying vec2 myUV;
void main() {
// float color = myUV.y; // 上白下黑
float color = 1.0 - myUV.y; // 上黑下白
gl_FragColor = vec4(color, color, color, 1.0);
}
`,
uniforms: {
posX: {
value: 2.0
}
},
side: THREE.DoubleSide
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
}
核心:所有物体都可以通过顶点着色器和片元着色器控制
难点:控制的计算过程,数学公式的使用
点击查看代码
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
// 2. 定义全局变量 material
let scene, camera, renderer, controls, material
function init() {
scene = new THREE.Scene()
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.set(0, 0, 5)
renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
const axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)
};
function createBasic() {
// 目标:实现旋转效果
const geometry = new THREE.PlaneGeometry(1, 1, 64, 64)
material = new THREE.ShaderMaterial({
vertexShader: `
// 4. 接收时间值-作为旋转角度
uniform float myTime;
void main() {
float angle = myTime; // 旋转角度(0-360数值之间)
float radian = radians(angle); // 角度转弧度(0-2PI)
float cosV = cos(radian); // 求解旋转角度余弦值
float sinV = sin(radian); // 求解旋转角度正弦值
mat4 mx = mat4(1,0,0,0, 0,cosV,-sinV,0, 0,sinV,cosV,0, 0,0,0,1); // x 轴顺时针
// mat4 mx = mat4(cosV,-sinV,0,0, sinV,cosV,0,0, 0,0,1,0, 0,0,0,1); // z 轴顺时针
// mat4 mx=mat4(cosV,0,sinV,0, 0,1,0,0, -sinV,0,cosV,0, 0,0,0,1); // y 轴顺时针
vec4 v = mx * vec4(position, 1.0);
gl_Position = projectionMatrix * viewMatrix * modelMatrix * v;
}
`,
fragmentShader: `
void main() {
gl_FragColor = vec4(0, 1.0, 0, 1.0);
}
`,
uniforms: {
// 1. 定义接收全局参数-时间变量值(作为旋转角度)
myTime: {
value: 0
}
},
side: THREE.DoubleSide
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
}
function renderLoop(t) {
// t 是毫秒级,距离最开始的时刻过了多久
console.log(t)
// 3. 把时间数值传入到材质的 uniforms 变量中
material.uniforms.myTime.value = t / 10 // 为了让旋转慢一些(200 -> 20度)
renderer.render(scene, camera)
controls.update()
requestAnimationFrame(renderLoop)
}
init()
createBasic()
renderLoop()
本文来自博客园,作者:jialiangzai,转载请注明原文链接:https://www.cnblogs.com/zsnhweb/p/17824851.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!