mitsuba-af602c6fd98a/src/bsdfs/irawan.cpp
/** parameters:
	 *	u	 to be compared to u(v) in texturing
	 *	v	 for filament, we compute u(v)
	 *	om_i  incident direction
	 *	om_r  exitant direction
	 *	ss	filament smoothing parameter
	 *  fiber properties
	 *	alpha uniform scattering
	 *	beta  forward scattering
	 *  yarn geometry
	 *	psi   fiber twist angle; because this is filament, psi = pi/2
	 *	umax  maximum inclination angle
	 *	kappa spine curvature parameter
	 *  weave pattern
	 *	w	 width of segment rectangle
	 *	l	 length of segment rectangle
	 */
u        to be compared to u(v) in texturing
v        for filament, we compute u(v)
om_i  incident direction
om_r  exitant direction
ss      filament smoothing parameter
fiber properties
alpha uniform scattering
beta  forward scattering
yarn geometry
psi   fiber twist angle; because this is filament, psi = pi/2
umax  maximum inclination angle
kappa spine curvature parameter
weave pattern
w        width of segment rectangle
l        length of segment rectangle
u to be compared to u ( v ) in texturing v for filament we compute u ( v ) om_i incident direction om_r exitant direction ss filament smoothing parameter fiber properties alpha uniform scattering beta forward scattering yarn geometry psi fiber twist angle ; because this is filament psi = pi / 2 umax maximum inclination angle kappa spine curvature parameter weave pattern w width of segment rectangle l length of segment rectangle
Float evalFilamentIntegrand(Float u, Float v, const Vector &om_i,
			const Vector &om_r, Float alpha, Float beta, Float ss,
			Float umax, Float kappa, Float w, Float l) const {
		if (ss < 0.0f || ss >= 1.0f)
			return 0.0f;
		if (w * std::sin(umax) >= l)
			return 0.0f;
		if (kappa < -1.0f)
			return 0.0f;
		Vector h = normalize(om_r + om_i);
		Float u_of_v = std::atan(h.y / h.z);
		if (std::abs(u_of_v) < umax) {
			Normal n = normalize(Normal(std::sin(v), std::sin(u_of_v) * std::cos(v),
					std::cos(u_of_v) * std::cos(v)));
			Vector t = normalize(Vector(0.0f, std::cos(u_of_v), -std::sin(u_of_v)));
			Float R = radiusOfCurvature(std::min(std::abs(u_of_v),
				(1-ss)*umax), (1-ss)*umax, kappa, w, l);
			Float a = 0.5f * w;
			Vector om_i_plus_om_r = om_i + om_r,
				   t_cross_h = cross(t, h);
			Float Gu = a * (R + a * std::cos(v)) /
				(om_i_plus_om_r.length() * std::abs(t_cross_h.x));
			Float fc = alpha + vonMises(-dot(om_i, om_r), beta);
			Float A = seeliger(dot(n, om_i), dot(n, om_r), 0, 1);
			Float As;
			if (ss == 0.0f)
				As = A;
			else
				As = A * (1.0f - math::smoothStep((Float) 0, (Float) 1, (std::abs(u_of_v)
					- (1.0f - ss) * umax) / (ss * umax)));
			Float fs = Gu * fc * As;
			fs = fs * M_PI * l;
			Float delta_y = l * m_pattern.hWidth;
			Float y_of_v = u_of_v * 0.5f * l / umax;
			if (y_of_v > 0.5f * (l - delta_y))
				y_of_v = 0.5f * (l - delta_y);
			else if (y_of_v < 0.5f * (delta_y - l))
				y_of_v = 0.5f * (delta_y - l);
			if (std::abs(y_of_v - u * 0.5f * l / umax) < 0.5f * delta_y)
				return fs / delta_y;
		}
		return 0.0f;
	}
