什麼是生成式 AI?大模型、LLM、Diffusion 一次懂

最近「AI」幾乎天天出現在新聞裡,但一深入就遇到一堆名詞:生成式 AI、大語言模型(LLM)、Diffusion、Transformer、推理模型……每個都好像懂,合起來又很模糊。

這篇文章目標是讓完全沒有背景的讀者也能建立正確的心智模型,之後讀後續系列(Prompt、RAG、Agent、工具比較)才會跟得上。我們不碰公式,只用比喻和例子把概念講清楚。

從 AI 發展史看現在

要理解生成式 AI 有多革命性,先看看它站在哪些巨人肩上:

時代 代表技術 能做什麼
1950–80s 規則系統、n-gram 依程式設計師寫死的規則回應
2012 後 深度學習、神經網路 從資料「學」特徵,而非手動設定
2017 Transformer 架構 一次看長距離關聯,讓大模型成為可能
2022 後 生成式 AI(ChatGPT 引爆) 產生文字、圖片、影片、程式碼等新內容

關鍵轉折點在 2017 年 Google 提出的 Transformer 架構(論文《Attention Is All You Need》)。它讓模型能同時關注輸入的所有部分,訓練出超大型模型變得可行。之後所有的現代 AI,幾乎都建立在這個基礎上。

什麼是「生成式」AI?

生成式 AI(Generative AI) 是一類會產生新內容的 AI。它不只是把既有資料撈出來,而是學到資料背後的規律後,輸出從未出現過的:

  • 文字:對話、文章、程式碼
  • 圖片:依描述繪製的圖像
  • 影片:文字或圖片生成的動態影像
  • 音訊:語音合成、音樂

它的核心行為可以簡化成一句話:學到訓練資料的規律 → 根據你的輸入(prompt)產生新內容。

這裡有個重要區分:

  • 傳統 AI / 判別式模型:做「分類」或「判斷」。例如辨識郵件是不是垃圾信、圖片裡是貓還是狗。它只給一個答案,不產生新東西。
  • 生成式模型:「創造」內容。你給一句開頭,它幫你續寫下去。

大語言模型(LLM):會說話的模型

大語言模型(Large Language Model, LLM) 是生成式 AI 裡最出名的一種,專門處理文字(後來也擴到多模態)。

幾個關鍵概念:

  • 訓練資料:幾乎吃掉了整個網路上的文字。因為看得夠多,它學會了語言的規律與知識。
  • 預測下一個字:LLM 本質上在做的事情很簡單——根據前面的文字,預測最可能的下一個 token(一個詞或字的一部分)。別小看這個能力,重複足夠多次,就能寫出連貫的文章、程式碼甚至推理過程。
  • 參數(Parameters):模型「學到的東西」的總量,常以十億(B)、千億(100B+)來衡量。數字越大通常代表容量越大,但不等於一定更好。
  • 上下文窗口(Context Window):模型一次能「記住」的文字長度。像讀一篇長報告、問一整份文件,都受這個限制。

常見的 LLM 產品你有聽過這些:ChatGPT、Claude、Google Gemini、DeepSeek、Qwen、Kimi、Grok 等。它們背後都是不同公司訓練的 LLM。

Diffusion:畫圖的模型

LLM 處理文字,但你可能也看過 AI 畫圖、生成影片。那些多半是另一類模型——Diffusion(擴散)模型

它的原理可以這樣理解:

  1. 從一張全是雜訊(像電視無訊號的雪花)的圖片開始。
  2. 反覆「去噪」,一步步把模糊的雜訊清成清晰的圖像。
  3. 你給的描述(prompt)會引導這個清理方向,最後出現你要的內容。

文字到圖片(Text-to-Image)、文字到影片(Text-to-Video)都是這個思路。代表性產品:Midjourney、Stable Diffusion、Adobe Firefly(圖),以及 Sora、Veo、LTX-Video(影片)。

簡單記:LLM 生成文字,Diffusion 生成圖像與影片,兩者常合稱「生成式 AI」。

