【Unity3D】Renderer Feature简介
1 3D 项目迁移到 URP 项目后出现的问题
3D 项目迁移至 URP 项目后,会出现很多渲染问题,如:材质显示异常、GL 渲染不显示、多 Pass 渲染异常、屏幕后处理异常等问题。下面将针对这些问题给出一些简单的解决方案。
URP 官方教程和 API 详见→Universal RP 文档、Universal RP API,URP 项目环境搭建详见→Shader Graph简介。
本文完整资源见→Renderer Feature实验。
1)内置材质渲染异常
在 Assets 窗口选中异常的内置材质,依次单击【Edit→Rendering→Materials→Convert Selected Built-in Materials to URP】,异常材质就会自动转换为 URP 内置材质,转换后的材质对应的 shader 为 "Universal Render Pipeline/Lit"。
2)GL 不渲染
3D 项目中,在 MonoBehaviour的生命周期 的 OnPostRender 方法中执行 GL 命令(详见→使用GL绘制线段)。但是,URP 项目中 OnPostRender 方法不会回调,我们可以将 GL 命令移至 OnRenderObject 方法中,以实现 GL 渲染。
3)多 Pass 渲染异常
URP 项目中,我们可以修改 Tag 里的 LightMode 属性以实现多 Pass 渲染,如下。但是,该方案最多只允许渲染 3 个 Pass 通道。
Tags{ "LightMode" = "SRPDefaultUnlit" }
Tags{ "LightMode" = "UniversalForward" }
Tags{ "LightMode" = "LightweightForward" }
4)屏幕后处理异常
3D 项目中,我们在 MonoBehaviour的生命周期 的 OnRenderImage 方法中实现屏幕后处理(详见→调整屏幕亮度、饱和度、对比度)。但是,在 URP 项目中,OnRenderImage 方法不会回调。所幸,Unity 为我们提供了 Rnederer Feature(详见第 3 节),为屏幕后处理提供了一个解决方案。另外,通过 Global Volume 也可以实现屏幕后处理特效。
2 Renderer Objects
2.1 Render Objects 简介
RenderObjects 是 ScriptableRendererFeature 的一种实现,它通过 RenderObjectsPass 渲染指定图层的对象。在 Assets 窗口选中 Universal Renderer Data 文件,在 Inspector 窗口依次点击【Add Renderer Feature→Render Objects】,如下。
添加 Render Objects 后,显示如下。
- Name:Render Objects 标识,建议修改,Frame Debugger 窗口中可以看到该标识符;
- Event:渲染的时序点,该渲染事件在什么时序上执行,详见 RenderPassEvent;
- Queue:渲染队列;
- Layer Mask:渲染指定图层的游戏对象;
- LightMode Tags:渲染路径,取值有:SRPDefaultUnlit、UniversalForward、LightweightForward;
- Material:待渲染的材质,拖入材质后,需要设置 Pass Index(Pass 通道索引);
- Depth:深度测试配置,开启后可以配置 Write Depth (写入深度缓存)和 Depth Test(深度测试,取值有 Less、Equal 等);
- Stencil:模板测试配置,开启后可以配置 Value(模板参考值)、Compare Function(比较函数,取值有 Less、Equal 等)、Pass(模板测试和深度测试均通过时的策略,取值有 Keep、Replace 等)、Fail(模板测试未通过时的策略,取值有 Keep、Replace 等)、ZFail(模板测试通过,但深度测试未通过时的策略,取值有 Keep、Replace 等),
- Camera:相机配置,开启后可以配置 Field of View(视角)、Position Offset(偏移)。
public enum RenderPassEvent {BeforeRendering = 0, // 渲染前BeforeRenderingShadows = 50, // 渲染阴影前AfterRenderingShadows = 100, // 渲染阴影后BeforeRenderingPrePasses = 150, // 渲染PrePasses前[EditorBrowsable(EditorBrowsableState.Never)][Obsolete("Obsolete, to match the capital from 'Prepass' to 'PrePass' (UnityUpgradable) -> BeforeRenderingPrePasses")]BeforeRenderingPrepasses = 151, // 渲染PrePasses前AfterRenderingPrePasses = 200, // 渲染PrePasses后BeforeRenderingGbuffer = 210, // 渲染Gbuffer前AfterRenderingGbuffer = 220, // 渲染Gbuffer后BeforeRenderingDeferredLights = 230, // 渲染延时光照前AfterRenderingDeferredLights = 240, // 渲染延时光照后BeforeRenderingOpaques = 250, // 渲染不透明物体前AfterRenderingOpaques = 300, // 渲染不透明物体后BeforeRenderingSkybox = 350, // 渲染天空盒子前AfterRenderingSkybox = 400, // 渲染天空盒子后BeforeRenderingTransparents = 450, // 渲染透明物体前AfterRenderingTransparents = 500, // 渲染透明物体后BeforeRenderingPostProcessing = 550, // 屏幕后处理前AfterRenderingPostProcessing = 600, // 屏幕后处理后AfterRendering = 1000 // 渲染前
}
2.2 Render Objects 应用
本节将通过一个简单的描边特效介绍 Render Objects 的应用,更复杂的描边详见→选中物体描边特效、基于模板测试和顶点膨胀的描边方法、边缘检测特效、基于深度和法线纹理的边缘检测方法。
1)创建 Shader
Outline.shader
Shader "MyShader/Outline" {Properties {_OutlineColor("_OutlineColor", Color) = (1, 0, 0, 1) // 描边颜色_OutlineWidth("Outline Width", Range(0.01, 1)) = 0.1 // 描边宽度}SubShader {Pass {Cull Front // 关闭剔除渲染, 取值有: Off、Front、Back, Off表示正面和背面都渲染CGPROGRAM#include "UnityCG.cginc"#pragma vertex vert#pragma fragment fragfixed4 _OutlineColor; // 描边颜色float _OutlineWidth; // 描边宽度struct a2v {float4 vertex : POSITION; // 模型空间顶点坐标float3 normal : NORMAL; // 模型空间法线向量};struct v2f {float4 pos : SV_POSITION; // 裁剪空间顶点坐标};v2f vert(a2v v) {v2f o;float3 viewNormal = normalize(mul((float3x3)UNITY_MATRIX_IT_MV, v.normal)); // 观察空间法线向量float3 viewPos = UnityObjectToViewPos(v.vertex); // 观察空间顶点坐标o.pos = UnityViewToClipPos(viewPos + viewNormal * _OutlineWidth * (-viewPos.z) * 0.1); // 裁剪空间顶点坐标return o;}fixed4 frag(v2f i) : SV_Target {return _OutlineColor;}ENDCG}}
}
说明:创建材质,并重命名为 OutlineMat,将 Outline.shader 拖拽到 OutlineMat 中。
2)创建 Render Objects
在 Assets 窗口选中 Universal Renderer Data 文件,在 Inspector 窗口点击 Add Renderer Feature 添加 Render Objects,配置 Render Objects 如下。
3)运行效果
给需要描边的物体设置图层为 Outline,效果如下。
3 自定义 Renderer Feature
要使用 Renderer Feature,我们需要编写两个类:继承自 ScriptableRendererFeature 的 Feature 类和继承自 ScriptableRenderPass 的 Pass 类。
3.1 Renderer Feature 简介
1)创建 Renderer Feature
在 Assets 窗口右键,弹出菜单栏,依次选择【Create→Rendering→URP Renderer Feature】,生成 CustomRenderPassFeature.cs 文件。
2)CustomRenderPassFeature
打开 CustomRenderPassFeature.cs 文件如下,其中 Debug 日志是笔者添加的,为方便后文查看 Feature 生命周期。
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;public class CustomRenderPassFeature : ScriptableRendererFeature { // 自定义的Featureclass CustomRenderPass : ScriptableRenderPass { // 自定义的Passpublic override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) { // 渲染Pass前回调, 此处可以申请内存Debug.Log("CustomRenderPass-OnCameraSetup");}public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { // 渲染执行逻辑Debug.Log("CustomRenderPass-Execute");}public override void OnCameraCleanup(CommandBuffer cmd) { // 渲染Pass后回调, 此处可以清除内存操作Debug.Log("CustomRenderPass-OnCameraCleanup");}}CustomRenderPass m_ScriptablePass; // 自定义的Passpublic override void Create() { // 创建自定义的PassDebug.Log("CustomRenderPassFeature-Create");m_ScriptablePass = new CustomRenderPass();m_ScriptablePass.renderPassEvent = RenderPassEvent.AfterRenderingOpaques; // 渲染事件注入的时机}public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { // 将Pass添加到渲染队列中Debug.Log("CustomRenderPassFeature-AddRenderPasses");renderer.EnqueuePass(m_ScriptablePass);}
}
3)添加自定义 Renderer Feature
在 Assets 窗口选中 Universal Renderer Data 文件,在 Inspector 窗口依次点击【Add Renderer Feature→Custom Render Pass Feature】,如下。
添加 Custom Render Pass Feature 后,显示如下,Name 建议修改,在 Frame Debugger 中可以看到该 Name,方便调试。
4)Renderer Feature 生命周期
运行程序后,打印日志如下。
由日志可以得出以下结论:
- Render Feature 的执行时序是:Create→AddRenderPasses→OnCameraSetup→Execute→OnCameraCleanup;
- Create 方法只在程序启动时执行几次,后面就不执行了;
- AddRenderPasses、OnCameraSetup、Execute、OnCameraCleanup 方法每帧都会执行一次。
3.2 Renderer Feature 应用
本节通过一个 调整屏幕亮度、饱和度、对比度 的案例,介绍 Render Feature 在屏幕后处理中的应用。
1)创建自定义 Feature
FullscreenFeature.cs
using UnityEngine.Rendering.Universal;
using UnityEngine;public class FullscreenFeature : ScriptableRendererFeature {public Settings settings = new Settings(); // 设置FullscreenPass blitPass; // 后处理的Passpublic override void Create() { // 创建后处理Pass(自动回调)blitPass = new FullscreenPass(name);}public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { // 添加渲染Pass(自动回调)if (settings.blitMaterial == null) {return;}blitPass.renderPassEvent = settings.renderPassEvent;blitPass.settings = settings;renderer.EnqueuePass(blitPass);}[System.Serializable]public class Settings { // 配置项public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingOpaques;public Material blitMaterial = null;}
}
说明:FullscreenFeature 不是单例, 可以在 Universal Renderer Data 中配置多实例(可能有多个屏幕后处理特效)。
2)创建自定义 Pass
FullscreenPass.cs
using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering;
using UnityEngine;internal class FullscreenPass : ScriptableRenderPass {public FullscreenFeature.Settings settings; // 配置项private string profilerTag; // 分析器标签, 在Frame Debugger中可以看到该标签private RenderTargetIdentifier source; // 源缓存标识private RenderTargetIdentifier destination; // 目标缓存标识private int destinationId; // 目标缓存idprivate FilterMode filterMode; // 纹理采样滤波模式, 取值有: Point、Bilinear、Trilinearpublic FullscreenPass(string tag) {profilerTag = tag;destinationId = Shader.PropertyToID("_TempRT");}public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) { // 渲染前回调RenderTextureDescriptor blitTargetDescriptor = renderingData.cameraData.cameraTargetDescriptor;blitTargetDescriptor.depthBufferBits = 0;ScriptableRenderer renderer = renderingData.cameraData.renderer;source = renderer.cameraColorTarget;cmd.GetTemporaryRT(destinationId, blitTargetDescriptor, filterMode);destination = new RenderTargetIdentifier(destinationId);}public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { // 执行渲染CommandBuffer cmd = CommandBufferPool.Get(profilerTag);Blit(cmd, source, destination, settings.blitMaterial);Blit(cmd, destination, source);context.ExecuteCommandBuffer(cmd);CommandBufferPool.Release(cmd);}public override void FrameCleanup(CommandBuffer cmd) { // 渲染后回调if (destinationId != -1) {cmd.ReleaseTemporaryRT(destinationId);}}
}
3)创建 Shader
BrigSatuCont.shader
Shader "MyShader/BrightnessSaturationContrast" { // 调整亮度、饱和度、对比度Properties{_MainTex("Base (RGB)", 2D) = "white" {} // 主纹理_Brightness("Brightness", Range(0.5, 3)) = 1 // 亮度_Saturation("Saturation", Range(0.1, 5)) = 1 // 饱和度_Contrast("Contrast", Range(0.4, 3)) = 1 // 对比度}SubShader{Pass {// 深度测试始终通过, 关闭深度写入//ZTest Always ZWrite OffCGPROGRAM#pragma vertex vert_img // 使用内置的vert_img顶点着色器#pragma fragment frag #include "UnityCG.cginc"sampler2D _MainTex; // 主纹理half _Brightness; // 亮度half _Saturation; // 饱和度half _Contrast; // 对比度fixed4 frag(v2f_img i) : SV_Target { // v2f_img为内置结构体, 里面只包含pos和uvfixed4 tex = tex2D(_MainTex, i.uv); // 纹理采样fixed3 finalColor = tex.rgb * _Brightness; // 应用亮度_Brightnessfixed luminance = 0.2125 * tex.r + 0.7154 * tex.g + 0.0721 * tex.b; // 计算亮度fixed3 luminanceColor = fixed3(luminance, luminance, luminance); // 饱和度为0、亮度为luminance的颜色finalColor = lerp(luminanceColor, finalColor, _Saturation); // 应用饱和度_Saturationfixed3 avgColor = fixed3(0.5, 0.5, 0.5); // 饱和度为0、亮度为0.5的颜色finalColor = lerp(avgColor, finalColor, _Contrast); // 应用对比度_Contrastreturn fixed4(finalColor, tex.a);}ENDCG}}Fallback Off
}
说明:创建材质,并重命名为 BrigSatuContMat,将 BrigSatuCont.shader 拖拽到 BrigSatuContMat 中。
4)添加 Feature
在 Assets 窗口选中 Universal Renderer Data 文件,在 Inspector 窗口依次点击【Add Renderer Feature→Fullscreen Feature】,如下。
将 BrigSatuContMat 材质拖拽到 Renderer Feature 中,并修改 Name 属性为 BrigSatuCont,如下。
5)运行效果
通过修改 BrigSatuContMat 中 Brightness、Saturation、Contrast 属性,运行效果如下。左侧是原图,右侧是调整亮度、饱和度、对比度后的渲染效果。
6)动态获取 Feature
用户如果想在 MonoBehaviour 中获取 Renderer Feature,可以通过以下代码片段获取。
private FullscreenFeature GetFeature(string name) { // 获取featureUniversalRendererData rendererData = Resources.Load<UniversalRendererData>("Full Universal Renderer Data");if (rendererData != null && !string.IsNullOrEmpty(name)) {List<FullscreenFeature> features = rendererData.rendererFeatures.OfType<FullscreenFeature>().ToList();foreach (FullscreenFeature feature in features) {if (name.Equals(feature.name)) {return feature;}}}return null;
}
也可以通过以下工具类获取 Renderer Feature。
URPFeatureUtils.cs
using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering;
using System.Reflection;public class URPFeatureUtils {private static URPFeatureUtils instance; // 单例private UniversalRendererData rendererData; // 渲染数据, 存储了feature列表private URPFeatureUtils() {rendererData = GetRendererData();}public static T GetFeature<T>(string name) where T : ScriptableRendererFeature { // 获取featureif (instance == null) {instance = new URPFeatureUtils();}if (instance.rendererData != null) {return GetFeature<T>(instance.rendererData, name);}return null;}private static T GetFeature<T>(UniversalRendererData rendererData, string name) where T : ScriptableRendererFeature { // 获取featureif (rendererData != null && !string.IsNullOrEmpty(name)) {foreach (ScriptableRendererFeature feature in rendererData.rendererFeatures) {if (feature is T && name.Equals(feature.name)) {return (feature as T);}}}return null;}private UniversalRendererData GetRendererData() { // 通过反射获取渲染数据, 也可以通过Resources.Load加载, 但是需要将UniversalRendererData文件放在Resources目录下UniversalRenderPipelineAsset urpAsset = GraphicsSettings.renderPipelineAsset as UniversalRenderPipelineAsset;FieldInfo propertyInfo = urpAsset.GetType().GetField("m_RendererDataList", BindingFlags.Instance | BindingFlags.NonPublic);ScriptableRendererData[] rendererDatas = (ScriptableRendererData[])propertyInfo.GetValue(urpAsset);if (rendererDatas != null && rendererDatas.Length > 0 && (rendererDatas[0] is UniversalRendererData)) {return rendererDatas[0] as UniversalRendererData;}return null;}
}
说明:之所以要使用反射,因为 UniversalRenderPipelineAsset 中的 m_RendererDataList 属性不是 public 的,并且没有给外界提供获取 m_RendererDataList 的接口。
相关文章:

