Chapter9 更复杂的光照——Shader入门精要学习笔记

Chapter9 更复杂的光照

  • 一、Unity的渲染路径
    • 1.渲染路径的概念
    • 2.渲染路径的类型
      • ①前向渲染路径
        • a. 前向渲染路径的原理
        • b. Unity中的前向渲染
        • c. 两种Pass
      • ②延迟渲染路径
        • a. 延迟渲染路径的原理
        • b. Unity中的延迟渲染
        • c. 两种Pass
      • ③顶点照明渲染路径
  • 二、Unity的光源类型
    • 1.光源类型
      • ①平行光
      • ②点光源
      • ③聚光灯
    • 2.前向渲染中处理不同的光源
      • ①实践
        • Base Pass
        • Additional Pass
  • 三、Unity光照衰减
    • 1.用于光照衰减的纹理
    • 2.数学公式计算
  • 四、Unity的阴影
    • 1.阴影如何实现
      • ①Shadow Map的生成
      • ②屏幕空间的阴影映射技术
      • ③阴影映射
    • 4.Unity Shader 使用内置宏和函数 来统一管理光照衰减和阴影
      • ①光照衰减和阴影的影响
      • ②内置宏 UNITY_LIGHT_ATTENUATION
    • 5.透明物体阴影的办法
      • ①透明物体阴影问题
      • ②透明度测试 物体的阴影处理
      • ③透明度混合 物体的阴影处理
  • 五、标准的Unity Shader

一、Unity的渲染路径

1.渲染路径的概念

渲染路径是 Unity 处理光照信息的方式,它决定了光照是如何被应用到 Unity Shader 中的。简单来说,渲染路径就像一个“沟通桥梁”,它告诉 Unity 底层渲染引擎,开发者想要以哪种方式来处理光照,以及需要哪些光照信息

2.渲染路径的类型

大多数情况下一个项目只使用一个渲染路径,在Player Setting中进行Rendering Path设置。也可以在每个摄像机中设置该摄像机的渲染路径。完成设置后,就可以在每个Pass中 使用 LightMode 标签 来指定Pass使用的渲染路径。
在这里插入图片描述

①前向渲染路径

a. 前向渲染路径的原理
  • 它将每个光源的光照计算独立进行,并逐个应用到物体上
  • 每进行一次完整的前向渲染,需要渲染该对象的渲染图元,计算两个缓冲区信息:颜色缓冲区(更新颜色缓存区中的颜色值)和 深度缓冲区(决定一个片元是否可见)
  • 对每个逐像素光源都要进行一次这样的Pass渲染,如果有多个逐像素光源,就要进行多次
b. Unity中的前向渲染
  • 渲染一个物体时,Unity会计算哪些光源照亮了它,以及这些光源照亮该物体的方式
  • 前向渲染中有三种照亮物体的方式:逐顶点处理、逐像素处理、球谐函数(SH)处理
  • 决定光源用哪种处理模式取决于 类型 和 渲染模式
    • 类型:指光源是平行光还是什么
    • 渲染模式:指该光源是否重要,重要就是逐像素
      在这里插入图片描述
c. 两种Pass
  • 前向渲染路径通常包含两个 Pass
  • Base Pass: 计算环境光、最重要的平行光(1个)、逐顶点/SH 光源和 Lightmaps
    • 只会执行一次
  • Additional Pass: 计算额外的逐像素光源,每个光源对应一个 Pass(不支持阴影)
    • 每个逐像素光源会被调用一次
    • 还开启和设置了渲染模式,每个Additional Pass可以与上一次的光照结果在帧缓存中进行叠加

②延迟渲染路径

a. 延迟渲染路径的原理
  • 除了前向渲染用到的颜色缓冲和深度缓冲,延迟渲染还会用到G缓冲(G-buffer),存储了我们所关心的表面的其他信息(法线、位置、用于光照计算的材质属性)
