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

自由学习记录(77)

官方模版、、都不用了,记得之前用gitextension 的时候也好像有这种问题,也不知道怎么回事

用自己的就行了

网上说什么都没用,还是要自己老实写,配上截图工具截屏目录直接转文字过去,其实字都不要打多少的

一张很深刻的图、、、,最后的gitignore优雅

 

Implementing a Dissolve Effect with Shaders and Particles in Three.js | Codrops

Tutorial 27 - Billboarding and the Geometry Shader

多个 primitive 并行执行的时序对你不可见

geom(triangle v2g IN[3], inout TriangleStream<g2f> triStream)

“geo 提供了这种额外的分组处理方式,是它唯一的作用吗?”
—— 是的。它正是用来把一组三角形(这里是 3 个顶点构成的三角形)变成 0 个、1 个或者更多三角形/边形(通过三角形条带)。这正是 VS/FS 无法提供的 “几何生成” 能力

如果完全不构建广告牌

geo shader 里面只执行这个

for (int j = 0; j < 3; j++)

                    {

                        g2f o;

                        o.pos = UnityObjectToClipPos(IN[j].objPos);

                        o.uv = TRANSFORM_TEX(IN[j].uv, _MainTex);

                        o.normal = UnityObjectToWorldNormal(IN[j].normal);

                        o.worldPos = float4(mul(unity_ObjectToWorld, IN[j].objPos).xyz, -1);

                        triStream.Append(o);

                    }

frag接受的是在顶点的属性被栅格化后,变成一个一个内部的像素,那这个像素里的属性值是谁的?

不会是geo传入的三角形中的任意一个顶点的一套属性,而是在一切顶点都已经插值完成之后,属于像素的属性?

是的! Fragment Shader 接收到的每个像素(fragment)输入值并不是某个顶点的直接属性,而是通过 几何着色器(或顶点着色器)输出的那三个顶点在三角形内的插值结果。也就是说,像素级的属性只在三角形内部才具有意义,是 所有顶点贡献后的“混合值”

像素属性,是屏幕层面的,光栅化的结果,就是1920x1080这些每一个像素上的插值的后的一套属性 ,frag shader的目标是对应分辨率下的光栅化处理结果 所以frag shader是因为设备的不同而产生各自光栅化效果的像素个数,的最终部分?----完全yes

假设输出目标分辨率为 1920 × 1080(逻辑像素或样本数),那最多会生成约 1920 × 1080 个 fragment(每个未被丢弃的采样点对应一个片段)。这种情况下,如果有 MSAA(多样本反锯齿),Fragment Shader 可能每个像素执行多次。

Fragment Shader执行次数与分辨率(和采样数)直接相关;

fragment 数量 ≈ Resolution × samples

float dissolve_value = tex2Dlod(_DissolveTexture, float4(avgUV, 0, 0)).r;
float t = clamp(_Weight * 2 - dissolve_value, 0, 1);

与常见的 tex2D() 采样方式相比,有几个 本质上的不同点

没有梯度信息 → 不能交由GPU自动选 mipmap

几何着色器 (GS) 和顶点着色器 (VS) 并不运行在屏幕空间采样网格上,即它们不会获得像素级的梯度信息 (ddx() / ddy()),也无法由硬件计算合理的 mipmap 级别。

tex2Dlod(sampler, float4(u, v, 0, LOD)) 是一个显式指定采样 mipmap 级别的函数。

VS 或 GS 中,如果你必须采样纹理又没有梯度,就 必须手动传入 LOD,一般0 表示 base 级别(全分辨率)

为什么在 Geometry Shader 中必须用 tex2Dlod()?

在你的 geom() 里,你使用了 avgUV 而不是屏幕坐标。

Geometry Shader 不具备自动计算 mipmap 的能力,也没有片元的梯度输入——因此正常的 tex2D() 调用本身是非法的

  • 当片元从三角形 rasterizer 阶段生成后,它会由三角形顶点插值得出多个属性值(uv、worldPos、normal 等)。

  • 然而,GPU还需要「知道这个属性在屏幕上变化有多快」——这就是梯度输入(partial derivatives),可以决定纹理采样时该用哪一层 mipmap、是否切换各向异性过滤等。
    这种衍生的差值,不是顶点自带的,而是在光栅阶段根据前后左右 fragment 自动计算出来的。 aclockworkberry.comGame Development Stack Exchange