【Unity3D】Renderer Feature简介
1 3D 项目迁移到 URP 项目后出现的问题 3D 项目迁移至 URP 项目后,会出现很多渲染问题,如:材质显示异常、GL 渲染不显示、多 Pass 渲染异常、屏幕后处理异常等问题。下面将针对这些问题给出一些简单的解决方案。 URP 官方教程和 API 详见→Un…...

麻了!包含中科院TOP,共16本期刊被标记为“On Hold”状态!
近日,小编从科睿唯安旗下的“Master Journal List”官网查到,除了知名老牌期刊Chemosphere竟然被标记为“On Hold”状态,目前共有7本SCI期刊,1本SSCI期刊,8本ESCI期刊被标记为“On Hold”,究竟是怎么回事呢…...

2.Flink应用
2.1 数据流 DataStream:DataStream是Flink数据流的核心抽象,其上定义了对数据流的一系列操作DataStreamSource:DataStreamSource 是 DataStream 的 起 点 , DataStreamSource 在StreamExecutionEnvironment 中 创 建 ,…...

Matlab进阶绘图第25期—三维密度散点图
三维密度散点图本质上是一种特征渲染的三维散点图,其颜色表示某一点所在区域的密度信息。 除了作图,三维密度散点图绘制的关键还在于密度的计算。 当然,不管是作图还是密度的计算,这些在《Matlab论文插图绘制模板》和《Matlab点…...

