Toshihiro Shimizu 890ddd
/*------------------------------------
Toshihiro Shimizu 890ddd
Iwa_SpectrumFx
Toshihiro Shimizu 890ddd
参照画像を位相差として、干渉色を出力する
Toshihiro Shimizu 890ddd
------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "iwa_spectrumfx.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "iwa_cie_d65.h"
Toshihiro Shimizu 890ddd
#include "iwa_xyz.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
const float PI = 3.14159265f;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------
Toshihiro Shimizu 890ddd
 シャボン色マップの生成
Toshihiro Shimizu 890ddd
------------------------------------*/
Toshihiro Shimizu 890ddd
void Iwa_SpectrumFx::calcBubbleMap(float3 *bubbleColor, double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int j, k;	 /*- bubbleColor[j][k] = [256][3] -*/
Toshihiro Shimizu 890ddd
	float d;	  /*- 膜厚(μm) -*/
Toshihiro Shimizu 890ddd
	int ram;	  /*- 波長のfor文用 -*/
Toshihiro Shimizu 890ddd
	float rambda; /*- 波長(μm) -*/
Toshihiro Shimizu 890ddd
	struct REFLECTIVITY {
Toshihiro Shimizu 890ddd
		float r_ab, t_ab, r_ba, t_ba; /*- 各境界での振幅反射率、振幅透過率 -*/
Toshihiro Shimizu 890ddd
		float r_real, r_img;		  /*- 薄膜の振幅反射率 -*/
Toshihiro Shimizu 890ddd
		float R;					  /*- エネルギー反射率 -*/
Toshihiro Shimizu 890ddd
	} p, s;
Toshihiro Shimizu 890ddd
	float R_final;					 /*- エネルギー反射率の最終版 -*/
Toshihiro Shimizu 890ddd
	float phi;						 /*- 位相 -*/
Toshihiro Shimizu 890ddd
	float color_x, color_y, color_z; /*- xyz表色系 -*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	float temp_rgb_f[3];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- パラメータを得る -*/
Toshihiro Shimizu 890ddd
	float intensity = (float)m_intensity->getValue(frame);
Toshihiro Shimizu 890ddd
	float refractiveIndex = (float)m_refractiveIndex->getValue(frame);
Toshihiro Shimizu 890ddd
	float thickMax = (float)m_thickMax->getValue(frame);
Toshihiro Shimizu 890ddd
	float thickMin = (float)m_thickMin->getValue(frame);
Toshihiro Shimizu 890ddd
	float rgbGamma[3] = {(float)m_RGamma->getValue(frame),
Toshihiro Shimizu 890ddd
						 (float)m_GGamma->getValue(frame),
Toshihiro Shimizu 890ddd
						 (float)m_BGamma->getValue(frame)};
Toshihiro Shimizu 890ddd
	float lensFactor = (float)m_lensFactor->getValue(frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- 入射角は0で固定 -*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- 各境界での振幅反射率、振幅透過率の計算(PS偏光とも) -*/
Toshihiro Shimizu 890ddd
	/*- P偏光 -*/
Toshihiro Shimizu 890ddd
	p.r_ab = (1.0 - refractiveIndex) / (1.0 + refractiveIndex);
Toshihiro Shimizu 890ddd
	p.t_ab = (1.0f - p.r_ab) / refractiveIndex;
Toshihiro Shimizu 890ddd
	p.r_ba = -p.r_ab;
Toshihiro Shimizu 890ddd
	p.t_ba = (1.0f + p.r_ab) * refractiveIndex;
Toshihiro Shimizu 890ddd
	/*- S偏光 -*/
Toshihiro Shimizu 890ddd
	s.r_ab = (1.0 - refractiveIndex) / (1.0 + refractiveIndex);
Toshihiro Shimizu 890ddd
	s.t_ab = 1.0f + s.r_ab;
Toshihiro Shimizu 890ddd
	s.r_ba = -s.r_ab;
Toshihiro Shimizu 890ddd
	s.t_ba = 1.0f - s.r_ab;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (j = 0; j < 256; j++) { /*- 膜厚d -*/
Toshihiro Shimizu 890ddd
		/*- 膜厚d(μm)の計算 -*/
Toshihiro Shimizu 890ddd
		d = thickMin + (thickMax - thickMin) * powf(((float)j / 255.0f), lensFactor);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*-  膜厚が負になることもありうる。その場合は d = 0 に合わせる -*/
Toshihiro Shimizu 890ddd
		if (d < 0.0f)
Toshihiro Shimizu 890ddd
			d = 0.0f;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*- これから積算するので、XYZ表色系各チャンネルの初期化 -*/
Toshihiro Shimizu 890ddd
		color_x = 0.0f;
Toshihiro Shimizu 890ddd
		color_y = 0.0f;
Toshihiro Shimizu 890ddd
		color_z = 0.0f;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (ram = 0; ram < 34; ram++) { /*- 波長λ(380nm-710nm) -*/
Toshihiro Shimizu 890ddd
			/*- 波長λ(μm)の計算 -*/
Toshihiro Shimizu 890ddd
			rambda = 0.38f + 0.01f * (float)ram;
Toshihiro Shimizu 890ddd
			/*- 位相の計算 -*/
Toshihiro Shimizu 890ddd
			phi = 4.0f * PI * refractiveIndex * d / rambda;
Toshihiro Shimizu 890ddd
			/*- 薄膜の振幅反射率の計算(PS偏光とも) -*/
Toshihiro Shimizu 890ddd
			/*- P偏光 -*/
Toshihiro Shimizu 890ddd
			p.r_real = p.r_ab + p.t_ab * p.r_ba * p.t_ba * cosf(phi);
Toshihiro Shimizu 890ddd
			p.r_img = p.t_ab * p.r_ba * p.t_ba * sinf(phi);
Toshihiro Shimizu 890ddd
			/*- S偏光 -*/
Toshihiro Shimizu 890ddd
			s.r_real = s.r_ab + s.t_ab * s.r_ba * s.t_ba * cosf(phi);
Toshihiro Shimizu 890ddd
			s.r_img = s.t_ab * s.r_ba * s.t_ba * sinf(phi);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			p.R = p.r_real * p.r_real + p.r_img * p.r_img;
Toshihiro Shimizu 890ddd
			s.R = s.r_real * s.r_real + s.r_img * s.r_img;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			/*- エネルギー反射率 -*/
Toshihiro Shimizu 890ddd
			R_final = (p.R + s.R) / 2.0f;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			color_x += intensity * cie_d65[ram] * R_final * xyz[ram * 3 + 0];
Toshihiro Shimizu 890ddd
			color_y += intensity * cie_d65[ram] * R_final * xyz[ram * 3 + 1];
Toshihiro Shimizu 890ddd
			color_z += intensity * cie_d65[ram] * R_final * xyz[ram * 3 + 2];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		} /*- 次のramへ(波長λ) -*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		temp_rgb_f[0] = 3.240479f * color_x - 1.537150f * color_y - 0.498535f * color_z;
Toshihiro Shimizu 890ddd
		temp_rgb_f[1] = -0.969256f * color_x + 1.875992f * color_y + 0.041556f * color_z;
Toshihiro Shimizu 890ddd
		temp_rgb_f[2] = 0.055648f * color_x - 0.204043f * color_y + 1.057311f * color_z;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*- オーバーフローをまるめる -*/
Toshihiro Shimizu 890ddd
		for (k = 0; k < 3; k++) {
Toshihiro Shimizu 890ddd
			if (temp_rgb_f[k] < 0.0f)
Toshihiro Shimizu 890ddd
				temp_rgb_f[k] = 0.0f;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			/*- ガンマ処理 -*/
Toshihiro Shimizu 890ddd
			temp_rgb_f[k] = powf((temp_rgb_f[k] / 255.0f), rgbGamma[k]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (temp_rgb_f[k] >= 1.0f)
Toshihiro Shimizu 890ddd
				temp_rgb_f[k] = 1.0f;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		bubbleColor[j].x = temp_rgb_f[0];
Toshihiro Shimizu 890ddd
		bubbleColor[j].y = temp_rgb_f[1];
Toshihiro Shimizu 890ddd
		bubbleColor[j].z = temp_rgb_f[2];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	} /*- 次のjへ(膜厚d) -*/
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------
Toshihiro Shimizu 890ddd
Iwa_SpectrumFx::Iwa_SpectrumFx()
Toshihiro Shimizu 890ddd
	: m_intensity(1.0), m_refractiveIndex(1.25), m_thickMax(1.0), m_thickMin(0.0), m_RGamma(1.0), m_GGamma(1.0), m_BGamma(1.0), m_lensFactor(1.0), m_lightThres(1.0), m_lightIntensity(1.0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	addInputPort("Source", m_input);
Toshihiro Shimizu 890ddd
	addInputPort("Light", m_light);
Toshihiro Shimizu 890ddd
	bindParam(this, "intensity", m_intensity);
Toshihiro Shimizu 890ddd
	bindParam(this, "refractiveIndex", m_refractiveIndex);
Toshihiro Shimizu 890ddd
	bindParam(this, "thickMax", m_thickMax);
Toshihiro Shimizu 890ddd
	bindParam(this, "thickMin", m_thickMin);
Toshihiro Shimizu 890ddd
	bindParam(this, "RGamma", m_RGamma);
Toshihiro Shimizu 890ddd
	bindParam(this, "GGamma", m_GGamma);
Toshihiro Shimizu 890ddd
	bindParam(this, "BGamma", m_BGamma);
Toshihiro Shimizu 890ddd
	bindParam(this, "lensFactor", m_lensFactor);
Toshihiro Shimizu 890ddd
	bindParam(this, "lightThres", m_lightThres);
Toshihiro Shimizu 890ddd
	bindParam(this, "lightIntensity", m_lightIntensity);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_intensity->setValueRange(0.0, 8.0);
Toshihiro Shimizu 890ddd
	m_refractiveIndex->setValueRange(1.0, 3.0);
Toshihiro Shimizu 890ddd
	m_thickMax->setValueRange(-1.5, 2.0);
Toshihiro Shimizu 890ddd
	m_thickMin->setValueRange(-1.5, 2.0);
Toshihiro Shimizu 890ddd
	m_RGamma->setValueRange(0.001, 1.0);
Toshihiro Shimizu 890ddd
	m_GGamma->setValueRange(0.001, 1.0);
Toshihiro Shimizu 890ddd
	m_BGamma->setValueRange(0.001, 1.0);
Toshihiro Shimizu 890ddd
	m_lensFactor->setValueRange(0.01, 10.0);
Toshihiro Shimizu 890ddd
	m_lightThres->setValueRange(-5.0, 1.0);
Toshihiro Shimizu 890ddd
	m_lightIntensity->setValueRange(0.0, 1.0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------
Toshihiro Shimizu 890ddd
void Iwa_SpectrumFx::doCompute(TTile &tile,
Toshihiro Shimizu 890ddd
							   double frame,
Toshihiro Shimizu 890ddd
							   const TRenderSettings &settings)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_input.isConnected())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- 薄膜干渉色マップ -*/
Toshihiro Shimizu 890ddd
	float3 *bubbleColor;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TDimensionI dim(tile.getRaster()->getLx(), tile.getRaster()->getLy());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- 256段階で干渉色を計算 -*/
Toshihiro Shimizu 890ddd
	TRasterGR8P bubbleColor_ras(sizeof(float3) * 256, 1);
Toshihiro Shimizu 890ddd
	bubbleColor_ras->lock();
Toshihiro Shimizu 890ddd
	bubbleColor = (float3 *)bubbleColor_ras->getRawData();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- シャボン色マップの生成 -*/
Toshihiro Shimizu 890ddd
	calcBubbleMap(bubbleColor, frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- いったん素材をTileに収める -*/
Toshihiro Shimizu 890ddd
	m_input->compute(tile, frame, settings);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*--------------------
Toshihiro Shimizu 890ddd
	 ここで、Lightが刺さっていた場合は、Lightのアルファを使用&HDRThresでスクリーン合成
Toshihiro Shimizu 890ddd
	--------------------*/
Toshihiro Shimizu 890ddd
	TRasterP lightRas = 0;
Toshihiro Shimizu 890ddd
	if (m_light.isConnected()) {
Toshihiro Shimizu 890ddd
		TTile light_tile;
Toshihiro Shimizu 890ddd
		m_light->allocateAndCompute(light_tile, tile.m_pos, dim, tile.getRaster(), frame, settings);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		lightRas = light_tile.getRaster();
Toshihiro Shimizu 890ddd
		lightRas->lock();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRaster32P ras32 = (TRaster32P)tile.getRaster();
Toshihiro Shimizu 890ddd
	TRaster64P ras64 = (TRaster64P)tile.getRaster();
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (ras32) {
Toshihiro Shimizu 890ddd
			if (lightRas)
Toshihiro Shimizu 890ddd
				convertRasterWithLight<traster32p, tpixel32="">(ras32,</traster32p,>
Toshihiro Shimizu 890ddd
															 dim,
Toshihiro Shimizu 890ddd
															 bubbleColor,
Toshihiro Shimizu 890ddd
															 (TRaster32P)lightRas,
Toshihiro Shimizu 890ddd
															 (float)m_lightThres->getValue(frame),
Toshihiro Shimizu 890ddd
															 (float)m_lightIntensity->getValue(frame));
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				convertRaster<traster32p, tpixel32="">(ras32, dim, bubbleColor);</traster32p,>
Toshihiro Shimizu 890ddd
		} else if (ras64) {
Toshihiro Shimizu 890ddd
			if (lightRas)
Toshihiro Shimizu 890ddd
				convertRasterWithLight<traster64p, tpixel64="">(ras64,</traster64p,>
Toshihiro Shimizu 890ddd
															 dim,
Toshihiro Shimizu 890ddd
															 bubbleColor,
Toshihiro Shimizu 890ddd
															 (TRaster64P)lightRas,
Toshihiro Shimizu 890ddd
															 (float)m_lightThres->getValue(frame),
Toshihiro Shimizu 890ddd
															 (float)m_lightIntensity->getValue(frame));
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				convertRaster<traster64p, tpixel64="">(ras64, dim, bubbleColor);</traster64p,>
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//メモリ解放
Toshihiro Shimizu 890ddd
	//brightness_ras->unlock();
Toshihiro Shimizu 890ddd
	bubbleColor_ras->unlock();
Toshihiro Shimizu 890ddd
	if (lightRas)
Toshihiro Shimizu 890ddd
		lightRas->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------
Toshihiro Shimizu 890ddd
template <typename pixel="" raster,="" typename=""></typename>
Toshihiro Shimizu 890ddd
void Iwa_SpectrumFx::convertRaster(const RASTER ras,
Toshihiro Shimizu 890ddd
								   TDimensionI dim,
Toshihiro Shimizu 890ddd
								   float3 *bubbleColor)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	float rr, gg, bb, aa;
Toshihiro Shimizu 890ddd
	float spec_r, spec_g, spec_b;
Toshihiro Shimizu 890ddd
	float brightness;
Toshihiro Shimizu 890ddd
	for (int j = 0; j < dim.ly; j++) {
Toshihiro Shimizu 890ddd
		PIXEL *pix = ras->pixels(j);
Toshihiro Shimizu 890ddd
		for (int i = 0; i < dim.lx; i++) {
Toshihiro Shimizu 890ddd
			aa = (float)pix->m / PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
			if (aa == 0.0f) /*- アルファが0なら変化なし -*/
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				pix++;
Toshihiro Shimizu 890ddd
				continue;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			/*- depremutiplyはしないでおく -*/
Toshihiro Shimizu 890ddd
			rr = (float)pix->r / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
			gg = (float)pix->g / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
			bb = (float)pix->b / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
			brightness = 0.298912f * rr + 0.586611f * gg + 0.114478f * bb;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			/*- 反転 -*/
Toshihiro Shimizu 890ddd
			brightness = 1.0f - brightness;
Toshihiro Shimizu 890ddd
			/*- 輝度MAXの場合 -*/
Toshihiro Shimizu 890ddd
			if (brightness >= 1.0f) {
Toshihiro Shimizu 890ddd
				spec_r = bubbleColor[255].x * aa;
Toshihiro Shimizu 890ddd
				spec_g = bubbleColor[255].y * aa;
Toshihiro Shimizu 890ddd
				spec_b = bubbleColor[255].z * aa;
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				/*- 線形補間する -*/
Toshihiro Shimizu 890ddd
				int index = (int)(brightness * 255.0f);
Toshihiro Shimizu 890ddd
				float ratio = brightness * 255.0f - (float)index;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				spec_r = bubbleColor[index].x * (1.0f - ratio) +
Toshihiro Shimizu 890ddd
						 bubbleColor[index + 1].x * ratio;
Toshihiro Shimizu 890ddd
				spec_g = bubbleColor[index].y * (1.0f - ratio) +
Toshihiro Shimizu 890ddd
						 bubbleColor[index + 1].y * ratio;
Toshihiro Shimizu 890ddd
				spec_b = bubbleColor[index].z * (1.0f - ratio) +
Toshihiro Shimizu 890ddd
						 bubbleColor[index + 1].z * ratio;
Toshihiro Shimizu 890ddd
				spec_r *= aa;
Toshihiro Shimizu 890ddd
				spec_g *= aa;
Toshihiro Shimizu 890ddd
				spec_b *= aa;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			/*- 元のピクセルに書き戻す -*/
Toshihiro Shimizu 890ddd
			float val;
Toshihiro Shimizu 890ddd
			/*- チャンネル範囲にクランプ -*/
Toshihiro Shimizu 890ddd
			val = spec_r * (float)PIXEL::maxChannelValue + 0.5f;
Toshihiro Shimizu 890ddd
			pix->r = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue) ? (float)PIXEL::maxChannelValue : val);
Toshihiro Shimizu 890ddd
			val = spec_g * (float)PIXEL::maxChannelValue + 0.5f;
Toshihiro Shimizu 890ddd
			pix->g = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue) ? (float)PIXEL::maxChannelValue : val);
Toshihiro Shimizu 890ddd
			val = spec_b * (float)PIXEL::maxChannelValue + 0.5f;
Toshihiro Shimizu 890ddd
			pix->b = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue) ? (float)PIXEL::maxChannelValue : val);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			pix++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------
Toshihiro Shimizu 890ddd
template <typename pixel="" raster,="" typename=""></typename>
Toshihiro Shimizu 890ddd
void Iwa_SpectrumFx::convertRasterWithLight(const RASTER ras,
Toshihiro Shimizu 890ddd
											TDimensionI dim,
Toshihiro Shimizu 890ddd
											float3 *bubbleColor,
Toshihiro Shimizu 890ddd
											const RASTER lightRas,
Toshihiro Shimizu 890ddd
											float lightThres,
Toshihiro Shimizu 890ddd
											float lightIntensity)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	float rr, gg, bb, aa;
Toshihiro Shimizu 890ddd
	float spec_r, spec_g, spec_b;
Toshihiro Shimizu 890ddd
	float brightness;
Toshihiro Shimizu 890ddd
	for (int j = 0; j < dim.ly; j++) {
Toshihiro Shimizu 890ddd
		PIXEL *light_pix = lightRas->pixels(j);
Toshihiro Shimizu 890ddd
		PIXEL *pix = ras->pixels(j);
Toshihiro Shimizu 890ddd
		for (int i = 0; i < dim.lx; i++) {
Toshihiro Shimizu 890ddd
			aa = (float)light_pix->m / PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
			if (aa == 0.0f) /*- アルファが0なら透明にする -*/
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				*pix = PIXEL::Transparent;
Toshihiro Shimizu 890ddd
				light_pix++;
Toshihiro Shimizu 890ddd
				pix++;
Toshihiro Shimizu 890ddd
				continue;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			/*- depremutiplyはしないでおく -*/
Toshihiro Shimizu 890ddd
			rr = (float)pix->r / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
			gg = (float)pix->g / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
			bb = (float)pix->b / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
			brightness = 0.298912f * rr + 0.586611f * gg + 0.114478f * bb;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			/*- 反転 -*/
Toshihiro Shimizu 890ddd
			brightness = 1.0f - brightness;
Toshihiro Shimizu 890ddd
			/*- 輝度MAXの場合 -*/
Toshihiro Shimizu 890ddd
			if (brightness >= 1.0f) {
Toshihiro Shimizu 890ddd
				spec_r = bubbleColor[255].x;
Toshihiro Shimizu 890ddd
				spec_g = bubbleColor[255].y;
Toshihiro Shimizu 890ddd
				spec_b = bubbleColor[255].z;
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				/*- 線形補間する -*/
Toshihiro Shimizu 890ddd
				int index = (int)(brightness * 255.0f);
Toshihiro Shimizu 890ddd
				float ratio = brightness * 255.0f - (float)index;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				spec_r = bubbleColor[index].x * (1.0f - ratio) +
Toshihiro Shimizu 890ddd
						 bubbleColor[index + 1].x * ratio;
Toshihiro Shimizu 890ddd
				spec_g = bubbleColor[index].y * (1.0f - ratio) +
Toshihiro Shimizu 890ddd
						 bubbleColor[index + 1].y * ratio;
Toshihiro Shimizu 890ddd
				spec_b = bubbleColor[index].z * (1.0f - ratio) +
Toshihiro Shimizu 890ddd
						 bubbleColor[index + 1].z * ratio;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			/*- ここで、Light画像とのスクリーン合成を行う -*/
Toshihiro Shimizu 890ddd
			float HDR_Factor;
Toshihiro Shimizu 890ddd
			if (aa <= lightThres ||
Toshihiro Shimizu 890ddd
				lightThres == 1.0f)
Toshihiro Shimizu 890ddd
				HDR_Factor = 0.0;
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				HDR_Factor = lightIntensity * (aa - lightThres) / (1.0 - lightThres);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			float light_r = (float)light_pix->r / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
			float light_g = (float)light_pix->g / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
			float light_b = (float)light_pix->b / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
			/*- スクリーン合成結果と虹色をHDR_Factorで混ぜる -*/
Toshihiro Shimizu 890ddd
			spec_r = (1.0f - HDR_Factor) * spec_r +
Toshihiro Shimizu 890ddd
					 HDR_Factor * (spec_r + light_r - spec_r * light_r);
Toshihiro Shimizu 890ddd
			spec_g = (1.0f - HDR_Factor) * spec_g +
Toshihiro Shimizu 890ddd
					 HDR_Factor * (spec_g + light_g - spec_g * light_g);
Toshihiro Shimizu 890ddd
			spec_b = (1.0f - HDR_Factor) * spec_b +
Toshihiro Shimizu 890ddd
					 HDR_Factor * (spec_b + light_b - spec_b * light_b);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			spec_r *= aa;
Toshihiro Shimizu 890ddd
			spec_g *= aa;
Toshihiro Shimizu 890ddd
			spec_b *= aa;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			/*- 元のピクセルに書き戻す -*/
Toshihiro Shimizu 890ddd
			float val;
Toshihiro Shimizu 890ddd
			/*- チャンネル範囲にクランプ -*/
Toshihiro Shimizu 890ddd
			val = spec_r * (float)PIXEL::maxChannelValue + 0.5f;
Toshihiro Shimizu 890ddd
			pix->r = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue) ? (float)PIXEL::maxChannelValue : val);
Toshihiro Shimizu 890ddd
			val = spec_g * (float)PIXEL::maxChannelValue + 0.5f;
Toshihiro Shimizu 890ddd
			pix->g = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue) ? (float)PIXEL::maxChannelValue : val);
Toshihiro Shimizu 890ddd
			val = spec_b * (float)PIXEL::maxChannelValue + 0.5f;
Toshihiro Shimizu 890ddd
			pix->b = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue) ? (float)PIXEL::maxChannelValue : val);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			pix->m = light_pix->m;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			pix++;
Toshihiro Shimizu 890ddd
			light_pix++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------
Toshihiro Shimizu 890ddd
 素材タイルを0〜1に正規化して格納
Toshihiro Shimizu 890ddd
------------------------------------*/
Toshihiro Shimizu 890ddd
template <typename pixel="" raster,="" typename=""></typename>
Toshihiro Shimizu 890ddd
void Iwa_SpectrumFx::setSourceRasters(
Toshihiro Shimizu 890ddd
	const RASTER ras,
Toshihiro Shimizu 890ddd
	float4 *in_out_tile_host,
Toshihiro Shimizu 890ddd
	const RASTER light_ras,
Toshihiro Shimizu 890ddd
	float4 *light_host,
Toshihiro Shimizu 890ddd
	TDimensionI dim,
Toshihiro Shimizu 890ddd
	bool useLight)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	float4 *chann_p = in_out_tile_host;
Toshihiro Shimizu 890ddd
	float4 *lightChann_p = light_host;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int j = 0; j < dim.ly; j++) {
Toshihiro Shimizu 890ddd
		PIXEL *pix = ras->pixels(j);
Toshihiro Shimizu 890ddd
		PIXEL *lightPix = (useLight) ? light_ras->pixels(j) : 0;
Toshihiro Shimizu 890ddd
		for (int i = 0; i < dim.lx; i++) {
Toshihiro Shimizu 890ddd
			(*chann_p).x = (float)pix->r / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
			(*chann_p).y = (float)pix->g / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
			(*chann_p).z = (float)pix->b / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
			(*chann_p).w = (float)pix->m / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
			pix++;
Toshihiro Shimizu 890ddd
			chann_p++;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (useLight) {
Toshihiro Shimizu 890ddd
				(*lightChann_p).x = (float)lightPix->r / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
				(*lightChann_p).y = (float)lightPix->g / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
				(*lightChann_p).z = (float)lightPix->b / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
				(*lightChann_p).w = (float)lightPix->m / (float)PIXEL::maxChannelValue;
Toshihiro Shimizu 890ddd
				lightPix++;
Toshihiro Shimizu 890ddd
				lightChann_p++;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------
Toshihiro Shimizu 890ddd
 出力結果をChannel値に変換してタイルに格納
Toshihiro Shimizu 890ddd
------------------------------------*/
Toshihiro Shimizu 890ddd
template <typename pixel="" raster,="" typename=""></typename>
Toshihiro Shimizu 890ddd
void Iwa_SpectrumFx::outputRasters(const RASTER outRas,
Toshihiro Shimizu 890ddd
								   float4 *in_out_tile_host,
Toshihiro Shimizu 890ddd
								   TDimensionI dim)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	float4 *chann_p = in_out_tile_host;
Toshihiro Shimizu 890ddd
	for (int j = 0; j < dim.ly; j++) {
Toshihiro Shimizu 890ddd
		PIXEL *pix = outRas->pixels(j);
Toshihiro Shimizu 890ddd
		for (int i = 0; i < dim.lx; i++) {
Toshihiro Shimizu 890ddd
			float val;
Toshihiro Shimizu 890ddd
			val = (*chann_p).x * (float)PIXEL::maxChannelValue + 0.5f;
Toshihiro Shimizu 890ddd
			pix->r = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue) ? (float)PIXEL::maxChannelValue : val);
Toshihiro Shimizu 890ddd
			val = (*chann_p).y * (float)PIXEL::maxChannelValue + 0.5f;
Toshihiro Shimizu 890ddd
			pix->g = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue) ? (float)PIXEL::maxChannelValue : val);
Toshihiro Shimizu 890ddd
			val = (*chann_p).z * (float)PIXEL::maxChannelValue + 0.5f;
Toshihiro Shimizu 890ddd
			pix->b = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue) ? (float)PIXEL::maxChannelValue : val);
Toshihiro Shimizu 890ddd
			val = (*chann_p).w * (float)PIXEL::maxChannelValue + 0.5f;
Toshihiro Shimizu 890ddd
			pix->m = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue) ? (float)PIXEL::maxChannelValue : val);
Toshihiro Shimizu 890ddd
			pix++;
Toshihiro Shimizu 890ddd
			chann_p++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool Iwa_SpectrumFx::doGetBBox(double frame,
Toshihiro Shimizu 890ddd
							   TRectD &bBox,
Toshihiro Shimizu 890ddd
							   const TRenderSettings &info)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_input.isConnected()) {
Toshihiro Shimizu 890ddd
		bBox = TRectD();
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return m_input->doGetBBox(frame, bBox, info);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool Iwa_SpectrumFx::canHandle(const TRenderSettings &info,
Toshihiro Shimizu 890ddd
							   double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FX_PLUGIN_IDENTIFIER(Iwa_SpectrumFx, "iwa_SpectrumFx")