8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【VBA】Excelで3Dグラフィックエンジンを作った

8
Posted at

Excelです。
3Dです。
回ります。

excel_3d_preview_small.gif

外部ライブラリなし、ActiveXなし。
VBAとShapeオブジェクトだけで動く、リアルタイム3Dグラフィックエンジンを作りました。

はじめに ― Excelは3Dエンジンである(暴論)

突然ですが、皆さんに質問です。

「Excelで何ができますか?」

表計算? グラフ作成? データ分析?

甘い。

Excelは 3Dグラフィックエンジン です。

……いや、正確に言うと「にしてやりました」。

今回作ったのは、Excel VBAだけで動く3Dグラフィックエンジン。回転する立体、発光エフェクト、リアルタイム操作、モーフィングアニメーション、そして3Dデジタル時計まで。外部ライブラリ? 使いません。ActiveXコントロール? 不要です。

VBAとShapeオブジェクトだけ で、ここまでできる。

動作環境: Excel 2016以降(Windows版)、マクロ有効ブック(.xlsm)
コード量: 約2,000行(1ファイル)
外部依存: なし(純粋VBAのみ)


まずはこれを見てほしい

▼ 3Dワイヤーフレームで描画されたCube(発光エフェクト付き)

excel_3d_all.gif

黒背景にシアンの発光線。右側のパネルで立体・色・エフェクトを切り替え、下部のボタンで回転・移動・ズームを操作。これ、全部Excelです。

▼ 7セグメント風3Dデジタル時計

時計.gif

リアルタイムで時刻を表示する3Dデジタル時計。6種のフォントと4段階の太さを選べます。AUTO ROTATEをONにすると、時計ごと3D空間で回転します。


完成形 ― 何ができるのか

🎮 基本機能

機能 説明
8種の立体 Cube / Pyramid / Octahedron / Diamond / Sphere / Torus / Star / ALL
リアルタイム3D回転 X軸・Y軸の回転をボタンまたはキーボードで操作
透視投影 奥行きに応じた線の太さ・透明度の変化
発光エフェクト Glowプロパティを使ったネオン風の光
8色カラー Cyan / Blue / Pink / Gold / Purple / Green / White / Red
ズーム・移動 拡大縮小、上下左右の平行移動

✨ エフェクトモード

モード 何が起きるか
RAINBOW 色がHSV空間を自動で巡回。虹色に光り続ける
TRAIL 残像が残る。回転させるとまるで光の軌跡
SOLID 面を半透明で塗りつぶし。ワイヤーフレームからソリッドモデルへ
DUAL 2つの立体を補色で同時表示。逆回転で干渉する美しさ

🔮 特殊機能

機能 説明
3D CLOCK 時針・分針・秒針が立体の上で回転するアナログ時計
DIGITAL 7セグメント風デジタル時計。6種のフォント+4段階の太さが選べる
3D TEXT 任意のテキストを入力 → A〜Z, 0〜9が3D空間で回転
3D BAR セルA1〜A5の数値を3D棒グラフとして描画
CUSTOM InputBoxで頂点と辺を入力 → 完全オリジナル立体
MORPH 立体から立体へ、頂点が滑らかに変形するアニメーション

技術解説 ― 何をどうやっているのか

🧮 3D数学の基本

3Dグラフィックの核心は たった2つの変換 です。

1. 回転(RotatePoint)

X軸回転とY軸回転の行列をかけるだけ。

Private Sub RotatePoint(ByRef x As Double, ByRef y As Double, ByRef z As Double, _
                         ax As Double, ay As Double)
    Dim ty As Double, tz As Double, tx As Double
    ' X軸回転
    ty = y * Cos(ax) - z * Sin(ax)
    tz = y * Sin(ax) + z * Cos(ax)
    y = ty: z = tz
    ' Y軸回転
    tx = x * Cos(ay) + z * Sin(ay)
    tz = -x * Sin(ay) + z * Cos(ay)
    x = tx: z = tz
