Unity中实现ShaderToy卡通火(移植篇)

文章目录

  • 前言
  • 一、准备好我们的后处理基础脚本
    • 1、C#:
    • 2、Shader:
  • 二、开始逐语句对ShaderToy进行转化
    • 1、首先,找到我们的主函数 mainImage
    • 2、其余的方法全部都是在 mainImage 函数中调用的方法
    • 3、替换后的代码(已经没报错了,但是效果不对)
  • 三、我们来调试一下Shader,看看问题出在了哪?
    • 1、return float4(col, 1.0);
    • 2、black or fire
    • 3、getDepth函数
  • 四、修改 STEPS 的数值出错问题
    • 法1:在属性面板增加 STEPS 参数,赋予初始值4
    • 法2:使用#define 预定义一个常量
  • 五、最终代码


前言

在上一篇文章中,我们讲解了基础的ShaderToy怎么转化为Unity中的Shader。我们在这篇文章中,复刻一个复杂的ShaderToy效果卡通火。

  • Unity中的ShaderToy

  • 卡通火

请添加图片描述


一、准备好我们的后处理基础脚本

1、C#:

using UnityEngine;//后处理脚本
[ExecuteInEditMode]
public class P2_9 : MonoBehaviour
{public Shader PostProcessingShader;private Material mat;public Material Mat{get{if (PostProcessingShader == null){Debug.LogError("没有赋予Shader");return null;}if (!PostProcessingShader.isSupported){Debug.LogError("当前Shader不支持");return null;}//如果材质没有创建,则根据Shader创建材质,并给成员变量赋值存储if (mat == null){Material _newMaterial = new Material(PostProcessingShader);_newMaterial.hideFlags = HideFlags.HideAndDontSave;mat = _newMaterial;return _newMaterial;}return mat;}}private void OnRenderImage(RenderTexture source, RenderTexture destination){Graphics.Blit(source,destination,Mat);}
}

2、Shader:

Shader "MyShader/P2_9"
{SubShader{// No culling or depthCull Off ZWrite Off ZTest AlwaysPass{CGPROGRAM#pragma vertex vert_img#pragma fragment frag#include "UnityCG.cginc"fixed4 frag (v2f_img i) : SV_Target{return 1;}ENDCG}}
}

二、开始逐语句对ShaderToy进行转化

1、首先,找到我们的主函数 mainImage

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{vec2 uv = fragCoord.xy / iResolution.xy;uv.x *= 4.0;float t = iTime * 3.0;    vec3 col = vec3(0);float noise = getNoise(uv, t);//shape cutoff to get higher further up the screenCUTOFF = uv.y;    //and at horiz edgesCUTOFF += pow(abs(uv.x*0.5 - 1.),1.0);   //debugview cutoff field//fragColor = vec4(vec3(CUTOFF),1.0);   if (noise < CUTOFF){       //blackcol = vec3(0.);}else{//firefloat d = pow(getDepth(noise),0.7);        vec3 hsv = vec3(d *0.17,0.8 - d/4., d + 0.8);col = hsv2rgb(hsv);}fragColor = vec4(col,1.0);   
}

2、其余的方法全部都是在 mainImage 函数中调用的方法

因此,我们可以直接使用把这些方法复制到 我们片元着色器的上方,把参数类型转化为CG中的参数类型,即可直接使用

  • vec2 :float2
  • vec3 :float3
  • vec4 :float4
  • float4(0,0) : 0
  • fract(x) : frac(x) (取 x 的小数部分)
  • mix(a,b,x) :lerp(a,b,x) (线性插值)

选中需要转化的变量名,使用快捷键 Ctrl + F,进行全部替换

在这里插入图片描述

3、替换后的代码(已经没报错了,但是效果不对)

//https://www.shadertoy.com/view/lsscWrShader "MyShader/P2_9"
{SubShader{// No culling or depthCull Off ZWrite Off ZTest AlwaysPass{CGPROGRAM#pragma vertex vert_img#pragma fragment frag#include "UnityCG.cginc"float3 mod289(float3 x){return x - floor(x * (1.0 / 289.0)) * 289.0;}float4 mod289(float4 x){return x - floor(x * (1.0 / 289.0)) * 289.0;}float4 permute(float4 x){return mod289(((x * 34.0) + 1.0) * x);}float4 taylorInvSqrt(float4 r){return 1.79284291400159 - 0.85373472095314 * r;}float snoise(float3 v){const float2 C = float2(1.0 / 6.0, 1.0 / 3.0);const float4 D = float4(0.0, 0.5, 1.0, 2.0);// First cornerfloat3 i = floor(v + dot(v, C.yyy));float3 x0 = v - i + dot(i, C.xxx);// Other cornersfloat3 g = step(x0.yzx, x0.xyz);float3 l = 1.0 - g;float3 i1 = min(g.xyz, l.zxy);float3 i2 = max(g.xyz, l.zxy);//   x0 = x0 - 0.0 + 0.0 * C.xxx;//   x1 = x0 - i1  + 1.0 * C.xxx;//   x2 = x0 - i2  + 2.0 * C.xxx;//   x3 = x0 - 1.0 + 3.0 * C.xxx;float3 x1 = x0 - i1 + C.xxx;float3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.yfloat3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y// Permutationsi = mod289(i);float4 p = permute(permute(permute(i.z + float4(0.0, i1.z, i2.z, 1.0))+ i.y + float4(0.0, i1.y, i2.y, 1.0))+ i.x + float4(0.0, i1.x, i2.x, 1.0));// Gradients: 7x7 points over a square, mapped onto an octahedron.// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)float n_ = 0.142857142857; // 1.0/7.0float3 ns = n_ * D.wyz - D.xzx;float4 j = p - 49.0 * floor(p * ns.z * ns.z); //  mod(p,7*7)float4 x_ = floor(j * ns.z);float4 y_ = floor(j - 7.0 * x_); // mod(j,N)float4 x = x_ * ns.x + ns.yyyy;float4 y = y_ * ns.x + ns.yyyy;float4 h = 1.0 - abs(x) - abs(y);float4 b0 = float4(x.xy, y.xy);float4 b1 = float4(x.zw, y.zw);//float4 s0 = float4(lessThan(b0,0.0))*2.0 - 1.0;//float4 s1 = float4(lessThan(b1,0.0))*2.0 - 1.0;float4 s0 = floor(b0) * 2.0 + 1.0;float4 s1 = floor(b1) * 2.0 + 1.0;float4 sh = -step(h, 0);float4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;float4 a1 = b1.xzyw + s1.xzyw * sh.zzww;float3 p0 = float3(a0.xy, h.x);float3 p1 = float3(a0.zw, h.y);float3 p2 = float3(a1.xy, h.z);float3 p3 = float3(a1.zw, h.w);//Normalise gradientsfloat4 norm = taylorInvSqrt(float4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));p0 *= norm.x;p1 *= norm.y;p2 *= norm.z;p3 *= norm.w;// Mix final noise valuefloat4 m = max(0.6 - float4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);m = m * m;return 42.0 * dot(m * m, float4(dot(p0, x0), dot(p1, x1),dot(p2, x2), dot(p3, x3)));}//END ASHIMA /const float STEPS = 4.;float CUTOFF = 0.15; //depth less than this, show blackfloat3 hsv2rgb(float3 c){float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);return c.z * lerp(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);}float getNoise(float2 uv, float t){//given a uv coord and time - return a noise val in range 0 - 1//using ashima noise//add time to y position to make noise field move upwardsfloat TRAVEL_SPEED = 1.5;//octave 1float SCALE = 2.0;float noise = snoise(float3(uv.x * SCALE, uv.y * SCALE - t * TRAVEL_SPEED, 0));//octave 2 - more detailSCALE = 6.0;noise += snoise(float3(uv.x * SCALE + t, uv.y * SCALE, 0)) * 0.2;//move noise into 0 - 1 range    noise = (noise / 2. + 0.5);return noise;}float getDepth(float n){//given a 0-1 value return a depth,//remap remaining non-cutoff region to 0 - 1float d = (n - CUTOFF) / (1. - CUTOFF);//step itd = floor(d * STEPS) / STEPS;return d;}fixed4 frag(v2f_img i) : SV_Target{float2 uv = i.uv;uv.x *= 4.0;float t = _Time.y * 3.0;float3 col = 0;float noise = getNoise(uv, t);//shape cutoff to get higher further up the screenCUTOFF = uv.y;//and at horiz edgesCUTOFF += pow(abs(uv.x * 0.5 - 1.), 1.0);//debugview cutoff field//fragColor = float4(float3(CUTOFF),1.0);   if (noise < CUTOFF){//blackcol = 0;}else{//firefloat d = pow(getDepth(noise), 0.7);float3 hsv = float3(d * 0.17, 0.8 - d / 4., d + 0.8);col = hsv2rgb(hsv);}return float4(col, 1.0);}ENDCG}}
}

在这里插入图片描述


三、我们来调试一下Shader,看看问题出在了哪?

我们在调试Shader时,因为主要效果是在 片元着色器 中实现的。
所以,我们调试Shader一般 从 输出 倒着 来调试

1、return float4(col, 1.0);

在 ShaderToy中,已经规定了透明值为 1 。所以,最终效果为黑色,不是透明值导致的。我们应该顺着 col 去找bug。

2、black or fire

if (noise < CUTOFF)
{//blackcol = 0;
}
else
{//firefloat d = pow(getDepth(noise), 0.7);float3 hsv = float3(d * 0.17, 0.8 - d / 4., d + 0.8);col = hsv2rgb(hsv);
}
  • 我们修改black中的col。发现黑色的背景变白了,说明这不是使col最终全为 0 的原因
    col = 1;
    请添加图片描述

  • 我们修改 fire 中的 col 分别为 hsv 、d 和 getDepth(noise); (没有变化,说明这也不是原因所在)
    col = hsv; / col = d; / col = getDepth(noise);
    在这里插入图片描述

  • 我们修改 fire 中的 col 为 noise 后,我们的火出现了变化(可以锁定getDepth函数出现了问题)
    col = noise;
    请添加图片描述

3、getDepth函数

float getDepth(float n)
{//given a 0-1 value return a depth,//remap remaining non-cutoff region to 0 - 1float d = (n - CUTOFF) / (1. - CUTOFF);//step itd = floor(d * STEPS) / STEPS;return d;
}
  • 在归一化(remap remaining non-cutoff region to 0 - 1)之后,返回一个d。(我们可以看出火有了大致的颜色,说明问题处在了d = floor(d * STEPS) / STEPS;这句话)
    请添加图片描述
  • 而 d 我们已经返回过了。所以,最终问题在 STEPS 参数上
    在这里插入图片描述

四、修改 STEPS 的数值出错问题

在Unity的Shader中,如果我们的常量直接定义在Pass中
不管初始值为多少,Unity都会默认为0。
如果我们想这样使用参数,必须在属性块定义一个变量给定初始值

法1:在属性面板增加 STEPS 参数,赋予初始值4

  • 在这样定义后,修改对应的变量名后即可使用
	Properties{_Steps("STEPS",float) = 4}

法2:使用#define 预定义一个常量

#define STEPS 4

  • 可以看出,我们效果正确了
    请添加图片描述

五、最终代码

//https://www.shadertoy.com/view/lsscWrShader "MyShader/P2_9"
{Properties{_Steps("STEPS",float) = 4_CUTOFF("CUTOFF",float) = 0.15}SubShader{// No culling or depthCull Off ZWrite Off ZTest AlwaysPass{CGPROGRAM#pragma vertex vert_img#pragma fragment frag#include "UnityCG.cginc"float3 mod289(float3 x){return x - floor(x * (1.0 / 289.0)) * 289.0;}float4 mod289(float4 x){return x - floor(x * (1.0 / 289.0)) * 289.0;}float4 permute(float4 x){return mod289(((x * 34.0) + 1.0) * x);}float4 taylorInvSqrt(float4 r){return 1.79284291400159 - 0.85373472095314 * r;}float snoise(float3 v){const float2 C = float2(1.0 / 6.0, 1.0 / 3.0);const float4 D = float4(0.0, 0.5, 1.0, 2.0);// First cornerfloat3 i = floor(v + dot(v, C.yyy));float3 x0 = v - i + dot(i, C.xxx);// Other cornersfloat3 g = step(x0.yzx, x0.xyz);float3 l = 1.0 - g;float3 i1 = min(g.xyz, l.zxy);float3 i2 = max(g.xyz, l.zxy);//   x0 = x0 - 0.0 + 0.0 * C.xxx;//   x1 = x0 - i1  + 1.0 * C.xxx;//   x2 = x0 - i2  + 2.0 * C.xxx;//   x3 = x0 - 1.0 + 3.0 * C.xxx;float3 x1 = x0 - i1 + C.xxx;float3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.yfloat3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y// Permutationsi = mod289(i);float4 p = permute(permute(permute(i.z + float4(0.0, i1.z, i2.z, 1.0))+ i.y + float4(0.0, i1.y, i2.y, 1.0))+ i.x + float4(0.0, i1.x, i2.x, 1.0));// Gradients: 7x7 points over a square, mapped onto an octahedron.// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)float n_ = 0.142857142857; // 1.0/7.0float3 ns = n_ * D.wyz - D.xzx;float4 j = p - 49.0 * floor(p * ns.z * ns.z); //  mod(p,7*7)float4 x_ = floor(j * ns.z);float4 y_ = floor(j - 7.0 * x_); // mod(j,N)float4 x = x_ * ns.x + ns.yyyy;float4 y = y_ * ns.x + ns.yyyy;float4 h = 1.0 - abs(x) - abs(y);float4 b0 = float4(x.xy, y.xy);float4 b1 = float4(x.zw, y.zw);//float4 s0 = float4(lessThan(b0,0.0))*2.0 - 1.0;//float4 s1 = float4(lessThan(b1,0.0))*2.0 - 1.0;float4 s0 = floor(b0) * 2.0 + 1.0;float4 s1 = floor(b1) * 2.0 + 1.0;float4 sh = -step(h, 0);float4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;float4 a1 = b1.xzyw + s1.xzyw * sh.zzww;float3 p0 = float3(a0.xy, h.x);float3 p1 = float3(a0.zw, h.y);float3 p2 = float3(a1.xy, h.z);float3 p3 = float3(a1.zw, h.w);//Normalise gradientsfloat4 norm = taylorInvSqrt(float4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));p0 *= norm.x;p1 *= norm.y;p2 *= norm.z;p3 *= norm.w;// Mix final noise valuefloat4 m = max(0.6 - float4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);m = m * m;return 42.0 * dot(m * m, float4(dot(p0, x0), dot(p1, x1),dot(p2, x2), dot(p3, x3)));}//END ASHIMA /float _Steps;float _CUTOFF; //depth less than this, show blackfloat3 hsv2rgb(float3 c){float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);return c.z * lerp(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);}float getNoise(float2 uv, float t){//given a uv coord and time - return a noise val in range 0 - 1//using ashima noise//add time to y position to make noise field move upwardsfloat TRAVEL_SPEED = 1.5;//octave 1float SCALE = 2.0;float noise = snoise(float3(uv.x * SCALE, uv.y * SCALE - t * TRAVEL_SPEED, 0));//octave 2 - more detailSCALE = 6.0;noise += snoise(float3(uv.x * SCALE + t, uv.y * SCALE, 0)) * 0.2;//move noise into 0 - 1 range    noise = (noise / 2. + 0.5);return noise;}float getDepth(float n){//given a 0-1 value return a depth,//remap remaining non-_CUTOFF region to 0 - 1float d = (n - _CUTOFF) / (1. - _CUTOFF);//step itd = floor(d * _Steps) / _Steps;return d;}fixed4 frag(v2f_img i) : SV_Target{float2 uv = i.uv;uv.x *= 4.0;float t = _Time.y * 3.0;float3 col = 0;float noise = getNoise(uv, t);//shape _CUTOFF to get higher further up the screen_CUTOFF = uv.y;//and at horiz edges_CUTOFF += pow(abs(uv.x * 0.5 - 1.), 1.0);//debugview _CUTOFF field//fragColor = float4(float3(_CUTOFF),1.0);   if (noise < _CUTOFF){//blackcol = 0;}else{//firefloat d = pow(getDepth(noise), 0.7);float3 hsv = float3(d * 0.17, 0.8 - d / 4., d + 0.8);col = hsv2rgb(hsv);}return float4(col, 1.0);}ENDCG}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/222192.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

七.子查询

子查询 1.需求分析与解决问题1.1.实际问题1.2子查询的基本使用1.3子查询分类 2.单行子查询2.1单行比较操作符2.2代码示例2.3HAVING中的子查询2.4CASE中的查询2.5子查询中的空值问题2.6非法使用子查询 3.多行子查询3.1多行比较符操作3.2代码示例3.3空值问题 4.相关子查询4.1相关…

国家开放大学 湖南开放大学形成性考核 平时作业 统一资料

试卷代号&#xff1a;1258 房屋建筑混凝土结构设计 参考试题 一、单项选择题&#xff08;每小题2分&#xff0c;共计40分&#xff09; 1.( )是将框架结构中的部分跨间布置剪力墙或把剪力墙结构的部分剪力墙抽掉改为框架承重。 A.梁板结构体系 B.框…

LeetCode 2132. 用邮票贴满网格图:二维前缀和 + 二维差分

【LetMeFly】2132.用邮票贴满网格图&#xff1a;二维前缀和 二维差分 力扣题目链接&#xff1a;https://leetcode.cn/problems/stamping-the-grid/ 给你一个 m x n 的二进制矩阵 grid &#xff0c;每个格子要么为 0 &#xff08;空&#xff09;要么为 1 &#xff08;被占据&…

大模型应用_PrivateGPT

https://github.com/imartinez/privateGPT 1 功能 整体功能&#xff0c;想解决什么问题 搭建完整的 RAG 系统&#xff0c;与 FastGPT相比&#xff0c;界面比较简单。但是底层支持比较丰富&#xff0c;可用于知识库的完全本地部署&#xff0c;包含大模型和向量库。适用于保密级…

AI抽烟识别系统研发关键

为了设计一个有效的AI抽烟识别系统&#xff0c;我们需要考虑几个关键组成部分&#xff1a;图像捕捉、数据处理、模型训练、以及实际应用场景。下面是这个方案的详细阐述&#xff1a; 1. 图像捕捉与数据收集 摄像头部署&#xff1a;首先&#xff0c;在需要监控的区域安装高分辨…

硬件基础常识【4】--利用戴维宁定理求运放复杂反馈电阻网络的增益

最近学到了一种求带T型电阻网络反馈运放增益的方法 如图所示为T型电阻网络反馈的反相放大器 求解思路 沿X-Y断开&#xff0c;右侧利用戴维宁定理等效成电压源串电阻的形式 由戴维宁定理可得&#xff1a; V T H V o u t ∗ R 4 / ( R 3 R 4 ) ( 式 1 ) VTHVout*R4/(R3R4)…

二叉树题目:从前序遍历还原二叉树

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;从前序遍历还原二叉树 出处&#xff1a;1028. 从前序遍历还原二叉树 难度 6 级 题目描述 要求 我们从二叉树的根结点 root \texttt{root} root 开…

5键键盘的输出 - 华为OD统一考试

OD统一考试 题解&#xff1a; Java / Python / C 题目描述 有一个特殊的 5键键盘&#xff0c;上面有 a,ctrl-c,ctrl-x,ctrl-v,ctrl-a五个键。 a 键在屏幕上输出一个字母 a; ctrl-c 将当前选择的字母复制到剪贴板; ctrl-x 将当前选择的 字母复制到剪贴板&#xff0c;并清空选择…

机器视觉【1】相机的成像(畸变)模型

零、前言 很久没写文章&#xff0c;简单唠一唠。 不知道巧合还是蜀道同归&#xff0c;部门领导设定了些研究课题&#xff0c;用于公司部门员工的超前发展&#xff0c;该课题是“2D to 3D的三维重建”&#xff0c;这一块刚好是我个人看中的一个大方向&#xff0c;所以就有了这…

leetcode-21-合并两个有序链表(C语言实现)

题目&#xff1a; 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示例 2&#xff1a; 输入&#xff1a;l1 [], l2 [] 输出…

一文读懂FastAPI:Python 开发者的福音

FastAPI是一个基于Python的现代化Web框架&#xff0c;它提供了快速、简单和高性能的方式来构建API。 它结合了Python的静态类型检查和自动化文档生成的功能&#xff0c;使得开发API变得更加容易和高效。 下面将介绍如何使用FastAPI快速开发接口&#xff0c;并且利用自动生成的…

《LeetCode力扣练习》代码随想录——字符串(KMP算法学习补充——针对next数组构建的回退步骤进行解释)

《LeetCode力扣练习》代码随想录——字符串&#xff08;KMP算法学习补充——针对next数组构建的回退步骤进行解释&#xff09; 学习路径 代码随想录&#xff1a;28. 实现 strStr() CSDN&#xff1a;【详解】KMP算法——多图&#xff0c;多例子&#xff08;c语言&#xff09; …

【Qt之QNetworkAccessManager】概述及示例

概述 QNetworkAccessManager类允许应用程序发送网络请求和接收应答 网络访问API是围绕一个QNetworkAccessManager对象构建的&#xff0c;该对象为它发送的请求保存通用配置和设置。它包含代理和缓存配置&#xff0c;以及与此类问题相关的信号&#xff0c;以及可用于监视网络操…

Antd Select 添加中框

默认antd 的 Select中间并没有竖框&#xff0c;但是ui design设计了&#xff0c;所以记录一下如何添加 默认&#xff1a; CSS&#xff1a; .custom-select-suffix-icon {display: flex;align-items: center; }.custom-select-suffix-icon::before {content: ;height: 31px; …

什么品牌的猫粮比较好?主食冻干猫粮品牌十大排行

咱们养猫人每天最愁的就是咋给自家猫咪选一款优质的猫粮&#xff0c;让猫主子吃了健健康康的。早些年大多养猫人的标准就是盯着进口的买&#xff0c;所以之前进口猫粮的销量一直遥遥领先&#xff0c;感觉品控也严&#xff0c;也就放心大胆的冲进口猫粮了&#xff0c;但近期百利…

flink中如何把DB大表的配置数据加载到内存中对数据流进行增强处理

背景 在处理flink的数据流时&#xff0c;比如处理商品流时&#xff0c;一般我们从kafka中只拿到了商品id&#xff0c;此时我们需要把商品的其他配置信息比如品牌品类等也拿到&#xff0c;此时就需要关联上外部配置表来达到丰富数据流的目的&#xff0c;如果外部配置表很大&…

我的隐私计算学习——隐私集合求交(1)

笔记内容来自多本书籍、学术资料、白皮书及ChatGPT等工具&#xff0c;经由自己阅读后整理而成。 &#xff08;一&#xff09;PSI的介绍 隐私计算关键技术&#xff1a;隐私集合求交&#xff08;PSI&#xff09;原理介绍 隐私计算关键技术&#xff1a;隐私集合求交&#xff08…

事务--03---TCC空回滚、悬挂、幂等解决方案

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Seata TCC 模式设计思路TCC存在的问题1、空回滚以及解决方案解决方案&#xff1a; 2、幂等问题以及解决方案解决方案&#xff1a; 3、悬挂问题以及解决方案解决方案…

PCIe设备热插拔-理论篇

硬件层面理解热插拔 PRSNT1#和PRSNT2#信号与PCIe设备的热插拔相关。在基于PCIe总线的Add-in 卡中&#xff0c;PRSNT1# 和PRSNT2#信号直接相连&#xff0c;而在处理器主板中&#xff0c;PRSNT1#信号接地&#xff0c;而PRSNT2#信号通过上 拉电阻接为高。 不同的处理器系统处理PC…

【Mysql】InnoDB的表空间(九)

概述 表空间是一个在 InnoDB 中比较抽象的概念&#xff0c;对于系统表空间来说&#xff0c;对应着文件系统中一个或多个实际文件&#xff1b;而对于每个独立表空间来说&#xff0c;对应着文件系统中一个名为表名.ibd 的实际文件。可以把表空间想象成由很多个页组成的池子&…