(文章)

招牌預覽系統的做法:標誌上傳、照片對位與 3D 展示間

SVG 標誌在瀏覽器內轉成立體字,掛上示範建築或店面照片;照片不傳伺服器,首頁用 KTX2 貼圖與預編譯控制載入。

磨人開發團隊・2026-08-12

目錄

淇豪廣告的官網讓客戶在付款前先看到招牌成品。客戶上傳 SVG 標誌,系統在瀏覽器內轉成發光立體字,掛到四棟示範建築的立面上;也可以上傳一張店面照片,把招牌放在自己的門面上對位。展示間與首頁的城市都是 React Three Fiber 的 WebGL 場景,標誌與照片都留在客戶的瀏覽器內。

3D 的載入與記憶體另有Web 3D 效能工程的完整流程,本文只帶一段;整體建置範圍見3D 互動網站開發。

桌機螢幕錄影:更換標誌與樣式、切換示範建築、以滑桿微調位置與大小,再切到照片模擬。

展示間:SVG 轉成立體字與發光材質

展示間有四棟示範建築,模型檔各在 140 KB 以內。每棟建築有自己的招牌位置、旋轉與縮放設定,其中一棟在中央招牌之外另有側面與頂部兩組,可分別更換標誌。客戶上傳的 SVG 先經 DOMParser 檢查,根節點是 svg 且至少含一個圖形節點,才送進場景。

轉換用 three.js 的 SVGLoader 解析路徑,每個形狀以 ExtrudeGeometry 擠出成立體字,曲線分 6 段。座標以最長邊 10 個單位正規化並置中,任何長寬比的標誌進場時大小一致,之後由大小與厚度滑桿調整。多色標誌預設沿用檔案內各路徑的填色,也可以改成單一自訂顏色;顏色選擇器附 14 個常用招牌色、色碼欄位與系統色票。

發光靠材質的自發光:填色面使用 MeshStandardMaterial,emissive 取與填色相同的顏色,亮度由 emissiveIntensity 控制,烤漆樣式則把自發光設為 0。照片模擬的預設金屬度為 0.3、粗糙度為 0.4。畫面最後經過 Bloom 後製,亮度門檻在照片模擬為 1.0、示範建築為 1.22,亮度超過門檻的像素才會產生光暈。

包邊沿著 SVG 路徑的每一段線段放一個長方體,以 InstancedMesh 合併成一次繪製呼叫,樣式分不包邊、突出與齊平。背發光在照片模擬中先把標誌輪廓畫成貼圖,再用自訂的模糊著色器(16 個方向、4 圈取樣)畫在字後方的平面上,以加法混色疊出外溢的光;示範建築改在字後方放一份擠出的副本,同樣加法混色。

展示間的招牌立面,樣式面板已展開。
展示間的招牌立面,樣式面板已展開。

樣式有正發光、背發光、正背發光、烤漆立體字與廣告燈箱五種,在面板上一鍵切換;廣告燈箱用於其中兩棟示範建築。

讓客戶自己動手,有研究支持這個方向。Franke 等,2010的論文摘要指出,自行設計的產品,支付意願明顯較高;這個差距無法由偏好更吻合或花了更多力氣解釋,效果透過完成感產生。研究對象為大量客製化商品,未涉及招牌,這裡只取方向。

同一套畫面可直接用於提案。按下「展示」,底部選單與頂部導覽列收起,並以 visibility 隱藏,鍵盤 Tab 不會停在看不見的控制項上。示範建築的鏡頭隨後以正弦曲線左右擺動,振幅依建築為 72 度或 45 度,週期約 52 秒;系統設為減少動態效果時,鏡頭不自動擺動。

一人盤腿坐著,膝上放著打開的筆記型電腦,低頭看著螢幕。

首次進入展示間,約 2.6 秒後出現七步驟導覽,每一步附實際操作畫面;Esc 關閉,左右方向鍵翻頁,焦點限制在對話框內,右上角的「如何使用」可隨時重看。上傳視窗有同樣的焦點管理,關閉後焦點回到原本的按鈕。

首次進入展示間,導覽逐步說明各項操作。

照片模擬:把招牌對位到客戶的店面

照片模擬把店面照片當成一張鋪滿視窗的背景平面,招牌是放在背景前方的立體物件,兩者在同一個 WebGL 場景裡合成。背景平面依照片長寬比做 cover 填滿,使用不受打光影響的材質,渲染順序固定在最底層;招牌受場景打光與 Bloom 影響,滑過時以 Outline 後製畫出白色外框,點選後出現拖曳控制軸。