b. Unity中的延迟渲染
  • 若光源数目多,前向渲染会造成性能瓶颈,就适合延迟渲染;延迟渲染中每个光源都可以按逐像素的方式处理
  • 缺点:
    • 不支持真正的抗锯齿(anti-aliasing)
    • 不能处理半透明物体
    • 对显卡有要求
c. 两种Pass
  • 第一个Pass:不进行任何光照计算,仅仅计算哪些片元是可见的(深度缓冲);如果该片元可见,就把相关信息存储到G缓冲区中
    • 漫反射颜色、高光反射颜色、平滑度、法线、自发光和深度信息
  • 第二个Pass:利用G缓冲区中的信息进行真正的光照计算
  • 不依赖与场景复杂度,而是与屏幕空间的大小有关(缓冲区可以理解为2D图像,空间即为图像空间)

③顶点照明渲染路径

  • 一种简单的渲染方式,它只使用逐顶点光照,不支持阴影、法线映射等高级光照效果

二、Unity的光源类型

  • Unity中有4中类型:平行光、点光源、聚光灯和面光源(面光源仅在烘焙时用到)

1.光源类型

①平行光

没有具体位置,也没有衰减,所有点的方向都是一样的

②点光源

  • 照亮的范围可以由面板中Range来调,有光照衰减(衰减可以由函数定义)
  • 需要用 点光源的位置 - 某点位置 来得到该点的方向

③聚光灯

  • 是一块锥形区域,半径由Range来调,角度由Spot Angle来调,有光照衰减(衰减可以由函数定义)
  • 需要用 聚光灯的位置 - 某点位置 来得到该点的方向

2.前向渲染中处理不同的光源

  • 如何在Shader中访问5个属性:位置、方向、颜色、强度、衰减

①实践

// Upgrade NOTE: replaced '_LightMatrix0' with 'unity_WorldToLight'
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'Shader "Unity Shaders Book/Chapter 9/Forward Rendering" {Properties {_Diffuse ("Diffuse", Color) = (1, 1, 1, 1)_Specular ("Specular", Color) = (1, 1, 1, 1)_Gloss ("Gloss", Range(8.0, 256)) = 20}SubShader {Tags { "RenderType"="Opaque" }Pass {// Pass for ambient light & first pixel light (directional light)Tags { "LightMode"="ForwardBase" }CGPROGRAM// Apparently need to add this declaration #pragma multi_compile_fwdbase	#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"fixed4 _Diffuse;fixed4 _Specular;float _Gloss;struct a2v {float4 vertex : POSITION;float3 normal : NORMAL;};struct v2f {float4 pos : SV_POSITION;float3 worldNormal : TEXCOORD0;float3 worldPos : TEXCOORD1;};v2f vert(a2v v) {v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;return o;}fixed4 frag(v2f i) : SV_Target {fixed3 worldNormal = normalize(i.worldNormal);fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0, dot(worldNormal, worldLightDir));fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);fixed3 halfDir = normalize(worldLightDir + viewDir);fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(worldNormal, halfDir)), _Gloss);fixed atten = 1.0;return fixed4(ambient + (diffuse + specular) * atten, 1.0);}ENDCG}Pass {// Pass for other pixel lightsTags { "LightMode"="ForwardAdd" }Blend One OneCGPROGRAM// Apparently need to add this declaration#pragma multi_compile_fwdadd#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"#include "AutoLight.cginc"fixed4 _Diffuse;fixed4 _Specular;float _Gloss;struct a2v {float4 vertex : POSITION;float3 normal : NORMAL;};struct v2f {float4 pos : SV_POSITION;float3 worldNormal : TEXCOORD0;float3 worldPos : TEXCOORD1;};v2f vert(a2v v) {v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;return o;}fixed4 frag(v2f i) : SV_Target {fixed3 worldNormal = normalize(i.worldNormal);#ifdef USING_DIRECTIONAL_LIGHTfixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);#elsefixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz - i.worldPos.xyz);#endiffixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0, dot(worldNormal, worldLightDir));fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);fixed3 halfDir = normalize(worldLightDir + viewDir);fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(worldNormal, halfDir)), _Gloss);#ifdef USING_DIRECTIONAL_LIGHTfixed atten = 1.0;#else#if defined (POINT)float3 lightCoord = mul(unity_WorldToLight, float4(i.worldPos, 1)).xyz;fixed atten = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL;#elif defined (SPOT)float4 lightCoord = mul(unity_WorldToLight, float4(i.worldPos, 1));fixed atten = (lightCoord.z > 0) * tex2D(_LightTexture0, lightCoord.xy / lightCoord.w + 0.5).w * tex2D(_LightTextureB0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL;#elsefixed atten = 1.0;#endif#endifreturn fixed4((diffuse + specular) * atten, 1.0);}ENDCG}}FallBack "Specular"
}
Base Pass
  • #pragma multi_compile_fwdbase 保证我们在shader中使用 光照衰减 等光照变量时可以被正确使用