C++设计模式之桥接设计模式
文章目录 C桥接设计模式什么是桥接设计模式该模式有什么优缺点优点缺点 如何使用 C桥接设计模式 什么是桥接设计模式 桥接设计模式是一种结构型设计模式,它可以将抽象接口和实现分离开来,以便它们可以独立地变化和扩展。 该模式有什么优缺点 优点 灵…...

论文笔记:SUPERVISED CONTRASTIVE REGRESSION
2022arxiv的论文,没有中,但一作是P大图班本MIT博,可信度应该还是可以的 0 摘要 深度回归模型通常以端到端的方式进行学习,不明确尝试学习具有回归意识的表示。 它们的表示往往是分散的,未能捕捉回归任务的连续性质。…...
Java 多线程并发 CAS 技术详解
一、CAS概念和应用背景 CAS的作用和用途 CAS(Compare and Swap)是一种并发编程中常用的技术,用于解决多线程环境下的并发访问问题。CAS操作是一种原子操作,它可以提供线程安全性,避免了使用传统锁机制所带来的性能开…...

如何压缩高清PDF文件大小?将PDF文件压缩到最小的三个方法
PDF格式是一种非常常用的文档格式,但是有时候我们需要将PDF文件压缩为更小的大小以便于传输和存储。在本文中,我们将介绍三种PDF压缩的方法,包括在线PDF压缩、利用软件PDF压缩以及使用WPS缩小pdf。 首先,在线PDF压缩是最常用的方…...
04 统计语言模型(n元语言模型)
博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from=333.1007.0.0 b 站直接看 配套 github 链接:https://github.com/nickchen121/Pre-training-language-model 配套博客链接:https://www.cnblogs.com/nickchen121/p/15105048.html 预训练 预先训练 我们…...
Linux各目录详解
Linux文件系统是一个树状结构,由多个目录(或文件夹)组成。以下是常见的Linux目录及其功能的详细解释: /(根目录):在Linux文件系统中,所有其他目录和文件都是从根目录派生的。所有的存…...
【css】属性选择器分类
属性选择器类型示例说明[attribute][target]选择带有 target 属性的所有元素[attributevalue][target_blank]选择带有 target“_blank” 属性的所有元素[attribute~value][title~flower]选择带有包含 “flower” 一词的 title 属性的所有元素[attribute|value][lang|en]选择带有…...