End Sub

三角関数を2回呼ぶだけ。これだけで3D空間の任意の回転ができます。

2. 透視投影(Project3D)

3D座標を2Dスクリーンに投影します。

Private Sub Project3D(x As Double, y As Double, z As Double, _
                       ByRef sx As Double, ByRef sy As Double, ByRef depth As Double)
    depth = z + CAM_DIST
    If depth < 0.1 Then depth = 0.1
    Dim f As Double
    f = FOV * ZoomLevel / depth
    sx = cx + x * f   ' cx = フィールド中心X
    sy = cy - y * f   ' cy = フィールド中心Y
End Sub

カメラからの距離(depth)が大きいほど、fが小さくなる。つまり遠くのものは小さく見える。たったこれだけで透視投影が成立します。

🎨 「Excelらしくない」描画の秘密

Shapeオブジェクトがキャンバスになる

ExcelにはShapes.AddLineShapes.AddShapeがあります。これを毎フレーム 全部消して → 全部描き直す ことでアニメーションを実現しています。

' 辺の描画(深度に応じた太さと透明度)
avgD = (d1 + d2) / 2
lw = 2.8 - (avgD - 2.5) * 0.3     ' 近いほど太く
alpha = 1 - (avgD - 2.5) * 0.15   ' 近いほど不透明

With ws.Shapes.AddLine(sx1, sy1, sx2, sy2)
    .Line.ForeColor.RGB = wireColor
    .Line.Weight = lw
    .Line.Transparency = 1 - alpha
End With

奥の線は細く薄く、手前の線は太く鮮明に。これだけで驚くほど立体感が出ます。

発光エフェクト

If alpha > 0.5 Then
    ws.Shapes(ln).Glow.Color.RGB = wireColor
    ws.Shapes(ln).Glow.Radius = 5
    ws.Shapes(ln).Glow.Transparency = 0.65
End If

ExcelのShapeにはGlow(発光)プロパティがあります。通常は図形のデコレーションに使うものですが、線に適用すると ネオンサインのような光 になります。

🌈 レインボーモードの実装

HSV色空間のHue(色相)を毎フレーム3度ずつ回転させます。

Private Sub UpdateRainbow()
    RainbowHue = RainbowHue + 3
    If RainbowHue >= 360 Then RainbowHue = RainbowHue - 360
    ' HSV → RGB変換
    Dim hi As Long: hi = Int(RainbowHue / 60) Mod 6
    ' ... Select Caseで6パターンに分岐
End Sub

360度を3度ずつ → 120フレームで一周。AUTO ROTATEで回しながらRAINBOWをONにすると、まるでスクリーンセーバーです。

🔄 モーフィングの仕組み

立体Aから立体Bへ変形するアニメーション。原理は単純で、対応する頂点の座標を線形補間 しているだけです。

For stp = 0 To 20
    MorphT = stp / 20#
    For i = 1 To maxV
        Verts(i, 1) = MorphFrom(i, 1) + (MorphTo(i, 1) - MorphFrom(i, 1)) * MorphT
        Verts(i, 2) = MorphFrom(i, 2) + (MorphTo(i, 2) - MorphFrom(i, 2)) * MorphT
        Verts(i, 3) = MorphFrom(i, 3) + (MorphTo(i, 3) - MorphFrom(i, 3)) * MorphT
    Next i
    RenderFrame ws
    Sleep 40
Next stp

頂点数が違う場合は? 少ない方の最後の頂点で埋めます。すると、足りない頂点が1点から「にょきっ」と生えてくるような変形になります。

⏰ 3Dデジタル時計 ― 7セグメントの再発明

数字を3D空間に描くには、7セグメントディスプレイの原理を使います。

  ___      ← セグメントA(上辺)
 |   |     ← セグメントF(左上)とB(右上)
  ---      ← セグメントG(中央)
 |   |     ← セグメントE(左下)とC(右下)
  ___      ← セグメントD(下辺)