為什麼現在這麼強?三種驅動力

為什麼 2022 年之前 AI 感覺一般,之後突然變神?主要靠三件事:

  1. 更大的模型:運力提升,能訓練出參數驚人的大模型。
  2. 更多的資料:網路文字資料豐富,供模型學習。
  3. 更好的訓練方法:除了預訓練,還用「人類回饋強化學習」(RLHF)讓模型的回應更符合人類期望、更好用、更安全。

新關鍵:推理模型(Reasoning / Thinking Models)

這是 2025–2026 最重要的進展,也是你之後用 AI 一定會碰到的概念。

傳統的 LLM 是「想到什麼就說什麼」,追求第一時間吐出答案。而推理模型會先在內部「先想一下、一步步推導」,再給出最終答案。類似的例子:解數學題時,不是直接報數字,而是先寫出計算過程。

代表產品與系列:OpenAI 的 o1 / gpt-5-thinking 系列、DeepSeek R1 之後的思考模型、Qwen 的 thinking 版本

對一般使用者意味著什麼?

  • 適合複雜問題:邏輯、數學、程式除錯、多步驟規劃,推理模型通常更準。
  • 要換「思考模式」很多工具裡需要主動開啟 thinking / reasoning 模式,它才會慢慢想。
  • 取代之餘更貴更慢:因為要多花算力思考,速度與成本都較高。日常閒聊或簡單任務,普通模型反而更快。

主流產品地圖(2026)

不用現在全記住,先有個印象就好,下一篇會詳細比較:

廠商 代表產品 強項印象
OpenAI ChatGPT 生態完整、插件與工具多
Anthropic Claude 寫作與程式能力受好評、注重安全
Google Gemini 深度整合 Google 服務、多模態強
DeepSeek DeepSeek(中國) 高CP值、推理模型出名
Alibaba Qwen 開放權重、本地部署熱門
Meta Llama 開放權重、可自建
xAI Grok 結合 X(Twitter)即時資訊

小結

  • 生成式 AI = 會「產生新內容」的 AI,涵蓋文字、圖、影片、音訊。
  • LLM 主要處理文字;Diffusion 主要處理圖像與影片。
  • 現代 AI 建立在 Transformer 架構上,靠大模型、大資料、好訓練方法變強。
  • 推理模型是最新趨勢,擅長複雜問題,但需要主動開啟思考模式。

掌握了這些概念,你已經比大多數人懂 AI 的底層邏輯了。接下來可以依序閱讀:

  1. ChatGPT vs Claude vs Gemini vs DeepSeek 該選哪個(下一篇)
  2. Prompt Engineering:讓 AI 聽懂你
  3. RAG:讓 AI 讀你自己的文件

這是《AI 新時代》系列第 01 篇。若覺得有幫助,歡迎分享給想認識 AI 的朋友。

圖片尺寸調整工具

Godot 中使用 地形 (Terrain)

Godot 4 提供了「地形 (Terrain)」系統,用來自動處理這類圖塊之間的連接。
這能讓你在繪製地圖時,自動使用「正確」的圖塊變體,而不需要手動切換。

地形(Terrains)系統是由 地形集 (Terrain Sets)、地形 (Terrains) 和 圖塊 (Tiles) 所組成的。

  • 一個 TileSet 可以包含一個或多個 地形集 (Terrain Sets);
  • 每個 地形集(Terrain Sets) 可以包含一個或多個 地形 (Terrains);
  • 而每個 地形(Terrains) 又可以包含一個或多個 圖塊 (Tiles)。

地形圖塊(Terrain Tile)具有一個 中心位 (Center Bit) 和多個 周圍偵測位 (Peering Bits)。
每個位元 (bit) 都可以被指定為某一種地形(Terrain)。
我們通常把「某個圖塊(Tile)的中心與相鄰位被指定的地形組合」稱為它的 位元遮罩 (bitmask)。