如何在 Shader 里“访问”梯度?

在 HLSL/CG 中,你可以用这两个内建函数:

float ddx(float v);   // 水平方向一像素变化率
float ddy(float v);   // 垂直方向一像素变化率
它们分别计算某个变量在 x 或 y 方向的差值,比如 ddx(i.uv.x) 表示当前像素 uv.x 与右边像素的差值。 
developer.download.nvidia.com

函数结果对一个 float2 或 float3 也可 element-wise 插值。

还可组合成 fwidth(v) = abs(ddx(v)) + abs(ddy(v)),表示该值在屏幕上的“总变化率”。通常用于实现无别名阶跃/渐变(step gradient)切割效果。 
aclockworkberry.com

它是如何计算得来的?GPU 结构揭秘

  • GPU 会把渲染目标的像素划分成 2×2 的像素块(quad),其中同一组的 4 个片元共享派发一起执行 Fragment Shader;

  • ddx(v) 就是用 quad 中右上角与左上角这两个 fragment 的 v 值差(vertical 为底与顶)来估算的;

  • 如果 Shader 被分支分流了(如 if (...) ddx(...)),某些 fragment 路径没跑时,ddx 的值可能是未定义的(误差或错误)。 aclockworkberry.comGame Development Stack Exchange

  • VS/GS 没有屏幕空间像素信息,也无 quad 概念,因此 GPU 无法估算一个变量的像素梯度值;

  • 如果你在 VS 或 GS 写 tex2D(),编译器也会报错,因为不知道该如何为 mipmap 选择级别

  • 而 Fragment Shader 正好在 raster 之后,因此自动拥有这些梯度输入。

An introduction to shader derivative functions | A Clockwork Berry

float smooth = smoothstep(edge0, edge1, fwidth(i.uv.x));


当 warp(UV扭曲)、偏移、大范围扭曲时,你可以用 ddx(i.uv) 的结果手动控制 tex2Dlod(),确保 lod 选择稳定。

在后期纹理 warping、极坐标映射、屏幕空间算法(如线框、网格显示、高宽比)中,梯度控制几乎是必需品。

片元的梯度输入”指的是 Fragment Shader 中 ddx() / ddy() 等函数返回的 屏幕空间插值值变化率 —— GPU 在片元光栅化阶段组织片元为 2×2 像素块后自动计算的差值。它是 mipmap 选择、程序滤波、抗锯齿、扭曲贴图等效果的重要基础,而顶部的 VS/GS 阶段是无法访问这一信息的。

dissolve 级联、流动法线、无缝抗锯齿边界、极坐标扭曲采样等,都是与此相关的

float2 flowUV = TRANSFORM_TEX(mul(unity_ObjectToWorld, avgPos).xz, _FlowMap);
float4 flowVector = remapFlowTexture(tex2Dlod(_FlowMap, float4(flowUV, 0, 0)));
float3 pseudoRandomPos = avgPos + _Direction;
pseudoRandomPos += flowVector.xyz * _Exapnd;

(Flow Map) 去给粒子添加“随风飘散”的局部偏移,即使 mesh 面朝向或形状不规则,也能让流散变形看起来自然又有层次感。

Flow Map 是一张二维向量贴图(通常 R=横向,G=纵向,归一化到 [0,1] 区间)
它不是噪声,而是**精准描绘各片区域想让粒子“往哪个方向飘”**的矢量数据 (相当于每个像素保存了一个 velocity vector)

靠近某边缘的三角片 UV 所对应的 flowVector 值可能指向斜下方向,而另一片可能向右上。这种方式比简单随机更具有真实感。

// remap 流向值:范围从 [0,1] 转换成 [-1,1]
float2 flow = tex2D(_FlowMap, flowUV).xy * 2 - 1;
float3 pseudoRandomPos = avgPos + _Direction + flow * _Exapnd;