各セグメントの表示/非表示を数字ごとに制御します。

' 例: セグメントA(上辺)が必要な数字
If d = 0 Or d = 2 Or d = 3 Or d = 5 Or d = 6 Or d = 7 Or d = 8 Or d = 9 Then
    AddEdge b + 1, b + 2  ' 上左 → 上右
End If

さらに 6種のフォント を用意しました。

フォント 特徴 仕組み
NORMAL 標準7セグ 基本形
WIDE 横に広い 幅パラメータを拡大
TALL 縦に長い 高さパラメータを拡大
DOT ドットマトリクス風 上下辺を2分割、Z方向にずらす
ITALIC 斜体 上段をX方向にオフセット
ROUND 丸みのある 角に追加頂点で曲線感

パラメータを変えるだけでこれだけ表情が変わる。3Dデータの面白いところです。

🔤 A〜Zの3Dフォントエンジン

テキスト入力機能では、アルファベット全26文字+数字を3D空間に描画します。各文字は 8頂点のグリッド 上で辺を選択的に描画しています。

 1---2---3     ← 上段(上左・上中・上右)
 |       |
 4       5     ← 中段(中左・中右)
 |       |
 6---7---8     ← 下段(下左・下中・下右)

たとえば「A」なら:

Case "A"
    AddEdge b + 6, b + 1  ' 左の縦線
    AddEdge b + 1, b + 2  ' 上の左半分
    AddEdge b + 2, b + 3  ' 上の右半分
    AddEdge b + 3, b + 8  ' 右の縦線
    AddEdge b + 4, b + 5  ' 中央の横線

この8頂点グリッドに フォントパラメータ(幅・高さ・奥行き・傾き) を適用すると、同じ文字データで全く違う印象のフォントが生まれます。


レイアウト設計 ― UIもExcelで

画面構成は以下の通りです。

┌──────────────────────┬─────────────────────────────────┐
│                      │  3D WIREFRAME RENDERER v4.1      │
│   3D描画フィールド    │  ──────────────────────────────  │
│   (720 x 520)        │  HUD(形状・角度・FPS等の情報)     │
│                      ├────────────────┬────────────────┤
│   [日付]             │  // SHAPE //   │  // EFFECT //  │
│   [時刻]             │  立体選択8種   │  RAINBOW TRAIL │
│                      │               │  SOLID  DUAL   │
│                      │  // COLOR //   │  // CLOCK&TEXT│
│                      │  色選択8色     │  3DCLOCK DIGI  │
│                      │               │  3DTEXT        │
│                      │               │  // MORPH TO //│
│                      │               │  ->CUB ->PYR...│
├──────────────────────┴────────────────┴────────────────┤
│  [FULL RESET]  [AUTO ROTATE]                           │
│  // ROTATE //   // MOVE //   // ZOOM+RESET //          │
│  [X+][X-][Y+][Y-]  [<<][>>][UP][DN]  [Z+][Z-][RSA][RSZ]│
│  [SPEED +]                  [SPEED -]                   │
│  KEYS: Arrows=Rotate  Num8/2=Zoom  Num4/6=Move ...     │
└─────────────────────────────────────────────────────────┘

ボタンは全てShapeオブジェクトの.OnActionで関数を呼んでいます。CSSもHTMLもなし。全てVBAのShape座標計算


導入方法

手順

  1. Excelで 新規ブック を開く
  2. Alt + F11VBAエディタ を開く
  3. 挿入 → 標準モジュール
  4. コードを 全て貼り付け
  5. Alt + F8Start3DRenderer を実行

注意: マクロを有効にする必要があります。.xlsm形式で保存してください。

キーボード操作(AUTO ROTATE中)

キー 操作
回転方向のリアルタイム変更
テンキー 8 / 2 ズームイン / アウト
テンキー 4 / 6 左右移動
テンキー 5 全パラメータリセット
テンキー 0 角度のみリセット