中心位(也就是圖塊本身的地形),代表整個圖塊所屬的地形類型;
而「相鄰位(Peering Bits)」則像拼圖邊緣一樣,決定這個圖塊可以與哪些其他圖塊相鄰拼接。
圖塊的形狀以及所使用的地形模式(Terrain Mode),
會共同決定這個圖塊擁有哪些相鄰位,以及這些相鄰位的外觀與排列方式。


Godot 4 中有三種 Terrain Modes

匹配邊緣模式 (Match Sides)

  • 此模式需要圖塊(Tile)數量為: 16
  • 優點:圖塊 (Til)最容易被設定與使用,
    • 你可以用它們畫出直線straight lines),
    • 也可以畫出轉角(turns)與交叉口(intersections),
    • 或是填滿整塊矩形區域(filled-in rectangles)。
  • 限制:你無法畫出斜向的線條diagonal lines)。此外,當你繪製矩形區域(rectangles)時,無法區別「外轉角(Outside corners)」與「內轉角(Inside corners)」。對於許多圖塊(Tiles)來說,美術設計上會要求內轉角的樣子必須與外轉角不同。如果你的情況是這樣,你將無法繪製比「單一矩形」更複雜的形狀。
  • 周圍偵測位元 (Peering Bits):
    • 在 匹配邊緣模式(Match Sides)下,會使用圖塊 (Tiles)邊緣的周圍偵測位元 (Peering Bits)。
    • 這表示 正方形(Square)和等軸測(Isometric)的圖塊(Tiles)具有四個周圍偵測位元 (Peering Bits);
    • 而六邊形的圖塊(hexagonal tiles)則有六個。
    • 每個周圍偵測位元 (Peering Bits)只會對應到一個鄰近圖塊 (neighboring tile)。位於角落的鄰居則不會被影響。

角對齊模式 (Match Corners)

  • 此模式需要圖塊(Tile)數量為: 16
  • 優點:圖塊 (Tile)最容易被設定與使用,
    • 你可以用它畫出較複雜的形狀,特別適合用於繪製大面積的陸地(landscape) 或是洞穴地形(caves)
  • 限制:圖塊 (Tile)只能以 4 個為一組(2x2 方塊)進行連接。這意味著無法實現細微的細節,也無法繪製寬度僅為單個圖塊 (Tile)的線條。
    • 注意為了避免錯誤,在此模式下,請使用 Rectangle 工具來繪製,並至少保證要四個 tile 在一起,
  • 周圍偵測位元 (Peering Bits):角對齊模式 (Match Corners)在圖塊 (Tile)的頂角(Corners)上使用周圍偵測位元(Peering bits)
    • 方形(Square)和等軸測(Isometric)的圖塊(Tiles): 具有四個周圍偵測位元 (Peering Bits),且每個周圍偵測位元 (Peering Bits)處會有 3 個鄰近圖塊(Tiles)。
    • 六角形 (Hexagonal) 圖塊(Tiles): 擁有 6 個周圍偵測位元 (Peering Bits),但每個周圍偵測位元 (Peering Bits)處只有 2 個鄰近圖塊(Tiles)。

角與邊對齊 (Match Corners and Sides)

  • 此模式需要圖塊(Tile)數量為: 47
  • 優點:最全能的模式,可以做到另外兩個模式能做到的所有形狀
  • 限制:他無法建立對角線(diagonal lines)且他需要最多的圖塊(Tile)。
  • 周圍偵測位元 (Peering Bits):
    • 在此模式下,圖塊 (Tiles)的頂角 (Corners) 與 邊緣 (Edges) 同時使用周圍偵測位元 (Peering Bits)。
    • 這表示 正方形(Square)和等軸測(Isometric)的圖塊(Tiles)具有8個周圍偵測位元 (Peering Bits);
    • 而六邊形的圖塊(hexagonal tiles)擁有 12 個。
    • 在每個「邊」的部分,每個周圍偵測位元 (Peering Bits)只會對應到一個鄰近圖塊 (neighboring tile)。
    • 在「角」的部分,方形與等距圖塊有 3 個鄰居,六角形圖塊則有 2 個鄰居。所有共享同一個頂角的圖塊 (Tiles),其該角的周圍偵測位元 (Peering Bits)必須設置為相同的地形。