#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)

  • name 是你在 ShaderLab Properties 中声明的贴图名,比如 _MainTex

  • Unity 会自动生成一个名为 name##_STfloat4 uniform:(关于默认uv的属性)

    • .xy 存储的是 UV 重复(tiling);

    • .zw 存储的是 UV 偏移(offset)。

IN.uv.xy * _MainTex_ST.xy + _MainTex_ST.zw

先缩放 (tiling),再偏移 (offset) UV。

direction4是控制大方向的一个属性

tex2Dlod(_DissolveTexture, float4(avgUV, 0, 0)).r;
确实是向 tex2Dlod() 传入了一个 4 维向量(float4),让你觉得“多余”,但它其实是 API 设计决定的正确用法。

为什么 tex2Dlod() 必须传入 float4 而不是 float2

根据 HLSL 文档,tex2Dlod(sampler2D s, float4 uv) 的签名明确要求第二个参数是一个完全的四维向量:

  • uv.xy:用于纹理的 UV 坐标

  • uv.z:在 2D 纹理中通常被忽略(可设为 0)

  • uv.w:用于指定 mipmap 级别(LOD),即你想手动控制采样的分辨率层级 Microsoft Learn

简而言之:你传入 (u, v, z, lod),其中只有 uvlod 是有效维度,剩下的 z 只填充占位。

float dissolve_value = tex2Dlod(_DissolveTexture, float4(avgUV, 0, 0)).r;

float t = clamp(_Weight * 2 - dissolve_value, 0, 1);

weight是0到1的限制范围,懂了

clamp是加保险的,,重点是控制范围,完全减和完全加的范围,最终需要是0到1的范围

才能转换给图像逻辑使用

float3 right = UNITY_MATRIX_IT_MV[0].xyz;  // 摄像机右侧方向 → X 轴
float3 up    = UNITY_MATRIX_IT_MV[1].xyz;  // 摄像机上方向 → Y 轴
// 然后用 radius * right + radius * up 构造四边形 → 所有 billboards 默认是朝向屏幕面。
➡️ 结果是所有粒子都会面向屏幕,且它们的「本地平面方向」一致,所以花瓣都是同样的“扭蛋角度”,缺乏随机性、美感或辨识度。

float3 right = UNITY_MATRIX_IT_MV[0].xyz;

float3 up = UNITY_MATRIX_IT_MV[1].xyz;

这两个得到的坐标系是哪个,为什么直接可以当right 和up ,都不用归一化

UNITY_MATRIX_IT_MVModel×View 矩阵 的 逆转置矩阵,通常用于将法线从物体空间正确变换到摄像机(视图)空间,

IT 版本用于转换法线

float3 right = UNITY_MATRIX_IT_MV[0].xyz;
float3 up = UNITY_MATRIX_IT_MV[1].xyz;
正是取 该矩阵的第 0 行和第 1 行的 .xyz 分量,而根据贴在 Gist 上的 Unity 社区经验,这两行分别等效于:

row[0].xyz → 摄像机空间的 Right(右方向向量)

row[1].xyz → 摄像机空间的 Up(上方向向量)

可以直接当做标准向量,不用再 normalize(归一化)?

理论上,inverse-transpose 在仅含旋转 + 均匀缩放的 ModelView 上不会改变轴向长度正交特性
如果你的 unity_ObjectToWorld 里没有非均匀缩放(即没有不同方向 scale ≠ 1、或 shear),那么使用这个习惯于转换法线的矩阵,其行向量已经是长度接近 1 的正交基。

Bonus:更自然花瓣姿态(不强制朝屏幕)

如果你想让花瓣朝向“世界垂直/重力方向”,而不是屏幕,可用类似思路构建:

float3 worldUp = float3(0,1,0);
float3 forward = normalize(cross(avgNormal, worldUp));  // 花瓣法线与 Up 做 cross → 世界空间方向
float3 right = normalize(cross(forward, avgNormal));
float3 up    = cross(avgNormal, right);  // 使三轴正交// 然后同样用 roll angle 随机旋转 right/up(绕 avgNormal)

这样花瓣保持自然“飘散倒地”的朝向(平面法线为 avgNormal),而每片依旧有随机翻转。

 fixed4 col = (1, 1, 1, _Opacity);