#pragma multi_compile_fwdbase	
  • 在Base Pass中计算环境光照后,在Additional Pass中就不会再计算(物体自发光也是)
Additional Pass
  • 同样使用#pragma multi_compile_fwdadd 指令
  • 开启了Blend 命令,设置了混合模式,希望Additional Pass计算得到的光照结果可以在帧缓存中与之前的光照结果进行叠加
Pass {// Pass for other pixel lightsTags { "LightMode"="ForwardAdd" }Blend One OneCGPROGRAM// Apparently need to add this declaration#pragma multi_compile_fwdadd
  • Additional Pass处理的光源类型可能是平行光、点光源或是聚光灯,在计算位置、方向、颜色、强度、衰减时,颜色和强度仍然可以使用 _LightColor0 来得到,由于位置、方向和衰减属性就需要根据光源类型分别计算
  • 方向
    如果是平行光,可以直接通过 _WorldSpaceLightPos0.xyz 来得到;如果是其他光源,_WorldSpaceLightPos0.xyz 表示的是光源在世界坐标中的位置,光源方向需要用这个位置减去世界空间下顶点的位置
			#ifdef USING_DIRECTIONAL_LIGHTfixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);#elsefixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz - i.worldPos.xyz);#endif
  • 衰减
			#ifdef USING_DIRECTIONAL_LIGHTfixed atten = 1.0;#else#if defined (POINT)float3 lightCoord = mul(unity_WorldToLight, float4(i.worldPos, 1)).xyz;fixed atten = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL;#elif defined (SPOT)float4 lightCoord = mul(unity_WorldToLight, float4(i.worldPos, 1));fixed atten = (lightCoord.z > 0) * tex2D(_LightTexture0, lightCoord.xy / lightCoord.w + 0.5).w * tex2D(_LightTextureB0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL;#elsefixed atten = 1.0;#endif#endif

三、Unity光照衰减

1.用于光照衰减的纹理

  • 在Unity内部使用一张名为 _LightTexture0 的纹理来计算光源衰减(通常只关心对角线上的纹理颜色值),比如(0,0)点表示与光源重合的点的衰减值,(1,1)点表示了在光源中距离最远的点的衰减
  • 为了对_LightTexture0纹理采样得到给定点到该光源的衰减值,先知道点在光源空间中的位置 ,_LightMatrix0 为把顶点从世界坐标变换到光源空间的矩阵,与世界空间中的顶点坐标相乘即可
  • 再使用坐标的模的平方对衰减纹理进行采样
float3 lightCoord = mul(_LightMatrix0, float4(i.worldPos, 1)).xyz;
fixed atten = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL;

2.数学公式计算

float3 distance = length(_WorldSpaceLightPos0.xyz - i.worldPosition.xyz);
fixed atten = 1.0 / distance;

四、Unity的阴影

1.阴影如何实现

  • 让一个物体向其他物体投影
  • 在实时渲染中,经常使用Shadow Map,先把摄像机放在光源位置上,光源的阴影区域就是摄像机看不到的区域

①Shadow Map的生成

  • 摄像机位置:将摄像机放置在与光源重合的位置
  • ShadowCaster Pass:使用 LightMode 标签为 ShadowCaster 的 Pass 专门更新光源的阴影映射纹理。这个 Pass 渲染的目标不是帧缓存,而是阴影映射纹理(或深度纹理)

②屏幕空间的阴影映射技术

  • 根据光源的阴影映射纹理和摄像机的深度纹理得到屏幕空间的阴影图
  • 步骤
    • 通过调用 LightMode 标签为 ShadowCaster 的 Pass 来得到 光源的阴影映射纹理相机的深度纹理
    • 根据 光源的阴影映射纹理相机的深度纹理 得到屏幕空间的阴影图
    • 若摄像机深度图中记录的表面深度 > 转换到阴影映射纹理中的深度值 → \rightarrow 物体表面虽然可见,但出于该光源的阴影中

③阴影映射

  • 让物体 接收 来自其他物体的投影
    • 在Shader中队阴影映射纹理(包括屏幕空间的阴影图)进行采样,把采样结果与光照结果相乘得到阴影
  • 让物体向其他 投射阴影
    • 把该物体加到光源的阴影映射纹理计算中(通过为该物体执行 LightMode 标签为 ShadowCaster 的 Pass 来实现的)

4.Unity Shader 使用内置宏和函数 来统一管理光照衰减和阴影

①光照衰减和阴影的影响

  • 两个对物体最终的渲染效果本质上是相同的,都是通过将衰减因子和阴影值与光照结果相乘得到最终结果
  • 可以使用一个方法来同时计算这两个信息

②内置宏 UNITY_LIGHT_ATTENUATION

  • 包含进需要的头文件 #include “AutoLight.cginc”
  • 在v2f结构体中使用内置宏 SHADOW_COORDS 声明阴影坐标
struct v2f{float4 pos : SV_POSITION;float3 worldNormal : TEXCOORD0;float3 worldPos : TEXCOORD1;SHADOW_COORDS(2);
};
  • 在顶点着色器中使用内置宏 TRANSFER_SHADOW 计算并向片元着色器传递阴影坐标
v2f vert(a2v v){v2f o;...TRANSFER_SHADOW(o);return o;
}
  • 在片元着色器中使用内置宏 UNITY_LIGHT_ATTENUATION 来计算光照衰减和阴影,有三个参数
    • 第一个:用于存储光照衰减和阴影值相乘后的结果
    • 第二个:结构体 v2f ,用于传递内置宏计算阴影值
    • 第三个:世界空间的坐标,计算光源空间下的坐标,再对光照衰减纹理采样来得到光照衰减
fixed4 frag(v2f i) : SV_Target {...UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);return fixed4(ambient + (diffuse + specular) * atten, 1.0);
} 
  • Base Pass 和 Additional Pass 代码得到统一,不需要在Base Pass里单独处理阴影,也不需要在Additional Pass中判断光源类型来处理光照衰减