開発中にハマったポイント

😱 VBAワンライナーの罠

VBAでは If ... Then 代入 : 次の文 がコロンで繋がるワンライナーで構文エラーが頻発します。

' ❌ これが通らない場合がある
Public Sub ZoomIn(): ZoomLevel = ZoomLevel + 0.15: If ZoomLevel > 3 Then ZoomLevel = 3: FrameCount = FrameCount + 1: End Sub

' ✅ 複数行にすれば安全
Public Sub ZoomIn()
    ZoomLevel = ZoomLevel + 0.15
    If ZoomLevel > 3 Then ZoomLevel = 3
    FrameCount = FrameCount + 1
    RenderFrame ActiveSheet
End Sub

これは何度もエラーを出して学びました。VBAでIf文を含むSubはワンライナーにしてはいけない。

😱 Shapeの残骸問題

毎フレーム線を消して描き直しますが、エラーや中断で Shapeが残ることがある。数千個のShapeがシートに散らかると、もうカオス。

この問題に悩まされた結果、FULL RESETボタンを実装。ws.DrawingObjects.Deleteで全消去してから再構築する方式にたどり着きました。

😱 GetAsyncKeyState の宣言

64bit版ExcelではPtrSafe宣言が必要です。#If VBA7 Thenで分岐します。

#If VBA7 Then
    Public Declare PtrSafe Function GetAsyncKeyState Lib "user32" _
        (ByVal vKey As Long) As Integer
#Else
    Public Declare Function GetAsyncKeyState Lib "user32" _
        (ByVal vKey As Long) As Integer
#End If

これを知らないと64bit版Excelで実行した瞬間にコンパイルエラーになります。ハマりやすいポイントです。


おわりに ― Excelの限界はどこにあるのか

約2,000行のVBAコードで、8種の3D立体、6種のデジタルフォント、モーフィングアニメーション、残像エフェクト、3D時計、テキスト描画、そしてリアルタイムキーボード操作。

これは「Excelでここまでできる」という技術的な挑戦であると同時に、「手段を限定されたときこそ、人は工夫する」 という話でもあります。

Excelは本来3Dグラフィックを描くためのソフトウェアではありません。
しかし、Shapeオブジェクトという限られた道具でも ここまで遊べる

ちなみにこの約2,000行のコード、バイブコーディング(AIとの対話)で作りました
「立体を回したい」「時計を3Dにしたい」「フォントを選べるようにして」と要望を伝えながら、一つずつ機能を積み上げていった結果がこれです。

プログラミングの経験や知識がなくても、アイデアと熱意があればここまで作れる。
そんな時代になったことを、このプロジェクトで実感しました。

次は何を作ろうか。レイトレーシング? パーティクルシステム? 
……いや、まずは仕事のマクロを片付けないと。

実は、先日投稿した「プログラミングで一番大事なのは……」という記事で触れた「伝える力」の具体的な証明として、今回のプロジェクトに取り組みました。コードが書けなくても、AIという相棒への「言語化」を極めれば、Excelの中でさえここまでの世界が構築できる。それを形にしておきたかったのです。

もちろん、実務としてのプログラミングにおいては、保守や設計の重要性が消えるわけではないことも承知しています。しかし、まずは「自分の手でこんなものが作れた!」という純粋な驚きこそが、この奥深い世界へ踏み出す最高のきっかけになると信じています。

Excelの限界を、一緒に壊しましょう。

コードの全文はGitHubで公開しています。
ダウンロードして、ぜひ自分のExcelで動かしてみてください。

👉 Excel3DRenderer_v41.bas - GitHub

「こんな機能を追加してほしい」「自分はこうアレンジした」等あれば、コメントやIssueでお気軽にどうぞ!

タグ

#VBA #Excel #3D #ワイヤーフレーム #個人開発

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?