Beispiel #1
0
Vec3f RayTracer::shadow(const Vec3f &point,
			const Vec3f &pointOnLight,
			const Face *f,
			const Ray &ray,
			const Hit &hit) const
{
        const Vec3f normal(hit.getNormal());
        const Material *m = hit.getMaterial();

	Vec3f dirToLight = pointOnLight - point;
	dirToLight.Normalize();
	/* If dot product < 0, surface is not facing light */
	if (normal.Dot3(dirToLight) > 0) {
		Ray rayToLight(point, dirToLight);
		Hit hLight;
		bool blocked = CastRay(rayToLight, hLight, false);
		while (std::fabs(hLight.getT()) < SURFACE_EPSILON &&
				std::fabs((pointOnLight - point).Length()) > SURFACE_EPSILON) {
			rayToLight = Ray(rayToLight.pointAtParameter(SURFACE_EPSILON),
					dirToLight);
			blocked = CastRay(rayToLight, hLight, false);
		}
		if (hLight.getT() == FLT_MAX || hLight.getMaterial() != f->getMaterial()) {
			return Vec3f(0, 0, 0);
		}

		const Vec3f lightColor = 0.2 * f->getMaterial()->getEmittedColor() * f->getArea();
		return m->Shade(ray,hit,dirToLight,lightColor,args);
	}
	return Vec3f(0, 0, 0);
}
Beispiel #2
0
static void TestSingleLightFace (entity_t *light, lightinfo_t *l, const vec3_t faceoffset)
{
	vec_t	dist;
	vec_t	add;
	vec_t	*surf;
	vec3_t	rel;
	int	surf_r;
	int	surf_g;
	int	surf_b;
	int	c;

	VectorSubtract (light->origin, bsp_origin, rel);
	dist = scaledDistance((DotProduct(rel, l->facenormal) - l->facedist), light);

	// don't bother with lights behind the surface
	if (dist <= 0)
		return;

	// don't bother with light too far away
	if (dist > abs(light->light))
	{
		return;
	}

	// mfah - find the light color based on the surface name
	FindTexlightColor (&surf_r, &surf_g, &surf_b, l->texname);

	surf = l->surfpt[0];

	// we could speed the whole thing up drastically by checking only
	// the first and last point of each face - trouble is, any large
	// faces may have a light that only hits the middle.
	for (c = 0 ; c < l->numsurfpt ; c++, surf+=3)
	{
		if (surf > l->surfpt[SINGLEMAP - 1])
			COM_Error ("%s: surf out of bounds (numsurfpt=%d)", __thisfunc__, l->numsurfpt);
		dist = scaledDistance(CastRay(light->origin, surf), light);

		if (dist < 0)
			continue;	// light doesn't reach

		add = scaledLight(CastRay(light->origin, surf), light);

		if (add < (light->light / 3))
			continue;

		// normal light - other lights already have a color assigned
		// to them from when they were initially loaded
		// this will give madly high color values here so we will
		// scale them down later on
		light->lightcolor[0] = light->lightcolor[0] + surf_r;
		light->lightcolor[1] = light->lightcolor[1] + surf_g;
		light->lightcolor[2] = light->lightcolor[2] + surf_b;

		// speed up the checking process some more - if we have one hit
		// on a face, all other hits on the same face are just going to
		// give the same result - so we can return now.
		return;
	}
}
Beispiel #3
0
void Camera::Render(Scene scene)
{
  // Compute upper left corner of frame
  Point UpperLeftCorner(CameraRay.Location);
  UpperLeftCorner = UpperLeftCorner.Translate(CameraRay.Direction.Normalize() * FrameDistance); // Currently in center of frame
  Vector UpUnit = UprightDir.Normalize();
  UpperLeftCorner = UpperLeftCorner.Translate(UpUnit*(Height / 2)); // Currently in top center of frame
  // Compute the perpendicular, leftward facing vector and move the point to the upper left corner
  Vector LeftUnit = UprightDir.Cross(CameraRay.Direction).Normalize() * -1;
  UpperLeftCorner = UpperLeftCorner.Translate(LeftUnit*(Width / 2));

  Vector HorzInc = LeftUnit * (-1 * Width/ static_cast<double>(Resolution.width)); // Progress to the right
  Vector VertInc = UpUnit * (-1 * Height/ static_cast<double>(Resolution.height)); // Progress downwards

  // Position upper left corner to be in the center of the pixel
  UpperLeftCorner = UpperLeftCorner.Translate((HorzInc * (0.5)) + (VertInc * (0.5)));

  Point PixelLocation(0,0,0);
  // Iterate over the image space and render each occupied pixel
  for (int YPixel = 0; YPixel < Resolution.height; YPixel++)
  {
    for (int XPixel = 0; XPixel < Resolution.width; XPixel++)
    {
      PixelLocation = UpperLeftCorner.Translate((VertInc * YPixel) + (HorzInc * XPixel));
      Ray CameraToPixel(CameraRay.Location, CameraRay.Location.FromThisToThat(PixelLocation));

      cv::Vec3b PixelValue = CastRay(scene, CameraToPixel);

      Image.at<cv::Vec3b>(YPixel, XPixel) = PixelValue;
    }
  }
}
Beispiel #4
0
// does the recursive (shadow rays & recursive/glossy rays) work
Vec3f RayTracer::TraceRay(const Ray &ray, Hit &hit, int bounce_count) const
{
        hit = Hit();
        bool intersect = CastRay(ray,hit,false);

        Vec3f answer(args->background_color_linear);

        if (intersect == true) {
                const Material *m = hit.getMaterial();
                assert (m != NULL);

                // rays coming from the light source are set to white, don't bother to ray trace further.
                if (m->getEmittedColor().Length() > 0.001) {
                        answer = Vec3f(1,1,1);
                } else {
                        // ambient light
                        answer = args->ambient_light_linear *
                                 m->getDiffuseColor(hit.get_s(),hit.get_t());

                        // Shadows
                        answer += shadows(ray, hit);

                        // Reflections
                        Vec3f reflectiveColor = m->getReflectiveColor();
                        double roughness = m->getRoughness();
                        if (bounce_count > 0 && reflectiveColor.Length() > MIN_COLOR_LEN) {
                        	answer += reflectiveColor * reflections(ray, hit, bounce_count, roughness);
                        }
                }
        }

        return answer;
}
Beispiel #5
0
bool TracingInstance::IsPointOccluded(const KRay& ray, float len)
{
	IntersectContext ctx;
	if (CastRay(ray, ctx)) {
		double diff = ctx.ray_t - len;
		float epsilon = mpScene->GetSceneEpsilon();
		if (diff > epsilon)
			return false;
		else
			return true;
	}
	else
		return false;
}
Beispiel #6
0
/*
================
SingleLightFace
================
*/
void SingleLightFace (lightentity_t *light, lightinfo_t *l)
{
    vec_t	dist;
    vec3_t	incoming;
    vec_t	angle;
    vec_t	add;
    vec_t	*surf;
    qboolean	hit;
    int		mapnum;
    int		size;
    int		c, i;
    vec3_t	rel;
    vec3_t	spotvec;
    vec_t	falloff;
    vec3_t	*lightsamp;
    float	intensity;

    VectorSubtract (light->origin, bsp_origin, rel);
    dist = scaledist * (DotProduct (rel, l->facenormal) - l->facedist);

// don't bother with lights behind the surface
    if (dist <= 0)
        return;

// don't bother with light too far away
    intensity = ( light->light[ 0 ] + light->light[ 1 ] + light->light[ 2 ] ) / 3.0;
    if( dist > intensity )
    {
        c_culldistplane++;
        return;
    }

    if (light->targetent)
    {
        VectorSubtract (light->targetorigin, light->origin, spotvec);
        VectorNormalize (spotvec);
        if (!light->angle)
            falloff = -cos(20*Q_PI/180);
        else
            falloff = -cos(light->angle/2*Q_PI/180);
    }
    else
        falloff = 0;	// shut up compiler warnings

    mapnum = 0;
    for (mapnum=0 ; mapnum<l->numlightstyles ; mapnum++)
        if (l->lightstyles[mapnum] == light->style)
            break;
    lightsamp = l->lightmaps[mapnum];
    if (mapnum == l->numlightstyles)
    {   // init a new light map
        if (mapnum == MAXLIGHTMAPS)
        {
            printf ("WARNING: Too many light styles on a face\n");
            return;
        }
        size = (l->texsize[1]+1)*(l->texsize[0]+1);
        for (i=0 ; i<size ; i++)
        {
            lightsamp[i][0] = 0;
            lightsamp[i][1] = 0;
            lightsamp[i][2] = 0;
        }
    }

//
// check it for real
//
    hit = false;
    c_proper++;

    surf = l->surfpt[0];
    for (c=0 ; c<l->numsurfpt ; c++, surf+=3)
    {
        dist = CastRay(light->origin, surf)*scaledist;
        if (dist < 0)
            continue;	// light doesn't reach

        VectorSubtract (light->origin, surf, incoming);
        VectorNormalize (incoming);
        angle = DotProduct (incoming, l->facenormal);
        if (light->targetent)
        {   // spotlight cutoff
            if (DotProduct (spotvec, incoming) > falloff)
                continue;
        }

        angle = (1.0-scalecos) + scalecos*angle;
        for( i=0; i<3; i++ )
        {
            add = light->light[i] - dist;
            add *= angle;
            if (add < 0)
                continue;

            lightsamp[c][i] += add;
        }

        // check intensity
        intensity = ( lightsamp[ c ][ 0 ] + lightsamp[ c ][ 1 ] + lightsamp[ c ][ 2 ] ) / 3.0;
        if( intensity > 1 )		// ignore real tiny lights
            hit = true;
    }

    if (mapnum == l->numlightstyles && hit)
    {
        l->lightstyles[mapnum] = light->style;
        l->numlightstyles++;	// the style has some real data now
    }
}
Beispiel #7
0
void CalcPoints (lightinfo_t *l)
{
    int		i;
    int		s, t, j;
    int		w, h, step;
    vec_t	starts, startt, us, ut;
    vec_t	*surf;
    vec_t	mids, midt;
    vec3_t	facemid, move;

//
// fill in surforg
// the points are biased towards the center of the surface
// to help avoid edge cases just inside walls
//
    surf = l->surfpt[0];
    mids = (l->exactmaxs[0] + l->exactmins[0])/2;
    midt = (l->exactmaxs[1] + l->exactmins[1])/2;

    for (j=0 ; j<3 ; j++)
        facemid[j] = l->texorg[j] + l->textoworld[0][j]*mids + l->textoworld[1][j]*midt;

    if (extrasamples)
    {   // extra filtering
        h = (l->texsize[1]+1)*2;
        w = (l->texsize[0]+1)*2;
        starts = (l->texmins[0]-0.5)*16;
        startt = (l->texmins[1]-0.5)*16;
        step = 8;
    }
    else
    {
        h = l->texsize[1]+1;
        w = l->texsize[0]+1;
        starts = l->texmins[0]*16;
        startt = l->texmins[1]*16;
        step = 16;
    }

    l->numsurfpt = w * h;
    for (t=0 ; t<h ; t++)
    {
        for (s=0 ; s<w ; s++, surf+=3)
        {
            us = starts + s*step;
            ut = startt + t*step;

            // if a line can be traced from surf to facemid, the point is good
            for (i=0 ; i<6 ; i++)
            {
                // calculate texture point
                for (j=0 ; j<3 ; j++)
                    surf[j] = l->texorg[j] + l->textoworld[0][j]*us
                              + l->textoworld[1][j]*ut;

                if (CastRay (facemid, surf) != -1)
                    break;	// got it
                if (i & 1)
                {
                    if (us > mids)
                    {
                        us -= 8;
                        if (us < mids)
                            us = mids;
                    }
                    else
                    {
                        us += 8;
                        if (us > mids)
                            us = mids;
                    }
                }
                else
                {
                    if (ut > midt)
                    {
                        ut -= 8;
                        if (ut < midt)
                            ut = midt;
                    }
                    else
                    {
                        ut += 8;
                        if (ut > midt)
                            ut = midt;
                    }
                }

                // move surf 8 pixels towards the center
                VectorSubtract (facemid, surf, move);
                VectorNormalize (move);
                VectorMA (surf, 8, move, surf);
            }
            if (i == 2)
                c_bad++;
        }
    }

}
Beispiel #8
0
/*
================
SingleLightFace
================
*/
static void SingleLightFace (entity_t *light, lightinfo_t *l, const vec3_t faceoffset)
{
	vec_t	dist;
	vec3_t	incoming;
	vec_t	angle;
	vec_t	add;
	vec_t	*surf;
	qboolean	hit;
	int		mapnum;
	int		size;
	int		c, i;
	vec3_t	rel;
	vec3_t	spotvec;
	vec_t	falloff;
	vec_t	*lightsamp;
	/* Colored lighting */
	vec3_t	*lightcolorsamp;

	VectorSubtract (light->origin, bsp_origin, rel);
	dist = scaledDistance((DotProduct(rel, l->facenormal) - l->facedist), light);

// don't bother with lights behind the surface
	if (dist <= 0)
		return;

// don't bother with light too far away
	//if (dist > light->light)
	if (dist > abs(light->light))
	{
		return;
	}

	if (light->targetent)
	{
		VectorSubtract (light->targetent->origin, light->origin, spotvec);
		VectorNormalize (spotvec);
		if (!light->angle)
			falloff = -cos(20*Q_PI/180);
		else
			falloff = -cos(light->angle/2*Q_PI/180);
	}
	else if (light->use_mangle)
	{
		VectorCopy (light->mangle, spotvec);
		if (!light->angle)
			falloff = -cos(20*Q_PI/180);
		else	falloff = -cos(light->angle/2*Q_PI/180);
	}
	else
	{
		falloff = 0;	// shut up compiler warnings
		VectorClear (spotvec); // shut up static analyzers
	}

	for (mapnum = 0; mapnum < l->numlightstyles; mapnum++)
	{
		if (l->lightstyles[mapnum] == light->style)
			break;
	}
	lightsamp = l->lightmaps[mapnum];
	lightcolorsamp = l->lightmapcolors[mapnum];
	if (mapnum == l->numlightstyles)
	{	// init a new light map
		if (mapnum == MAXLIGHTMAPS)
		{
			printf ("WARNING: Too many light styles on a face\n");
			return;
		}
		size = (l->texsize[1]+1)*(l->texsize[0]+1);
		for (i = 0 ; i < size ; i++)
		{
			lightcolorsamp[i][0] = 0;
			lightcolorsamp[i][1] = 0;
			lightcolorsamp[i][2] = 0;
			lightsamp[i] = 0;
		}
	}

//
// check it for real
//
	hit = false;

	surf = l->surfpt[0];
	for (c = 0 ; c < l->numsurfpt ; c++, surf+=3)
	{
		if (surf > l->surfpt[SINGLEMAP - 1])
			COM_Error ("%s: surf out of bounds (numsurfpt=%d)", __thisfunc__, l->numsurfpt);
		dist = scaledDistance(CastRay(light->origin, surf), light);
		if (dist < 0)
			continue;	// light doesn't reach

		VectorSubtract (light->origin, surf, incoming);
		VectorNormalize (incoming);
		angle = DotProduct (incoming, l->facenormal);
		if (light->targetent || light->use_mangle)
		{	// spotlight cutoff
			if (DotProduct (spotvec, incoming) > falloff)
				continue;
		}

		angle = (1.0-scalecos) + scalecos*angle;
		add = scaledLight(CastRay(light->origin, surf), light);
		add *= angle;
		lightsamp[c] += add;
		if (lightsamp[c] > 255)
			lightsamp[c] = 255;

		add /= 255.0;
		lightcolorsamp[c][0] += add * light->lightcolor[0];
		lightcolorsamp[c][1] += add * light->lightcolor[1];
		lightcolorsamp[c][2] += add * light->lightcolor[2];

		if (abs((int) lightsamp[c]) > 1)	// ignore really tiny lights
			hit = true;
	}

	if (mapnum == l->numlightstyles && hit)
	{
		if (mapnum == MAXLIGHTMAPS-1)
		{
			printf ("WARNING: Too many light styles on a face\n");
			return;
		}
		l->lightstyles[mapnum] = light->style;
		l->numlightstyles++;	// the style has some real data now
	}
}