如何使用 Rovo Dev CLI

以下紀錄在 Mac 中如何使用 Rovo Dev CLI

首先訪問 https://developer.atlassian.com/cloud/acli/guides/install-macos/

透過 Homebrew 安裝 acli

1
2
brew tap atlassian/homebrew-acli
brew install acli

再到 https://www.atlassian.com/software/rovo-dev 註冊一個帳號
完成後到你的 Atlassian 帳戶後台,找到 https://id.atlassian.com/manage-profile/security/api-tokens 建立權杖(token),目前最多只能設定一年。

有了權杖(token) 之後,開啟終端機,輸入以下登入指令

1
acli rovodev auth login

之後會提示要輸入你的 Email 和以及剛剛產生的 API 權杖(Token)

登入成功後,我們就可以開始使用,終端機位置移動到你程式碼專案的資料夾下,並輸入

1
acli rovodev run

如果一切沒有問題,就可以看到 Rovo 啟動的畫面

1
2
3
4
5
6
7
8
9
10
11
12
╭────────────────────────────────────────────╮
│ ⬢ Rovo Dev │
╰────────────────────────────────────────────╯

Working in /Volumes/test/git/your_project

Using model: auto

╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ > █ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
Type "/" for available commands or "#" for file search. Uses AI. Verify results.

在執行的過程中,如果 Rovo 需要執行需要權限的指令 (如 mkdir) ,它都會詢問你的權限。

  • Allow (ones): 僅同意這一次。
  • Allow (session): 在這個 session 中永遠同意此操作。
  • Allow (always): 永遠允許此操作。
  • Deny (ones): 拒絕這一次。
  • Deny (session): 在這個 session 中永遠Deny此操作。
  • Deny (always): 永遠Deny此操作。

如果想更改,可以到 /Users/使用者/.rovodev/config.yml 檔案中修改

Chrome 播放影片時,顯示即時字幕

有時候英文影片沒有字幕,我們可以使用 Chrome 來播放它,並產生即時字幕。
這個功能預設是不開啟的,以下說明如何開啟。

在 Chrome 瀏覽器位置輸入 chrome://settings ,進入設定畫面,找到 無障礙設定
無障礙設定 中的 即時字幕 開啟,他會自動下載語言,你可以選擇添加自己想要的語言。

之後,將影片檔案拖入到 Chrome 中,它就會為你即時產生字幕了。

LTX-Video Test

以下紀錄使用 LTX-Video 的筆記

https://github.com/Lightricks/LTX-Video

首先要將它從 GitHub 拉下來

1
git clone https://github.com/Lightricks/LTX-Video.git

切換到他的資料夾下

1
cd LTX-Video

建立 Python 虛擬環境

1
2
3
python -m venv env
source env/bin/activate
python -m pip install -e .\[inference-script\]

前往 https://huggingface.co/Lightricks/LTX-Video 下載 Model

使用 文字生成影片

1
python inference.py --ckpt_path /Volumes/test/video/ltx-video-2b-v0.9.1.safetensors --prompt "A monkey dance" --height 768 --width 1024 --num_frames 10 --seed 2

使用 圖片生成影片

1
python inference.py --ckpt_path /Volumes/test/video/ltx-video-2b-v0.9.1.safetensors --prompt "A monkey dance" --input_image_path /Volumes/test/video/8e5352fc-70b0-41cd-9a9a-704445df7ab0.png --height 768 --width 1024 --num_frames 200 --frame_rate 20 --seed 3

Mac 使用 ComfyUI

以下紀錄在 Mac 上安裝 ComfyUI 的步驟。

