HOME > natural science Laboratory > コンピュータ・シミュレーション講座 > 仮想物理実験室

光の波長からRGBを算出する関数の定義

文責:遠藤 理平 (2016年5月13日) カテゴリ:仮想物理実験室(325)計算物理学(165)

波長とRGBの関係式(変換式)

光は、波長がおよそ380[nm]から750[nm]まで電磁波です。
3次元グラフィックスなどで波長λ[nm]に対応した描画色を与えるために、RGB値を算出する計算式を考えてみます。
CIE(国際照明委員会 Commission internationale de l'eclairage)では、赤(R):700.0[nm]、緑(G):546.1[nm]、青(B):435.8[nm]と定めています。

光の三原色(赤・緑・青)の重ねあわせ

まずは一番単純に、先のCIEで定義された赤・緑・青の波長に合わせて、380[nm]から750[nm]の光のスペクトルをこの3色の重ね合わせで表現してみます。 それぞれの色の明るさは、中心波長を最大値とする正規分布であると仮定します。

r(\lambda) = I_r \ \exp\left[ - \left( \frac{\lambda - \lambda_r}{ \Delta \lambda_r } \right)^2  \right]
g(\lambda) = I_g \ \exp\left[ - \left( \frac{\lambda - \lambda_g}{ \Delta \lambda_g } \right)^2  \right]
b(\lambda) = I_b \ \exp\left[ - \left( \frac{\lambda - \lambda_b}{ \Delta \lambda_b } \right)^2  \right]

ただし、I_r = 1.0 , I_g = 1.0, I_b = 1.0は明るさの最大強度、\lambda_r = 700.0, \lambda_g = 546.1, \lambda_b = 435.8は各色の中心波長、\Delta \lambda_r = 90, \Delta \lambda_g = 80, \Delta \lambda_b = 80は正規分布の半値半幅です。子の半値半幅の大きさは、赤・緑・青の各中心波長の波長で、他の色の強度が0.1程度となるように設定しています。

この関係式を用いて光のスペクトルを描画した結果と、RGB値の波長依存性をグラフ化した結果を示します。

光の三原色(赤・緑・青)のみの光のスペクトル

3色が独立しているように見えるため、光のスペクトルというより液晶のドットのようです。 これは、強度グラフを見ると、620[nm]あたりと490[nm]あたりでRGB値が低くなってしまうため、その部分が暗くなってしまっていることに起因します。 そこで、虹色(紫・青・藍・緑・黄・橙・赤)を構成する残りの色(+橙・黄・藍・紫)を加えることで、光のスペクトルを作成します。

光の三原色(赤・緑・青)+橙・黄・藍・紫の重ねあわせ

残りの4色(橙・黄・藍・紫)を同じ表式で考えます。添字は「o:橙」「y:黄」「c:藍」「p:紫」を表します。

o(\lambda) = I_o \ \exp\left[ - \left( \frac{\lambda - \lambda_o}{ \Delta \lambda_o } \right)^2  \right]
y(\lambda) = I_g \ \exp\left[ - \left( \frac{\lambda - \lambda_y}{ \Delta \lambda_y } \right)^2  \right]
c(\lambda) = I_b \ \exp\left[ - \left( \frac{\lambda - \lambda_c}{ \Delta \lambda_c } \right)^2  \right]
p(\lambda) = I_b \ \exp\left[ - \left( \frac{\lambda - \lambda_p}{ \Delta \lambda_p } \right)^2  \right]

ただし、各色の明るさの最大強度をI_o = 0.4 , I_y = 0.1, I_c = 0.3, I_p = 0.3、中心波長を\lambda_o = 605.0, \lambda_y = 580.0, \lambda_c = 490.0, \lambda_p = 400.0、正規分布の半値半幅は\Delta \lambda_o = 60, \Delta \lambda_y = 50, \Delta \lambda_c = 50, \Delta \lambda_p = 40です。4色を追加した際にRGB値の最大値が1となるように、先の赤・緑・青の明るさの最大強度をI_r = 0.95 , I_g =0.74, I_b =0.75に再設定します。

それぞれの色はもともとRGB値の混合で表現されるため、その混同割合を次のとおりとします。

orange #ffa500  1: 0.715 : 0.230
yellow #ffff00  1: 1     : 0
cian   #00ff00  0: 1     : 1
purple #804080  1: 0.5   : 1


虹色(紫・青・藍・緑・黄・橙・赤)による光のスペクトル

少し不自然な気がしないでもないですが、一応完成しました。 それらしく見えるように試行錯誤しました。より良いパラメータがわかりましたら教えて下さい。

プログラムソース

//////////////////////////////////////////////
// 波長からRGB値を算出する関数「waveLengthToRGB関数」
//////////////////////////////////////////////
function waveLengthToRGB( lambda , color ){

	//中心波長[nm]
	var r0 = 700.0; //赤色
	var g0 = 546.1; //緑色
	var b0 = 435.8; //青色
	var o0 = 605.0; //橙色
	var y0 = 580.0; //黄色
	var c0 = 490.0; //藍色
	var p0 = 400.0; //紫色

	//半値半幅
	var wR = 90;
	var wG = 80;
	var wB = 80;
	var wO = 60;
	var wY = 50;
	var wC = 50;
	var wP = 40;
	//強度
	var iR = 0.95;
	var iG = 0.74;
	var iB = 0.75;

	var iO = 0.4;
	var iY = 0.1;
	var iC = 0.3;
	var iP = 0.3;

	//正規分布の計算
	var r = iR * Math.exp( - ( lambda - r0 ) * ( lambda - r0 ) / ( wR * wR )  );
	var g = iG * Math.exp( - ( lambda - g0 ) * ( lambda - g0 ) / ( wG * wG )  );
	var b = iB * Math.exp( - ( lambda - b0 ) * ( lambda - b0 ) / ( wB * wB )  );
	var o = iO * Math.exp( - ( lambda - o0 ) * ( lambda - o0 ) / ( wO * wO )  );
	var y = iY * Math.exp( - ( lambda - y0 ) * ( lambda - y0 ) / ( wY * wY )  );
	var c = iC * Math.exp( - ( lambda - c0 ) * ( lambda - c0 ) / ( wC * wC )  );
	var p = iP * Math.exp( - ( lambda - p0 ) * ( lambda - p0 ) / ( wP * wP )  );

	/*
	orange #ffa500  1: 0.715 : 0.230
	yellow #ffff00  1: 1     : 0
	cian   #00ff00  0: 1     : 1
	purple #804080  1: 0.5   : 1
	*/

	r = r + o + y + p;
	g = g + o*0.715 + y*0.83 + c + p *0.50;
	b = b + o*0.23 + c + p;

	if( r > 1.0 ) r = 1.0;
	if( g > 1.0 ) g = 1.0;
	if( b > 1.0 ) b = 1.0;

	if ( typeof color == "object" ){

		color.r = r;
		color.g = g;
		color.b = b;

	} else {

		return {r:r, g:g, b:b};

	}

}

参考

イラストレイテッド光の科学

・数式の表示は「Tex表記によるHTML文書への式の埋め込み」をご覧ください。 ・グラフ描画は「HTML5による物理シミュレーション」を参照ください。



▲このページのトップNPO法人 natural science トップ

関連記事

仮想物理実験室







計算物理学

▲このページのトップNPO法人 natural science トップ




Warning: mysqli_connect(): (28000/1045): Access denied for user 'xsvx1015071_ri'@'sv102.xserver.jp' (using password: YES) in /home/xsvx1015071/include/natural-science/include_counter-d.php on line 8
MySQL DBとの接続に失敗しました