內建九張店面場景,日景與夜景皆有,每張帶一組預設的位置、大小與旋轉角,斜拍的立面另帶上下與左右的傾角。切換背景時,照片以 0.35 秒淡出、0.45 秒淡入,淡出結束、換上新照片的同時套用該場景的預設值。位置範圍取視窗寬高的四分之一,超出時自動拉回;拖曳時位置與旋轉每次移動只更新一次,滑桿的旋轉範圍為上下、左右、深度三軸各正負 90 度。

上傳照片時,瀏覽器以 URL.createObjectURL 讀入檔案,在 canvas 上縮到最長邊 2000 px,再以 JPEG 品質 0.85 輸出成貼圖來源,上傳視窗接受 JPEG 與 PNG。手機直出的 4000 x 3000 照片縮成 2000 x 1500 後,解壓後的貼圖由約 48 MB 降到約 12 MB(寬、高與每像素 4 位元組相乘,未計 mipmap)。照片只在瀏覽器內處理,不會傳到伺服器。

圖 1標誌與店面照片只在瀏覽器內處理,伺服器只供應靜態檔案

使用者瀏覽器

  • 讀入 SVG 與照片FileReader、canvas 縮圖
  • 轉成立體字並合成WebGL 場景與 Bloom 後製
模型、貼圖、解碼器

開發團隊的伺服器

  • 靜態檔案建築模型、KTX2 貼圖、解碼器、環境光貼圖

不送出去客戶上傳的 SVG 標誌與店面照片

淇豪廣告官網展示間與照片模擬的資料流。

手機螢幕錄影:切換標誌範本與樣式,並以滑桿調整位置與旋轉。

手機上同樣可以操作。操作面板高度上限 260 px,內容超出時在面板內捲動,下緣保留系統安全區域;畫布高度用 svh 單位,單指平移、雙指縮放。

3D 城市首頁:載入順序與鏡頭控制

首頁是一座可拖曳、可縮放的 3D 城市,六個熱點分別連到諮詢、案例、關於、服務、展示間與 ESG 頁面。整個 3D 場景以 next/dynamic 延後載入並關閉伺服器端渲染,three、drei 與城市模型不進入首屏的初始載入,下方文字內容的水合與首次繪製不受影響。

手機版首頁,3D 城市載入完成。
手機版首頁,3D 城市載入完成。

鏡頭控制器為自行撰寫,取代 drei 內建的 CameraControls。縮放沿視線移動,距離限制在 10 到 30 個單位,平移限制在正負 12 個單位,輸入以指數平滑處理,與畫面更新率無關。滾輪只在按住 Ctrl 或 Command 時縮放,一般捲動留給頁面;畫布設為 touch-action: pan-y,手機上垂直滑動仍可捲頁,水平拖曳與雙指縮放才交給 3D。相機距離縮到 25 個單位以內時,熱點標籤才出現。

進場流程依序是:

  1. Preload 先把場景內的材質編譯完成,並把貼圖上傳到 GPU。
  2. gl.compileAsync 在背景編譯全部 shader,完成後才標記場景就緒,最多等待 3 秒。
  3. 場景就緒後,EffectComposer 的模糊 pass 在 1.2 秒內由模糊轉為清晰,結束時整個 pass 卸載,沒有常駐的全螢幕後製。
  4. 模糊結束時,導覽列與標語淡入,鏡頭同時沿視線拉近 1.5 秒。

MDN 的 WebGL 建議也把著色器先全部編譯再連結列為做法,並可用 KHR_parallel_shader_compile 避免阻塞。渲染的 dpr 上限為 1.5;首屏捲出視窗後,frameloop 由 IntersectionObserver 切為 never,城市停止繪製。

貼圖與幾何:KTX2、Draco 與自架解碼器

城市場景有 34 個網格與 25 段循環播放的動畫,幾何以 Draco 壓縮,GLB 檔約 2.7 MB;Khronos 的 Draco 擴充規格定義了這種壓縮在 glTF 中的寫法。所有網格共用九個 MeshBasicMaterial,不做即時打光,離開首頁時逐一 dispose。

貼圖原本是八張 4K,降為 2K 後改用 KTX2(ETC1S),貼圖在 GPU 記憶體中維持壓縮格式,估算由約 681 MB 降到約 30 MB。KHR_texture_basisu 規格說明,KTX2 容器搭配 Basis Universal 超壓縮的貼圖,引擎要轉碼成平台支援的區塊壓縮格式;規格只描述轉碼機制,沒有給節省數字,約 30 MB 是這個場景的估算值。

Draco 與 Basis 的解碼器,以及展示間使用的六組環境光貼圖,都放在自己的主機。環境光的 preset 若沒有對應的本地檔,就不掛載環境貼圖,不會轉向第三方網址取用。前後對照與核算方式見3D 模型優化前後對照表,手機能放進多少見手機 3D 的記憶體預算。

載入失敗時的處理