5.透明物体阴影的办法

①透明物体阴影问题

  • 透明物体的实现通常会使用透明度测试或透明度混合,需要小心设置这些物体的 Fallback
  • 使用 VertexLit、Diffuse、Specular 等作为回调,往往无法得到正确的阴影(不透明物体可以,VertexLit中有ShadowCaster Pass),因为这些 Shader 中的 ShadowCaster Pass 没有进行透明度测试的计算。

②透明度测试 物体的阴影处理

  • 需要提供一个有透明度测试功能的 ShadowCaster Pass
  • Fallback “VertexLit” 改为 “Transparent/Cutout/VertexLit”
  • Cude 的 Mesh Renderer 的Cast Shadows 设置为 Two Sided
    在这里插入图片描述

③透明度混合 物体的阴影处理

  • 因为透明度混合需要关闭深度写入,这会带来阴影生成的问题,所以所有内置的透明度混合的 Unity Shader 都没有包含阴影投射的 Pass,因此,这些半透明物体不会向其他物体投射阴影,也不会接收来自其他物体的阴影
  • 可以使用一些 dirty trick 来强制为半透明物体生成阴影
    • 把它们的 Fallback 设置为 VertexLit、Diffuse 等不透明物体使用的 Unity Shader
    • 通过物体的 Mesh Renderer 组件上的 Cast Shadows 和 Receive Shadows 选项来控制是否需要向其他物体投射或接收阴影
      在这里插入图片描述

