Пример #1
0
Vec3f TraceBase::attenuatedEmission(PathSampleGenerator &sampler,
                         const Primitive &light,
                         const Medium *medium,
                         float expectedDist,
                         IntersectionTemporary &data,
                         IntersectionInfo &info,
                         int bounce,
                         bool startsOnSurface,
                         Ray &ray,
                         Vec3f *transmittance)
{
    CONSTEXPR float fudgeFactor = 1.0f + 1e-3f;

    if (light.isDirac()) {
        ray.setFarT(expectedDist);
    } else {
        if (!light.intersect(ray, data) || ray.farT()*fudgeFactor < expectedDist)
            return Vec3f(0.0f);
    }
    info.p = ray.pos() + ray.dir()*ray.farT();
    info.w = ray.dir();
    light.intersectionInfo(data, info);

    Vec3f shadow = generalizedShadowRay(sampler, ray, medium, &light, startsOnSurface, true, bounce);
    if (transmittance)
        *transmittance = shadow;
    if (shadow == 0.0f)
        return Vec3f(0.0f);

    return shadow*light.evalDirect(data, info);
}
Пример #2
0
SurfaceScatterEvent TraceBase::makeLocalScatterEvent(IntersectionTemporary &data, IntersectionInfo &info,
        Ray &ray, PathSampleGenerator *sampler) const
{
    TangentFrame frame;
    info.primitive->setupTangentFrame(data, info, frame);

    bool hitBackside = frame.normal.dot(ray.dir()) > 0.0f;
    bool isTransmissive = info.bsdf->lobes().isTransmissive();

    bool flipFrame = _settings.enableTwoSidedShading && hitBackside && !isTransmissive;

    if (flipFrame) {
        // TODO: Should we flip info.Ns here too? It doesn't seem to be used at the moment,
        // but it may be in the future. Modifying the intersection info itself could be a bad
        // idea though
        frame.normal = -frame.normal;
        frame.tangent = -frame.tangent;
    }

    return SurfaceScatterEvent(
        &info,
        sampler,
        frame,
        frame.toLocal(-ray.dir()),
        BsdfLobes::AllLobes,
        flipFrame
    );
}
Пример #3
0
bool Quad::intersect(Ray &ray, IntersectionTemporary &data) const
{
    float nDotW = ray.dir().dot(_frame.normal);
    if (std::abs(nDotW) < 1e-6f)
        return false;

    float t = _frame.normal.dot(_base - ray.pos())/nDotW;
    if (t < ray.nearT() || t > ray.farT())
        return false;

    Vec3f q = ray.pos() + t*ray.dir();
    Vec3f v = q - _base;
    float l0 = v.dot(_edge0)*_invUvSq.x();
    float l1 = v.dot(_edge1)*_invUvSq.y();

    if (l0 < 0.0f || l0 > 1.0f || l1 < 0.0f || l1 > 1.0f)
        return false;

    ray.setFarT(t);
    QuadIntersection *isect = data.as<QuadIntersection>();
    isect->p = q;
    isect->u = l0;
    isect->v = 1.0f - l1;
    isect->backSide = nDotW >= 0.0f;
    data.primitive = this;

    return true;
}
Пример #4
0
Vec3f AtmosphericMedium::transmittance(PathSampleGenerator &/*sampler*/, const Ray &ray) const
{
    Vec3f p = (ray.pos() - _center);
    float t0 = p.dot(ray.dir());
    float t1 = ray.farT() + t0;
    float  h = (p - t0*ray.dir()).length();

    return std::exp(-_sigmaT*densityIntegral(h, t0, t1));
}
Пример #5
0
bool Cylinder::intersect_unit_circle( const Ray& inc, Ray& hit )
{
  double Z = inc.from().z();
  double z = -inc.dir().z();

  Vec3 v = inc.from() + inc.dir() * Z / z;
  v.z() = 0;

  if( v.l2() > 1 ) return false;
  hit.from() = v;
  return true;
}
Пример #6
0
bool Triangle::hit ( const Ray& original_ray, interval_t& tmin ) const
{
    Ray ray = original_ray.transform(inv_trans_);

    float A = a_[0] - b_[0];
    float B = a_[1] - b_[1];
    float C = a_[2] - b_[2];

    float D = a_[0] - c_[0];
    float E = a_[1] - c_[1];
    float F = a_[2] - c_[2];

    float G = ray.dir()[0];
    float H = ray.dir()[1];
    float I = ray.dir()[2];

    float J = a_[0] - ray.origin()[0];
    float K = a_[1] - ray.origin()[1];
    float L = a_[2] - ray.origin()[2];

    float EIHF = E*I - H*F;
    float GFDI = G*F - D*I;
    float DHEG = D*H - E*G;

    float denom = A*EIHF + B*GFDI + C*DHEG;

    float beta = ( J*EIHF + K*GFDI + L*DHEG ) / denom;

    if ( beta <= 0.0 or beta >= 1.0 )
        return false;

    float AKJB = A*K - J*B;
    float JCAL = J*C - A*L;
    float BLKC = B*L - K*C;

    float gamma = ( I*AKJB + H*JCAL + G*BLKC ) / denom;

    if ( gamma <= 0.0 or beta + gamma >= 1.0 )
        return false;

    float t = -( F*AKJB + E*JCAL + D*BLKC ) / denom;

    if ( t > epsilon )
    {
        tmin = t;
        return true;
    }

    return false;
}
Пример #7
0
inline RTCRay convert(const Ray &r)
{
    RTCRay ray;
    ray.org[0] = r.pos().x();
    ray.org[1] = r.pos().y();
    ray.org[2] = r.pos().z();
    ray.dir[0] = r.dir().x();
    ray.dir[1] = r.dir().y();
    ray.dir[2] = r.dir().z();
    ray.tnear = r.nearT();
    ray.tfar  = r.farT();
    ray.geomID = RTC_INVALID_GEOMETRY_ID;
    ray.primID = RTC_INVALID_GEOMETRY_ID;
    return ray;
}
Пример #8
0
Vec3f TraceBase::volumePhaseSample(const Primitive &light,
                    PathSampleGenerator &sampler,
                    MediumSample &mediumSample,
                    const Medium *medium,
                    int bounce,
                    const Ray &parentRay)
{
    PhaseSample phaseSample;
    if (!mediumSample.phase->sample(sampler, parentRay.dir(), phaseSample))
        return Vec3f(0.0f);

    Ray ray = parentRay.scatter(mediumSample.p, phaseSample.w, 0.0f);
    ray.setPrimaryRay(false);

    IntersectionTemporary data;
    IntersectionInfo info;
    Vec3f e = attenuatedEmission(sampler, light, medium, -1.0f, data, info, bounce, false, ray, nullptr);

    if (e == Vec3f(0.0f))
        return Vec3f(0.0f);

    Vec3f phaseF = e*phaseSample.weight;

    phaseF *= SampleWarp::powerHeuristic(phaseSample.pdf, light.directPdf(_threadId, data, info, mediumSample.p));

    return phaseF;
}
Пример #9
0
Vec3f TraceBase::volumeLightSample(PathSampleGenerator &sampler,
                    MediumSample &mediumSample,
                    const Primitive &light,
                    const Medium *medium,
                    int bounce,
                    const Ray &parentRay)
{
    LightSample lightSample;
    if (!light.sampleDirect(_threadId, mediumSample.p, sampler, lightSample))
        return Vec3f(0.0f);

    Vec3f f = mediumSample.phase->eval(parentRay.dir(), lightSample.d);
    if (f == 0.0f)
        return Vec3f(0.0f);

    Ray ray = parentRay.scatter(mediumSample.p, lightSample.d, 0.0f);
    ray.setPrimaryRay(false);

    IntersectionTemporary data;
    IntersectionInfo info;
    Vec3f e = attenuatedEmission(sampler, light, medium, lightSample.dist, data, info, bounce, false, ray, nullptr);
    if (e == 0.0f)
        return Vec3f(0.0f);

    Vec3f lightF = f*e/lightSample.pdf;

    if (!light.isDirac())
        lightF *= SampleWarp::powerHeuristic(lightSample.pdf, mediumSample.phase->pdf(parentRay.dir(), lightSample.d));

    return lightF;
}
Пример #10
0
bool TraceBase::volumeLensSample(const Camera &camera,
                                 PathSampleGenerator &sampler,
                                 MediumSample &mediumSample,
                                 const Medium *medium,
                                 int bounce,
                                 const Ray &parentRay,
                                 Vec3f &weight,
                                 Vec2f &pixel)
{
    LensSample lensSample;
    if (!camera.sampleDirect(mediumSample.p, sampler, lensSample))
        return false;

    Vec3f f = mediumSample.phase->eval(parentRay.dir(), lensSample.d);
    if (f == 0.0f)
        return false;

    Ray ray = parentRay.scatter(mediumSample.p, lensSample.d, 0.0f);
    ray.setPrimaryRay(false);
    ray.setFarT(lensSample.dist);

    Vec3f transmittance = generalizedShadowRay(sampler, ray, medium, nullptr, false, true, bounce);
    if (transmittance == 0.0f)
        return false;

    weight = f*transmittance*lensSample.weight;
    pixel = lensSample.pixel;

    return true;
}
Пример #11
0
bool intersectAabb(const Aabb& box, const Ray& ray, floating& a, floating& b) {
    const Point  origin = ray.origin();
    const Vector dir = ray.dir();

    a = std::numeric_limits<floating>::min();
    b = std::numeric_limits<floating>::max();

    for (uint8_t i = 0; i < 3; ++i) {
        if (almost_zero(dir[i])) {
            if (origin[i] < box.m_p1[i] || origin[i] > box.m_p2[i]) {
                return false;
            }

            continue;
        }

        floating idir = 1.0 / dir[i];
        floating at = (box.m_p1[i] - origin[i]) * idir;
        floating bt = (box.m_p2[i] - origin[i]) * idir;

        if (at > bt)
            idir = at, at = bt, bt = idir;
        if (at > a)
            a = at;
        if (bt < b)
            b = bt;
        if (b < 0 || a > b)
            return false;
    }

    return true;
}
Пример #12
0
bool Cube::intersect(Ray &ray, IntersectionTemporary &data) const
{
    Vec3f p = _invRot*(ray.pos() - _pos);
    Vec3f d = _invRot*ray.dir();

    Vec3f invD = 1.0f/d;
    Vec3f relMin((-_scale - p));
    Vec3f relMax(( _scale - p));

    float ttMin = ray.nearT(), ttMax = ray.farT();
    for (int i = 0; i < 3; ++i) {
        if (invD[i] >= 0.0f) {
            ttMin = max(ttMin, relMin[i]*invD[i]);
            ttMax = min(ttMax, relMax[i]*invD[i]);
        } else {
            ttMax = min(ttMax, relMin[i]*invD[i]);
            ttMin = max(ttMin, relMax[i]*invD[i]);
        }
    }

    if (ttMin <= ttMax) {
        if (ttMin > ray.nearT() && ttMin < ray.farT()) {
            data.primitive = this;
            ray.setFarT(ttMin);
            data.as<CubeIntersection>()->backSide = false;
        } else if (ttMax > ray.nearT() && ttMax < ray.farT()) {
            data.primitive = this;
            ray.setFarT(ttMax);
            data.as<CubeIntersection>()->backSide = true;
        }
        return true;
    }
    return false;
}
Пример #13
0
bool Sphere::intersectP(Ray &ray){
    float a, b, c,t1, t2, discriminant;
    Vector3f dir = ray.dir();
    Vector3f e_minus_c = ray.pos().sub(center);

    a = dir.dot(dir);
    b= (2*dir).dot((e_minus_c));
    c = (e_minus_c).dot(e_minus_c)-pow(radius,2.0);
    
    discriminant = pow(b,2.0)-(4*a*c);
    
	if(discriminant < 0){
		return false;
	}
	else{
		float sqrtdisc = sqrt(discriminant);
		t1 = (-b + sqrtdisc) / (2 * a);
		t2 = (-b - sqrtdisc) / (2 * a);
		
		if((t1 > ray.t_min() && t1 < ray.t_max()) ||
           (t2 > ray.t_min() && t2 < ray.t_max())){
			return true;
		}
		else{
			return false;
		}
	}
}
Пример #14
0
/**
 * Performs ray/box intersection. Returns true if the ray
 * intersects the box, and the hit time for the entry/exit
 * in tmin/tmax respectively.
 */