说这一行有错误,可能,,,就是你这里的值初始化了又不用,所以就警告了

雪地路径 Shader Graph—Unity_哔哩哔哩_bilibili

[Unity] 集群行为初探-鱼群_哔哩哔哩_bilibili

参考:https://github.com/Shinao/Unity-GPU-Boids?tab=readme-ov-file

Unity 鱼群(School of Fish / Flocking)

涵盖 Boids 算法、VFX Graph、Shader Graph 等实现路径

Cam Ayres 的“Shader Graph + VFX Graph 制作鱼群”(即 《Unity 6: Creating a School of Fish…》),核心都依赖 Shader Graph/VFX Graph。而这两者 只能在 Unity 的 SRP 管线(也即 URP/HDRP)下使用

https://www.youtube.com/watch?v=voegALuuO2I

Shinao/Unity-GPU-Boids: GPU powered boids with multiple implementations

How to achieve boid/flocking effect (e.g. fish school) in VFX Graph without Compute Shader? - #2 by OrsonFavrel - Unity Engine - Unity Discussions

https://github.com/Streamweaver/FishFlocker?utm_source=chatgpt.com

“Colorful FX” 是一个 很久之前的 Unity 插件,主要用于后处理调色和色彩校正,让 Unity 场景具有类似 Photoshop 效果的视觉表现。

提供一系列高质量、可自定义的 后期处理效果,包括 PCC、色调转换、LUT、色彩提炼、动效预设、模糊、饱和度调整等—类似游戏版 Photoshop 调色工具。

❓为什么现在较少使用?

  • 随着 Unity Post-processing Stack 和 URP/HDRP 的普及,Unity 官方已经提供更加现代、集成度高的调色与后期处理解决方案;

  • 很多效果如 Bloom、Tone mapping、Color grading、Vignette 等都内置支持,无需额外插件;

  • Colorful FX 自 2012 年发布以来几乎不再更新,目前兼容性有限,尤其对 URP/HDRP 支持不佳。

Colorful FX 是 Unity 早期为 Built-in 管线提供的高效调色与后处理特效插件,但现在更多被 Unity 官方后期管线所替代。”

https://www.bilibili.com/video/BV1DG4y1n7md/?vd_source=8edbc527019213f5a0f28f3a4b395636

Git 并不跟踪“文件的差异”,而是将每次 commit 时项目里的所有文件生成一次 全量快照(snapshot),只保存改变过的内容。对于未变化的文件,它会用引用链接已有存储以节省空间

Checkout...回到某个老版本看看当时的代码

Revert...创建一个“反向的提交”来撤销它的改动

「我刚删了不要的脚本,现在 checkout 到后一个节点当前这个节点就会消失吗?

🧠 答案:

❌ 不会“消失”,但会暂时 “看不见”

你当前这个节点(删除了不要的脚本)是一个 提交记录(commit),它永远保留在 Git 历史里,只要有分支指向它,或者你回去引用它,它就不会被 Git 清理。

但⚠️如果你 checkout 到后面节点,而这个节点 没有分支指向它(如 HEAD 脱离状态下新提交的),它就会成为孤儿 commit,之后 Git 有可能自动清理它(GC)

detached HEAD 是你离开了“正常历史线”,回头看了一眼旧日时刻;
但如果你不小心写了新东西没保存分支,那些改动就可能随风而去。

ref:

手把手教你用git管理unity游戏项目,让你少掉5根头发_哔哩哔哩_bilibili

Git 是开源的,用在本地,不依赖网络

github 是云端,可以管控本地的git,(前提是本地的git存在了)

xxxx

假设你有一个 Unity 项目,并且想要 Git 管理它,其中包含 Assets/ProjectSettings/ 等文件:

Git

  1. 在项目根目录运行 git init,本地初始化 Git 仓库;

  2. 编辑 .gitignore 忽略 Library/, Temp/ 等缓存文件;

  3. git add Assets ProjectSettings,第一次提交;

  4. 修改脚本或场景后用 git commit 生成更新快照;

  5. 随时通过 git checkoutgit revert 回退历史版本。