注意:ComfyUI 官方現在最推薦新手使用 桌面版應用程式(Windows 與 macOS 都有),這是目前最簡單、最省心的安裝方式,內建模型管理與更新。以下的手動安裝步驟則留給想自己控制環境、或需要客製化的使用者。

  1. 安裝 Homebrew
    • /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    • https://brew.sh/zh-tw/
  2. 安裝 Python
    • brew install cmake protobuf rust python@3.13 git wget
  3. 切換到你想放 ComfyUI 的位置,再執行 git clone
  4. 切換到該資料夾的 ComfyUI 位置
    • cd ComfyUI
  5. 執行 Python
    • python3 -m venv venv
  6. 執行以下指令安裝
    • ./venv/bin/pip install torch torchvision torchaudio
    • ./venv/bin/pip install -r requirements.txt
  7. 下載模型
  8. 下載下來的檔案副檔名可能是 .ckpt.safetensors
  9. 把下載完畢的模型放到 ComfyUI 中的 /models/checkpoints 的路徑
    • /ComfyUI/models/checkpoints
  10. 啟動 ComfyUI
    • ./venv/bin/python main.py

若想與 AUTOMATIC1111 Stable Diffusion WebUI 一起使用相同的模型的話,可以找到 extra_model_paths.yaml.example 這個檔案,它應該直接在 ComfyUI 的目錄下。
將檔案複製一份,並更改檔名為 extra_model_paths.yaml
打開後會看到

1
2
a111:
base_path: path/to/stable-diffusion-webui/

把 base_path: 更改為你的 AUTOMATIC1111 Stable Diffusion WebUI 位置。

1
2
a111:
base_path: /Volumes/test/stable-diffusion-webui/

最後重新啟動 ComfyUI 就可以了。


想更新的話,再資料夾中執行 git pull,然後再執行 ./venv/bin/python main.py 即可

Spring Console Line App

以下紀錄如何使用 Spring Boot 作為 Console Line App
Spring Boot 的版本是 3.4.2

在 application.properties 中加入 spring.main.web-application-type=NONE , 告訴 Spring Boot 不啟動 Web 環境

1
spring.main.web-application-type=NONE

新增一個實作 CommandLineRunner 的類,並標記上 @Component
之後你就可以在這個類的 run() 方法中寫你的 Console Line App 邏輯並使用 Spring 的依賴注入了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Component
public class AppCommandLineRunner implements CommandLineRunner {

Logger logger = LoggerFactory.getLogger(AppCommandLineRunner.class);


@Autowired
private SomeService service;

@Override
public void run(String... args) throws Exception {

logger.info("run the app, args="+ Arrays.toString(args));

service.do();
}

}

如果你每次在執行 Console Line App 時,不想要顯示 Spring banner 的訊息的話,可以在 application.properties 中加入

1
spring.main.banner-mode=off

Java 時間

GMT(Greenwich Mean Time): GMT 是格林威治標準時間,基於地球自轉,定義為通過倫敦格林威治天文台的子午線(本初子午線)的時間。
UTC(Coordinated Universal Time):UTC 是全球協調時間,基於原子鐘的精確計時,與 GMT 基本一致。
在 Java 等程式語言中,通常使用 UTC 作為標準時間,如 Instant.now() 獲取的是 UTC 時間。

台灣的時區是 GMT+8,這表示台灣的時間比格林威治標準時間(GMT)快 8 小時
而英國的時區為 GMT+0 ,這意味著英國的時間與 GMT 相同。
而這兩個地區的時間差了 8 小時 。

如果在台灣的時間是 2025年2月19日 15:30(GMT+8),那麼同一個時間裡,在英國(GMT+0)看到的時間會是 2025年2月19日 15:30 - 8小時 = 2025年2月19日 07:30

Timestamp(時間戳) 是一個整數,代表著從 UTC 1970 年 1 月 1 日 0 時 0 分 0 秒 起至現在的總秒數。

  • 在 Java 中使用 System.currentTimeMillis() 取得 Timestamp

Java 8 以前, 使用 Date ,而 Date 有以下缺陷,不建議使用

  • 是可變的(mutable),是執行緒不安全的
  • 時區 和 Timestamp 混在一起,會因不同的電腦系統導致顯示不同時間。
  • 若要處理時區需借助 SimpleDateFormat 或其他 Library 輔助。
    • SimpleDateFormat 是執行緒不安全的
  • 日期與時間沒有分開,無法只單獨處理時間或是日期。
    • 你只想要日期的話,在 Date 物件中仍然會有時間的部分,它會顯示為 2025-02-06 00:00:00