备份容灾哪家好怎么样
数字化时代,数据安全是我们不容忽视的问题。云呐容灾备份系统不仅提供了强大的数据保护功能,而且操作简单,使用方便。无论你是企业管理员,还是个人用户,都可以轻松上手。它还提供了丰富的报告和监控功能,让…...

【前端实习生备战秋招】—HTML 和 CSS面试题总结(三)
【前端实习生备战秋招】—HTML 和 CSS面试题总结(三) 1.行内元素有哪些?块级元素有哪些? 空(void)元素有那些? CSS 规范规定,每个元素都有 display 属性,确定该元素的类型,每个元素…...
Ansible Rsync 使用Ansible Rsync模块进行文件传输
在Ansible自动化工具中,Rsync模块(Rsync Module)是一个强大的组件,用于在Ansible控制节点和目标主机之间进行文件传输和同步。本文将深入探讨Ansible Rsync模块,了解它如何成为自动化任务中高效同步的自动化利器。 Ans…...

Eclipse如何自动添加作者、日期等注释
一、创建类时自动添加注释 1、Window->Preferences 2、Java->Code Syle->Code Templates->Code->New Java files->Edit->要添加的注释->Apply 二、选中要添加的类或者方法通过AltShiftJ快捷键添加 1、Window->Preferences 2、Java->Code Syle…...