bool AABB::intersect(const Ray& ray, float& tmin, float& tmax) const
{
	float t0 = ray.minT;
	float t1 = ray.maxT;

	// Loop over the three axes and compute the hit time for the
	// two axis-aligned bounding box planes in each, decreasing the
	// parametric range of the ray until start>end time, which means
	// the ray missed the box, or until we finish which means there
	// is an intersection.
	for (int i = 0; i < 3; i++) {
		float invDir = 1.0f / ray.dir(i);
		float tNear = (mMin(i) - ray.orig(i)) * invDir;
		float tFar  = (mMax(i) - ray.orig(i)) * invDir;
		
		if (tNear > tFar) swap(tNear,tFar);
		
		if (tNear > t0) t0 = tNear;
		if (tFar < t1) t1 = tFar;
		if (t0 > t1) return false;
	}
	
	tmin = t0;
	tmax = t1;
	return true;
}
Пример #15
0
bool Sphere::intersect(Ray &ray, IntersectionTemporary &data) const
{
    Vec3f p = ray.pos() - _pos;
    float B = p.dot(ray.dir());
    float C = p.lengthSq() - _radius*_radius;
    float detSq = B*B - C;
    if (detSq >= 0.0f) {
        float det = std::sqrt(detSq);
        float t = -B - det;
        if (t < ray.farT() && t > ray.nearT()) {
            ray.setFarT(t);
            data.primitive = this;
            data.as<SphereIntersection>()->backSide = false;
            return true;
        }
        t = -B + det;
        if (t < ray.farT() && t > ray.nearT()) {
            ray.setFarT(t);
            data.primitive = this;
            data.as<SphereIntersection>()->backSide = true;
            return true;
        }
    }

    return false;
}
Пример #16
0
bool Quad::occluded(const Ray &ray) const
{
    float nDotW = ray.dir().dot(_frame.normal);

    float t = _frame.normal.dot(_base - ray.pos())/nDotW;
    if (t < ray.nearT() || t > ray.farT())
        return false;

    Vec3f q = ray.pos() + t*ray.dir();
    Vec3f v = q - _base;
    float l0 = v.dot(_edge0)*_invUvSq.x();
    float l1 = v.dot(_edge1)*_invUvSq.y();

    if (l0 < 0.0f || l0 > 1.0f || l1 < 0.0f || l1 > 1.0f)
        return false;
    return true;
}
Пример #17
0
float AtmosphericMedium::pdf(PathSampleGenerator &/*sampler*/, const Ray &ray, bool onSurface) const
{
    if (_absorptionOnly) {
        return 1.0f;
    } else {
        Vec3f p = (ray.pos() - _center);
        float t0 = p.dot(ray.dir());
        float t1 = ray.farT() + t0;
        float  h = (p - t0*ray.dir()).length();

        Vec3f transmittance = std::exp(-_sigmaT*densityIntegral(h, t0, t1));
        if (onSurface) {
            return transmittance.avg();
        } else {
            return (density(h, t0)*_sigmaT*transmittance).avg();
        }
    }
}
Пример #18
0
Vec3f AtmosphericMedium::transmittanceAndPdfs(PathSampleGenerator &/*sampler*/, const Ray &ray, bool startOnSurface,
        bool endOnSurface, float &pdfForward, float &pdfBackward) const
{
    Vec3f p = (ray.pos() - _center);
    float t0 = p.dot(ray.dir());
    float t1 = ray.farT() + t0;
    float  h = (p - t0*ray.dir()).length();

    Vec3f transmittance = std::exp(-_sigmaT*densityIntegral(h, t0, t1));

    if (_absorptionOnly) {
        pdfForward = pdfBackward = 1.0f;
    } else {
        pdfForward  =   endOnSurface ? transmittance.avg() : (density(h, t1)*_sigmaT*transmittance).avg();
        pdfBackward = startOnSurface ? transmittance.avg() : (density(h, t0)*_sigmaT*transmittance).avg();
    }

    return transmittance;
}
Пример #19
0
Vec3f ExponentialMedium::transmittance(PathSampleGenerator &/*sampler*/, const Ray &ray) const
{
    float  x = _falloffScale*(ray.pos() - _unitPoint).dot(_unitFalloffDirection);
    float dx = _falloffScale*ray.dir().dot(_unitFalloffDirection);

    if (ray.farT() == Ray::infinity() && dx <= 0.0f)
        return Vec3f(0.0f);
    else
        return std::exp(-_sigmaT*densityIntegral(x, dx, ray.farT()));
}
Пример #20
0
bool ExponentialMedium::sampleDistance(PathSampleGenerator &sampler, const Ray &ray,
        MediumState &state, MediumSample &sample) const
{
    if (state.bounce > _maxBounce)
        return false;

    float  x = _falloffScale*(ray.pos() - _unitPoint).dot(_unitFalloffDirection);
    float dx = _falloffScale*ray.dir().dot(_unitFalloffDirection);

    float maxT = ray.farT();
    if (_absorptionOnly) {
        if (maxT == Ray::infinity() && dx <= 0.0f)
            return false;
        sample.t = maxT;
        sample.weight = std::exp(-_sigmaT*densityIntegral(x, dx, ray.farT()));
        sample.pdf = 1.0f;
        sample.exited = true;
    } else {
        int component = sampler.nextDiscrete(3);
        float sigmaTc = _sigmaT[component];
        float xi = 1.0f - sampler.next1D();
        float logXi = std::log(xi);

        float t = inverseOpticalDepth(x, dx, sigmaTc, logXi);
        sample.t = min(t, maxT);
        sample.weight = std::exp(-_sigmaT*densityIntegral(x, dx, sample.t));
        sample.exited = (t >= maxT);
        if (sample.exited) {
            sample.pdf = sample.weight.avg();
        } else {
            float rho = density(x, dx, sample.t);
            sample.pdf = (rho*_sigmaT*sample.weight).avg();
            sample.weight *= rho*_sigmaS;
        }
        sample.weight /= sample.pdf;

        state.advance();
    }
    sample.p = ray.pos() + sample.t*ray.dir();
    sample.phase = _phaseFunction.get();

    return true;
}
Пример #21
0
bool AtmosphericMedium::sampleDistance(PathSampleGenerator &sampler, const Ray &ray,
        MediumState &state, MediumSample &sample) const
{
    if (state.bounce > _maxBounce)
        return false;

    Vec3f p = (ray.pos() - _center);
    float t0 = p.dot(ray.dir());
    float  h = (p - t0*ray.dir()).length();

    float maxT = ray.farT() + t0;
    if (_absorptionOnly) {
        sample.t = ray.farT();
        sample.weight = std::exp(-_sigmaT*densityIntegral(h, t0, maxT));
        sample.pdf = 1.0f;
        sample.exited = true;
    } else {
        int component = sampler.nextDiscrete(3);
        float sigmaTc = _sigmaT[component];
        float xi = 1.0f - sampler.next1D();

        float t = inverseOpticalDepth(h, t0, sigmaTc, xi);
        sample.t = min(t, maxT);
        sample.weight = std::exp(-_sigmaT*densityIntegral(h, t0, sample.t));
        sample.exited = (t >= maxT);
        if (sample.exited) {
            sample.pdf = sample.weight.avg();
        } else {
            float rho = density(h, sample.t);
            sample.pdf = (rho*_sigmaT*sample.weight).avg();
            sample.weight *= rho*_sigmaS;
        }
        sample.weight /= sample.pdf;
        sample.t -= t0;

        state.advance();
    }
    sample.p = ray.pos() + sample.t*ray.dir();
    sample.phase = _phaseFunction.get();

    return true;
}
Пример #22
0
bool TraceBase::handleSurface(SurfaceScatterEvent &event, IntersectionTemporary &data,
                              IntersectionInfo &info, const Medium *&medium,
                              int bounce, bool adjoint, bool enableLightSampling, Ray &ray,
                              Vec3f &throughput, Vec3f &emission, bool &wasSpecular,
                              Medium::MediumState &state, Vec3f *transmittance)
{
    const Bsdf &bsdf = *info.bsdf;

    // For forward events, the transport direction does not matter (since wi = -wo)
    Vec3f transparency = bsdf.eval(event.makeForwardEvent(), false);
    float transparencyScalar = transparency.avg();

    Vec3f wo;
    if (event.sampler->nextBoolean(transparencyScalar) ){
        wo = ray.dir();
        event.pdf = transparencyScalar;
        event.weight = transparency/transparencyScalar;
        event.sampledLobe = BsdfLobes::ForwardLobe;
        throughput *= event.weight;
    } else {
        if (!adjoint) {
            if (enableLightSampling && bounce < _settings.maxBounces - 1)
                emission += estimateDirect(event, medium, bounce + 1, ray, transmittance)*throughput;

            if (info.primitive->isEmissive() && bounce >= _settings.minBounces) {
                if (!enableLightSampling || wasSpecular || !info.primitive->isSamplable())
                    emission += info.primitive->evalDirect(data, info)*throughput;
            }
        }

        event.requestedLobe = BsdfLobes::AllLobes;
        if (!bsdf.sample(event, adjoint))
            return false;

        wo = event.frame.toGlobal(event.wo);

        if (!isConsistent(event, wo))
            return false;

        throughput *= event.weight;
        wasSpecular = event.sampledLobe.hasSpecular();
        if (!wasSpecular)
            ray.setPrimaryRay(false);
    }

    bool geometricBackside = (wo.dot(info.Ng) < 0.0f);
    medium = info.primitive->selectMedium(medium, geometricBackside);
    state.reset();

    ray = ray.scatter(ray.hitpoint(), wo, info.epsilon);

    return true;
}
Пример #23
0
inline bool YZRect::hit(const Ray& r, float t_min, float t_max, hit_record& rec) const
{
    auto t = (_k-r.origin().x)/r.dir().x;
    if(t < t_min || t > t_max) return false;
    auto interesction = r.pointAtParam(t);
    if(interesction.y < _y_dim.x || interesction.y > _y_dim.y || interesction.z < _z_dim.x || interesction.z > _z_dim.y) return false;
    rec.uv = glm::vec2((interesction.y - _y_dim.x)/(_y_dim.y - _y_dim.x), (interesction.z - _z_dim.x)/(_z_dim.y - _z_dim.x));
    rec.t = t;
    rec.mat = _mat;
    rec.p = interesction;
    rec.n = glm::vec3(1,0,0);
    return true;
}
Пример #24
0
bool Sphere::intersect(Ray& ray, float *thit, LocalGeo *local){
    /*If the discriminant is positive, there are two solutions: one solution where
     the ray enters the sphere and one where it leaves. If the discriminant is zero, the
     ray grazes the sphere touching it at exactly one point.*/
    float a, b, c, discriminant;
    Vector3f dir = ray.dir();
    Vector3f e_minus_c = ray.pos().sub(center);
    a = dir.dot(dir);
    b= (2*dir).dot((e_minus_c));
    c = (e_minus_c).dot(e_minus_c)-pow(radius,2.0);
    
    discriminant = pow(b,2.0)-(4*a*c);
    
    if(discriminant < 0){
		return false;
	}
 	else  {

        float discr = pow( dir.dot(e_minus_c) ,2.0) - a*c;
        float t1 = (-dir.dot(e_minus_c) - sqrt( discr ))/a;
        float t2= (-dir.dot(e_minus_c) + sqrt( discr ))/a;
        float t = fmin(t1,t2);
        
        if (t<ray.t_min() || t>ray.t_max()){
            return false;
        }
 
        
        else {
            *thit=t;
            ray.pos().add(t*ray.dir());
            local->setPos(ray.pos());
            local->setNormal((ray.pos().sub(center))/radius); //normal will be vector3f
        }
        return true;
    }
}
Пример #25
0
float Triangle::crossing(const Ray & r)
{
    //_mm_prefetch(&v0, _MM_HINT_T0);
    vec4 pos = r.pos();
    vec4 dir = r.dir();
    vec4 t = v0 - pos;

    vec4 q = cross(dir, t);

    vec4 tmp (dot(t, normal), dot(e2, q), dot(e1, q), 0.0f);
    vec4 tuv = tmp * 1.0f / dot (dir, normal);

    int b = (tuv[1]>=0.0f && tuv[2]>=0.0f && tuv[0]>=0.0f && (tuv[1] + tuv[2] <= 1.0f));
    return b*tuv[0] + (b - 1);
}
Пример #26
0
float ExponentialMedium::pdf(PathSampleGenerator &/*sampler*/, const Ray &ray, bool onSurface) const
{
    if (_absorptionOnly) {
        return 1.0f;
    } else {
        float  x = _falloffScale*(ray.pos() - _unitPoint).dot(_unitFalloffDirection);
        float dx = _falloffScale*ray.dir().dot(_unitFalloffDirection);

        Vec3f transmittance = std::exp(-_sigmaT*densityIntegral(x, dx, ray.farT()));
        if (onSurface) {
            return transmittance.avg();
        } else {
            return (density(x, dx, ray.farT())*_sigmaT*transmittance).avg();
        }
    }
}
Пример #27
0
bool Sphere::occluded(const Ray &ray) const
{
    Vec3f p = ray.pos() - _pos;
    float B = p.dot(ray.dir());
    float C = p.lengthSq() - _radius*_radius;
    float detSq = B*B - C;
    if (detSq >= 0.0f) {
        float det = std::sqrt(detSq);
        float t = -B - det;
        if (t < ray.farT() && t > ray.nearT())
            return true;
        t = -B + det;
        if (t < ray.farT() && t > ray.nearT())
            return true;
    }

    return false;
}
Пример #28
0
bool TraceBase::handleVolume(PathSampleGenerator &sampler, MediumSample &mediumSample,
           const Medium *&medium, int bounce, bool adjoint, bool enableLightSampling,
           Ray &ray, Vec3f &throughput, Vec3f &emission, bool &wasSpecular)
{
    wasSpecular = !enableLightSampling;

    if (!adjoint && enableLightSampling && bounce < _settings.maxBounces - 1)
        emission += throughput*volumeEstimateDirect(sampler, mediumSample, medium, bounce + 1, ray);

    PhaseSample phaseSample;
    if (!mediumSample.phase->sample(sampler, ray.dir(), phaseSample))
        return false;

    ray = ray.scatter(mediumSample.p, phaseSample.w, 0.0f);
    ray.setPrimaryRay(false);
    throughput *= phaseSample.weight;

    return true;
}
Пример #29
0
Vec3f ExponentialMedium::transmittanceAndPdfs(PathSampleGenerator &/*sampler*/, const Ray &ray, bool startOnSurface,
        bool endOnSurface, float &pdfForward, float &pdfBackward) const
{
    float  x = _falloffScale*(ray.pos() - _unitPoint).dot(_unitFalloffDirection);
    float dx = _falloffScale*ray.dir().dot(_unitFalloffDirection);

    if (ray.farT() == Ray::infinity() && dx <= 0.0f) {
        pdfForward = pdfBackward = 0.0f;
        return Vec3f(0.0f);
    }

    Vec3f transmittance = std::exp(-_sigmaT*densityIntegral(x, dx, ray.farT()));

    if (_absorptionOnly) {
        pdfForward = pdfBackward = 1.0f;
    } else {
        pdfForward  =   endOnSurface ? transmittance.avg() : (density(x, dx, ray.farT())*_sigmaT*transmittance).avg();
        pdfBackward = startOnSurface ? transmittance.avg() : (density(x, dx,       0.0f)*_sigmaT*transmittance).avg();
    }

    return transmittance;
}
Пример #30
0
bool Cube::occluded(const Ray &ray) const
{
    Vec3f p = _invRot*(ray.pos() - _pos);
    Vec3f d = _invRot*ray.dir();

    Vec3f invD = 1.0f/d;
    Vec3f relMin((-_scale - p));
    Vec3f relMax(( _scale - p));

    float ttMin = ray.nearT(), ttMax = ray.farT();
    for (int i = 0; i < 3; ++i) {
        if (invD[i] >= 0.0f) {
            ttMin = max(ttMin, relMin[i]*invD[i]);
            ttMax = min(ttMax, relMax[i]*invD[i]);
        } else {
            ttMax = min(ttMax, relMin[i]*invD[i]);
            ttMin = max(ttMin, relMax[i]*invD[i]);
        }
    }

    return ttMin <= ttMax;
}