Creative Lab Figure API
透過兩個階段將照片轉換為Q 版手辦收藏級3D手辦。原型任務會根據照片生成一張概念圖像。構建任務會將該圖像轉換為帶材質貼圖的3D模型,並將原型任務的ID作為 input_task_id 傳入。
POST /openapi/creative-lab/figure/v1/prototypePOST /openapi/creative-lab/figure/v1/build
建立 Figure prototype 任務
根據一張照片生成一張 Q 版風格的概念圖。要建構 3D 模型,請將此任務的 ID 作為 input_task_id 傳遞給 build endpoint。有關該任務欄位的說明,請參閱 The Figure prototype task object。
Request
# Stage 1: generate a chibi-style concept image
curl https://api.meshy.ai/openapi/creative-lab/figure/v1/prototype \
-X POST \
-H "Authorization: Bearer ${YOUR_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{
"image_url": "<your publicly accessible image url or base64-encoded data URI>"
}'
Response
{
"result": "018a210d-8ba4-705c-b111-1f1776f7f578"
}


參數
- Name
- image_url
- Type
- string
- 必選
- Description
要轉換為 Q 版手辦的照片,可以是公開可存取的 URL 或 Data URI(
data:image/jpeg;base64,<your base64-encoded image data>)。圖片必須是 JPG、JPEG、PNG 或 WebP 檔案,且最大不超過 20 MB。
- Name
- name
- Type
- string
- Description
任務的名稱,最多 100 個字元。它會在任務的
name欄位中回傳。名稱過長會回傳400。
- Name
- remove_background
- Type
- boolean
- 預設值 false
- Description
是否從 prototype 圖片中移除背景。
true會回傳一張透明的 RGBA PNG,這樣你可以將主體放置在任意背景上。建構過程也會從去除背景後的圖片開始。如果 Meshy 無法移除背景,它會回傳帶有背景的圖片,任務仍然會成功。
回傳值
result 欄位保存新 prototype 任務的 ID。取得該任務或對其進行串流取得,直到 status 為 SUCCEEDED。然後將該 ID 作為 input_task_id 傳遞給 build endpoint。
失敗情形
- Name
400 - Bad Request- Description
請求無法執行。例如:
- 缺少
image_url。 - 圖片不是 JPG、JPEG、PNG 或 WebP 檔案。
- 圖片過小、超過 20 MB,或超過最大像素數。
- Meshy 無法下載該圖片,例如因為該 URL 回傳
404或請求逾時。 - Data URI 不是有效的 base64 編碼。
- 該圖片被標記為 NSFW。
錯誤訊息會說明具體發現了哪個問題。修正請求後重新發送。
- 缺少
- Name
401 - Unauthorized- Description
API 金鑰缺失或無效。請檢查
Authorization請求標頭。
- Name
402 - Payment Required- Description
以下情形之一適用:
- 帳戶的積分不足。
- API 金鑰、工作區或成員已達到其積分限額。
- 該帳戶使用的是免費方案。
請檢查你的積分和方案,然後重試。
- Name
403 - Forbidden- Description
你的團隊開啟了 IP Filtering,Meshy 將該圖片標記為涉及第三方智慧財產權。請發送你擁有使用權的圖片。
- Name
429 - Too Many Requests- Description
達到了以下限制之一:
- 你發送的請求超過了速率限制所允許的數量。請等待幾秒鐘後重試。參見 Rate limits。
- 你排隊或正在執行的任務過多。請等待部分任務完成後重試。
- 在沒有積分的無限方案下,你已達到可在無積分情況下執行的任務數量上限。請等待某個任務完成,或新增積分。
- Name
500 - Internal Server Error- Description
Meshy 遇到了伺服器錯誤,例如無法對該圖片執行智慧財產權檢查。Meshy 不會建立該任務,並會退還已扣除的所有積分。請重試該請求。
建立 Figure 構建任務
從一個成功的原型任務產生帶貼圖的 3D figure。有關其欄位,請參閱 Figure 構建任務物件。
Request
# Stage 2: chain build off a succeeded prototype task
curl https://api.meshy.ai/openapi/creative-lab/figure/v1/build \
-X POST \
-H "Authorization: Bearer ${YOUR_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{
"input_task_id": "018a210d-8ba4-705c-b111-1f1776f7f578"
}'
Response
{
"result": "019c320e-9a8f-7a1c-9c11-2a1876f8a9bb"
}

