生成画像の「光の方向」を揃える:複数枚を一つの場面にする
遊びをつくる執筆にClaudeを使用しています。

背景、手前の小物、キャラクターを別々に生成して重ねると、一枚ずつは良くできているのに、並べた途端に場面が崩れることがあります。背景では木漏れ日が左から差しているのに、キャラクターの影は左へ伸びている、といった状態です。光の向きがずれると、人は理由が分からなくても「貼り合わせた絵だ」と感じます。 この記事で確かめるのは、「光の向きを文章で指定すると、どのくらい揃うのか。揃わなかったとき、どの順で直すのが手間に見合うのか」という二点です。結果はここには書きません。読者が自分のツールと自分の絵柄で測れるよう、問いの立て方、準備、手順、記録の取り方、結果の読み方、誤りやすい点を順に示します。 「手描きで影を足す」という最後の手段までを含めて設計するのが、このシリーズらしい点です。生成だけで揃えられる範囲と、手を入れたほうが早い範囲の境目を、自分のデータで見つけます。
問いと準備:何を、何で比べるのか
問いは一つに絞ります。「光源の指示の書き方を変えると、影の向きが揃う枚数は変わるか」です。色や画風、構図の良し悪しは今回の対象外です。
比べる指示は次の四条件にします。
- 条件A:「左上からの光」とだけ書く。
- 条件B:画面を基準に、光の来る方向、影の落ちる方向、光の高さ、主光源が一つであることを書く。
- 条件C:条件Bに加えて、最初に気に入った一枚を参照画像として渡す。ツールが参照画像に対応している場合だけ行います。
- 条件D:指示では向きを指定せず、生成後に左右反転で揃える。
条件Bの文面の例です。
画面の左上から差す、午後の暖かい日差し。影は被写体の右下へ短く落ちる。光源は一つだけ。
「左」を被写体から見た左と読むか、画面を見る側の左と読むかで、結果が割れる可能性があります。どちらに解釈されやすいかも、この実験で分かります。そのため文面では「画面の」と明記します。
準備するものは次のとおりです。
- 使う画像生成ツール。条件Cを行うなら参照画像に対応したもの。
- 場面の要素を三種。例として、背景(地面のある野外)、小物(木箱や切り株)、人物またはキャラクターを想定します。
- 記録用の表(表計算ソフトで十分です)。
- 画像編集ソフト。レイヤーと左右反転が使えれば何でも構いません。
- 次の節のコードを保存した判定用HTML。
手順:光源を変えながら、同じ場面を生成する
要素ごとの主題は固定し、変えるのは光の指示だけにします。主題の文は三要素それぞれで条件A〜Dに共通させてください。
- 要素(背景・小物・人物)ごとに、主題の文を一文で決めます。
- 条件Aの指示を付けて、各要素を5枚ずつ生成します。気に入った枚だけを選ぶことはしません。生成した順に全部を残します。
- 条件Bで同じことを行います。
- 条件Cは、条件Bで最初に出た背景の一枚を参照画像にして、小物と人物を5枚ずつ生成します。
- 条件Dは、指示に光の向きを入れず、5枚ずつ生成して保存します。これは反転で直せるかを見る条件なので、判定後に反転版も作ります。
- 画像に通し番号とファイル名(例:B_char_03)を付けます。
枚数は目安です。要素3種、条件4種、各5枚なら合計60枚になり、負担が大きければ要素を人物と背景の二種に絞って構いません。ただし、条件間で枚数と要素は必ず揃えてください。
ここで、影の向きを判定する小さな補助ページを使います。画像を複数選び、「足元」と「影の先端」を順にクリックすると、画面基準の8方向で記録します。外部ライブラリは不要で、単独で動きます。
<!doctype html>
<meta charset="utf-8">
<input type="file" id="f" accept="image/*" multiple>
<canvas id="c" width="480" height="480"></canvas>
<pre id="o">画像を選び、足元→影の先端の順に2回クリックします。</pre>
<script>
const f=document.getElementById('f'),c=document.getElementById('c'),
x=c.getContext('2d'),o=document.getElementById('o');
const names=['右','右下','下','左下','左','左上','上','右上'];
let imgs=[],i=0,pts=[],log=[];
function show(){
if(i>=imgs.length){o.textContent=log.join('\n');return;}
const m=imgs[i].img;
c.width=480;c.height=Math.round(480*m.height/m.width);
x.drawImage(m,0,0,c.width,c.height);
}
f.onchange=e=>{
imgs=[];log=[];i=0;
const files=[...e.target.files];
files.forEach(file=>{
const img=new Image();
img.onload=()=>{imgs.push({img,name:file.name});
if(imgs.length===files.length)show();};
img.src=URL.createObjectURL(file);
});
};
c.onclick=e=>{
if(i>=imgs.length)return;
const r=c.getBoundingClientRect();
pts.push([e.clientX-r.left,e.clientY-r.top]);
if(pts.length===2){
const a=Math.atan2(pts[1][1]-pts[0][1],pts[1][0]-pts[0][0]);
const k=(Math.round(a/(Math.PI/4))+8)%8;
log.push(imgs[i].name+' : 影は'+names[k]+'向き');
pts=[];i++;show();
}
};
</script>読み込みの順序は選んだ順と一致しないことがありますが、結果にファイル名が付くので、表への転記では名前を見て照合してください。
記録の取り方:何を、どの単位で残すか
一枚ごとに一行、次の項目を残します。
- 画像ID、記入の仕方:条件と要素と番号(例:B_char_03)
- 影の向き、記入の仕方:補助ページが出した8方向
- 明るい面の向き、記入の仕方:目視で8方向。影と反対側になっているかの確認用
- 影の長さ、記入の仕方:短・中・長の3段階
- 色温度、記入の仕方:暖・中立・寒の3段階
- 光源の数、記入の仕方:1つ/複数/判定不能
- 判定不能、記入の仕方:逆光や曇天で影が見えないときに印を付ける
揃っているかの基準は、場面の「基準画像」に決めます。たとえば条件Bの背景で最初に出た一枚の影の向きを基準にし、同じ8方向なら一致、隣の方向なら「ずれ小」、それ以外は「不一致」と三段階にします。隣の方向まで含めて一致とみなすかは、重ねたときの見え方で決めてください。自分の絵柄で許容できるかを確かめる作業でもあります。
集計の単位は「条件ごとの一致枚数÷枚数」です。パーセントにすると五枚程度の差が大きく見えるので、「5枚中何枚」のまま比べます。
判定の安定性のため、全画像を日を置いてもう一度判定します。二回の判定で食い違う画像が多いなら、基準が曖昧です。その場合、結果を読む前に判定基準を見直してください。
結果の読み方と直し方:揃わなかったときの順番
集計後は、次のように読みます。
- AよりBの一致が明らかに多い:向きの指示は効いています。以降は条件Bの文面をひな形にします。
- AとBに差がほとんどない:書き足しの効果は薄い可能性があります。ただ、枚数が少なければ偶然の範囲かもしれません。差が1枚程度なら判断を保留し、各条件を10枚に増やして再確認します。
- BよりCの一致が多い:参照画像が効いています。背景を最初に決めてから他を作る順序が向いています。
- 不一致の多くが「正反対」:左右の解釈が割れている可能性が高いです。画面基準の表現に変えるか、条件Dのように反転で直します。
- 向きは合うが影の長さが違う:光の高さの指定が弱い状態です。「低い角度で長い影」など高さを足して再生成します。
- 向きは合うが色が違う:色補正で直します。
直し方は手間の少ない順に並べると、次のようになります。
- 再生成:数枚の範囲で当たりが出るなら、これが最も安くなります。
- 左右反転:向きだけが逆のときに有効です。ただし文字、看板、時計、服の非対称な模様、顔の分け目などは反転すると不自然になります。反転前に、そうした要素がないか確認します。
- 色・明るさの補正:色温度は色相の調整レイヤーで寄せられます。明るい面と暗い面の差が弱いときは、光の来る側から反対側へかけた弱いグラデーションを重ねます。
- 手描きで影を足す:影を別のレイヤーに乗算で描き、基準の向きに合わせます。元の影が逆向きなら、薄くして残すか、消してから描き直します。
三番目までで直らない場合に四番目へ進む、と決めておくと迷いません。時間がかかるのは手描きですが、再生成を何十回も回すより早く済む場合もあります。その分かれ目は、再生成で一致した枚数を記録しておけば自分で判断できます。
誤りやすい点
- 条件を同時に変える:向きの指示と画風の指示を同時に変えると、何が効いたか分からなくなります。一回に変えるのは一つだけです。
- 良い一枚だけを残す:気に入った絵だけを集計すると、揃い率が実際より高くなります。生成した全枚数を記録します。
- 「左」の基準が混ざる:指示文では画面基準で統一し、判定も画面基準で行います。
- 逆光や曇天の場面を混ぜる:影が見えない画像は判定できません。「判定不能」の列を作り、一致率の分母から外すか、別に集計します。
- 切り抜き後の縁:背景を消した人物の縁に、元の背景の明るい色が残ることがあります。向きが揃っていても、縁の光だけが逆に見える原因になります。
- 解像度や拡大率を揃えずに比べる:影の長さは、画像の拡大率が違うと比べられません。重ねる前に同じ縮尺にそろえてください。
- 複数の光源を許す:窓と焚き火が両方ある場面は、影が二方向になります。最初は主光源が一つの場面で測り、複雑な場面は後に回します。
次の行動
まず背景と人物の二要素だけで、条件AとBを各5枚ずつ生成し、補助ページで影の向きを記録してみてください。一致が足りない要素が見つかったら、上の直し方を手間の少ない順に試します。
ゲームに組み込むときは、画像を相対パスで参照し、直下のindex.htmlから読み込む構成にしておくと、アソバースへのアップロードでも差し替えが楽です。画像を多く使う場合は、アップロードの容量(20MiB以内)も意識しておくと安心です。