uniapp返回
// 监听返回事件onNavigationBarButtonTap() {uni.showModal({title: 提示,content: 确定要返回吗?,success: (res) > {if (res.confirm) {uni.navigateBack({delta: 2})}}})},...
【Antd】antd form表单的rules文案无法跟随状态重渲染的原因及解决办法
问题背景 我有两个表单项,当我选择出库类型,调用onChange改变inOutType 状态,这时候发现这句代码不生效: rules{[{ required: true, message: 请选择${inOutType 1 ? 持有人 : 负责人} }]}示例代码 <TypographyForm.Group…...

Rocketmq Filter 消息过滤(TAGS、SQL92)原理详解 源码解析
1. 背景 1.1 Rocketmq 支持的过滤方式 Rocketmq 作为金融级的业务消息中间件,拥有强大的消息过滤能力。其支持多种消息过滤方式: 表达式过滤:通过设置过滤表达式的方式进行过滤 TAG:根据消息的 tag 进行过滤。SQL92:…...

Attacks in NLP
一、 Introduction NLP对抗攻击是人工智能对抗攻击的一个重要的组成部分,但是最近几年才逐渐开始兴起,究其原因在于NLP对抗攻击与传统computer vision或者audio对抗攻击有很大的不同,主要在于值空间的连续性(CV、audio࿰…...

04-7_Qt 5.9 C++开发指南_QTreeWidget和QDockWidget
文章目录 1. 实例功能简述2. 源码2.1 可视化UI设计2.2 mainwindow.h2.3 mainwindow.cpp 1. 实例功能简述 本节介绍 QTreeWidget、QDockWidget 的使用,以及用 QLabel 显示图片的方法。实例 samp4_8以QTreeWidget 为主要组件,创建一个照片管理器ÿ…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
嵌入式常见 CPU 架构
架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集,单周期执行;低功耗、CIP 独立外设;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel(原始…...