參數
- Name
- input_task_id
- Type
- string
- 必選
- Description
要構建的原型任務的 ID。它必須是你的帳戶透過
POST /openapi/creative-lab/figure/v1/prototype建立的任務,且狀態為SUCCEEDED。如果該 ID 不是你透過 API 建立的 Figure 原型任務之一,將回傳
404,這也包括在網頁應用程式中製作的原型。
- Name
- name
- Type
- string
- Description
任務的名稱,最多 100 個字元。它會出現在任務的
name欄位中。名稱過長會回傳400。
回傳值
result 欄位保存新構建任務的 ID。取得該任務或以串流方式取得它,直到 status 變為 SUCCEEDED。然後從 model_urls.glb 下載帶貼圖的 GLB。如果想改為下載 OBJ,請從 model_urls.obj 下載,並從 model_urls.mtl 下載其材質檔案。
失敗模式
- Name
400 - Bad Request- Description
請求無法執行。例如:
input_task_id缺失或不是有效的任務 ID。- 原型任務的狀態不是
SUCCEEDED。如果它仍在執行中,請等待後重試。如果它已失敗或被取消,請建立一個新的原型任務。 - 原型任務已成功,但沒有圖片。請建立一個新的原型任務。
錯誤訊息會說明發現的具體問題。
- Name
401 - Unauthorized- Description
API 金鑰缺失或無效。請檢查
Authorization請求標頭。
- Name
402 - Payment Required- Description
以下情況之一適用:
- 帳戶沒有足夠的積分。
- API 金鑰、工作區或成員已達到其積分上限。
- 帳戶處於免費方案。
請檢查你的積分和方案,然後重試。
- Name
404 - Not Found- Description
input_task_id與你的帳戶透過 API 建立的任何 Figure 原型任務都不相符。在網頁應用程式中製作的原型也會回傳404。請傳送原型建立回應中的resultID。
- Name
429 - Too Many Requests- Description
達到了以下限制之一:
- 你傳送的請求超過了速率限制允許的數量。請等待幾秒後重試。參見速率限制。
- 你排隊或正在執行的任務過多。請等待部分任務完成後重試。
- 在無限制方案下且沒有剩餘積分時,你已達到可在沒有積分的情況下執行的任務數量上限。請等待某個任務完成,或加值積分。
取得 Figure 任務
返回一個原型(prototype)或構建(build)任務。路徑必須與任務所處的階段相符。透過 /prototype/:id 請求一個構建任務會返回 404,同樣,透過 /build/:id 請求一個原型任務也會返回 404。
有關欄位說明,請參閱 Figure 原型任務物件 和 Figure 構建任務物件。
Request
# Prototype
curl https://api.meshy.ai/openapi/creative-lab/figure/v1/prototype/018a210d-8ba4-705c-b111-1f1776f7f578 \
-H "Authorization: Bearer ${YOUR_API_KEY}"
# Build
curl https://api.meshy.ai/openapi/creative-lab/figure/v1/build/019c320e-9a8f-7a1c-9c11-2a1876f8a9bb \
-H "Authorization: Bearer ${YOUR_API_KEY}"
Prototype Response
{
"id": "018a210d-8ba4-705c-b111-1f1776f7f578",
"type": "creative-lab-figure-prototype",
"name": "",
"status": "SUCCEEDED",
"progress": 100,
"created_at": 1729123456000,
"started_at": 1729123460000,
"finished_at": 1729123486000,
"expires_at": 1729382686000,
"preceding_tasks": 0,
"task_error": null,
"consumed_credits": 6,
"image_urls": [
"https://assets.meshy.ai/***/concept.png?Expires=***"
]
}
Build Response
{
"id": "019c320e-9a8f-7a1c-9c11-2a1876f8a9bb",
"type": "creative-lab-figure-build",
"name": "",
"status": "SUCCEEDED",
"progress": 100,
"created_at": 1729123500000,
"started_at": 1729123510000,
"finished_at": 1729123535000,
"expires_at": 1729382735000,
"preceding_tasks": 0,
"task_error": null,
"consumed_credits": 30,
"prompt": "",
"negative_prompt": "",
"texture_prompt": "",
"texture_image_url": "",
"model_urls": {
"glb": "https://assets.meshy.ai/***/tasks/019c320e-9a8f-7a1c-9c11-2a1876f8a9bb/output/model.glb?Expires=***",
"obj": "https://assets.meshy.ai/***/tasks/019c320e-9a8f-7a1c-9c11-2a1876f8a9bb/output/model.obj?Expires=***",
"mtl": "https://assets.meshy.ai/***/tasks/019c320e-9a8f-7a1c-9c11-2a1876f8a9bb/output/model.mtl?Expires=***"
},
"thumbnail_url": "https://assets.meshy.ai/***/tasks/019c320e-9a8f-7a1c-9c11-2a1876f8a9bb/output/preview.png?Expires=***",
"texture_urls": [
{
"base_color": "https://assets.meshy.ai/***/tasks/019c320e-9a8f-7a1c-9c11-2a1876f8a9bb/output/texture_0.png?Expires=***"
}
],
"remove_lighting": true
}
參數
- Name
- id
- Type
- path
- Description
建立回應中返回的任務 ID。
返回值
失敗模式
- Name
400 - Bad Request- Description
id不是有效的任務 ID。請傳送建立回應中返回的resultID。
- Name
403 - Forbidden- Description
你的團隊已開啟 IP Filtering(IP 過濾) 功能,且 Meshy 將該任務的圖片標記為涉及第三方智慧財產權。Enterprise 方案的團隊不會出現此錯誤。請使用你擁有合法使用權的圖片來建立原型任務。
- Name
404 - Not Found- Description
你的帳戶下沒有與此 ID 對應的 Figure 任務,或者該任務所處的階段與路徑不符。請檢查 ID,並使用
/prototype或/build來對應該任務。
- Name
500 - Internal Server Error- Description
Meshy 無法執行智慧財產權檢查。請重試該請求。
刪除 Q 版手辦任務
取消一個 Q 版手辦任務。取消 PENDING 狀態的任務會退還其積分。IN_PROGRESS 狀態的任務會被取消但不退款,因為已經有工作節點開始處理該任務。處於最終狀態(SUCCEEDED、FAILED 或 CANCELED)的任務無法取消。
路徑必須與任務所處的階段匹配。例如,對一個 build 任務的 ID 使用 /prototype/:id 路徑執行 DELETE 會返回 404。
Request
curl --request DELETE \
--url https://api.meshy.ai/openapi/creative-lab/figure/v1/prototype/018a210d-8ba4-705c-b111-1f1776f7f578 \
-H "Authorization: Bearer ${YOUR_API_KEY}"
Response
// Returns 204 No Content on success (empty body).
路徑參數
- Name
- id
- Type
- path
- Description
要取消的任務的 ID。
返回值
204 No Content,回應內容為空。
失敗情況
- Name
400 - Bad Request- Description
以下情況之一:
id不是有效的任務 ID。請傳送建立回應中的resultID。- 任務已處於最終狀態(
SUCCEEDED、FAILED或CANCELED),因此無法取消。
- Name
404 - Not Found- Description
沒有屬於你帳戶的、具有此 ID 的 Q 版手辦任務,或者該任務所處的階段與路徑不匹配。請檢查 ID,並使用
/prototype或/build以符合對應任務。
流式取得 Q 版手辦任務
以伺服器發送事件(SSE)的形式串流傳輸 Q 版手辦任務的更新。路徑必須與任務所處的階段相符。如果不相符,例如將 build 任務的 ID 用於 /prototype/:id/stream,該串流會發送一條 status_code: 404 的 error 事件,然後關閉連線。
Request
curl -N https://api.meshy.ai/openapi/creative-lab/figure/v1/build/019c320e-9a8f-7a1c-9c11-2a1876f8a9bb/stream \
-H "Authorization: Bearer ${YOUR_API_KEY}"
Response Stream
// Error event example (wrong stage or task not found)
event: error
data: {
"status_code": 404,
"message": "Task not found"
}
// Message event examples illustrate task progress.
// Every frame is the full task object; fields not yet populated are null / empty.
// The following PENDING frame is shortened to the fields that change.
event: message
data: {
"id": "019c320e-9a8f-7a1c-9c11-2a1876f8a9bb",
"progress": 0,
"status": "PENDING"
}
event: message
data: {
"id": "019c320e-9a8f-7a1c-9c11-2a1876f8a9bb",
"type": "creative-lab-figure-build",
"status": "SUCCEEDED",
"progress": 100,
"created_at": 1729123500000,
"started_at": 1729123510000,
"finished_at": 1729123535000,
"expires_at": 1729382735000,
"task_error": null,
"consumed_credits": 30,
"prompt": "",
"negative_prompt": "",
"texture_prompt": "",
"texture_image_url": "",
"model_urls": {
"glb": "https://assets.meshy.ai/***/tasks/019c320e-9a8f-7a1c-9c11-2a1876f8a9bb/output/model.glb?Expires=***",
"obj": "https://assets.meshy.ai/***/tasks/019c320e-9a8f-7a1c-9c11-2a1876f8a9bb/output/model.obj?Expires=***",
"mtl": "https://assets.meshy.ai/***/tasks/019c320e-9a8f-7a1c-9c11-2a1876f8a9bb/output/model.mtl?Expires=***"
},
"thumbnail_url": "https://assets.meshy.ai/***/tasks/019c320e-9a8f-7a1c-9c11-2a1876f8a9bb/output/preview.png?Expires=***",
"texture_urls": [
{
"base_color": "https://assets.meshy.ai/***/tasks/019c320e-9a8f-7a1c-9c11-2a1876f8a9bb/output/texture_0.png?Expires=***"
}
],
"remove_lighting": true
}
參數
- Name
- id
- Type
- path
- Description
建立回應中回傳的任務 ID。
回傳值
一個由 prototype 或 build 任務物件組成的串流。每個事件都包含完整的任務物件,與 取得 Q 版手辦任務 回傳的結構相同。當任務處於 PENDING 或 IN_PROGRESS 狀態時,其輸出欄位仍為空(null、[] 或 {}),且 finished_at 為 null。
如果 IP 過濾 攔截了任務結果,串流會在原本應回傳結果的位置發送一條 error 事件,其中包含該次 get 請求本應回傳的 status_code。
取得 Q 版手辦任務清單
回傳某一階段的 Q 版手辦任務,每次回傳一頁。路徑決定了階段:/prototype 僅回傳 prototype 任務,/build 僅回傳 build 任務。
Request
# List prototype tasks
curl https://api.meshy.ai/openapi/creative-lab/figure/v1/prototype?page_size=10 \
-H "Authorization: Bearer ${YOUR_API_KEY}"
# List build tasks
curl https://api.meshy.ai/openapi/creative-lab/figure/v1/build?page_size=10 \
-H "Authorization: Bearer ${YOUR_API_KEY}"
Response (List Prototype Tasks)
[
{
"id": "018a210d-8ba4-705c-b111-1f1776f7f578",
"type": "creative-lab-figure-prototype",
"name": "",
"status": "SUCCEEDED",
"progress": 100,
"created_at": 1729123456000,
"started_at": 1729123460000,
"finished_at": 1729123486000,
"expires_at": 1729382686000,
"preceding_tasks": 0,
"task_error": null,
"consumed_credits": 6,
"image_urls": [
"https://assets.meshy.ai/***/concept.png?Expires=***"
]
}
]
路徑參數
- Name
- stage
- Type
- path
- 必選
- Description
要列出的階段,
prototype或build。
查詢參數
- Name
- page_num
- Type
- integer
- 預設值 1
- Description
要回傳的頁碼,取值範圍為
1到255。0回傳第一頁。超出0到255範圍的值將回傳400。
- Name
- page_size
- Type
- integer
- 預設值 10
- Description
每頁的任務數量,最多
100。取值在101到255之間時將回傳 100 個任務,0則使用預設值。超出0到255範圍的值將回傳400。
- Name
- sort_by
- Type
- string
- 預設值 -created_at
- Description
排序方式。
可選值:
-created_at:最新的排在最前+created_at:最早的排在最前
回傳值
一個陣列,包含與路徑中階段相對應的 prototype 任務物件 或 build 任務物件。
Q 版手辦原型任務物件
Prototype 任務根據一張照片生成 Q 版風格的概念圖。要將該圖片轉換為 3D 模型,請將該任務的 ID 作為 input_task_id 傳遞給建置端點。
Properties
Example Figure Prototype Task Object
{
"id": "018a210d-8ba4-705c-b111-1f1776f7f578",
"type": "creative-lab-figure-prototype",
"name": "",
"status": "SUCCEEDED",
"progress": 100,
"created_at": 1729123456000,
"started_at": 1729123460000,
"finished_at": 1729123486000,
"expires_at": 1729382686000,
"preceding_tasks": 0,
"task_error": null,
"consumed_credits": 6,
"image_urls": [
"https://assets.meshy.ai/***/concept.png?Expires=***"
]
}
- Name
- id
- Type
- string
- Description
任務 ID。不要依賴其具體格式。
- Name
- type
- Type
- string
- Description
任務類型,始終為
creative-lab-figure-prototype。
- Name
- name
- Type
- string
- Description
你在建立任務時傳送的
name,如果你沒有傳送,則為""。
- Name
- status
- Type
- string
- Description
任務的狀態。
可選值:
PENDING:在佇列中等待IN_PROGRESS:正在生成結果SUCCEEDED:最終狀態,已取得結果FAILED:最終狀態,失敗原因見task_errorCANCELED:最終狀態,沒有結果
- Name
- progress
- Type
- integer
- Description
已完成工作的百分比,數值從
0到100。任務開始前為0,成功後為100。
- Name
- created_at
- Type
- timestamp
- Description
任務建立的時間,單位為 Unix 毫秒。
- Name
- started_at
- Type
- timestamp
- Description
工作程序開始處理該任務的時間,單位為 Unix 毫秒。在此之前為
null。
- Name
- finished_at
- Type
- timestamp
- Description
任務到達最終狀態的時間,單位為 Unix 毫秒。在此之前為
null。
- Name
- expires_at
- Type
- timestamp
- Description
任務結果的過期時間,單位為 Unix 毫秒。該時間為
finished_at之後 3 天,在任務完成之前則為created_at之後 3 天。對於可無限期保留 API 結果的企業帳戶,該時間約為 100 年後。請參閱資產保留期。
- Name
- preceding_tasks
- Type
- integer
- Description
任務處於
PENDING狀態時在佇列中的位置。1表示該任務是下一個要開始的任務。任務離開佇列後為0,在列表結果中則始終為0。
- Name
- task_error
- Type
- object
- Description
任務失敗的原因。除非
status為FAILED,否則為null。請參閱 錯誤。
- Name
- consumed_credits
- Type
- integer
- Description
該任務在扣除任何退款後所扣的積分數量。回傳錯誤的請求不會被扣費。失敗的任務為
0,因為 Meshy 會對其退款。只有在任務處於PENDING狀態時取消,才會退還積分。如果 Meshy 無法讀取扣費資訊,get 或 stream 回應會省略該欄位,而 list 請求會回傳500。在這種情況下,請重試該請求。
- Name
- image_urls
- Type
- array of strings
- Description
概念圖的下載 URL。任務成功後,該陣列包含一個 URL;在此之前為空。
Q 版手辦構建任務物件
構建任務會根據一個成功的原型任務生成一個帶紋理的 3D Q 版手辦。其 model_urls、thumbnail_url 和 texture_urls 欄位的格式與 影象生成 3D 任務物件 中的相同。
屬性
Example Figure Build Task Object
{
"id": "019c320e-9a8f-7a1c-9c11-2a1876f8a9bb",
"type": "creative-lab-figure-build",
"name": "",
"status": "SUCCEEDED",
"progress": 100,
"created_at": 1729123500000,
"started_at": 1729123510000,
"finished_at": 1729123535000,
"expires_at": 1729382735000,
"preceding_tasks": 0,
"task_error": null,
"consumed_credits": 30,
"prompt": "",
"negative_prompt": "",
"texture_prompt": "",
"texture_image_url": "",
"model_urls": {
"glb": "https://assets.meshy.ai/***/tasks/019c320e-9a8f-7a1c-9c11-2a1876f8a9bb/output/model.glb?Expires=***",
"obj": "https://assets.meshy.ai/***/tasks/019c320e-9a8f-7a1c-9c11-2a1876f8a9bb/output/model.obj?Expires=***",
"mtl": "https://assets.meshy.ai/***/tasks/019c320e-9a8f-7a1c-9c11-2a1876f8a9bb/output/model.mtl?Expires=***"
},
"thumbnail_url": "https://assets.meshy.ai/***/tasks/019c320e-9a8f-7a1c-9c11-2a1876f8a9bb/output/preview.png?Expires=***",
"texture_urls": [
{
"base_color": "https://assets.meshy.ai/***/tasks/019c320e-9a8f-7a1c-9c11-2a1876f8a9bb/output/texture_0.png?Expires=***"
}
],
"remove_lighting": true
}
- Name
- id
- Type
- string
- Description
任務 ID。不要依賴其格式。
- Name
- type
- Type
- string
- Description
任務類型,固定為
creative-lab-figure-build。
- Name
- name
- Type
- string
- Description
你在建立任務時傳送的
name;如果沒有傳送,則為""。
- Name
- status
- Type
- string
- Description
任務的狀態。
可用值:
PENDING:在佇列中等待IN_PROGRESS:正在生成結果SUCCEEDED:最終狀態,附帶結果FAILED:最終狀態,原因見task_errorCANCELED:最終狀態,沒有結果
- Name
- progress
- Type
- integer
- Description
已完成工作的百分比,從
0到100。任務開始前為0,成功時為100。
- Name
- created_at
- Type
- timestamp
- Description
任務建立的時間,以 Unix 毫秒表示。
- Name
- started_at
- Type
- timestamp
- Description
工作程序開始執行任務的時間,以 Unix 毫秒表示。在此之前為
null。
- Name
- finished_at
- Type
- timestamp
- Description
任務達到最終狀態的時間,以 Unix 毫秒表示。在此之前為
null。
- Name
- expires_at
- Type
- timestamp
- Description
任務結果過期的時間,以 Unix 毫秒表示。該時間為
finished_at之後 3 天;在任務完成之前,則為created_at之後 3 天。對於可無限期保留 API 結果的 Enterprise 帳戶,這個時間大約是 100 年後。參見資產保留期。
- Name
- preceding_tasks
- Type
- integer
- Description
任務處於
PENDING狀態時在佇列中的位置。1表示它將是下一個開始的任務。任務離開佇列後為0,並且在列表結果中始終為0。
- Name
- task_error
- Type
- object
- Description
任務失敗的原因。除非
status為FAILED,否則為null。參見 錯誤。
- Name
- consumed_credits
- Type
- integer
- Description
任務扣除的積分數(已扣除任何退款後的數值)。回傳錯誤的請求不會被扣費。失敗的任務為
0,因為 Meshy 會退還積分。只有在任務處於PENDING狀態時取消才會退還積分。如果 Meshy 無法讀取扣費資訊,get 或 stream 回應會省略該欄位,而 list 請求會回傳500。在這種情況下,請重試該請求。
- Name
- prompt
- Type
- string
- Description
對於 Q 版手辦構建任務,始終為
""。
- Name
- negative_prompt
- Type
- string
- Description
與
prompt一樣,對於 Q 版手辦構建任務始終為""。
- Name
- texture_prompt
- Type
- string
- Description
與
prompt一樣,對於 Q 版手辦構建任務始終為""。
- Name
- texture_image_url
- Type
- string
- Description
與
prompt一樣,對於 Q 版手辦構建任務始終為""。
- Name
- model_urls
- Type
- object
- Description
3D 模型的下載連結,包括帶紋理的 GLB 檔案,以及帶有其 MTL 檔案的 OBJ 檔案。
- Name
glb- Type
- string
- Description
帶紋理的 GLB 檔案的下載連結。
- Name
obj- Type
- string
- Description
OBJ 檔案的下載連結,包含幾何體和 UV。
- Name
mtl- Type
- string
- Description
與
obj配套的 MTL 材質檔案的下載連結。請將其與obj以及texture_urls[0].base_color中的紋理一起使用。
- Name
- thumbnail_url
- Type
- string
- Description
模型預覽圖像的下載連結。
- Name
- texture_urls
- Type
- array
- Description
紋理貼圖,是一個包含一個物件的陣列,該物件存放基礎色彩貼圖。
- Name
base_color- Type
- string
- Description
基礎色彩貼圖的下載連結。
- Name
- remove_lighting
- Type
- boolean
- Description
Meshy 是否已從基礎色彩紋理中移除高光和陰影。