五、标准的Unity Shader

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

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

相关文章

Webpack: 核心流程之Init、Make、Seal

概述 在前文中,我们了解了 Webpack 的基本应用、性能优化、Loader 与 Plugin 组件开发方方面面的知识,相信学习过这些内容之后,你已经对 Webpack 有相当深入的理解了,可以开始从更底层的视角,自底向上重新审视 Webpac…

直流电机介绍

一、引入 电机,即电动机(motor)俗称马达,是电能转化为机械能的总称,按工作原理分类电机可以分为:直流电机(通过直流电源供电,依靠电刷和换向器改变电流方向,产生连续转动…

文献解读-长读长测序-第十四期|《作为了解棉花驯化的资源,印度棉(Gossypium herbaceum L. Wagad)基因组》

关键词:基因组;长读长测序;棉花基因组; 文献简介 标题(英文):The Gossypium herbaceum L. Wagad genome as a resource for understanding cotton domestication标题(中文&#xff…

DBdoctor v3.2.2 版本发布,支持对sqlserver、vastbase的纳管!

DBdoctor 3.2.2版本新增PgSQL的索引推荐及性能审核功能;拓展了oracle的纳管版本并支持纳管oracle rac;新增对sqlserver、vastbase数据库的纳管支持;修复了体验官活动中大家提出的一系列体验问题。 详细更新内容如下: 功能优化 Pg…

贪心算法题目总结

1. 整数替换 看到这道题目,我们首先能想到的方法就应该是递归解法,我们来画个图 此时我们出现了重复的子问题,就可以使用递归,只要我们遇到偶数,直接将n除以2递归下去,如果是奇数,选出加1和减1中…

我在手提电脑上将大模型训练成了语文老师

(图片由大模型生成,如有侵权,立删) 记得一年多以前,和不少商家交流大模型解决方案时,他们谈到内部有很多的资料,可以对大模型进行训练,让大模型变得更有智慧,从而为客户…

Day9:逆波兰表达式求值150 滑动窗口最大值239 前 K 个高频元素347

题目150. 逆波兰表达式求值 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int evalRPN(vector<string>& tokens) {//使用栈来消除stack<string> st;for(int i0;i<tokens.size();i){if(tokens[i]""||tokens[i]"-"|…

创新赋能,高效二开!CRMEB 标准版 v5.4公测版发布

历经十年磨砺&#xff0c;CRMEB 标准版如今已成为众多技术开发者与企业二次开发、构建定制化项目的热门系统&#xff0c;其全开源无加密、功能齐全、独立部署的特质&#xff0c;造就了标准版系统方便二开的优势&#xff0c;不仅深受开发者喜爱&#xff0c;更因其实用性和可靠性…

运行vue : 无法加载文件 C:\Program Files\nodejs\node_global\vue.ps1,因为在此系统上禁止运行脚本。

报错背景: 重装了win10系统,然后准备安装Vue,这个时候我已经安装好了node.js和npm,输入node -v和npm -v都有正确输出,但是每次输入npm install -g vue/cli 安装的时候,就会报错. 大家安装node.js的时候最好就是默认路径(C:\Program Files\nodejs),别去修改不然很多报错.(个人…

Linux Centos7部署Zookeeper

目录 一、下载zookeeper 二、单机部署 1、创建目录 2、解压 3、修改配置文件名 ​4、创建保存数据的文件夹 ​5、修改配置文件保存数据的地址 ​6、启动服务 7、api创建节点 一、下载zookeeper 地址&#xff1a;Index of /dist/zookeeper/zookeeper-3.5.7 (apache.org…

名企面试必问30题(十五)——你的学历有点低,你怎么看?

1.思路 首先承认学历低这一事实&#xff1a;我坦诚地承认自己的学历相对较低。 后续解决方案&#xff1a;不过&#xff0c;我相信能力的展现不仅仅取决于学历。在过往的工作经历中&#xff0c;我积累了丰富的实践经验&#xff0c;培养了较强的学习能力和解决问题的能力。我会持…

两台电脑怎么传文件?干货分享教程

当需要在两台电脑之间传输文件时&#xff0c;有多种方便的方法可供选择&#xff0c;以下是一些常见的方式及教程&#xff1a; 使用局域网共享&#xff1a; 确保两台电脑连接在同一个局域网内。 在其中一台电脑上&#xff0c;设置要共享的文件夹。右键点击文件夹&#xff0c;选…

论文学习——使用基于多项式拟合的预测算法求解动态多目标问题

论文题目&#xff1a;Solving dynamic multi-objective problems using polynomial fitting-based prediction algorithm 使用基于多项式拟合的预测算法求解动态多目标问题&#xff08;Qingyang Zhang , Xiangyu He,Shengxiang Yang , Yongquan Dong , Hui Song , Shouyong Ji…

归并排序-MergeSort (C语言详解)

目录 前言归并排序的思想归并排序的递归法归并排序的非递归法归并排序的时间复杂度与适用场景总结 前言 好久不见, 前面我们了解到了快速排序, 那么本篇旨在介绍另外一种排序, 它和快速排序的思想雷同, 但又有区别, 这就是归并排序, 如下图, 我们对比快速排序与归并排序. 本…

Nacos配置中心客户端源码分析(二): 客户端和服务端交互

本文收录于专栏 Nacos 推荐阅读&#xff1a;Nacos 架构 & 原理 ⚠️&#xff1a;使用的Nacos版本为2.3.X 文章目录 前言一、NacosConfigLoader二、NacosConfigService三、ClientWorker四、服务端处理逻辑总结 前言 上篇文章我们简单看了看Nacos客户端在启动的时候&#xf…

远程抄表管理系统建设方案(Word原件)

远程抄表管理系统建设方案应涵盖智能表计安装、数据采集与传输、数据处理与分析三大核心环节。首先&#xff0c;安装智能表计以实时采集水、电、气等数据&#xff1b;其次&#xff0c;利用先进的通信技术&#xff08;如GPRS、LoRa等&#xff09;实现数据的稳定传输&#xff1b;…

c语言回顾-数组(全网最详细,哈哈哈)

目录 前言&#xff0c;和小编一起感受数组的魅力&#xff01;&#xff01;&#xff01; 1.数组的概念 2.一维数组的创建和初始化 2.1数组创建 2.2数组的初始化 2.3数组的类型 3.一维数组的使用 3.1数组下标 3.2数组元素的输入输出 小结&#xff1a; 4.一维数组在内存…

pycharm的usages在哪设置?

参考文章&#xff1a;https://blog.51cto.com/save/8961821 在代码编辑器&#xff08;如PyCharm或IntelliJ IDEA&#xff09;中&#xff0c;"1 usage"通常表示当前光标所在的代码元素&#xff08;如变量、函数、类等&#xff09;在其他地方被使用了一次。这个功能可…

什么是自动气象站呢

自动气象站&#xff0c;作为现代气象观测的重要工具&#xff0c;已经深入到我们生活的各个领域&#xff0c;从气象预报到农业生产&#xff0c;再到环境保护&#xff0c;自动气象站都发挥着不可或缺的作用。 自动气象站&#xff0c;顾名思义&#xff0c;是一种能够自动收集、处理…

昇思25天学习打卡营第7天|网络构建

网络构建 神经网络模型由tensor操作和神经网络层构成。 MIndSporezhong&#xff0c;Cell是构建所有网络的基类&#xff0c;也是网络的基本单元。cell也由子cell构成。 定义模型类 # 继承nn.Cell类 class Network(nn.Cell):def __init__(self):super().__init__()self.flatte…