示例#1
0
文件: phong.cpp 项目: bssrdf/dpt
Float Phong::GetKsWeight() const {
    Float ksAvg = Luminance(Ks->Avg());
    Float kdAvg = Luminance(Kd->Avg());
    Float sum = ksAvg + kdAvg;
    if (sum <= Float(0.0)) {
        return Float(0.0);
    } else {
        return ksAvg / sum;
    }
}
示例#2
0
	float HeterogeneousVolume::pMedium(const Ray &inRay, float dist) const{
		const float tau = HeterogeneousVolume::integrateDensity(inRay, dist);
		const vec3f sigmaAtT = isSubsurface ?
			lookUpSubSurfaceVolumeData(inRay.origin + inRay.direction * dist, EXTINCTION): 
			extinctionCoeff*lookUpDensity(inRay.origin + inRay.direction * dist);
		return Luminance(sigmaAtT) * exp(-tau);
	}
示例#3
0
	float HeterogeneousVolume::integrateDensity(const Ray &inRay, float dist) const{
		float densityAccumulation = 0;
		float intersectDist = std::numeric_limits<float>::max();
		if(check(inRay, &intersectDist)){
			return densityAccumulation;
		}
		dist = MIN(dist, intersectDist);

		vec3f p = inRay.origin;
		uint nSteps = std::ceil(dist / (2*stepSize));
		double ss = dist / nSteps, multiplier = (1.0/6.0)*ss;
		const vec3f fullStep = inRay.direction * ss, halfStep = fullStep * 0.5;

		float node1 = isSubsurface ? Luminance(lookUpSubSurfaceVolumeData(p, EXTINCTION)) : lookUpDensity(p);

		for(uint i = 0; i < nSteps; i++){
			float node2 = isSubsurface ? Luminance(lookUpSubSurfaceVolumeData(p+halfStep, EXTINCTION)) : lookUpDensity(p+halfStep), 
				node3 = isSubsurface ? Luminance(lookUpSubSurfaceVolumeData(p+fullStep, EXTINCTION)) : lookUpDensity(p+fullStep);
			densityAccumulation += multiplier*(node1+node2*4+node3);
			node1 = node3;
			p += fullStep;
		}
		return densityAccumulation;
	}
示例#4
0
bool Footprint(location loc, bitmap* bmp) {
    
    const int footprint = 5; // 9x9 footprint
    const int offset = footprint - 1;
    const rgb rgbWhite(255,255,255);
    
    if (loc.x - offset < 0 || loc.x + offset > bmp->max().x) return false;
    if (loc.y - offset < 0 || loc.y + offset > bmp->max().y) return false;
    
    int bottom_y = loc.y - offset;
    int top_y    = loc.y + offset;

    int left_x   = loc.x - offset;
    int right_x  = loc.x + offset;

    for (int x = left_x; x <= right_x; x ++)
    for (int y = bottom_y; y <= top_y; y ++)
        if (Luminance(location(x,y),bmp) == false) return false;
        
    return true;
}
示例#5
0
	// 0 - success
	// 1 - check fail
	// 2 - iter > 30
	// 3 - can not make forward progress
	// 4 - finally failed. 
	// return true:		sample succeed, use pdfSuccess
	//		  false:	sample fail, use pdfFailure
	bool HeterogeneousVolume::sampleDistance(const Ray &inRay, float &distance, float &pdfSuccess, float &pdfFailure) const{
		float intersectDist;
		float desiredDensity = isSubsurface ? -log(1.0 - rng->genFloat()) : -log(1.0 - rng->genFloat()) / Luminance(extinctionCoeff);
		float t = 0, integratedDensity = 0, densityAtMinT = 0, densityAtT = 0;

		int flag = findDesiredIntegralDensity(inRay, desiredDensity, t, integratedDensity, densityAtMinT, densityAtT);
		float expVal = exp(-integratedDensity);

		bool sampleState = false;
		switch(flag){
		case 0:
			// success
			// satisfying: [desiredDensity = integratedDensity], [denisityAtT is real], [sample distance = t].
			pdfSuccess = expVal * densityAtT;
			distance = t;
			sampleState = true;
			break;
		case 1:
			// check fail
			// this one need extra calculation
			pdfFailure = expVal;
			distance = inRay.intersectDist;
			sampleState = false;
			break;

		case 2:
			// it > 30
			// we may use the integratedDensity with errorbound
			pdfSuccess = expVal * densityAtT;
			distance = t;
			sampleState = true;
			break;

		case 3:
			// stuck in progress
			pdfFailure = expVal;
			distance = inRay.intersectDist;
			sampleState = false;
			break;
		case 4:
			// finally failed.
			pdfFailure = expVal;
			distance = inRay.intersectDist;
			sampleState = false;
			break;
		default:
			break;
		}

		return sampleState;
	}
