Unity中Shader的Standard材質解析(二)

文章目錄

  • 前言
  • 一、我們對 Standard 的 PBR 的 GI 進行解析
    • 1、我們先創建一個PBR的.cginc文件,用于整理用到的函數
    • 2、然后在Standard的Shader中引用該cginc文件
  • 二、依次整理函數到該cginc文件中
    • 我們來看一下PBR中GI的鏡面反射做了些什么
  • 二、最終代碼
    • .cginc代碼:
    • Shader代碼:


前言

Unity中Shader的Standard材質解析(二),對 Standard 的 PBR 的 GI 進行解析

  • Unity中Shader的Standard材質解析(一)

一、我們對 Standard 的 PBR 的 GI 進行解析

在這里插入圖片描述

1、我們先創建一個PBR的.cginc文件,用于整理用到的函數

在這里插入圖片描述

2、然后在Standard的Shader中引用該cginc文件

#include “CGInclude/MyPhysicallyBasedRendering.cginc”


二、依次整理函數到該cginc文件中

  • 整理 LightingStandard_GI1(o, giInput, gi); 中的數據

在這里插入圖片描述

  • Unity_GlossyEnvironmentData表示GI中的反射準備數據

在這里插入圖片描述

  • 準備好反射數據后,計算得出GI中的 漫反射 和 鏡面反射

在這里插入圖片描述

  • 輸出漫反射看看效果

在這里插入圖片描述
在這里插入圖片描述

  • 輸出鏡面反射看看效果

在這里插入圖片描述

在這里插入圖片描述

  • 我們可以自定義一下Cubemap,看看不同的反射效果

(這就是PBR的優點,可以根據不同的環境,直接呈現效果,不用再根據環境調節參數)

請添加圖片描述

我們來看一下PBR中GI的鏡面反射做了些什么

  • 這個程序塊只會在,反射探針中開啟Box Projection時,才會運行

在這里插入圖片描述
在這里插入圖片描述
這選項的作用是:使用反射探針的物體在移動時,效果不會變,只有在攝像機方向變時,效果才會變化。那么,要讓物體動時,反射效果同時改變的話,就需要開啟該選項。

  • 在取消了材質的Reflection后,會運行該程序塊
  • 反之,運行之后的部分

在這里插入圖片描述

在這里插入圖片描述

  • 在開啟反射效果后,對于感性粗糙度的計算。
  • 在Unity中的粗糙度,使用分級貼圖來模擬粗糙度(節省性能)

在這里插入圖片描述

  • 由于粗糙度與反射探針的mip變化不呈現線性正比,所以需要一個公式來改變

//r = r * (1.7 - 0.7r)
perceptualRoughness = perceptualRoughness
(1.7 - 0.7*perceptualRoughness);

在這里插入圖片描述

在Blender中,粗糙度是按數值改變的:
請添加圖片描述

在Unity中,反射探針是按貼圖分級來模擬的粗糙度:

請添加圖片描述

在這里插入圖片描述


二、最終代碼

.cginc代碼:

#ifndef MYPHYSICALLYBASERENDERING_INCLUDE#define MYPHYSICALLYBASERENDERING_INCLUDEhalf3 Unity_GlossyEnvironment1 (UNITY_ARGS_TEXCUBE(tex), half4 hdr, Unity_GlossyEnvironmentData glossIn){half perceptualRoughness = glossIn.roughness /* perceptualRoughness */ ;// TODO: CAUTION: remap from Morten may work only with offline convolution, see impact with runtime convolution!// For now disabled#if 0float m = PerceptualRoughnessToRoughness(perceptualRoughness); // m is the real roughness parameterconst float fEps = 1.192092896e-07F;        // smallest such that 1.0+FLT_EPSILON != 1.0  (+1e-4h is NOT good here. is visibly very wrong)float n =  (2.0/max(fEps, m*m))-2.0;        // remap to spec power. See eq. 21 in --> https://dl.dropboxusercontent.com/u/55891920/papers/mm_brdf.pdfn /= 4;                                     // remap from n_dot_h formulatino to n_dot_r. See section "Pre-convolved Cube Maps vs Path Tracers" --> https://s3.amazonaws.com/docs.knaldtech.com/knald/1.0.0/lys_power_drops.htmlperceptualRoughness = pow( 2/(n+2), 0.25);      // remap back to square root of real roughness (0.25 include both the sqrt root of the conversion and sqrt for going from roughness to perceptualRoughness)#else// MM: came up with a surprisingly close approximation to what the #if 0'ed out code above does.//r = r * (1.7 - 0.7*r)//由于粗糙度與反射探針的mip變化不呈現線性正比,所以需要一個公式來改變perceptualRoughness = perceptualRoughness*(1.7 - 0.7*perceptualRoughness);#endif//UNITY_SPECCUBE_LOD_STEPS = 6,表示反射探針的mip級別有 6 檔。粗糙度X6得到最終得mip級別half mip = perceptualRoughnessToMipmapLevel(perceptualRoughness);half3 R = glossIn.reflUVW;half4 rgbm = UNITY_SAMPLE_TEXCUBE_LOD(tex, R, mip);return DecodeHDR(rgbm, hdr);}//GI中的鏡面反射inline half3 UnityGI_IndirectSpecular1(UnityGIInput data, half occlusion, Unity_GlossyEnvironmentData glossIn){half3 specular;//如果開啟了反射探針的Box Projection#ifdef UNITY_SPECCUBE_BOX_PROJECTION// we will tweak reflUVW in glossIn directly (as we pass it to Unity_GlossyEnvironment twice for probe0 and probe1), so keep original to pass into BoxProjectedCubemapDirectionhalf3 originalReflUVW = glossIn.reflUVW;glossIn.reflUVW = BoxProjectedCubemapDirection (originalReflUVW, data.worldPos, data.probePosition[0], data.boxMin[0], data.boxMax[0]);#endif#ifdef _GLOSSYREFLECTIONS_OFFspecular = unity_IndirectSpecColor.rgb;#elsehalf3 env0 = Unity_GlossyEnvironment1 (UNITY_PASS_TEXCUBE(unity_SpecCube0), data.probeHDR[0], glossIn);//如果開啟了反射探針混合#ifdef UNITY_SPECCUBE_BLENDINGconst float kBlendFactor = 0.99999;float blendLerp = data.boxMin[0].w;UNITY_BRANCHif (blendLerp < kBlendFactor){#ifdef UNITY_SPECCUBE_BOX_PROJECTIONglossIn.reflUVW = BoxProjectedCubemapDirection (originalReflUVW, data.worldPos, data.probePosition[1], data.boxMin[1], data.boxMax[1]);#endifhalf3 env1 = Unity_GlossyEnvironment (UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1,unity_SpecCube0), data.probeHDR[1], glossIn);specular = lerp(env1, env0, blendLerp);}else{specular = env0;}#elsespecular = env0;#endif#endifreturn specular * occlusion;}inline UnityGI UnityGlobalIllumination1 (UnityGIInput data, half occlusion, half3 normalWorld){return UnityGI_Base(data, occlusion, normalWorld);}//GI計算inline UnityGI UnityGlobalIllumination1 (UnityGIInput data, half occlusion, half3 normalWorld, Unity_GlossyEnvironmentData glossIn){//計算得出GI中的漫反射UnityGI o_gi = UnityGI_Base(data, occlusion, normalWorld);//計算得出GI中的鏡面反射o_gi.indirect.specular = UnityGI_IndirectSpecular1(data, occlusion, glossIn);return o_gi;}float SmoothnessToPerceptualRoughness1(float smoothness){return (1 - smoothness);}Unity_GlossyEnvironmentData UnityGlossyEnvironmentSetup1(half Smoothness, half3 worldViewDir, half3 Normal, half3 fresnel0){Unity_GlossyEnvironmentData g;//粗糙度g.roughness /* perceptualRoughness */   = SmoothnessToPerceptualRoughness1(Smoothness);//反射球的采樣坐標g.reflUVW   = reflect(-worldViewDir, Normal);return g;}//PBR光照模型的GI計算inline void LightingStandard_GI1(SurfaceOutputStandard s,UnityGIInput data,inout UnityGI gi){//如果是延遲渲染PASS并且開啟了延遲渲染反射探針的話#if defined(UNITY_PASS_DEFERRED) && UNITY_ENABLE_REFLECTION_BUFFERSgi = UnityGlobalIllumination1(data, s.Occlusion, s.Normal);#else//Unity_GlossyEnvironmentData表示GI中的反射準備數據Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup1(s.Smoothness, data.worldViewDir, s.Normal,lerp(unity_ColorSpaceDielectricSpec.rgb, s.Albedo,s.Metallic));//進行GI計算并返回輸出gigi = UnityGlobalIllumination1(data, s.Occlusion, s.Normal, g);#endif}#endif