xxxx 

“Git GUI” 是 Git 软件自带,目录下 右键 更多属性里调出

然后是里面具体的管理-----可以在GUI里做(不用,因为gui里ignore都不能写,功能太少)

创建.git文件夹在unity总文件夹里之后,这个项目打开脚本时,VScode自动就变了

VS Code 的 Git 功能默认在打开文件夹是自动检测最近的 .git 仓库

实际上,这些就是 VS Code 调用了底层 git status 命令,自动显示每个文件状态,以简化你的版本控制流程(无需手动运行命令行)。

.gitignore可以去掉repository里不要管的文件夹

xxx

这里直接在vscode里面git完全管理

直接点分支,create repository,自动对unity项目根目录下创建git文件夹

CommitCommit Staged 都需要先 Stage,Commit All 则直接提交所有修改

暂存Staging,让你可以add挑出更改--提交

 只有进行了 commit(提交)之后,Git 才会记录那些改动,并且之后才会在 UI 或 git status 输出中显示那些「改变了的文件」

半天下来,git可能损坏文件,但是是最好的,要注意绑定的关系变化就是,模型被绑定了就不要删了

https://docs.unity3d.com/Packages/com.unity.visualscripting%401.9/manual/vs-version-control.html

答辩官方文档,差评(虽然估计是自己哪里没注意到)

右键菜单中的 “Reset current branch to this Commit...” 操作

 

Unity 粒子系统(Particle System)的底层原理和构成模块,可以从三个核心阶段拆解:发射 → 模拟更新 → 渲染

Particle System模拟 / 更新阶段(Simulation)

  • 每帧基于时间间隔,更新每个粒子状态:

    • 位置更新:由速度控制,结合重力、风力、外力模块(Force over Lifetime)、噪声模块等;

    • 生命周期:递减剩余寿命,寿命结束则销毁;

    • 属性变化:大小、颜色、旋转、透明度可随生命周期插值变化(Size over Lifetime、Color over Lifetime);

  • 工作流程为:模拟 → lifetime 判断 → 属性插值 → 位置更新。

  • 粒子最终以 2D 点精灵 (Point Sprites) 或 billboard 四边形形式渲染,每个粒子朝向摄像机;

  • 可以通过材质、纹理、混合模式等控制效果;

  • 可进一步定制为使用 Mesh 或 GPU 渲染(或 Visual Effect Graph 模块支持百万级粒子)。

Unity 粒子 特有模块和高级功能

  • 子发射器(Sub-Emitter):某些粒子出生、死亡或碰撞时触发再次发射子粒子;

  • 碰撞模块(Collision):支持粒子与场景 collider 或刚体交互,无需写代码;

  • 脚本 API:可通过粒子系统脚本接口控制粒子生命周期事件、自定义行为;

  • Visual Effect Graph(VFX Graph):基于 GPU 的可视化图形编辑工具,支持大规模 GPU 粒子渲染。

Shader Graph 如何接入 VFX Graph

  • 首先,你需要在 Shader Graph 的设置中启用 “Support VFX Graph”,并指定正确的渲染管线(HDRP/URP)
    Unity Discussions+9Unity Documentation+9Unity+9

  • 然后在 VFX Graph 的输出 Context 中选择该 Shader Graph,即可用自定义 Shader 来定义粒子着色
    Unity Documentation+2Unity Discussions+2

这样你能完全控制粒子的视觉属性,比如发光、变色、顶点动画(如渐变形变、扭曲等)都可由 Shader Graph 处理。

Unity 的 Visual Effect Graph(VFX Graph) 是 Unity 针对高性能 GPU 粒子效果设计的节点式可视化编辑系统

VFX Graph 完全在 GPU 上执行粒子发射、模拟与渲染流程,利用 GPU 并行处理数百万甚至上亿粒子,高性能、低 CPU 占用

VFX Graph 基于 GPU 渲染 时,其核心技术是通过 Compute Shader 将粒子模拟与粒子渲染一并交由 GPU 控制,然后根据 Shader Graph(或 HLSL)定义每个粒子的外观与行为。

