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

轻量封装WebGPU渲染系统示例<42>- vsm阴影实现过程(源码)

前向实时渲染vsm阴影实现的主要步骤:

        1. 编码深度数据,存到一个rtt中。

        2. 纵向和横向执行遮挡信息blur filter sampling, 存到对应的rtt中。

        3. 将上一步的结果(rtt)应用到可接收阴影的材质中。

具体代码情况文章最后附上的实现源码。

当前示例源码github地址:

https://github.com/vilyLei/voxwebgpu/blob/feature/rendering/src/voxgpu/sample/BaseVSMShadowTest.ts

当前示例运行效果:

主要的WGSL Shader代码:

编码深度:

struct VertexOutput {@builtin(position) Position: vec4<f32>,@location(0) projPos: vec4<f32>,@location(1) objPos: vec4<f32>
}
@vertex
fn vertMain(@location(0) position: vec3<f32>
) -> VertexOutput {let objPos = vec4(position.xyz, 1.0);let wpos = objMat * objPos;var output: VertexOutput;let projPos = projMat * viewMat * wpos;output.Position = projPos;output.projPos = projPos;output.objPos = objPos;return output;
}const PackUpscale = 256. / 255.; // fraction -> 0..1 (including 1)
const UnpackDownscale = 255. / 256.; // 0..1 -> fraction (excluding 1)const PackFactors = vec3<f32>(256. * 256. * 256., 256. * 256., 256.);
const UnpackFactors = UnpackDownscale / vec4<f32>(PackFactors, 1.0);const ShiftRight8 = 1. / 256.;fn packDepthToRGBA(v: f32) -> vec4<f32> {var r = vec4<f32>(fract(v * PackFactors), v);let v3 = r.yzw - (r.xyz * ShiftRight8);r = vec4<f32>(v3.x, v3);return r * PackUpscale;
}@fragment
fn fragMain(@location(0) projPos: vec4<f32>,@location(1) objPos: vec4<f32>
) -> @location(0) vec4<f32> {let fragCoordZ = 0.5 * projPos[2] / projPos[3] + 0.5;var color4 = packDepthToRGBA( fragCoordZ );return color4;
}

纵向和横向执行遮挡信息blur filter sampling:

struct VertexOutput {@builtin(position) Position: vec4<f32>,@location(0) uv: vec2<f32>
}
@vertex
fn vertMain(@location(0) position: vec3<f32>,@location(1) uv: vec2<f32>
) -> VertexOutput {var output: VertexOutput;output.Position = vec4(position.xyz, 1.0);output.uv = uv;return output;
}const PackUpscale = 256. / 255.; // fraction -> 0..1 (including 1)
const UnpackDownscale = 255. / 256.; // 0..1 -> fraction (excluding 1)const PackFactors = vec3<f32>(256. * 256. * 256., 256. * 256., 256.);
const UnpackFactors = UnpackDownscale / vec4<f32>(PackFactors, 1.0);const ShiftRight8 = 1. / 256.;fn packDepthToRGBA(v: f32) -> vec4<f32> {var r = vec4<f32>(fract(v * PackFactors), v);let v3 = r.yzw - (r.xyz * ShiftRight8);return vec4<f32>(v3.x, v3) * PackUpscale;
}fn unpackRGBAToDepth( v: vec4<f32> ) -> f32 {return dot( v, UnpackFactors );
}fn pack2HalfToRGBA( v: vec2<f32> ) -> vec4<f32> {let r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ));return vec4<f32>( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w);
}
fn unpackRGBATo2Half( v: vec4<f32> ) -> vec2<f32> {return vec2<f32>( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );
}const SAMPLE_RATE = 0.25;
const HALF_SAMPLE_RATE = 0.125;
@fragment
fn fragMain(@location(0) uv: vec2<f32>,
) -> @location(0) vec4<f32> {var mean = 0.0;var squared_mean = 0.0;let resolution = viewParam.zw;let fragCoord = resolution * uv;let radius = param[3];let c4 = textureSample(shadowDepthTexture, shadowDepthSampler, uv);var depth = unpackRGBAToDepth( c4 );for ( var i = -1.0; i < 1.0 ; i += SAMPLE_RATE) {#ifdef USE_HORIZONAL_PASSlet distribution = unpackRGBATo2Half( textureSample(shadowDepthTexture, shadowDepthSampler, ( fragCoord.xy + vec2( i, 0.0 ) * radius ) / resolution ) );mean += distribution.x;squared_mean += distribution.y * distribution.y + distribution.x * distribution.x;#elsedepth = unpackRGBAToDepth( textureSample(shadowDepthTexture, shadowDepthSampler, ( fragCoord.xy + vec2( 0.0, i ) * radius ) / resolution ) );mean += depth;squared_mean += depth * depth;#endif}mean = mean * HALF_SAMPLE_RATE;squared_mean = squared_mean * HALF_SAMPLE_RATE;let std_dev = sqrt( squared_mean - mean * mean );var color4 = pack2HalfToRGBA( vec2<f32>( mean, std_dev ) );return color4;
}

应用到可接收阴影的材质中(示例用法):


struct VertexOutput {@builtin(position) Position: vec4<f32>,@location(0) uv: vec2<f32>,@location(1) worldNormal: vec3<f32>,@location(2) svPos: vec4<f32>
}
@vertex
fn vertMain(@location(0) position: vec3<f32>,@location(1) uv: vec2<f32>,@location(2) normal: vec3<f32>
) -> VertexOutput {let objPos = vec4(position.xyz, 1.0);let wpos = objMat * objPos;var output: VertexOutput;let projPos = projMat * viewMat * wpos;output.Position = projPos;// output.normal = normal;let invMat33 = inverseM33(m44ToM33(objMat));output.uv = uv;output.worldNormal = normalize(normal * invMat33);output.svPos = shadowMatrix * wpos;return output;
}fn pack2HalfToRGBA( v: vec2<f32> ) -> vec4<f32> {let r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ));return vec4<f32>( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w);
}
fn unpackRGBATo2Half( v: vec4<f32> ) -> vec2<f32> {return vec2<f32>( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );
}fn texture2DDistribution( uv: vec2<f32> ) -> vec2<f32> {let v4 = textureSample(shadowDepthTexture, shadowDepthSampler, uv );return unpackRGBATo2Half( v4 );}
fn VSMShadow (uv: vec2<f32>, compare: f32 ) -> f32 {var occlusion = 1.0;let distribution = texture2DDistribution( uv );let hard_shadow = step( compare , distribution.x ); // Hard Shadowif (hard_shadow != 1.0 ) {let distance = compare - distribution.x ;let variance = max( 0.00000, distribution.y * distribution.y );var softness_probability = variance / (variance + distance * distance ); // Chebeyshevs inequalitysoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 ); // 0.3 reduces light bleedocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );}return occlusion;}
fn getVSMShadow( shadowMapSize: vec2<f32>, shadowBias: f32, shadowRadius: f32, shadowCoordP: vec4<f32> ) -> f32 {var shadowCoord = vec4<f32>(shadowCoordP.xyz / vec3<f32>(shadowCoordP.w), shadowCoordP.z + shadowBias);let inFrustumVec = vec4<bool> ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );let inFrustum = all( inFrustumVec );let frustumTestVec = vec2<bool>( inFrustum, shadowCoord.z <= 1.0 );var shadow = VSMShadow( shadowCoord.xy, shadowCoord.z );if ( !all( frustumTestVec ) ) {shadow = 1.0;}return shadow;
}@fragment
fn fragMain(@location(0) uv: vec2<f32>,@location(1) worldNormal: vec3<f32>,@location(2) svPos: vec4<f32>
) -> @location(0) vec4<f32> {var color = vec4<f32>(1.0);var shadow = getVSMShadow(params[1].xy, params[0].x, params[0].z, svPos );let shadowIntensity = 1.0 - params[0].w;shadow = clamp(shadow, 0.0, 1.0) * (1.0 - shadowIntensity) + shadowIntensity;var f = clamp(dot(worldNormal, params[2].xyz),0.0,1.0);if(f > 0.0001) {f = min(shadow,clamp(f, shadowIntensity,1.0));}else {f = shadowIntensity;}var color4 = vec4<f32>(color.xyz * vec3(f * 0.9 + 0.1), 1.0);return color4;
}

此示例基于此渲染系统实现,当前示例TypeScript源码如下:

