|
Toshihiro Shimizu |
890ddd |
/*------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
Iwa_PNPerspectiveFx
|
|
shun-iwasawa |
267c1f |
render perspective noise pattern.
|
|
Toshihiro Shimizu |
890ddd |
------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "iwa_pnperspectivefx.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "trop.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tparamuiconcept.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "iwa_fresnel.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "iwa_simplexnoise.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "iwa_noise1234.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include <vector></vector>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
#ifndef M_PI
|
|
Toshihiro Shimizu |
890ddd |
const double M_PI = 3.1415926535897932384626433832795;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
267c1f |
inline double dot(double3 a, double3 b) {
|
|
Shinya Kitaoka |
120a6e |
return a.x * b.x + a.y * b.y + a.z * b.z;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
shun-iwasawa |
267c1f |
inline double3 cross(double3 a, double3 b) {
|
|
shun-iwasawa |
267c1f |
double3 ret = {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z,
|
|
shun-iwasawa |
267c1f |
a.x * b.y - a.y * b.x};
|
|
Shinya Kitaoka |
120a6e |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
shun-iwasawa |
267c1f |
inline double3 normalize(double3 v) {
|
|
shun-iwasawa |
267c1f |
double length = std::sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
|
|
shun-iwasawa |
267c1f |
double3 ret = {v.x / length, v.y / length, v.z / length};
|
|
Shinya Kitaoka |
120a6e |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
double getFresnel(double deg) {
|
|
shun-iwasawa |
267c1f |
if (deg < 0.0) return 0.0;
|
|
shun-iwasawa |
267c1f |
if (deg >= 90.0) return 1.0;
|
|
shun-iwasawa |
267c1f |
int index = (int)std::floor(deg);
|
|
shun-iwasawa |
267c1f |
double ratio = deg - (double)index;
|
|
shun-iwasawa |
267c1f |
return fresnel[index] * (1.0 - ratio) + fresnel[index + 1] * ratio;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
267c1f |
} // namespace
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename pixel="" raster,="" typename=""></typename>
|
|
shun-iwasawa |
267c1f |
void Iwa_PNPerspectiveFx::setOutputRaster(double4 *srcMem, const RASTER dstRas,
|
|
Shinya Kitaoka |
120a6e |
TDimensionI dim, int drawLevel,
|
|
Shinya Kitaoka |
120a6e |
const bool alp_rend_sw) {
|
|
Shinya Kitaoka |
120a6e |
typename PIXEL::Channel halfChan =
|
|
Shinya Kitaoka |
120a6e |
(typename PIXEL::Channel)(PIXEL::maxChannelValue / 2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (alp_rend_sw)
|
|
Shinya Kitaoka |
120a6e |
dstRas->fill(PIXEL(halfChan, halfChan, halfChan, halfChan));
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
dstRas->fill(PIXEL(halfChan, halfChan, halfChan));
|
|
shun-iwasawa |
267c1f |
double4 *chan_p = srcMem;
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < drawLevel; j++) {
|
|
Shinya Kitaoka |
120a6e |
PIXEL *pix = dstRas->pixels(j);
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < dstRas->getLx(); i++, chan_p++, pix++) {
|
|
shun-iwasawa |
267c1f |
double val;
|
|
shun-iwasawa |
267c1f |
val = (*chan_p).x * (double)PIXEL::maxChannelValue + 0.5;
|
|
shun-iwasawa |
267c1f |
pix->r = (typename PIXEL::Channel)((val > (double)PIXEL::maxChannelValue)
|
|
shun-iwasawa |
267c1f |
? (double)PIXEL::maxChannelValue
|
|
Shinya Kitaoka |
120a6e |
: val);
|
|
shun-iwasawa |
267c1f |
val = (*chan_p).y * (double)PIXEL::maxChannelValue + 0.5;
|
|
shun-iwasawa |
267c1f |
pix->g = (typename PIXEL::Channel)((val > (double)PIXEL::maxChannelValue)
|
|
shun-iwasawa |
267c1f |
? (double)PIXEL::maxChannelValue
|
|
Shinya Kitaoka |
120a6e |
: val);
|
|
shun-iwasawa |
267c1f |
val = (*chan_p).z * (double)PIXEL::maxChannelValue + 0.5;
|
|
shun-iwasawa |
267c1f |
pix->b = (typename PIXEL::Channel)((val > (double)PIXEL::maxChannelValue)
|
|
shun-iwasawa |
267c1f |
? (double)PIXEL::maxChannelValue
|
|
Shinya Kitaoka |
120a6e |
: val);
|
|
shun-iwasawa |
267c1f |
val = (*chan_p).w * (double)PIXEL::maxChannelValue + 0.5;
|
|
shun-iwasawa |
267c1f |
pix->m = (typename PIXEL::Channel)((val > (double)PIXEL::maxChannelValue)
|
|
shun-iwasawa |
267c1f |
? (double)PIXEL::maxChannelValue
|
|
Shinya Kitaoka |
120a6e |
: val);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
481b59 |
template <>
|
|
shun-iwasawa |
481b59 |
void Iwa_PNPerspectiveFx::setOutputRaster<trasterfp, tpixelf="">(</trasterfp,>
|
|
shun-iwasawa |
481b59 |
double4 *srcMem, const TRasterFP dstRas, TDimensionI dim, int drawLevel,
|
|
shun-iwasawa |
481b59 |
const bool alp_rend_sw) {
|
|
shun-iwasawa |
481b59 |
if (alp_rend_sw)
|
|
shun-iwasawa |
481b59 |
dstRas->fill(TPixelF(0.5f, 0.5f, 0.5f, 0.5f));
|
|
shun-iwasawa |
481b59 |
else
|
|
shun-iwasawa |
481b59 |
dstRas->fill(TPixelF(0.5f, 0.5f, 0.5f));
|
|
shun-iwasawa |
481b59 |
double4 *chan_p = srcMem;
|
|
shun-iwasawa |
481b59 |
for (int j = 0; j < drawLevel; j++) {
|
|
shun-iwasawa |
481b59 |
TPixelF *pix = dstRas->pixels(j);
|
|
shun-iwasawa |
481b59 |
for (int i = 0; i < dstRas->getLx(); i++, chan_p++, pix++) {
|
|
shun-iwasawa |
481b59 |
pix->r = (float)(*chan_p).x;
|
|
shun-iwasawa |
481b59 |
pix->g = (float)(*chan_p).y;
|
|
shun-iwasawa |
481b59 |
pix->b = (float)(*chan_p).z;
|
|
shun-iwasawa |
481b59 |
pix->m = std::min((float)(*chan_p).w, 1.f);
|
|
shun-iwasawa |
481b59 |
}
|
|
shun-iwasawa |
481b59 |
}
|
|
shun-iwasawa |
481b59 |
}
|
|
shun-iwasawa |
481b59 |
|
|
shun-iwasawa |
267c1f |
//------------------------------------------------------------
|
|
shun-iwasawa |
267c1f |
// obtain parameters
|
|
Toshihiro Shimizu |
890ddd |
void Iwa_PNPerspectiveFx::getPNParameters(TTile &tile, double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &settings,
|
|
Shinya Kitaoka |
120a6e |
PN_Params ¶ms,
|
|
Shinya Kitaoka |
120a6e |
TDimensionI &dimOut) {
|
|
shun-iwasawa |
267c1f |
params.renderMode = (PN_Params::RenderMode)m_renderMode->getValue();
|
|
shun-iwasawa |
267c1f |
params.noiseType = (PN_Params::NoiseType)m_noiseType->getValue();
|
|
shun-iwasawa |
267c1f |
params.size = m_size->getValue(frame);
|
|
shun-iwasawa |
267c1f |
// adjust size of Simplex Noise to be with the same density as Perlin Noise
|
|
shun-iwasawa |
267c1f |
if (params.noiseType == PN_Params::Simplex) params.size *= std::sqrt(2.0);
|
|
shun-iwasawa |
267c1f |
params.octaves = m_octaves->getValue() + 1;
|
|
shun-iwasawa |
267c1f |
params.offset = m_offset->getValue(frame);
|
|
shun-iwasawa |
267c1f |
params.p_intensity = m_persistance_intensity->getValue(frame);
|
|
shun-iwasawa |
267c1f |
params.p_size = m_persistance_size->getValue(frame);
|
|
shun-iwasawa |
267c1f |
params.p_offset = m_persistance_offset->getValue(frame);
|
|
shun-iwasawa |
267c1f |
params.eyeLevel = m_eyeLevel->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
params.alp_rend_sw = m_alpha_rendering->getValue();
|
|
shun-iwasawa |
267c1f |
params.waveHeight = m_waveHeight->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
267c1f |
double fov = m_fov->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
267c1f |
TAffine aff = settings.m_affine;
|
|
shun-iwasawa |
267c1f |
double scale = 1.0 / std::sqrt(std::abs(aff.det()));
|
|
shun-iwasawa |
267c1f |
params.aff = TScale(scale) * TTranslation(tile.m_pos);
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
267c1f |
params.time = m_evolution->getValue(frame) * 0.05;
|
|
shun-iwasawa |
267c1f |
params.p_evolution = m_persistance_evolution->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD eyePoint =
|
|
shun-iwasawa |
267c1f |
aff * params.eyeLevel - (tile.m_pos + tile.getRaster()->getCenterD());
|
|
shun-iwasawa |
267c1f |
double eyeHeight = eyePoint.y;
|
|
shun-iwasawa |
267c1f |
// distance from the bottom of the render region to the eye level
|
|
shun-iwasawa |
267c1f |
params.drawLevel = (int)((double)dimOut.ly / 2.0 + eyeHeight);
|
|
Shinya Kitaoka |
120a6e |
if (params.drawLevel > dimOut.ly) params.drawLevel = dimOut.ly;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int camHeight = settings.m_cameraBox.getLy();
|
|
shun-iwasawa |
267c1f |
TPointD vec_p0p1((double)camHeight * params.aff.a12,
|
|
shun-iwasawa |
267c1f |
(double)camHeight * params.aff.a22);
|
|
shun-iwasawa |
267c1f |
params.fy_2 =
|
|
shun-iwasawa |
267c1f |
std::sqrt(vec_p0p1.x * vec_p0p1.x + vec_p0p1.y * vec_p0p1.y) / 2.0;
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
double fov_radian_2 = (fov / 2.0) * M_PI_180;
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
// distance from the camera to the center of projection plane
|
|
shun-iwasawa |
267c1f |
double D = params.fy_2 / std::tan(fov_radian_2);
|
|
shun-iwasawa |
267c1f |
// distance from the camera to the projected point of the horizon
|
|
shun-iwasawa |
267c1f |
params.A = std::sqrt(params.eyeLevel.y * params.eyeLevel.y + D * D);
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
// angle between horizon and the vector [ camera center - bottom of the camera
|
|
shun-iwasawa |
267c1f |
// frame ]
|
|
shun-iwasawa |
267c1f |
double theta = fov_radian_2 + std::asin(params.eyeLevel.y / params.A);
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
double M = params.fy_2 / std::sin(fov_radian_2);
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
params.cam_pos = double3{0.0, -M * std::cos(theta), M * std::sin(theta)};
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
// compute normalize range
|
|
shun-iwasawa |
267c1f |
params.base_fresnel_ref = 0.0;
|
|
shun-iwasawa |
267c1f |
params.top_fresnel_ref = 1.0;
|
|
shun-iwasawa |
267c1f |
if (params.renderMode == PN_Params::Fresnel &&
|
|
shun-iwasawa |
267c1f |
m_normalize_fresnel->getValue()) {
|
|
shun-iwasawa |
267c1f |
double phi = 90.0 - theta * M_180_PI;
|
|
shun-iwasawa |
267c1f |
params.base_fresnel_ref = getFresnel(phi);
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
// frsnel value at the upper-side corner of the camera frame
|
|
shun-iwasawa |
267c1f |
double fx_2 =
|
|
shun-iwasawa |
267c1f |
params.fy_2 * (double)settings.m_cameraBox.getLx() / (double)camHeight;
|
|
shun-iwasawa |
267c1f |
double side_A = std::sqrt(fx_2 * fx_2 + params.A * params.A);
|
|
shun-iwasawa |
267c1f |
double top_theta = -fov_radian_2 + std::asin(params.eyeLevel.y / side_A);
|
|
shun-iwasawa |
267c1f |
phi = 90.0 - top_theta * M_180_PI;
|
|
shun-iwasawa |
267c1f |
params.top_fresnel_ref = getFresnel(phi);
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
double marginRatio = m_normalize_margin->getValue(frame);
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
// adding margin
|
|
shun-iwasawa |
267c1f |
double margin =
|
|
shun-iwasawa |
267c1f |
(params.top_fresnel_ref - params.base_fresnel_ref) * marginRatio;
|
|
shun-iwasawa |
267c1f |
params.base_fresnel_ref = std::max(0.0, params.base_fresnel_ref - margin);
|
|
shun-iwasawa |
267c1f |
params.top_fresnel_ref = std::min(1.0, params.top_fresnel_ref + margin);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
267c1f |
// for normalizing intensity
|
|
shun-iwasawa |
267c1f |
double intensity = 2.0; // from -1 to 1
|
|
shun-iwasawa |
267c1f |
params.int_sum = 0.0;
|
|
Shinya Kitaoka |
120a6e |
for (int o = 0; o < params.octaves; o++) {
|
|
Shinya Kitaoka |
120a6e |
params.int_sum += intensity;
|
|
Shinya Kitaoka |
120a6e |
intensity *= params.p_intensity;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Iwa_PNPerspectiveFx::Iwa_PNPerspectiveFx()
|
|
shun-iwasawa |
267c1f |
: m_renderMode(new TIntEnumParam(PN_Params::Noise, "Noise"))
|
|
shun-iwasawa |
267c1f |
, m_noiseType(new TIntEnumParam(PN_Params::Perlin, "Perlin Noise"))
|
|
Shinya Kitaoka |
120a6e |
, m_size(10.0)
|
|
Shinya Kitaoka |
120a6e |
, m_evolution(0.0)
|
|
Shinya Kitaoka |
120a6e |
, m_octaves(new TIntEnumParam(0, "1"))
|
|
Shinya Kitaoka |
120a6e |
, m_offset(TPointD(0, 0))
|
|
Shinya Kitaoka |
120a6e |
, m_persistance_intensity(0.5)
|
|
Shinya Kitaoka |
120a6e |
, m_persistance_size(0.5)
|
|
Shinya Kitaoka |
120a6e |
, m_persistance_evolution(0.5)
|
|
Shinya Kitaoka |
120a6e |
, m_persistance_offset(0.5)
|
|
Shinya Kitaoka |
120a6e |
, m_fov(30)
|
|
Shinya Kitaoka |
120a6e |
, m_eyeLevel(TPointD(0, 0))
|
|
Shinya Kitaoka |
120a6e |
, m_alpha_rendering(true)
|
|
shun-iwasawa |
267c1f |
, m_waveHeight(10.0)
|
|
shun-iwasawa |
267c1f |
, m_normalize_fresnel(false)
|
|
shun-iwasawa |
267c1f |
, m_normalize_margin(0.1) {
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "renderMode", m_renderMode);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "noiseType", m_noiseType);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "size", m_size);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "evolution", m_evolution);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "octaves", m_octaves);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "offset", m_offset);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "persistance_intensity", m_persistance_intensity);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "persistance_size", m_persistance_size);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "persistance_evolution", m_persistance_evolution);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "persistance_offset", m_persistance_offset);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "fov", m_fov);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "eyeLevel", m_eyeLevel);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "alpha_rendering", m_alpha_rendering);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "waveHeight", m_waveHeight);
|
|
shun-iwasawa |
267c1f |
bindParam(this, "normalize_fresnel", m_normalize_fresnel);
|
|
shun-iwasawa |
267c1f |
bindParam(this, "normalize_margin", m_normalize_margin);
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
267c1f |
m_noiseType->addItem(PN_Params::Simplex, "Simplex Noise");
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
267c1f |
m_renderMode->addItem(PN_Params::Noise_NoResample, "Noise (no resampled)");
|
|
shun-iwasawa |
267c1f |
m_renderMode->addItem(PN_Params::WarpHV, "Warp HV offset");
|
|
shun-iwasawa |
267c1f |
m_renderMode->addItem(PN_Params::WarpHV2, "Warp HV offset 2");
|
|
shun-iwasawa |
267c1f |
m_renderMode->addItem(PN_Params::Fresnel, "Fresnel reflectivity");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_size->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_size->setValueRange(0.0, 1000.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_octaves->addItem(1, "2");
|
|
Shinya Kitaoka |
120a6e |
m_octaves->addItem(2, "3");
|
|
Shinya Kitaoka |
120a6e |
m_octaves->addItem(3, "4");
|
|
Shinya Kitaoka |
120a6e |
m_octaves->addItem(4, "5");
|
|
Shinya Kitaoka |
120a6e |
m_octaves->addItem(5, "6");
|
|
Shinya Kitaoka |
120a6e |
m_octaves->addItem(6, "7");
|
|
Shinya Kitaoka |
120a6e |
m_octaves->addItem(7, "8");
|
|
Shinya Kitaoka |
120a6e |
m_octaves->addItem(8, "9");
|
|
Shinya Kitaoka |
120a6e |
m_octaves->addItem(9, "10");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_persistance_intensity->setValueRange(0.1, 2.0);
|
|
Shinya Kitaoka |
120a6e |
m_persistance_size->setValueRange(0.1, 2.0);
|
|
Shinya Kitaoka |
120a6e |
m_persistance_evolution->setValueRange(0.1, 2.0);
|
|
Shinya Kitaoka |
120a6e |
m_persistance_offset->setValueRange(0.1, 2.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_fov->setValueRange(10, 90);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_eyeLevel->getX()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_eyeLevel->getY()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_waveHeight->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_waveHeight->setValueRange(1.0, 100.0);
|
|
shun-iwasawa |
267c1f |
m_normalize_margin->setValueRange(0.0, 3.0);
|
|
shun-iwasawa |
481b59 |
|
|
shun-iwasawa |
481b59 |
enableComputeInFloat(true);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool Iwa_PNPerspectiveFx::doGetBBox(double frame, TRectD &bBox,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &info) {
|
|
Shinya Kitaoka |
120a6e |
bBox = TConsts::infiniteRectD;
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool Iwa_PNPerspectiveFx::canHandle(const TRenderSettings &info, double frame) {
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void Iwa_PNPerspectiveFx::doCompute(TTile &tile, double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &settings) {
|
|
shun-iwasawa |
481b59 |
if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster()) &&
|
|
shun-iwasawa |
481b59 |
!((TRasterFP)tile.getRaster())) {
|
|
Shinya Kitaoka |
120a6e |
throw TRopException("unsupported input pixel type");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TDimensionI dimOut(tile.getRaster()->getLx(), tile.getRaster()->getLy());
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
267c1f |
// obtain parameters
|
|
Shinya Kitaoka |
120a6e |
PN_Params pnParams;
|
|
Shinya Kitaoka |
120a6e |
getPNParameters(tile, frame, settings, pnParams, dimOut);
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
267c1f |
// return if the horizon is below the rendering area
|
|
Shinya Kitaoka |
120a6e |
if (pnParams.drawLevel < 0) {
|
|
Shinya Kitaoka |
120a6e |
tile.getRaster()->clear();
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
267c1f |
double evolution = m_evolution->getValue(frame);
|
|
shun-iwasawa |
267c1f |
double p_evolution = m_persistance_evolution->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
267c1f |
double4 *out_host;
|
|
shun-iwasawa |
267c1f |
// allocate buffer
|
|
shun-iwasawa |
267c1f |
TRasterGR8P out_host_ras(sizeof(double4) * dimOut.lx, pnParams.drawLevel);
|
|
Shinya Kitaoka |
120a6e |
out_host_ras->lock();
|
|
shun-iwasawa |
267c1f |
out_host = (double4 *)out_host_ras->getRawData();
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
481b59 |
doCompute_CPU(frame, settings, out_host, dimOut, pnParams);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
tile.getRaster()->clear();
|
|
Shinya Kitaoka |
120a6e |
TRaster32P outRas32 = (TRaster32P)tile.getRaster();
|
|
Shinya Kitaoka |
120a6e |
TRaster64P outRas64 = (TRaster64P)tile.getRaster();
|
|
shun-iwasawa |
481b59 |
TRasterFP outRasF = (TRasterFP)tile.getRaster();
|
|
Shinya Kitaoka |
120a6e |
if (outRas32)
|
|
Shinya Kitaoka |
120a6e |
setOutputRaster<traster32p, tpixel32="">(</traster32p,>
|
|
Shinya Kitaoka |
120a6e |
out_host, outRas32, dimOut, pnParams.drawLevel, pnParams.alp_rend_sw);
|
|
Shinya Kitaoka |
120a6e |
else if (outRas64)
|
|
Shinya Kitaoka |
120a6e |
setOutputRaster<traster64p, tpixel64="">(</traster64p,>
|
|
Shinya Kitaoka |
120a6e |
out_host, outRas64, dimOut, pnParams.drawLevel, pnParams.alp_rend_sw);
|
|
shun-iwasawa |
481b59 |
else if (outRasF)
|
|
shun-iwasawa |
481b59 |
setOutputRaster<trasterfp, tpixelf="">(</trasterfp,>
|
|
shun-iwasawa |
481b59 |
out_host, outRasF, dimOut, pnParams.drawLevel, pnParams.alp_rend_sw);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
out_host_ras->unlock();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
shun-iwasawa |
481b59 |
void Iwa_PNPerspectiveFx::doCompute_CPU(double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &settings,
|
|
shun-iwasawa |
267c1f |
double4 *out_host, TDimensionI &dimOut,
|
|
Shinya Kitaoka |
120a6e |
PN_Params &pnParams) {
|
|
shun-iwasawa |
267c1f |
if (pnParams.renderMode == PN_Params::Noise ||
|
|
shun-iwasawa |
267c1f |
pnParams.renderMode == PN_Params::Noise_NoResample) {
|
|
Shinya Kitaoka |
120a6e |
calcPerinNoise_CPU(out_host, dimOut, pnParams,
|
|
shun-iwasawa |
267c1f |
pnParams.renderMode == PN_Params::Noise);
|
|
shun-iwasawa |
267c1f |
} else if (pnParams.renderMode == PN_Params::WarpHV ||
|
|
shun-iwasawa |
267c1f |
pnParams.renderMode == PN_Params::Fresnel ||
|
|
shun-iwasawa |
267c1f |
pnParams.renderMode == PN_Params::WarpHV2) {
|
|
Shinya Kitaoka |
120a6e |
calcPNNormal_CPU(out_host, dimOut, pnParams);
|
|
shun-iwasawa |
267c1f |
if (pnParams.renderMode == PN_Params::WarpHV2) {
|
|
Shinya Kitaoka |
120a6e |
calcPNNormal_CPU(out_host, dimOut, pnParams, true);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
267c1f |
//------------------------------------------------------------
|
|
shun-iwasawa |
267c1f |
// render for 2 Noise modes
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
void Iwa_PNPerspectiveFx::calcPerinNoise_CPU(double4 *out_host,
|
|
Shinya Kitaoka |
120a6e |
TDimensionI &dimOut, PN_Params &p,
|
|
Shinya Kitaoka |
120a6e |
bool doResample) {
|
|
shun-iwasawa |
267c1f |
int reso = (doResample) ? 10 : 1;
|
|
shun-iwasawa |
267c1f |
double4 *out_p = out_host;
|
|
shun-iwasawa |
267c1f |
// compute for each pixel
|
|
Shinya Kitaoka |
120a6e |
for (int yy = 0; yy < p.drawLevel; yy++) {
|
|
Shinya Kitaoka |
120a6e |
for (int xx = 0; xx < dimOut.lx; xx++, out_p++) {
|
|
shun-iwasawa |
267c1f |
double val_sum = 0.0;
|
|
shun-iwasawa |
267c1f |
int count = 0;
|
|
shun-iwasawa |
267c1f |
// for each sampling points
|
|
Shinya Kitaoka |
120a6e |
for (int tt = 0; tt < reso; tt++) {
|
|
Shinya Kitaoka |
120a6e |
for (int ss = 0; ss < reso; ss++) {
|
|
shun-iwasawa |
267c1f |
TPointD tmpPixPos(
|
|
shun-iwasawa |
267c1f |
(double)xx - 0.5 + ((double)ss + 0.5) / (double)reso,
|
|
shun-iwasawa |
267c1f |
(double)yy - 0.5 + ((double)tt + 0.5) / (double)reso);
|
|
shun-iwasawa |
267c1f |
TPointD screenPos = p.aff * tmpPixPos;
|
|
shun-iwasawa |
267c1f |
// compute coordinate on the noise plane
|
|
shun-iwasawa |
267c1f |
TPointD noisePos;
|
|
Shinya Kitaoka |
120a6e |
noisePos.x = -(p.eyeLevel.y + p.fy_2) * (screenPos.x - p.eyeLevel.x) /
|
|
Shinya Kitaoka |
120a6e |
(screenPos.y - p.eyeLevel.y) +
|
|
Shinya Kitaoka |
120a6e |
p.eyeLevel.x;
|
|
Shinya Kitaoka |
120a6e |
noisePos.y =
|
|
Shinya Kitaoka |
120a6e |
(p.fy_2 + screenPos.y) * p.A / (p.eyeLevel.y - screenPos.y);
|
|
shun-iwasawa |
267c1f |
double tmpVal = 0.5;
|
|
shun-iwasawa |
267c1f |
double currentSize = p.size;
|
|
shun-iwasawa |
267c1f |
TPointD currentOffset = p.offset;
|
|
shun-iwasawa |
267c1f |
double currentIntensity = 1.0;
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
267c1f |
double currentEvolution = p.time;
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
267c1f |
// sum noise values
|
|
Shinya Kitaoka |
120a6e |
for (int o = 0; o < p.octaves; o++) {
|
|
shun-iwasawa |
267c1f |
TPointD currentNoisePos =
|
|
shun-iwasawa |
267c1f |
(noisePos - currentOffset) * (1.0 / currentSize);
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
267c1f |
if (p.noiseType == PN_Params::Perlin) {
|
|
Shinya Kitaoka |
120a6e |
tmpVal += currentIntensity *
|
|
Shinya Kitaoka |
120a6e |
Noise1234::noise(currentNoisePos.x, currentNoisePos.y,
|
|
Shinya Kitaoka |
120a6e |
currentEvolution) /
|
|
Shinya Kitaoka |
120a6e |
p.int_sum;
|
|
shun-iwasawa |
267c1f |
} else { // Simplex case
|
|
Shinya Kitaoka |
120a6e |
tmpVal +=
|
|
Shinya Kitaoka |
120a6e |
currentIntensity *
|
|
Shinya Kitaoka |
120a6e |
SimplexNoise::noise(currentNoisePos.x, currentNoisePos.y,
|
|
Shinya Kitaoka |
120a6e |
currentEvolution) /
|
|
Shinya Kitaoka |
120a6e |
p.int_sum;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
currentSize *= p.p_size;
|
|
Shinya Kitaoka |
120a6e |
currentOffset.x *= p.p_offset;
|
|
Shinya Kitaoka |
120a6e |
currentOffset.y *= p.p_offset;
|
|
Shinya Kitaoka |
120a6e |
currentIntensity *= p.p_intensity;
|
|
Shinya Kitaoka |
120a6e |
currentEvolution *= p.p_evolution;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
val_sum += tmpVal;
|
|
Shinya Kitaoka |
120a6e |
count += 1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
267c1f |
double val = val_sum / (double)count;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
(*out_p).x = val;
|
|
Shinya Kitaoka |
120a6e |
(*out_p).y = val;
|
|
Shinya Kitaoka |
120a6e |
(*out_p).z = val;
|
|
shun-iwasawa |
481b59 |
if (p.alp_rend_sw) // clamp
|
|
shun-iwasawa |
481b59 |
(*out_p).w = (val < 0.0) ? 0.0 : ((val > 1.0) ? 1.0 : val);
|
|
shun-iwasawa |
481b59 |
else
|
|
shun-iwasawa |
481b59 |
(*out_p).w = 1.0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
267c1f |
//------------------------------------------------------------
|
|
shun-iwasawa |
267c1f |
// render WarpHV / Fresnel modes
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
void Iwa_PNPerspectiveFx::calcPNNormal_CPU(double4 *out_host,
|
|
Shinya Kitaoka |
120a6e |
TDimensionI &dimOut, PN_Params &p,
|
|
Shinya Kitaoka |
120a6e |
bool isSubWave) {
|
|
shun-iwasawa |
267c1f |
double4 *out_p = out_host;
|
|
shun-iwasawa |
267c1f |
// compute for each pixel
|
|
Shinya Kitaoka |
120a6e |
for (int yy = 0; yy < p.drawLevel; yy++) {
|
|
Shinya Kitaoka |
120a6e |
for (int xx = 0; xx < dimOut.lx; xx++, out_p++) {
|
|
shun-iwasawa |
267c1f |
TPointD screenPos = p.aff * TPointD((double)xx, (double)yy);
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
267c1f |
// compute coordinate on the noise plane
|
|
shun-iwasawa |
267c1f |
TPointD noisePos;
|
|
Shinya Kitaoka |
120a6e |
noisePos.x = -(p.eyeLevel.y + p.fy_2) * (screenPos.x - p.eyeLevel.x) /
|
|
Shinya Kitaoka |
120a6e |
(screenPos.y - p.eyeLevel.y) +
|
|
Shinya Kitaoka |
120a6e |
p.eyeLevel.x;
|
|
Shinya Kitaoka |
120a6e |
noisePos.y = (p.fy_2 + screenPos.y) * p.A / (p.eyeLevel.y - screenPos.y);
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
267c1f |
double gradient[2]; // 0 : horizontal 1 : vertical
|
|
shun-iwasawa |
267c1f |
double delta = 0.001;
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
for (int hv = 0; hv < 2; hv++) {
|
|
shun-iwasawa |
267c1f |
// initialize gradient
|
|
shun-iwasawa |
267c1f |
gradient[hv] = 0.0;
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
// compute offset of sampling position
|
|
shun-iwasawa |
267c1f |
TPointD neighborNoisePos[2] = {
|
|
shun-iwasawa |
267c1f |
TPointD(noisePos.x - ((hv == 0) ? delta : 0.0),
|
|
shun-iwasawa |
267c1f |
noisePos.y - ((hv == 0) ? 0.0 : delta)),
|
|
shun-iwasawa |
267c1f |
TPointD(noisePos.x + ((hv == 0) ? delta : 0.0),
|
|
shun-iwasawa |
267c1f |
noisePos.y + ((hv == 0) ? 0.0 : delta))};
|
|
shun-iwasawa |
267c1f |
double currentSize = p.size;
|
|
shun-iwasawa |
267c1f |
TPointD currentOffset = p.offset;
|
|
shun-iwasawa |
267c1f |
double currentIntensity = 1.0;
|
|
shun-iwasawa |
267c1f |
double currentEvolution = (isSubWave) ? p.time + 100.0 : p.time;
|
|
shun-iwasawa |
267c1f |
// for each generation
|
|
Shinya Kitaoka |
120a6e |
for (int o = 0; o < p.octaves; o++, currentSize *= p.p_size,
|
|
Shinya Kitaoka |
120a6e |
currentOffset.x *= p.p_offset, currentOffset.y *= p.p_offset,
|
|
Shinya Kitaoka |
120a6e |
currentIntensity *= p.p_intensity) {
|
|
shun-iwasawa |
267c1f |
// compute offset noise position
|
|
shun-iwasawa |
267c1f |
TPointD currentOffsetNoisePos[2];
|
|
Shinya Kitaoka |
120a6e |
for (int mp = 0; mp < 2; mp++)
|
|
Shinya Kitaoka |
120a6e |
currentOffsetNoisePos[mp] =
|
|
shun-iwasawa |
267c1f |
(neighborNoisePos[mp] - currentOffset) * (1.0 / currentSize);
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
267c1f |
// sum noise values differences
|
|
shun-iwasawa |
267c1f |
double noiseDiff;
|
|
Shinya Kitaoka |
120a6e |
// Perlin Noise
|
|
shun-iwasawa |
267c1f |
if (p.noiseType == PN_Params::Perlin) {
|
|
Shinya Kitaoka |
120a6e |
noiseDiff =
|
|
Shinya Kitaoka |
120a6e |
Noise1234::noise(currentOffsetNoisePos[1].x,
|
|
Shinya Kitaoka |
120a6e |
currentOffsetNoisePos[1].y, currentEvolution) -
|
|
Shinya Kitaoka |
120a6e |
Noise1234::noise(currentOffsetNoisePos[0].x,
|
|
Shinya Kitaoka |
120a6e |
currentOffsetNoisePos[0].y, currentEvolution);
|
|
shun-iwasawa |
267c1f |
} else { // Simplex
|
|
shun-iwasawa |
267c1f |
// compute cell indexes
|
|
shun-iwasawa |
267c1f |
CellIds neighborIds[2] = {
|
|
Shinya Kitaoka |
120a6e |
SimplexNoise::getCellIds(currentOffsetNoisePos[0].x,
|
|
Shinya Kitaoka |
120a6e |
currentOffsetNoisePos[0].y,
|
|
Shinya Kitaoka |
120a6e |
currentEvolution),
|
|
Shinya Kitaoka |
120a6e |
SimplexNoise::getCellIds(currentOffsetNoisePos[1].x,
|
|
Shinya Kitaoka |
120a6e |
currentOffsetNoisePos[1].y,
|
|
Shinya Kitaoka |
120a6e |
currentEvolution)};
|
|
shun-iwasawa |
267c1f |
// simply compute difference if points are in the same cell
|
|
shun-iwasawa |
267c1f |
if (neighborIds[0] == neighborIds[1]) {
|
|
Shinya Kitaoka |
120a6e |
noiseDiff = SimplexNoise::noise(currentOffsetNoisePos[1].x,
|
|
Shinya Kitaoka |
120a6e |
currentOffsetNoisePos[1].y,
|
|
Shinya Kitaoka |
120a6e |
currentEvolution) -
|
|
Shinya Kitaoka |
120a6e |
SimplexNoise::noise(currentOffsetNoisePos[0].x,
|
|
Shinya Kitaoka |
120a6e |
currentOffsetNoisePos[0].y,
|
|
Shinya Kitaoka |
120a6e |
currentEvolution);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
luz paz |
6454c4 |
// use center cell id if points are in the different cells
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
shun-iwasawa |
267c1f |
TPointD currentCenterNoisePos =
|
|
shun-iwasawa |
267c1f |
(noisePos - currentOffset) * (1.0 / currentSize);
|
|
Shinya Kitaoka |
120a6e |
CellIds centerIds = SimplexNoise::getCellIds(
|
|
Shinya Kitaoka |
120a6e |
currentCenterNoisePos.x, currentCenterNoisePos.y,
|
|
Shinya Kitaoka |
120a6e |
currentEvolution);
|
|
shun-iwasawa |
267c1f |
if (neighborIds[0] == centerIds) {
|
|
Shinya Kitaoka |
120a6e |
noiseDiff = SimplexNoise::noise(currentCenterNoisePos.x,
|
|
Shinya Kitaoka |
120a6e |
currentCenterNoisePos.y,
|
|
Shinya Kitaoka |
120a6e |
currentEvolution) -
|
|
Shinya Kitaoka |
120a6e |
SimplexNoise::noise(currentOffsetNoisePos[0].x,
|
|
Shinya Kitaoka |
120a6e |
currentOffsetNoisePos[0].y,
|
|
Shinya Kitaoka |
120a6e |
currentEvolution);
|
|
shun-iwasawa |
267c1f |
} else // if(neighborIds[1] == centerIds)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
noiseDiff = SimplexNoise::noise(currentOffsetNoisePos[1].x,
|
|
Shinya Kitaoka |
120a6e |
currentOffsetNoisePos[1].y,
|
|
Shinya Kitaoka |
120a6e |
currentEvolution) -
|
|
Shinya Kitaoka |
120a6e |
SimplexNoise::noise(currentCenterNoisePos.x,
|
|
Shinya Kitaoka |
120a6e |
currentCenterNoisePos.y,
|
|
Shinya Kitaoka |
120a6e |
currentEvolution);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
shun-iwasawa |
267c1f |
// multiply the difference
|
|
shun-iwasawa |
267c1f |
// 片端→中心の変位を使っているので、片端→片端に合わせて変位を2倍する
|
|
shun-iwasawa |
267c1f |
noiseDiff *= 2.0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
shun-iwasawa |
267c1f |
// sum gradient
|
|
shun-iwasawa |
267c1f |
gradient[hv] += currentIntensity * noiseDiff / p.int_sum;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
currentEvolution *= p.p_evolution;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
267c1f |
// compute neighbor vectors
|
|
shun-iwasawa |
267c1f |
double3 vec_x = {delta * 2, 0.0, gradient[0] * p.waveHeight};
|
|
shun-iwasawa |
267c1f |
double3 vec_y = {0.0, delta * 2, gradient[1] * p.waveHeight};
|
|
shun-iwasawa |
267c1f |
double3 normal = normalize(cross(vec_x, vec_y));
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
// camera to the center of projection plane
|
|
shun-iwasawa |
267c1f |
double3 cam_vec = {noisePos.x - p.cam_pos.x, noisePos.y - p.cam_pos.y,
|
|
shun-iwasawa |
267c1f |
-p.cam_pos.z};
|
|
shun-iwasawa |
267c1f |
cam_vec = normalize(cam_vec);
|
|
shun-iwasawa |
267c1f |
if (p.renderMode == PN_Params::WarpHV ||
|
|
shun-iwasawa |
267c1f |
p.renderMode == PN_Params::WarpHV2) {
|
|
luz paz |
6454c4 |
// reflected vector from the plane
|
|
shun-iwasawa |
267c1f |
double alpha = dot(normal, cam_vec);
|
|
shun-iwasawa |
267c1f |
double3 reflect_cam = {
|
|
shun-iwasawa |
267c1f |
2.0 * alpha * normal.x - cam_vec.x,
|
|
shun-iwasawa |
267c1f |
2.0 * alpha * normal.y - cam_vec.y,
|
|
shun-iwasawa |
267c1f |
2.0 * alpha * normal.z -
|
|
shun-iwasawa |
267c1f |
cam_vec.z}; // the length of this vector should be 1
|
|
shun-iwasawa |
267c1f |
// reflection vector if the plane is flat
|
|
shun-iwasawa |
267c1f |
double3 reflect_cam_mirror = {cam_vec.x, cam_vec.y, -cam_vec.z};
|
|
shun-iwasawa |
267c1f |
// compute the angle difference
|
|
shun-iwasawa |
267c1f |
// between the range from -PI/2 to PI/2
|
|
shun-iwasawa |
267c1f |
double angle_h = std::atan(reflect_cam.x / reflect_cam.y) -
|
|
shun-iwasawa |
267c1f |
std::atan(reflect_cam_mirror.x / reflect_cam_mirror.y);
|
|
shun-iwasawa |
267c1f |
double angle_v = std::atan(reflect_cam.z / reflect_cam.y) -
|
|
shun-iwasawa |
267c1f |
std::atan(reflect_cam_mirror.z / reflect_cam_mirror.y);
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
// maximum 30 degrees
|
|
shun-iwasawa |
267c1f |
angle_h = 0.5 + angle_h / 0.5236f;
|
|
shun-iwasawa |
267c1f |
angle_v = 0.5 - angle_v / 0.5236f;
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
// clamp
|
|
shun-iwasawa |
267c1f |
angle_h = (angle_h < 0.0) ? 0.0 : ((angle_h > 1.0) ? 1.0 : angle_h);
|
|
shun-iwasawa |
267c1f |
angle_v = (angle_v < 0.0) ? 0.0 : ((angle_v > 1.0) ? 1.0 : angle_v);
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
if (p.renderMode == PN_Params::WarpHV) {
|
|
Shinya Kitaoka |
120a6e |
(*out_p).x = angle_h;
|
|
Shinya Kitaoka |
120a6e |
(*out_p).y = angle_v;
|
|
shun-iwasawa |
267c1f |
(*out_p).z = 0.0;
|
|
shun-iwasawa |
267c1f |
(*out_p).w = 1.0;
|
|
shun-iwasawa |
267c1f |
} else // WarpHV2 case
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (!isSubWave) {
|
|
Shinya Kitaoka |
120a6e |
(*out_p).y = angle_v;
|
|
shun-iwasawa |
267c1f |
(*out_p).z = 0.0;
|
|
shun-iwasawa |
267c1f |
(*out_p).w = 1.0;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
(*out_p).x = angle_v;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
shun-iwasawa |
267c1f |
// fresnel refrection mode
|
|
shun-iwasawa |
267c1f |
else if (p.renderMode == PN_Params::Fresnel) {
|
|
shun-iwasawa |
267c1f |
cam_vec.x *= -1.0;
|
|
shun-iwasawa |
267c1f |
cam_vec.y *= -1.0;
|
|
shun-iwasawa |
267c1f |
cam_vec.z *= -1.0;
|
|
shun-iwasawa |
267c1f |
double diffuse_angle = std::acos(dot(normal, cam_vec)) * M_180_PI;
|
|
shun-iwasawa |
267c1f |
double fresnel_ref = getFresnel(diffuse_angle);
|
|
shun-iwasawa |
267c1f |
double ref = (fresnel_ref - p.base_fresnel_ref) /
|
|
shun-iwasawa |
267c1f |
(p.top_fresnel_ref - p.base_fresnel_ref);
|
|
shun-iwasawa |
267c1f |
|
|
shun-iwasawa |
267c1f |
// clamp
|
|
shun-iwasawa |
267c1f |
ref = (ref < 0.0) ? 0.0 : ((ref > 1.0) ? 1.0 : ref);
|
|
Shinya Kitaoka |
120a6e |
(*out_p).x = ref;
|
|
Shinya Kitaoka |
120a6e |
(*out_p).y = ref;
|
|
Shinya Kitaoka |
120a6e |
(*out_p).z = ref;
|
|
shun-iwasawa |
267c1f |
(*out_p).w = (p.alp_rend_sw) ? ref : 1.0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void Iwa_PNPerspectiveFx::getParamUIs(TParamUIConcept *&concepts, int &length) {
|
|
Shinya Kitaoka |
120a6e |
concepts = new TParamUIConcept[length = 1];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
concepts[0].m_type = TParamUIConcept::POINT;
|
|
Shinya Kitaoka |
120a6e |
concepts[0].m_label = "Eye Level";
|
|
Shinya Kitaoka |
120a6e |
concepts[0].m_params.push_back(m_eyeLevel);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
FX_PLUGIN_IDENTIFIER(Iwa_PNPerspectiveFx, "iwa_PNPerspectiveFx");
|