掛上 3D 之前先探測 WebGL:依序嘗試 webgl2 與 webgl,並確認 context 沒有處於遺失狀態;拿不到就直接換成靜態封面,同時把導覽列顯示出來。探測只在掛載後執行,第一次渲染一律視為可用,與伺服器輸出一致,避免 hydration 不符。場景渲染期間拋出的例外另由錯誤邊界接住,同樣退回靜態封面。封面由品牌標誌、一句主張與備註組成,首屏以下的內容不受影響。

展示間的載入進度層以 drei 的 useProgress 顯示百分比。資源都在快取時,約 1.5 秒的寬限後自動收起;載入出錯時立即收起,另設 20 秒的上限。離開展示間時,該場景專屬的 GLB 與貼圖從快取釋放,共用的環境光貼圖保留給下一個展示間。

圖 2WebGL 不可用或場景渲染出錯時,首頁顯示靜態封面,下方內容照常讀取
  1. 進入首頁掛載後探測 webgl2 與 webgl,並確認 context 未遺失
  2. 載入城市場景貼圖上傳與 shader 預編譯,最多等待 3 秒
  • 場景就緒
    介面進場,城市可拖曳縮放
  • WebGL 不可用,或渲染期間拋出例外
    顯示靜態封面並顯示導覽列首屏以下的內容照常讀取

淇豪廣告首頁 3D 城市的載入流程。

從預覽到諮詢:業務提案與表單

展示間在首頁就能走到。客戶自己換標誌、對到店面,看到成品後再進入詢問;業務在會議上打開同一個畫面即可說明。

圖 3客戶從 3D 城市走到諮詢表單,業務可用展示間的畫面提案
看見
動手換
對到店面
詢問
客戶
業務
1
客戶拖曳、縮放 3D 城市六個熱點連到展示間與諮詢
2
客戶上傳 SVG 標誌,換樣式四棟示範建築任選
3
客戶上傳店面照片,拖曳對位照片只在瀏覽器內處理
4
客戶送出諮詢表單先問需求項目與預算區間
5
業務按「展示」,控制項收起示範建築的鏡頭自動擺動,筆電上直接提案

淇豪廣告官網的使用路徑。

每篇案例頁末嵌有諮詢表單,先問清楚需求項目與預算區間。

案例頁末的諮詢表單,先問需求項目與預算區間。
案例頁末的諮詢表單,先問需求項目與預算區間。

官網現有繁中、英、日、馬來四種語言。展示間的內容在 canvas 裡,頁面另有只供爬蟲與讀屏軟體讀取的 H1 與說明段落,並輸出 CollectionPage 與 BreadcrumbList 結構化資料;案例輸出 FAQ 結構化資料與 llms.txt。Google 的 JavaScript SEO 文件說明,渲染後看得到的內容才會被索引,渲染在資源允許時才執行,也不是所有機器人都會執行 JavaScript,因此建議伺服器端渲染或預先渲染。完整做法見3D 網站的搜尋與 AI 爬蟲可讀性。

適用的產品類型

同樣做法適用於成品完成後客戶才看得到的產業:招牌、建材、門窗帷幕、室內裝修、展場與燈具。共通條件是訂製,客戶付款時成品還不存在。訂製型服務的另一種做法見婚宴外燴的線上提案。

不適合的情況

  • 標準品。型號與外觀固定,客戶看型錄就能決定。
  • 決定主要取決於價格或交期的專案。
  • 訂單量少,而且每筆都要現場丈量才能定案的專案,預覽的建置與維護成本較難回收。

開始前要準備什麼

  • 客戶在付款前最常卡住的決定
  • 想預覽的品項與樣式種類
  • 現有的標誌(最好是 SVG)與店面照片
  • 業務提案時使用的裝置

備妥後,可以討論展示間與預覽的規劃。

(聯絡)

Start a project.

三個步驟,取得可判斷的做法與預算區間。

  1. 01預約第一場會議:選擇時段,不需要完整規格。
  2. 02線上諮詢 15 至 30 分鐘:取得做法方向、預算區間與時程草案。
  3. 03檢視素材後,約 3 至 5 個工作天提供報價單暨交付規格明細表。
信箱
hello@polish-design.com.tw
通訊地址
(104) 台北市中山區植福路191-1號3F

預約第一場會議

週一至週五 16:00–18:00線上 30 分鐘

先選時段,再用 Google 帳號或信箱確認,預約完成可加入行事曆。

選擇時段

或先送出資料

還沒想好時段,可以先留下專案內容,專人以信箱回覆。送出後也能接著預約。

補充資料(選填):服務項目、目前階段、現有連結、得知管道

資料僅用於本次專案評估。

ISO/IEC 27001:2022 證書

(Certificate)

ISO/IEC 27001:2022

驗證機構
ARES International Certification
驗證範圍
互動沉浸式 3D 系統之開發流程,及網路與基礎設施之維運與管理。

到驗證機構網站查證