export class BaseVSMShadowTest {private mRscene = new RendererScene();private mShadowCamera: Camera;private mDebug = false;initialize(): void {this.mRscene.initialize({canvasWith: 512,canvasHeight: 512,rpassparam: { multisampleEnabled: true }});this.initScene();this.initEvent();}private mEntities: Entity3D[] = [];private initScene(): void {let rc = this.mRscene;this.buildShadowCam();let sph = new SphereEntity({radius: 80,transform: {position: [-230.0, 100.0, -200.0]}});this.mEntities.push(sph);rc.addEntity(sph);let box = new BoxEntity({minPos: [-30, -30, -30],maxPos: [130, 230, 80],transform: {position: [160.0, 100.0, -210.0],rotation: [50, 130, 80]}});this.mEntities.push(box);rc.addEntity(box);let torus = new TorusEntity({transform: {position: [160.0, 100.0, 210.0],rotation: [50, 30, 80]}});this.mEntities.push(torus);rc.addEntity(torus);if (!this.mDebug) {this.applyShadow();}}private mShadowDepthRTT = { uuid: "rtt-shadow-depth", rttTexture: {}, shdVarName: 'shadowDepth' };private mOccVRTT = { uuid: "rtt--occV", rttTexture: {}, shdVarName: 'shadowDepth' };private mOccHRTT = { uuid: "rtt--occH", rttTexture: {}, shdVarName: 'shadowDepth' };private applyShadowDepthRTT(): void {let rc = this.mRscene;// rtt texture proxy descriptorlet rttTex = this.mShadowDepthRTT;// define a rtt pass color colorAttachment0let colorAttachments = [{texture: rttTex,// green clear background colorclearValue: { r: 1, g: 1, b: 1, a: 1.0 },loadOp: "clear",storeOp: "store"}];// create a separate rtt rendering passlet rPass = rc.createRTTPass({ colorAttachments });rPass.node.camera = this.mShadowCamera;let extent = [-0.5, -0.5, 0.8, 0.8];const shadowDepthShdSrc = {shaderSrc: { code: shadowDepthWGSL, uuid: "shadowDepthShdSrc" }};let material = this.createDepthMaterial(shadowDepthShdSrc);let es = this.createDepthEntities([material], false);for (let i = 0; i < es.length; ++i) {rPass.addEntity(es[i]);}// 显示渲染结果extent = [-0.95, -0.95, 0.4, 0.4];let entity = new FixScreenPlaneEntity({ extent, flipY: true, textures: [{ diffuse: rttTex }] });rc.addEntity(entity);}private applyBuildDepthOccVRTT(): void {let rc = this.mRscene;// rtt texture proxy descriptorlet rttTex = this.mOccVRTT;// define a rtt pass color colorAttachment0let colorAttachments = [{texture: rttTex,// green clear background colorclearValue: { r: 1, g: 1, b: 1, a: 1.0 },loadOp: "clear",storeOp: "store"}];// create a separate rtt rendering passlet rPass = rc.createRTTPass({ colorAttachments });let material = new ShadowOccBlurMaterial();let ppt = material.property;ppt.setShadowRadius(this.mShadowRadius);ppt.setViewSize(this.mShadowMapW, this.mShadowMapH);material.addTextures([this.mShadowDepthRTT]);let extent = [-1, -1, 2, 2];let rttEntity = new FixScreenPlaneEntity({ extent, materials: [material] });rPass.addEntity(rttEntity);// 显示渲染结果extent = [-0.5, -0.95, 0.4, 0.4];let entity = new FixScreenPlaneEntity({ extent, flipY: true, textures: [{ diffuse: rttTex }] });rc.addEntity(entity);}private applyBuildDepthOccHRTT(): void {let rc = this.mRscene;// rtt texture proxy descriptorlet rttTex = this.mOccHRTT;// define a rtt pass color colorAttachment0let colorAttachments = [{texture: rttTex,// green clear background colorclearValue: { r: 1, g: 1, b: 1, a: 1.0 },loadOp: "clear",storeOp: "store"}];// create a separate rtt rendering passlet rPass = rc.createRTTPass({ colorAttachments });let material = new ShadowOccBlurMaterial();let ppt = material.property;ppt.setShadowRadius(this.mShadowRadius);ppt.setViewSize(this.mShadowMapW, this.mShadowMapH);material.property.toHorizonalBlur();material.addTextures([this.mOccVRTT]);let extent = [-1, -1, 2, 2];let rttEntity = new FixScreenPlaneEntity({ extent, materials: [material] });rPass.addEntity(rttEntity);// 显示渲染结果extent = [-0.05, -0.95, 0.4, 0.4];let entity = new FixScreenPlaneEntity({ extent, flipY: true, textures: [{ diffuse: rttTex }] });rc.addEntity(entity);}private createDepthMaterial(shaderSrc: WGRShderSrcType, faceCullMode = "none"): WGMaterial {let pipelineDefParam = {depthWriteEnabled: true,faceCullMode,blendModes: [] as string[]};const material = new WGMaterial({shadinguuid: "shadow-depth_material",shaderSrc,pipelineDefParam});return material;}private createDepthEntities(materials: WGMaterial[], flag = false): Entity3D[] {const rc = this.mRscene;let entities = [];let ls = this.mEntities;let tot = ls.length;for (let i = 0; i < tot; ++i) {let et = ls[i];let entity = new Entity3D({ transform: et.transform });entity.materials = materials;entity.geometry = et.geometry;entities.push(entity);if (flag) {rc.addEntity(entity);}}return entities;}private mShadowBias = -0.0005;private mShadowRadius = 2.0;private mShadowMapW = 512;private mShadowMapH = 512;private mShadowViewW = 1300;private mShadowViewH = 1300;private buildShadowCam(): void {const cam = new Camera({eye: [600.0, 800.0, -600.0],near: 0.1,far: 1900,perspective: false,viewWidth: this.mShadowViewW,viewHeight: this.mShadowViewH});cam.update();this.mShadowCamera = cam;const rsc = this.mRscene;let frameColors = [[1.0, 0.0, 1.0], [0.0, 1.0, 1.0], [1.0, 0.0, 0.0], [0.0, 1.0, 1.0]];let boxFrame = new BoundsFrameEntity({ vertices8: cam.frustum.vertices, frameColors });rsc.addEntity(boxFrame);}private initEvent(): void {const rc = this.mRscene;rc.addEventListener(MouseEvent.MOUSE_DOWN, this.mouseDown);new MouseInteraction().initialize(rc, 0, false).setAutoRunning(true);}private mFlag = -1;private buildShadowReceiveEntity(): void {let cam = this.mShadowCamera;let transMatrix = new Matrix4();transMatrix.setScaleXYZ(0.5, -0.5, 0.5);transMatrix.setTranslationXYZ(0.5, 0.5, 0.5);let shadowMat = new Matrix4();shadowMat.copyFrom(cam.viewProjMatrix);shadowMat.append(transMatrix);let material = new ShadowReceiveMaterial();let ppt = material.property;ppt.setShadowRadius(this.mShadowRadius);ppt.setShadowBias(this.mShadowBias);ppt.setShadowSize(this.mShadowMapW, this.mShadowMapH);ppt.setShadowMatrix(shadowMat);ppt.setDirec(cam.nv);material.addTextures([this.mOccHRTT]);const rc = this.mRscene;let plane = new PlaneEntity({axisType: 1,extent: [-600, -600, 1200, 1200],transform: {position: [0, -1, 0]},materials: [material]});rc.addEntity(plane);}private applyShadow(): void {this.applyShadowDepthRTT();this.applyBuildDepthOccVRTT();this.applyBuildDepthOccHRTT();this.buildShadowReceiveEntity();}private mouseDown = (evt: MouseEvent): void => {this.mFlag++;if (this.mDebug) {if (this.mFlag == 0) {this.applyShadowDepthRTT();} else if (this.mFlag == 1) {this.applyBuildDepthOccVRTT();} else if (this.mFlag == 2) {this.applyBuildDepthOccHRTT();} else if (this.mFlag == 3) {this.buildShadowReceiveEntity();}}};run(): void {this.mRscene.run();}
}

相关文章:

轻量封装WebGPU渲染系统示例<42>- vsm阴影实现过程(源码)

前向实时渲染vsm阴影实现的主要步骤: 1. 编码深度数据&#xff0c;存到一个rtt中。 2. 纵向和横向执行遮挡信息blur filter sampling, 存到对应的rtt中。 3. 将上一步的结果(rtt)应用到可接收阴影的材质中。 具体代码情况文章最后附上的实现源码。 当前示例源码github地址: …...

[Electron] 将应用日志文件输出

​ 日志文件输出可以使用 electron-log 模块。 electron-log 是一个用于 Electron 应用程序的日志记录库。它提供了一种简单且方便的方式来在 Electron 应用中记录日志信息&#xff0c;并支持将日志输出到文件、控制台和其他自定义目标。 以下是 electron-log 的一些主要特点…...

特性【C#】

C#特性是一种用于在编译时向程序元素添加声明性信息的语言结构。 下面是C#特性的使用方法&#xff1a; 1.使用系统提供的特性&#xff1a; 可以使用系统提供的特性来标记类、方法、属性等&#xff0c;以便在编译时进行验证或者提供其他信息。例如&#xff0c;可以使用Obsole…...

理解SpringIOC和DI第一课(Spring的特点),IOC对应五大注解,ApplicationContext vs BeanFactory

Spring是一个包含众多工具等Ioc容器 对象这个词在Spring范围内&#xff0c;称为bean Spring两大核心思想 1.IOC (IOC是控制反转&#xff0c;意思是控制权反转-控制权&#xff08;正常是谁用这个对象&#xff0c;谁去创建&#xff0c;&#xff09;-控制对象的控制权&#xf…...

【微服务】分布式限流如何实现

Sentinel 是一款阿里巴巴开源的分布式系统级流量控制组件&#xff0c;它提供了流量的自适应控制、熔断降级、系统负载保护等功能。下面是使用 Sentinel 实现分布式限流方案的基本步骤&#xff1a; 引入 Sentinel 依赖&#xff1a;首先在你的 Java 项目中引入 Sentinel 的相关依…...

【S32K3环境搭建】-0.3-S32DS安装实时驱动RTD(Real-Time Driver)

目录 1 什么是“实时驱动RTD(Real-Time Driver)” 2 安装“实时驱动RTD(Real-Time Driver)” 2.1 方法一&#xff1a;通过S32DS Extensions and Updates安装“实时驱动RTD(Real-Time Driver)” 2.2 方法二&#xff1a;通过Install New Software…安装“实时驱动RTD(Real-Ti…...

软件设计之适配器模式

类模式 我们知道插座的电压为交流电220V&#xff0c;而日常电器使用的是直流电且电压会较小&#xff0c;比如手机充电会通过插头适配器达到额定的输入电流。下面我们实现这个案例&#xff1a;将220V电压转化为5V的电压。 package Adapter.Class;public class Adapter extends …...

虚拟化逻辑架构:OVS 交换机与端口管理

目录 一、实验 1.OVS 交换机管理 2.OVS端口管理 二、问题 1.KVM下的br0和virbr0有何区别 2.OVS 虚拟交换机 与接口如何实现关联的创建和删除 3.两个ovs之间如何进行流量交互 4.虚拟网络如何和物理网络互联 一、实验 1.OVS 交换机管理 &#xff08;1&#xff09;查看网…...

【springboot】idea项目启动端口被占用

问题 idea本地启动springboot项目端口老是被占用 解决 关闭被占用的端口进程 步骤: 1. winR打开程序框 2. 查出被占用端口的进程id netstat -ano | finderstr 端口号 例如 netstat -ano | finderstr 81013.杀死进程 taskkill /pid 进程id -t -f 例如 taskkill /pid 2…...

linux环境下编译安装OpenCV For Java(CentOS 7)

最近在业余时间学习了一些有关图像处理的代码&#xff0c;但是只能本地处理&#xff0c;满足不了将来开放远程服务的需求。 因此&#xff0c;查找并参考了一些资料&#xff0c;成功在centos7环境安装上了opencv 460。 下面上具体安装步骤&#xff0c;希望能帮到有需要的同学。 …...

健康学习到 150 岁:人体系统调优不完全指南 | 开源日报 No.93

jesseduffield/lazygit Stars: 40.0k License: MIT lazygit&#xff0c;一个用 Go 语言编写的简单终端UI工具&#xff0c;可以执行 Git 命令。 该项目旨在让使用者更加方便地使用 Git&#xff0c;并提供了以下功能&#xff1a; 可视化操作&#xff1a;用户可以通过图形界面进…...

C++ Easyx 三子棋

目录 思路 框架​编辑 读取操作 数据操作 绘制画面 游戏的数据结构 用二维数组来模拟棋盘格 赢的情况 平局情况 Code 代码细节部分 &#xff08;1&#xff09;初始化棋盘格 &#xff08;2&#xff09; 初始化棋子类型​编辑 事件处理部分 落子 框架内代码的完善 数据处…...

[NAND Flash 2.1] NAND Flash 闪存改变了现代生活

依公知及经验整理&#xff0c;原创保护&#xff0c;禁止转载。 专栏 《深入理解NAND Flash》 <<<< 返回总目录 <<<< ​ 1989年NAND闪存面世了&#xff0c;它曾经且正在改变了我们的日常生活。 NAND 闪存发明之所以伟大&#xff0c;是因为&#xff0c…...

2015年五一杯数学建模B题空气污染问题研究解题全过程文档及程序

2015年五一杯数学建模 B题 空气污染问题研究 原题再现 近十年来&#xff0c;我国 GDP 持续快速增长&#xff0c;但经济增长模式相对传统落后&#xff0c;对生态平衡和自然环境造成一定的破坏&#xff0c;空气污染的弊病日益突出&#xff0c;特别是日益加重的雾霾天气已经干扰…...

java面试题,上楼梯有多少种方式

java面试题&#xff0c;上楼梯有多少种方式 题目&#xff1a;一个小孩上一个N级台阶的楼梯&#xff0c;他可以一次走1阶、2阶或3阶&#xff0c;那么走完N阶有多少种方式。 很自然的想法是使用递归&#xff1a; public class Test04 { public static int countWays(int n) {…...

8.HTTP工作原理

HTTP是什么 HTTP工作原理 HTTP协议的请求类型和响应状态码 总结 1.HTTP是什么 HTTP超文本传输协议就是在一个网络中上传下载文件的一套规则 2.HTTP工作原理 HTTP超文本传输协议的本质是TCP通信&#xff0c;链接—>请求—>响应—>断开 3.HTTP协议的请求类型和响应状…...

环境部署的学习笔记(Docker)

1 前言 在现场测试时&#xff0c;常常需要在现场机器上搭建开发环境&#xff0c;此时使用容器会是一个比较方便的途径&#xff1b; 2 常见的容器技术 2.1 Docker⭐️31k&#xff1a;目前使用最为广泛的容器技术 2.2 Nix⭐️13.8k&#xff1a;镜像文件占用会比Docker少 Chat…...

Navicat在分辨率不同的屏幕窗口显示大小不一致问题解决

1.主屏幕为2560*1600分辨率&#xff0c;能够显示较多数据连接 2.在第二屏幕分辨率低&#xff0c;字体变大&#xff0c;显示内容变少 解决办法&#xff1a; 1.右击navicat图标-属性 2.选择【兼容性】-在兼容性页面中选择**“更改高DPI设置”** 3…勾选“高DPI缩放替代”&a…...

通过代码搞明白JAVA中值传递和引用传递

public static void main(String[] args) {Map a new HashMap();a.put("a", 1);System.out.println(a "我在main中的值");aaa(a);System.out.println(a "我在main中的值");bbb(a);System.out.println(a "我在main中的值");int b …...

ambari 开启hdfs回收站机制

hdfs回收站类似于我们常用的windows中的回收站&#xff0c;被删除的文件会被暂时存储于此&#xff0c;和回收站相关的参数有两个&#xff1a; fs.trash.interval&#xff1a;默认值为0 代表禁用回收站&#xff0c;其他值为回收站保存文件时间&#xff0c;单位为分钟 fs.trash…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码"&#xff1a;Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力&#xff0c;从金融交易到交通管控&#xff0c;这些关乎国计民生的关键领域…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准

城市路内停车管理常因行道树遮挡、高位设备盲区等问题&#xff0c;导致车牌识别率低、逃费率高&#xff0c;传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法&#xff0c;正成为破局关键。该设备安装于车位侧方0.5-0.7米高度&#xff0c;直接规避树枝遮…...

Linux部署私有文件管理系统MinIO

最近需要用到一个文件管理服务&#xff0c;但是又不想花钱&#xff0c;所以就想着自己搭建一个&#xff0c;刚好我们用的一个开源框架已经集成了MinIO&#xff0c;所以就选了这个 我这边对文件服务性能要求不是太高&#xff0c;单机版就可以 安装非常简单&#xff0c;几个命令就…...

mac:大模型系列测试

0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何&#xff0c;是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试&#xff0c;是可以跑通文章里面的代码。训练速度也是很快的。 注意…...

【堆垛策略】设计方法

堆垛策略的设计是积木堆叠系统的核心&#xff0c;直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法&#xff0c;涵盖基础规则、优化算法和容错机制&#xff1a; 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则&#xff1a; 大尺寸/重量积木在下&#xf…...