コード例 #1
0
ファイル: phong.cpp プロジェクト: AlexVeuthey/acg15
    Color3f sample(BSDFQueryRecord &bRec, const Point2f &sample_) const {
        Point2f sample(sample_);
        if (Frame::cosTheta(bRec.wi) <= 0)
            return Color3f(0.0f);

        bRec.measure = ESolidAngle;

        // 1. Select diffuse or specular
        bool useSpecular = true;
        if (sample.x() <= m_specSamplingWeight) {
            sample.x() /= m_specSamplingWeight;
        } else {
            sample.x() = (sample.x() - m_specSamplingWeight) / m_diffSamplingWeight;
            useSpecular = false;
        }

        if (useSpecular) {
            // this is a tricky one
            // See http://mathinfo.univ-reims.fr/IMG/pdf/Using_the_modified_Phong_reflectance_model_for_Physically_based_rendering_-_Lafortune.pdf
            
            float sinTheta = std::sqrt(1.0f - std::pow(sample.y(), 2.0f/(m_exp + 1.0f)));
            float cosTheta = std::pow(sample.y(), 1.0f/(m_exp + 1.0f));
            float phi = 2.0f * M_PI * sample.x();
            float cosPhi, sinPhi;
            sincosf(phi, &sinPhi, &cosPhi);
            // direction from the lobe axis (i.e. reflection of wi) in lobe coordinate
            Vector3f lobeAxis = reflect(bRec.wi);
            Vector3f lobeWo(
                    sinTheta * std::cos(phi),
                    sinTheta * std::sin(phi),
                    cosTheta
            );
            bRec.wo = Frame(lobeAxis).toWorld(lobeWo);
            
            // check that we are on the hemisphere
            if(Frame::cosTheta(bRec.wo) <= 0.0f)
                return Color3f(0.0f);
        } else {
            /* Warp a uniformly distributed sample on [0,1]^2
                to a direction on a cosine-weighted hemisphere */
            bRec.wo = squareToCosineHemisphere(sample);
        }

        /* Relative index of refraction: no change */
        bRec.eta = 1.0f;

        // the importance-weighted sample is given by
        //      f / pdf * cos(wo)
        Color3f f_eval = eval(bRec);
        float pdf_eval = pdf(bRec);
        if(pdf_eval <= 0.0f) return Color3f(0.0f); // let's not explode here
        
        return f_eval / pdf_eval * Frame::cosTheta(bRec.wo);
    }
コード例 #2
0
ファイル: diffuse.cpp プロジェクト: UIKit0/nori
	/// Draw a a sample from the BRDF model
	Color3f sample(BSDFQueryRecord &bRec, const Point2f &sample) const {
		if (Frame::cosTheta(bRec.wi) <= 0) 
			return Color3f(0.0f);

		bRec.measure = ESolidAngle;
		
		/* Warp a uniformly distributed sample on [0,1]^2
		   to a direction on a cosine-weighted hemisphere */
		bRec.wo = squareToCosineHemisphere(sample);

		/* eval() / pdf() * cos(theta) = albedo. There
		   is no need to call these functions. */
		return m_albedo;
	}