Java 8 推出了 java.time

無時區的日期時間

LocalDate

  • LocalDate 代表日期,只儲存了年、月、日。
  • 是不可變的(immutable)
1
2
3
4
5
6
7
8
9
10
LocalDate date = LocalDate.now();
System.out.println(date1); // 2025-02-06

date = LocalDate.of(2025, 2, 6);
// 由於是不可變的,因此透過重新賦值來更改。
date = date.plusDays(5); // 增加 5 天
System.out.println(date.getYear()); // 2025
System.out.println(date.getMonth()); // FEBRUARY
System.out.println(date.getMonthValue()); // 2
System.out.println(date.getDayOfMonth()); // 11

LocalTime

  • 代表時間,只儲存時間,時、分、秒,此外,也儲存奈秒。
  • 是不可變的(immutable)
1
2
3
4
5
6
7
LocalTime time = LocalTime.now();
System.out.println(time); // 15:40:54.204743

time = time.minusSeconds(5); // 減少 5 秒
System.out.println(time.getHour()); // 15
System.out.println(time.getMinute()); // 40
System.out.println(time.getSecond()); // 49

LocalDateTime

  • 封裝了 LocalDateLocalTime 代表日期時間
  • 是不可變的(immutable)
1
2
3
4
5
6
7
8
9
10
11
LocalDateTime dateTime = LocalDateTime.now();
System.out.println(dateTime); // 2025-02-19T15:43:26.124154

dateTime = dateTime.plusDays(30);

System.out.println(dateTime.getYear()); // 2025
System.out.println(dateTime.getMonthValue()); // 3
System.out.println(dateTime.getDayOfMonth()); // 21
System.out.println(dateTime.getHour()); // 15
System.out.println(dateTime.getMinute()); // 43
System.out.println(dateTime.getSecond()); // 26

DateTimeFormatter

  • 和 SimpleDateFormat 類似,用來進行日期時間物件,與字串之間的互換,但不用處理 ParseException 這個 checked exception。
1
2
3
4
5
var formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");

LocalDateTime dateTime = LocalDateTime.parse("2025/02/06 01:02:03", formatter);
System.out.println(dateTime); // 2025-02-06T01:02:03
System.out.println(formatter.format(dateTime)); // 2025/02/06 01:02:03

有時區的日期時間

ZonedDateTime

  • 有時區的日期時間

ZoneId

  • 可以使用 ZoneId.getAvailableZoneIds() 取得支援的 key 值。
1
2
3
4
5
6
7
8
ZonedDateTime now = ZonedDateTime.now();
System.out.println("Current ZonedDateTime: " + now); // Current ZonedDateTime: 2025-02-19T15:56:36.652708+08:00[Asia/Taipei]

ZonedDateTime nowInUTC = ZonedDateTime.now(ZoneId.of("UTC"));
System.out.println("Current time in UTC: " + nowInUTC); // Current time in UTC: 2025-02-19T07:56:36.652850Z[UTC]

ZonedDateTime nowInTaipei = ZonedDateTime.now(ZoneId.of("Asia/Taipei"));
System.out.println("Current time in Taipei: " + nowInTaipei); // Current time in Taipei: 2025-02-19T15:56:36.652881+08:00[Asia/Taipei]

亦可直接使用偏移量即 UTC/GMT,來定義 ZoneId

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var dateTime = LocalDateTime.now();

// 定義東京的 ZoneId (UTC+9)
var tokyoZoneId = ZoneId.of("+0900");
var tokyoDateTime = ZonedDateTime.of(dateTime, tokyoZoneId);

// 定義倫敦的 ZoneId (UTC+0)
var londonZoneId = ZoneId.of("+0000");
var londonDateTime = tokyoDateTime.withZoneSameInstant(londonZoneId);