Float evalFilamentIntegrand ( Float u , Float v , const Vector & om_i , const Vector & om_r , Float alpha , Float beta , Float ss , Float umax , Float kappa , Float w , Float l ) const { if ( ss < 0.0f || ss >= 1.0f ) return 0.0f ; if ( w * std :: sin ( umax ) >= l ) return 0.0f ; if ( kappa < -1.0f ) return 0.0f ; Vector h = normalize ( om_r + om_i ) ; Float u_of_v = std :: atan ( h . y / h . z ) ; if ( std :: abs ( u_of_v ) < umax ) { Normal n = normalize ( Normal ( std :: sin ( v ) , std :: sin ( u_of_v ) * std :: cos ( v ) , std :: cos ( u_of_v ) * std :: cos ( v ) ) ) ; Vector t = normalize ( Vector ( 0.0f , std :: cos ( u_of_v ) , - std :: sin ( u_of_v ) ) ) ; Float R = radiusOfCurvature ( std :: min ( std :: abs ( u_of_v ) , ( 1 - ss ) * umax ) , ( 1 - ss ) * umax , kappa , w , l ) ; Float a = 0.5f * w ; Vector om_i_plus_om_r = om_i + om_r , t_cross_h = cross ( t , h ) ; Float Gu = a * ( R + a * std :: cos ( v ) ) / ( om_i_plus_om_r . length ( ) * std :: abs ( t_cross_h . x ) ) ; Float fc = alpha + vonMises ( - dot ( om_i , om_r ) , beta ) ; Float A = seeliger ( dot ( n , om_i ) , dot ( n , om_r ) , 0 , 1 ) ; Float As ; if ( ss == 0.0f ) As = A ; else As = A * ( 1.0f - math :: smoothStep ( ( Float ) 0 , ( Float ) 1 , ( std :: abs ( u_of_v ) - ( 1.0f - ss ) * umax ) / ( ss * umax ) ) ) ; Float fs = Gu * fc * As ; fs = fs * M_PI * l ; Float delta_y = l * m_pattern . hWidth ; Float y_of_v = u_of_v * 0.5f * l / umax ; if ( y_of_v > 0.5f * ( l - delta_y ) ) y_of_v = 0.5f * ( l - delta_y ) ; else if ( y_of_v < 0.5f * ( delta_y - l ) ) y_of_v = 0.5f * ( delta_y - l ) ; if ( std :: abs ( y_of_v - u * 0.5f * l / umax ) < 0.5f * delta_y ) return fs / delta_y ; } return 0.0f ; }
parameters:
      u        to be compared to u(v) in texturing
      v        for filament, we compute u(v)
      om_i  incident direction
      om_r  exitant direction
      ss      filament smoothing parameter
  fiber properties
      alpha uniform scattering
      beta  forward scattering
  yarn geometry
      psi   fiber twist angle; because this is filament, psi = pi/2
      umax  maximum inclination angle
      kappa spine curvature parameter
  weave pattern
      w        width of segment rectangle
      l        length of segment rectangle
parameters : u to be compared to u ( v ) in texturing v for filament we compute u ( v ) om_i incident direction om_r exitant direction ss filament smoothing parameter fiber properties alpha uniform scattering beta forward scattering yarn geometry psi fiber twist angle ; because this is filament psi = pi / 2 umax maximum inclination angle kappa spine curvature parameter weave pattern w width of segment rectangle l length of segment rectangle
// 0 <= ss < 1.0 // w * sin(umax) < l // -1 < kappa < inf // h is the half vector // u_of_v is location of specular reflection. // Check if u_of_v within the range of valid u values // n is normal to the yarn surface // t is tangent of the fibers. // R is radius of curvature. // G is geometry factor. // fc is phase function // A is attenuation function without smoothing. // As is attenuation function with smoothing. // fs is scattering function. // Domain transform. // Highlight has constant width delta_y on screen. // Clamp y_of_v between -(l - delta_y)/2 and (l - delta_y)/2. // Check if |y(u(v)) - y(u)| < delta_y/2.