示例#6
0
	int HeterogeneousVolume::findDesiredIntegralDensity(const Ray &inRay, const float desiredDensity, 
		float &t, float &integratedDensity, float &densityAtMinT, float &densityAtT) const
	{
		float dist;
		if(check(inRay, &dist)){
			return 1;
		}

		integratedDensity = 0;

		vec3f p = inRay.origin;
		uint nSteps = std::ceil(dist / (2*stepSize));
		double ss = dist / nSteps, multiplier = (1.0/6.0)*ss;
		const vec3f fullStep = inRay.direction * ss, halfStep = fullStep * 0.5;

		float node1 = isSubsurface ? Luminance(lookUpSubSurfaceVolumeData(p, EXTINCTION)) : lookUpDensity(p);
		densityAtMinT = node1;


		for(uint i = 0; i < nSteps; i++){
			float node2 = isSubsurface ? Luminance(lookUpSubSurfaceVolumeData(p+halfStep, EXTINCTION)) : lookUpDensity(p+halfStep), 
				node3 = isSubsurface ? Luminance(lookUpSubSurfaceVolumeData(p+fullStep, EXTINCTION)) : lookUpDensity(p+fullStep);
			float newDensity = integratedDensity + multiplier*(node1+node2*4+node3);
			if(newDensity >= desiredDensity){
				float a = 0, b = ss, x = a,
					fx = integratedDensity - desiredDensity,
					stepSizeSqr = ss * ss,
					temp = 1.0 / stepSizeSqr;

				int it = 1;
				while(true){
					float dfx = temp * (node1 * stepSizeSqr
						- (3 * node1 - 4 * node2 + node3) * ss * x
						+ 2 * (node1 - 2 * node2 + node3) * x * x);

					x -= fx / dfx;

					if(x <= a || x >= b || dfx == 0){
						x = 0.5 * (b + a);
					}

					float intval = integratedDensity + temp * (1.0/6.0) * (x *
						(6 * node1 * stepSizeSqr - 3 * (3 * node1 - 4 * node2 + node3) * ss * x
						+ 4 * (node1 - 2 * node2 + node3) * x * x));
					fx = intval - desiredDensity;

					if(std::abs(fx) < NEWTON_BISECTION_EPS){
						t = x + ss * i;
						integratedDensity = intval;
						densityAtT = temp * (node1 * stepSizeSqr
							- (3*node1 - 4*node2 + node3)*ss*x
							+ 2*(node1 - 2*node2 + node3)*x*x);
						return 0;
					}
					else if(++it > 30){
						// we still use the distance sample.
						t = x + ss * i;
						integratedDensity = intval;
						densityAtT = temp * (node1 * stepSizeSqr
							- (3*node1 - 4*node2 + node3)*ss*x
							+ 2*(node1 - 2*node2 + node3)*x*x);

				/*		std::cerr << "findDesiredIntegralDensity(): stuck in Newton-Bisection -- fx = " << fx << " dfx = " << dfx 
							<< " a = " << a << " b = " << b << " stepsize = " << ss << std::endl;*/
						return 2;
					}

					if(fx > 0){
						b = x;
					}
					else{
						a = x;
					}

				}
			}
			vec3f next = p + fullStep;
			if(p == next){
			//	std::cerr << "findDesiredIntegralDensity(): can not make forward progress -- stepsize = " << ss << std::endl;
				return 3;
			}
			integratedDensity = newDensity;
			node1 = node3;
			p = next;
		}
		return 4;
	}
示例#7
0
	float HeterogeneousVolume::getAlbedo(const vec3f &p) const{
		return Luminance(lookUpSubSurfaceVolumeData(p, SCATTERING)) / Luminance(lookUpSubSurfaceVolumeData(p, EXTINCTION));
	}
示例#8
0
	float HeterogeneousVolume::getAlbedo() const{
		return Luminance(scatteringCoeff) / Luminance(extinctionCoeff);
	}