// 輸出東京時間
System.out.println(tokyoDateTime); // 2025-02-19T16:04:38.833229+09:00
// 輸出倫敦時間
System.out.println(londonDateTime); // 2025-02-19T07:04:38.833229Z


參考

Shader Graph 入門

以下將使用 Shader Graph 建立一個簡單的 Shader , 這個 Shader 能夠正常接收 Sprite Renderer 的 Sprite,並允許透過 Sprite Renderer 的 Color 來調整顏色。

  1. 建立 Shader Graph : 在 Unity,前往 Assets 資料夾,右鍵點擊 → Create → Shader Graph → Unlit Shader Graph。命名 為 Color Shader Graph。並雙擊打開 Shader Graph 編輯器。
  2. 在 Shader Graph 中,我們需要一個 Texture2D 屬性
    • 在左側的面板上,找到 + , 點擊 + 並選擇 Texture2D,將其命名(Name)為 MainTex。
    • 命名為 MainTex , 會發現 Reference 變為 _MainTex。這樣當這個 Shader 被應用到 Sprite Renderer 的 Material 上時,Sprite Renderer 會自動把它的 Sprite 貼圖傳遞給 _MainTex。這樣 Shader 就能正確使用 Sprite 的貼圖,而不需要手動指定 Texture。
  3. 在 Shader Graph 中,我們需要三個 Node
    • Sample Texture 2D : 把建立好的 Texture2D 屬性 (_MainTex) 輸入到這個 Sample Texture 2D 節點的 Texture 2D 。
    • Vertex Color : 這個節點會讀取 Sprite Renderer 設定的 Color 。
    • Multiply : 建立一個 後。
      • 將 Sample Texture 2D 的輸出(RGBA) 連接到 Multiply(A 輸入)
      • 將 Vertex Color 的輸出(RGBA) 連接到 Multiply(B 輸入)
  4. 最後將 Multiply 的輸出 連接到 Fragment Output 的 Base Color。
  5. 建立一個 Material , 將他的 Shader 設為在上面的 Shader Graph 。
  6. 建立一個 Sprite Renderer , 指定一個 Sprite , 並賦予剛剛建立的 Material
  7. 調整 Sprite Renderer 中的 Color 看看是否有變更顏色。
  8. 可以發現當 Sprite Renderer Color 為白色的時候,呈現的是材質本身的顏色。這就是我們為何使用相乘 (Multiply) 的原因。

為什麼需要建立一個 Vertex Color ?

  • 這是因為 Sprite Renderer 的 Color 其實是「頂點顏色(Vertex Color)」,Unity 會把它當作一個 Color 傳進 Shader。
  • 如果你的 Shader 沒有讀取 Vertex Color,那麼 Sprite Renderer 改變 Color 也不會影響最終顯示的顏色。

為什麼要用相乘 (Multiply)?

  • 因為 Sprite Renderer 的 Color 本質上是「顏色的縮放因子」,影響材質的最終顏色。
  • 所以,Shader 必須把 Texture 的顏色與 Vertex Color 相乘,這樣才能讓 Color 正確影響結果!
  • 假設:
    • Texture Color 是 (1, 1, 1, 1)(白色)
    • Vertex Color 是 (1, 0, 0, 1)(紅色)
    • 那麼,最終顏色 = 𝑇𝑒𝑥𝑡𝑢𝑟𝑒𝐶𝑜𝑙𝑜𝑟 × 𝑉𝑒𝑟𝑡𝑒𝑥𝐶𝑜𝑙𝑜𝑟 = (1,1,1,1)×(1,0,0,1)=(1,0,0,1) → 結果變成紅色!
  • 同理:
    • (0.5, 0.5, 0.5, 1) × (1, 0, 0, 1) = (0.5, 0, 0, 1) → 半透明紅色!
    • (1, 1, 1, 1) × (1, 1, 1, 1) = (1, 1, 1, 1) → 不變!
    • (1, 1, 1, 1) × (0.5, 0.5, 0.5, 1) = (0.5, 0.5, 0.5, 1) → 降低亮度!