VFX粒子模拟(Update Loop)

  • 每帧由 GPU compute shader 更新粒子状态(重点,一般用GPU更新逻辑,而这里使用GPU了):位置由速度更新,并应用引力、风力、噪声等模块。

  • 生命周期结束的粒子自动销毁,属性如颜色、透明度、大小随着时间变化插值控制

VFX渲染输出(Rendering)

  • 支持多种渲染类型:点精灵(Point Sprites)、Billboard 四边形、Mesh、线条(Trail)、条带(Strip)等。

  • 可结合 Shader Graph 自定义像素与片段着色器,实现纹理动画(Flipbook)、变形、混合模式、LOD、HDRP/URP 支持等渲染细节

VFX交互与事件控制

  • 事件系统(Events):粒子在生命周期中可触发子发射器、发送事件到其他系统(如触发摄像机震动、声音、碰撞反馈)。

  • 碰撞与环境交互:支持深度缓冲、Signed Distance Fields(SDF)作为碰撞输入,使粒子与场景几何体互动Unity。

  • 与 ECS / DOTS 集成:VFX Graph 可与 DOTS 架构结合使用,将实体系统 CPU 数据提供给 GPU 缓冲区,实现模拟与渲染的协同运算Reddit。

性能与优化

  • 使用 GPU 并行计算,不会频繁切换 CPU↔GPU,保持高帧率。

  • 内置可见性剔除(bounding volume culling)、粒子 LOD、粒子遮挡透明度优化机制支持数万个实例高效渲染

知乎/论坛语录 & 经验引用

“Unity DOTS + VFX Graph 超强… 每分钟发射百万颗子弹还能保持编辑器 120fps。”
“通过在粒子上添加一个 custom BulletID,将实体与粒子匹配,再把碰撞列表传给 VFX Graph,使粒子知道自己应该销毁。”
来自 Reddit 用户经验分享,说明 VFX Graph 可接受 CPU→GPU 双向数据,实时控制粒子行为Unity Documentation+5Reddit+580.lv+5。

https://www.reddit.com/r/Unity3D/comments/y29exn/i_love_to_combine_vfx_graph_and_shader_graph_have/?utm_source=chatgpt.com

 

http://www.dtcms.com/a/315515.html

相关文章:

  • 【递归完全搜索】USACO Bronze 2023 January - 牛栏降温 IIAir Cownditioning II
  • 水库安全“守护者”:智能雨水情监测预报系统
  • 联发科芯片组曝高危漏洞:越界写入缺陷危及智能手机与物联网设备安全
  • 论文阅读笔记:《Curriculum Coarse-to-Fine Selection for High-IPC Dataset Distillation》
  • table行内--图片预览--image
  • 防御保护07-08
  • 2025年服务器漏洞生存指南:从应急响应到长效免疫的实战框架
  • 多层Model更新多层ListView
  • 4. 什么是字节码采用字节码的好处是什么
  • avue---upload 图片上传
  • 南柯电子|直流电机EMC整改:从干扰源到解决方案的实战指南
  • DHCP 握手原理
  • Laravel The requested URL /hellowzy was not found on this server. 404 问题的解决
  • gRPC Keepalive 机制详解与最佳实践
  • 本地部署文档管理平台 BookStack 并实现外部访问( Windows 版本)
  • C# LINQ(标准询运算符)
  • Windows 电脑远程访问,ZeroTier 实现内网穿透完整指南(含原理讲解)
  • 汽车OBD定位器:即插即用车辆管理省心又实用
  • CodeBuddy IDE 使用测评——半小时做一个web可视化数据工具
  • 数据可视化发展历程
  • eclipse类IDE导入现有工程教程
  • 分布式CAP定理
  • Java 中抽象概念的全面解析与实战指南
  • Python爬虫09_Requests用bs4进行数据解析
  • 【科研绘图系列】R语言绘制误差棒图
  • 【C++】模板深入进阶
  • 通信算法之298: verilog语法generate和for介绍
  • 深入浅出:Ajax 与 Servlet 实现前后端数据交互
  • VUE+SPRINGBOOT从0-1打造前后端-前后台系统-登录实现
  • 平面设计软件PS+AI百度云网盘资源在线观看