Shader代碼:

//Standard材質
Shader "MyShader/P2_2_5"
{Properties{_Color ("Color", Color) = (1,1,1,1)_MainTex ("Albedo (RGB)", 2D) = "white" {}[NoScaleOffset]_MetallicTex("Metallic(R) Smoothness(G) AO(B)",2D) = "white" {}[NoScaleOffset][Normal]_NormalTex("NormalTex",2D) = "bump" {}_Glossiness ("Smoothness", Range(0,1)) = 0.0_Metallic ("Metallic", Range(0,1)) = 0.0_AO("AO",Range(0,1)) = 1.0}SubShader{Tags{"RenderType"="Opaque"}LOD 200// ---- forward rendering base pass:Pass{Name "FORWARD"Tags{"LightMode" = "ForwardBase"}CGPROGRAM// compile directives#pragma vertex vert#pragma fragment frag#pragma target 3.0#pragma multi_compile_instancing#pragma multi_compile_fog#pragma multi_compile_fwdbase#include "UnityCG.cginc"#include "Lighting.cginc"#include "UnityPBSLighting.cginc"#include "AutoLight.cginc"#include "CGInclude/MyPhysicallyBasedRendering.cginc"sampler2D _MainTex;float4 _MainTex_ST;half _Glossiness;half _Metallic;fixed4 _Color;sampler2D _MetallicTex;half _AO;sampler2D _NormalTex;struct appdata{float4 vertex : POSITION;float4 tangent : TANGENT;float3 normal : NORMAL;float4 texcoord : TEXCOORD0;float4 texcoord1 : TEXCOORD1;float4 texcoord2 : TEXCOORD2;float4 texcoord3 : TEXCOORD3;fixed4 color : COLOR;UNITY_VERTEX_INPUT_INSTANCE_ID};// vertex-to-fragment interpolation data// no lightmaps:struct v2f{float4 pos : SV_POSITION;float2 uv : TEXCOORD0; // _MainTexfloat3 worldNormal : TEXCOORD1;float3 worldPos : TEXCOORD2;#if UNITY_SHOULD_SAMPLE_SHhalf3 sh : TEXCOORD3; // SH#endif//切線空間需要使用的矩陣float3 tSpace0 : TEXCOORD4;float3 tSpace1 : TEXCOORD5;float3 tSpace2 : TEXCOORD6;UNITY_FOG_COORDS(7)UNITY_SHADOW_COORDS(8)};// vertex shaderv2f vert(appdata v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex);float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;float3 worldNormal = UnityObjectToWorldNormal(v.normal);//世界空間下的切線half3 worldTangent = UnityObjectToWorldDir(v.tangent);//切線方向half tangentSign = v.tangent.w * unity_WorldTransformParams.w;//世界空間下的副切線half3 worldBinormal = cross(worldNormal, worldTangent) * tangentSign;//切線矩陣o.tSpace0 = float3(worldTangent.x, worldBinormal.x, worldNormal.x);o.tSpace1 = float3(worldTangent.y, worldBinormal.y, worldNormal.y);o.tSpace2 = float3(worldTangent.z, worldBinormal.z, worldNormal.z);o.worldPos.xyz = worldPos;o.worldNormal = worldNormal;// SH/ambient and vertex lights#if UNITY_SHOULD_SAMPLE_SH && !UNITY_SAMPLE_FULL_SH_PER_PIXELo.sh = 0;// Approximated illumination from non-important point lights#ifdef VERTEXLIGHT_ONo.sh += Shade4PointLights (unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb,unity_4LightAtten0, worldPos, worldNormal);#endifo.sh = ShadeSHPerVertex (worldNormal, o.sh);#endifUNITY_TRANSFER_LIGHTING(o, v.texcoord1.xy);UNITY_TRANSFER_FOG(o, o.pos); // pass fog coordinates to pixel shaderreturn o;}// fragment shaderfixed4 frag(v2f i) : SV_Target{UNITY_EXTRACT_FOG(i);float3 worldPos = i.worldPos.xyz;float3 worldViewDir = normalize(UnityWorldSpaceViewDir(worldPos));SurfaceOutputStandard o;UNITY_INITIALIZE_OUTPUT(SurfaceOutputStandard, o);fixed4 mainTex = tex2D(_MainTex, i.uv);o.Albedo = mainTex.rgb * _Color;o.Emission = 0.0;fixed4 metallicTex = tex2D(_MetallicTex, i.uv);o.Metallic = metallicTex.r * _Metallic;o.Smoothness = metallicTex.g * _Glossiness;o.Occlusion = metallicTex.b * _AO;o.Alpha = 1;half3 normalTex = UnpackNormal(tex2D(_NormalTex,i.uv));half3 worldNormal = half3(dot(i.tSpace0,normalTex),dot(i.tSpace1,normalTex),dot(i.tSpace2,normalTex));o.Normal = worldNormal;// compute lighting & shadowing factorUNITY_LIGHT_ATTENUATION(atten, i, worldPos)// Setup lighting environmentUnityGI gi;UNITY_INITIALIZE_OUTPUT(UnityGI, gi);gi.indirect.diffuse = 0;gi.indirect.specular = 0;gi.light.color = _LightColor0.rgb;gi.light.dir = _WorldSpaceLightPos0.xyz;// Call GI (lightmaps/SH/reflections) lighting functionUnityGIInput giInput;UNITY_INITIALIZE_OUTPUT(UnityGIInput, giInput);giInput.light = gi.light;giInput.worldPos = worldPos;giInput.worldViewDir = worldViewDir;giInput.atten = atten;#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)giInput.lightmapUV = IN.lmap;#elsegiInput.lightmapUV = 0.0;#endif#if UNITY_SHOULD_SAMPLE_SH && !UNITY_SAMPLE_FULL_SH_PER_PIXELgiInput.ambient = i.sh;#elsegiInput.ambient.rgb = 0.0;#endifgiInput.probeHDR[0] = unity_SpecCube0_HDR;giInput.probeHDR[1] = unity_SpecCube1_HDR;#if defined(UNITY_SPECCUBE_BLENDING) || defined(UNITY_SPECCUBE_BOX_PROJECTION)giInput.boxMin[0] = unity_SpecCube0_BoxMin; // .w holds lerp value for blending#endif#ifdef UNITY_SPECCUBE_BOX_PROJECTIONgiInput.boxMax[0] = unity_SpecCube0_BoxMax;giInput.probePosition[0] = unity_SpecCube0_ProbePosition;giInput.boxMax[1] = unity_SpecCube1_BoxMax;giInput.boxMin[1] = unity_SpecCube1_BoxMin;giInput.probePosition[1] = unity_SpecCube1_ProbePosition;#endifLightingStandard_GI1(o, giInput, gi);//return fixed4(gi.indirect.specular,1);// PBS的核心計算fixed4 c = LightingStandard(o, worldViewDir, gi);UNITY_APPLY_FOG(_unity_fogCoord, c); // apply fogUNITY_OPAQUE_ALPHA(c.a); //把c的Alpha置1return c;}ENDCG}}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/167740.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/167740.shtml
英文地址,請注明出處:http://en.pswp.cn/news/167740.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

OpenGL 繪制旋轉球(Qt)

文章目錄 一、簡介二、實現代碼三、實現效果一、簡介 這里其實就是指三個互相垂直的三個圓形,正好之前已經完成了圓形平面的繪制,那么這里就需要對之前的圓形進行一些改造,使得它們可以以任意一種姿態在OpenGL中進行繪制(添加變換矩陣)。 這里同樣對其進行封裝,具體內容如…

【教學類-06-07】20231124 (55格版)X-X之間的加法、減法、加減混合題

背景需求 在大四班里&#xff0c;預測試55格“5以內、10以內、20以內的加法題、減法題、加減混合題”的“實用性”。 由于只打印一份20以內加法減法混合題。 “這套20以內的加減法最難”&#xff0c;我詢問誰會做&#xff08;摸底幼兒的水平&#xff09; 有兩位男孩舉手想挑…

joplin筆記同步 到騰訊云S3

創建存儲桶 打開騰訊云的存儲桶列表&#xff0c;點擊“創建存儲桶”&#xff0c;輸入名稱&#xff0c;選擇地域&#xff08;建議選擇離自己較近的地域以降低訪問時延&#xff09;和訪問權限&#xff08;建議選擇“私有讀寫”&#xff09;。 s3 存儲桶&#xff1a; 存儲桶的名稱…

【經典小練習】簡單的文件加密解密

文章目錄 &#x1f339;什么是文件加密?應用場景 &#x1f6f8;案例&#x1f33a;描述&#x1f33a;代碼 &#x1f339;什么是文件加密 Java文件加密是指使用Java編程語言和相關的加密算法對文件進行加密處理。通過這種方式&#xff0c;可以將文件內容轉換為一種非常規的形式…

Halcon Solution Guide I basics(4): Blob Analysis(連通性解析)

文章目錄 文章專欄前言文章解析開頭步驟分析簡單案例進階方案 進階代碼案例crystal&#xff0c;結晶匹配需求分析 文章專欄 Halcon開發 Halcon學習 練習項目gitee倉庫 CSDN Major 博主Halcon文章推薦 前言 今天來看第三章內容&#xff0c;既然是零基礎&#xff0c;而且我還有大…

希寶貓罐頭怎么樣?專業人士告訴你口碑好的貓罐頭推薦

作為一個從業寵物營養師7年的人&#xff0c;可以說對于貓咪的食物很有研究和貓罐頭品牌選購上&#xff0c;我有自己的見解。那么希寶貓罐頭怎么樣呢&#xff1f; 希寶貓罐頭采用了先進的加工工藝&#xff0c;注重產品的包裝和密封性&#xff0c;其包裝設計簡潔時尚&#xff0c…

Java定時任務 ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor 的創建 ScheduledThreadPoolExecutor executorService new ScheduledThreadPoolExecutor(1, // 核心線程數new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d") // 線程命名規則.daemon(true) // 設置線程為…

STM32 中斷系統

單片機學習 目錄 文章目錄 前言 一、中斷系統 1.1 什么是中斷 1.2 中斷優先級 1.3 中斷嵌套 1.4 C語言中的中斷程序 二、STM32的中斷通道和中斷向量 2.1 中斷通道 2.2 嵌套向量中斷控制器NVIC 2.2.1 什么是NVIC 2.2.2 NVIC基本結構 2.2.3搶占優先級和響應優先級 2.2.4 NVIC的優…

間隔分區表(DM8:達夢數據庫)

DM8:達夢數據庫 - 間隔分區表 環境介紹1 按 年 - 間隔分區表2 按 月 - 間隔分區3 按 日 - 間隔分區4 按 數值 - 間隔分區表5 達夢數據庫學習使用列表 環境介紹 間隔分區表使用說明&#xff1a; 僅支持一級范圍分區創建間隔分區。 只能有一個分區列&#xff0c;且分區列類型為…

究竟什么是阻塞與非阻塞、同步與異步

文章目錄 前言阻塞與非阻塞同步與異步復雜的網絡IO真正的異步IOIO分類與示例總結 前言 這幾個名詞在程序開發時經常聽到&#xff0c;但是突然問起來各個詞的含義一時間還真是說不清楚&#xff0c;貌似這幾個詞都是翻譯過來的&#xff0c;每個人的解釋都不太一樣&#xff0c;我…

深度學習卷積神經網絡參數計算難點重點

目錄 一、卷積層圖像輸出尺寸 二、池化層圖像輸出尺寸 三、全連接層輸出尺寸 四、卷積層參數數量 五、全連接層參數數量 六、代碼實現與驗證 以LeNet5經典模型為例子并且通道數為1 LeNet5網絡有7層&#xff1a; ? 1.第1層&#xff1a;卷積層 ? 輸入&#xff1a;原始的圖片像素…

c語言數字轉圈

數字轉圈 題干輸入整數 N&#xff08;1≤N≤9&#xff09;&#xff0c;輸出如下 N 階方陣。 若輸入5顯示如下方陣&#xff1a; * 1** 2** 3** 4** 5* *16**17**18**19** 6* *15**24**25**20** 7* *14**23**22**21** 8* *13**12**11**10** 9*輸入樣例3輸出樣例* 1*…

PTA 海盜分贓

P 個海盜偷了 D 顆鉆石后來到公海分贓&#xff0c;一致同意如下分贓策略&#xff1a; 首先&#xff0c;P 個海盜通過抽簽決定 1 - P 的序號。然后由第 1 號海盜提出一個分配方案&#xff08;方案應給出每個海盜分得的具體數量&#xff09;&#xff0c;如果能夠得到包括 1 號在…

linux高級篇基礎理論六(firewalld,防火墻類型,,區域,服務端口,富語言)

??作者&#xff1a;小劉在C站 ??個人主頁&#xff1a; 小劉主頁 ??不能因為人生的道路坎坷,就使自己的身軀變得彎曲;不能因為生活的歷程漫長,就使求索的 腳步遲緩。 ??學習兩年總結出的運維經驗&#xff0c;以及思科模擬器全套網絡實驗教程。專欄&#xff1a;云計算技…

基于戰爭策略算法優化概率神經網絡PNN的分類預測 - 附代碼

基于戰爭策略算法優化概率神經網絡PNN的分類預測 - 附代碼 文章目錄 基于戰爭策略算法優化概率神經網絡PNN的分類預測 - 附代碼1.PNN網絡概述2.變壓器故障診街系統相關背景2.1 模型建立 3.基于戰爭策略優化的PNN網絡5.測試結果6.參考文獻7.Matlab代碼 摘要&#xff1a;針對PNN神…

測試工具JMeter的使用

目錄 JMeter的安裝配置 測試的性能指標 TPS 響應時長 并發連接 和 并發用戶 CPU/內存/磁盤/網絡 負載 性能測試實戰流程 JMeter JMeter快速上手 GUI模式 運行 HTTP請求默認值 錄制網站流量 模擬間隔時間 Cookie管理器 消息數據關聯 變量 后置處理器 CSV 數據文…

中國企業500強的排名也在不斷變化。面對不確定性的挑戰,企業如何應對?

隨著全球經濟的不斷發展和變化&#xff0c;中國企業500強的排名也在不斷變化。面對不確定性的挑戰&#xff0c;企業如何應對&#xff1f;在本文中&#xff0c;挖數據平臺將提供數據源探討中國企業500強在應對不確定性方面的突圍與變革。 一、數據挖掘與分析 從2006年到2023年&…

【電子通識】什么是物料清單BOM(Bill of Material))

BOM (Bill of Materials)是我們常說的物料清單。BOM是制造業管理的重點之一&#xff0c;用于記載產品組成所需要的全部物料&#xff08;Items&#xff09;。物料需求的計算是從最終產品開始&#xff0c;層層往下推算出部件&#xff0c;組件&#xff0c;零件和原材料的需求量。這…

【C++11】nullptr關鍵字使用詳解

系列文章目錄 C11新特性使用詳解-持續更新 https://blog.csdn.net/xiaofeizai1116/category_12498334.html 文章目錄 系列文章目錄一、簡介二、引入nullptr原因1. 消除歧義2. 兼容性問題3. 類型安全 三、使用場景1. 初始化指針變量2. 判斷指針是否為空3. 釋放內存后置為空 四、…

【nlp】3.5 Transformer論文復現:3.解碼器部分(解碼器層)和4.輸出部分(線性層、softmax層)

Transformer論文復現:3.解碼器部分(解碼器層)和4.輸出部分(線性層、softmax層) 3.1 解碼器介紹3.2 解碼器層3.2.1 解碼器層的作用3.2.2 解碼器層的代碼實現3.2.3 解碼器層總結3.3 解碼器3.3.1 解碼器的作用3.3.2 解碼器的代碼實現3.3.3 解碼器總結4.1 輸出部分介紹4.2 線性…