Пример #1
0
        /// <summary>
        /// </summary>
        /// <param name="u">value between 0 to 1</param>
        /// <param name="v">value between 0 to 1</param>
        /// <param name="rec">IntersectionRecord to be texture mapped</param>
        /// <param name="g">the geometry</param>
        /// <returns></returns>
        public override Vector3 GetTexile(float u, float v, IntersectionRecord rec, RTGeometry g)
        {
            float useU = u * mRepeat;

            useU = useU - ((int)useU);
            return((useU * mColor2) + (1 - useU) * mColor1);
        }
        /// <summary>
        /// Intersects the ray, if intersection is closer than the one inside the record,
        /// sets the records with intersection information.
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="record"></param>
        /// <returns></returns>
        public override bool Intersect(Ray ray, IntersectionRecord record)
        {
            float   dist = 0f;
            Vector3 hitPt, n;

            n = mNormal;    // because ray/plane intersection may flip the normal!
            if (!RayPlaneIntersection(ray, ref n, mD, ref dist))
            {
                return(false);
            }

            /*
             * rectangle behind the ray or there are other closer intersections
             */
            if ((dist < 0) || (dist > record.HitDistance))
            {
                return(false);
            }

            hitPt = ray.Origin + (ray.Direction * dist);

            /*
             * Now need to decide inside or outside
             */
            if (!InsidePolygon(hitPt))
            {
                return(false);
            }

            record.UpdateRecord(dist, hitPt, n, ray, mMaterialIndex, GetResourceIndex());
            return(true);
        }
        public bool FindNearest(Ray ray, IntersectionRecord rec, int exceptGeom)
        {
            float enterD=0f, exitD=0f;
            if (!ComputeEntryAndExitSignedDistances(ray, out enterD, out exitD))
                return false;

            if (IsLeafNode())
            {
                bool hit = IntersectWithGeom(ray, rec, exceptGeom);
                return (hit &&
                         (rec.HitDistance >= enterD) &&
                         (rec.HitDistance <= exitD)
                         );
            }

            Vector3 enterPos = ray.Origin + enterD * ray.Direction;
            Vector3 exitPos = ray.Origin + exitD * ray.Direction;
            bool rightHit = false;
            bool leftHit = false;

            if (PositionLeftOfSplit(enterPos)) {
                leftHit = LeftChild.FindNearest(ray, rec, exceptGeom);
                if ((!leftHit) && PositionRightOfSplit(exitPos))
                    rightHit = RightChild.FindNearest(ray, rec, exceptGeom);
            } else {
                rightHit = RightChild.FindNearest(ray, rec, exceptGeom);
                if ((!rightHit) && PositionLeftOfSplit(exitPos))
                    leftHit = LeftChild.FindNearest(ray, rec, exceptGeom);
            }
            return leftHit || rightHit;
        }
Пример #4
0
        private Vector3 ShadeRec(Vector3 V, RTLight lgt, IntersectionRecord rec)
        {
            RTMaterial m = mSceneDatabase.GetMaterial(rec.MaterialIndex);
            Vector3    r = Vector3.Zero;

            float percentToUse = 1f;

            if (mComputeShadow)
            {
                percentToUse = lgt.PercentVisible(rec.IntersectPosition, rec.GeomIndex, mSceneDatabase);
            }

            if (percentToUse > 0f)
            {
                Vector3 L     = lgt.GetNormalizedDirection(rec.IntersectPosition);
                float   NdotL = Vector3.Dot(rec.NormalAtIntersect, L);

                if (NdotL > 0)
                {
                    Vector3 diffColor  = m.GetDiffuse(mSceneDatabase, rec);
                    Vector3 lightColor = percentToUse * lgt.GetColor(rec.IntersectPosition);
                    r += diffColor * NdotL * lightColor;

                    Vector3 R     = 2 * NdotL * rec.NormalAtIntersect - L;
                    float   VdotR = Vector3.Dot(V, R);

                    if (VdotR > 0)
                    {
                        r += m.GetSpecular(mSceneDatabase, rec) * (float)Math.Pow(VdotR, m.GetN) * lightColor;
                    }
                }
            }

            return(r);
        }
        private Vector3 ShadeRec(Vector3 V, RTLight lgt, IntersectionRecord rec)
        {
            RTMaterial m = mSceneDatabase.GetMaterial(rec.MaterialIndex);
            Vector3 r = Vector3.Zero;

            float percentToUse = 1f;
            if (mComputeShadow)
                percentToUse = lgt.PercentVisible(rec.IntersectPosition, rec.GeomIndex, mSceneDatabase);

            if (percentToUse > 0f)
            {
                Vector3 L = lgt.GetNormalizedDirection(rec.IntersectPosition);
                float NdotL = Vector3.Dot(rec.NormalAtIntersect, L);

                if (NdotL > 0)
                {
                    Vector3 diffColor = m.GetDiffuse(mSceneDatabase, rec);
                    Vector3 lightColor = percentToUse * lgt.GetColor(rec.IntersectPosition);
                    r += diffColor * NdotL * lightColor;

                    Vector3 R = 2 * NdotL * rec.NormalAtIntersect - L;
                    float VdotR = Vector3.Dot(V, R);

                    if (VdotR > 0)
                        r += m.GetSpecular(mSceneDatabase, rec) * (float)Math.Pow(VdotR, m.GetN) * lightColor;
                }
            }

            return r;
        }
        private bool IsBlocked(Vector3 org, Vector3 target, int exceptGeomIndex)
        {
            Vector3            d    = target - org;
            float              dist = d.Length();
            IntersectionRecord rec  = new IntersectionRecord(dist);

            d /= dist;
            Ray r = Ray.CrateRayFromPtDir(org, d);

#if KDTREE
            mKdTree.ComputeVisibility(r, rec, exceptGeomIndex);
            return(rec.GeomIndex != RTCore.kInvalidIndex);
#else
            bool blocked = false;
            int  count   = 0;

            while ((!blocked) && (count < mSceneDatabase.GetNumGeom()))
            {
                if (count != exceptGeomIndex)
                {
                    blocked = mSceneDatabase.GetGeom(count).Intersect(r, rec);
                }
                count++;
            }
            return(blocked);
#endif
        }
Пример #7
0
        /// <summary>
        /// Intersects the ray with the sphere. If intersection is closer than what is
        /// in the record, updates the record with new intersection information.
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="record"></param>
        /// <returns></returns>
        public override bool Intersect(Ray ray, IntersectionRecord record)
        {
            Vector3 v1   = ray.Origin - mCenter;
            float   b    = 2f * Vector3.Dot(v1, ray.Direction);
            float   c    = v1.LengthSquared() - mRadiusSquared;
            float   root = b * b - 4 * c;

            if (root < 0f)
            {
                return(false);
            }

            root = (float)Math.Sqrt(root);
            float t0 = 0.5f * (-b - root);
            float t1 = 0.5f * (-b + root);

            if ((t0 < 0) && (t1 < 0))
            {
                return(false);
            }

            float dist;

            if (t0 < t1)
            {
                if (t0 > 0)
                {
                    dist = t0;
                }
                else
                {
                    dist = t1;
                }
            }
            else
            {
                if (t1 > 0)
                {
                    dist = t1;
                }
                else
                {
                    dist = t0;
                }
            }

            if (dist > record.HitDistance)
            {
                return(false);
            }

            // intersection found
            Vector3 pt = ray.Origin + dist * ray.Direction;
            Vector3 n  = pt - mCenter;

            record.UpdateRecord(dist, pt, n, ray, mMaterialIndex, GetResourceIndex());

            return(true);
        }
        /// <summary>
        /// </summary>
        /// <param name="u">value between 0 to 1</param>
        /// <param name="v">value between 0 to 1</param>
        /// <param name="rec">IntersectionRecord to be texture mapped</param>
        /// <param name="g">the geometry</param>
        /// <returns></returns>
        public override Vector3 GetTexile(float u, float v, IntersectionRecord rec, RTGeometry g)
        {
            float useU = u * mDirection.X + v * mDirection.Y;
            float theta = useU * mThetaRange;
            float sineV = 0.5f * (((float) Math.Sin(theta)) + 1);

            return (sineV * mColor1) + (1f - sineV) * mColor2;
        }
        /// <summary>
        /// </summary>
        /// <param name="u">value between 0 to 1</param>
        /// <param name="v">value between 0 to 1</param>
        /// <param name="rec">IntersectionRecord to be texture mapped</param>
        /// <param name="g">the geometry</param>
        /// <returns></returns>
        public override Vector3 GetTexile(float u, float v, IntersectionRecord rec, RTGeometry g)
        {
            float useU  = u * mDirection.X + v * mDirection.Y;
            float theta = useU * mThetaRange;
            float sineV = 0.5f * (((float)Math.Sin(theta)) + 1);

            return((sineV * mColor1) + (1f - sineV) * mColor2);
        }
        /// <summary>
        /// UV are values between 0 to 1, maps to texture width/height linearly and returns the
        /// corresponding textile.
        /// </summary>
        /// <param name="u">value between 0 to 1</param>
        /// <param name="v">value between 0 to 1</param>
        /// <param name="rec">IntersectionRecord to be texture mapped</param>
        /// <param name="g">the geometry</param>
        /// <returns></returns>
        public override Vector3 GetTexile(float u, float v, IntersectionRecord rec, RTGeometry g)
        {
            Vector3 norm = Vector3.UnitY;

            if ((u >= 0) && (u <= 1f) && (v >= 0) && (v <= 1f))
            {
                int   u0Index = 0, u1Index = 0, v0Index = 0, v1Index = 0;
                float uIndex, vIndex;
                float bumpAtu0v0, bumpAtu0v1, bumpAtu1v0, bumpAtu1v1;
                lock (mTextureImage)
                {
                    GetIndices(u, mTextureImage.Width, ref u0Index, ref u1Index);
                    GetIndices(v, mTextureImage.Height, ref v0Index, ref v1Index);
                    v0Index = mTextureImage.Height - 1 - v0Index;
                    v1Index = mTextureImage.Height - 1 - v1Index;
                    uIndex  = u * mTextureImage.Width;
                    vIndex  = mTextureImage.Height - 1 - (v * mTextureImage.Height);

                    bumpAtu0v0 = ColorToVec(mTextureImage.GetPixel(u0Index, v0Index)).Length();
                    bumpAtu1v0 = ColorToVec(mTextureImage.GetPixel(u1Index, v0Index)).Length();
                    bumpAtu0v1 = ColorToVec(mTextureImage.GetPixel(u0Index, v1Index)).Length();
                    bumpAtu1v1 = ColorToVec(mTextureImage.GetPixel(u1Index, v1Index)).Length();
                }
                float du       = uIndex - u0Index;
                float dv       = vIndex - v1Index;
                float bumpAtV0 = du * bumpAtu1v0 + (1 - du) * bumpAtu0v0;
                float bumpAtV1 = du * bumpAtu1v1 + (1 - du) * bumpAtu0v1;
                float bumpAtU0 = dv * bumpAtu0v1 + (1 - dv) * bumpAtu0v0;
                float bumpAtU1 = dv * bumpAtu1v1 + (1 - dv) * bumpAtu1v0;

                float dDu = mGain * (bumpAtV1 - bumpAtV0);
                float dDv = mGain * (bumpAtU1 - bumpAtU0);

                float u0Ref, u1Ref, v0Ref, v1Ref;
                u0Ref = u0Index * mInvWidth;
                u1Ref = u1Index * mInvWidth;
                v0Ref = v0Index * mInvHeight;
                v1Ref = v1Index * mInvHeight;

                Vector3 Pu0 = g.GetPosition(u0Ref, v);
                Vector3 Pu1 = g.GetPosition(u1Ref, v);
                Vector3 Pv0 = g.GetPosition(u, v0Ref);
                Vector3 Pv1 = g.GetPosition(u, v1Ref);
                Vector3 Pu  = Pu1 - Pu0;
                Vector3 Pv  = Pv1 - Pv0;

                Vector3 aDir = Vector3.Normalize(Vector3.Cross(Pu, rec.NormalAtIntersect));
                Vector3 bDir = Vector3.Normalize(Vector3.Cross(Pv, rec.NormalAtIntersect));
                Vector3 D    = (dDv * aDir) - (dDu * bDir);

                norm = rec.NormalAtIntersect + D;
                norm.Normalize();
            }

            return(norm);
        }
Пример #11
0
        /// <summary>
        /// Diffuse color lookup: if texture mapped, scale the texture value by mKd
        /// </summary>
        /// <param name="database"></param>
        /// <param name="rec"></param>
        /// <returns></returns>
        public Vector3 GetDiffuse(SceneDatabase database, IntersectionRecord rec)
        {
            Vector3 result = mKd.AttributeValue();

            if (mKd.IsTextureMapped())
            {
                result *= mKd.AttributeLookup(database, rec);
            }
            return(result);
        }
        /// <summary>
        /// UV are values between 0 to 1, maps to texture width/height linearly and returns the
        /// corresponding textile.
        /// </summary>
        /// <param name="u">value between 0 to 1</param>
        /// <param name="v">value between 0 to 1</param>
        /// <param name="rec">IntersectionRecord to be texture mapped</param>
        /// <param name="g">the geometry</param>
        /// <returns></returns>
        public override Vector3 GetTexile(float u, float v, IntersectionRecord rec, RTGeometry g)
        {
            Vector3 norm = Vector3.UnitY;
            if ((u >= 0) && (u <= 1f) && (v >= 0) && (v <= 1f))
            {
                int u0Index=0, u1Index=0, v0Index=0, v1Index=0;
                float uIndex, vIndex;
                float bumpAtu0v0, bumpAtu0v1, bumpAtu1v0, bumpAtu1v1;
                lock (mTextureImage)
                {
                    GetIndices(u, mTextureImage.Width, ref u0Index, ref u1Index);
                    GetIndices(v, mTextureImage.Height, ref v0Index, ref v1Index);
                    v0Index = mTextureImage.Height - 1 - v0Index;
                    v1Index = mTextureImage.Height - 1 - v1Index;
                    uIndex = u * mTextureImage.Width;
                    vIndex = mTextureImage.Height - 1 - (v * mTextureImage.Height);

                    bumpAtu0v0 = ColorToVec(mTextureImage.GetPixel(u0Index, v0Index)).Length();
                    bumpAtu1v0 = ColorToVec(mTextureImage.GetPixel(u1Index, v0Index)).Length();
                    bumpAtu0v1 = ColorToVec(mTextureImage.GetPixel(u0Index, v1Index)).Length();
                    bumpAtu1v1 = ColorToVec(mTextureImage.GetPixel(u1Index, v1Index)).Length();
                }
                float du = uIndex - u0Index;
                float dv = vIndex - v1Index;
                float bumpAtV0 = du * bumpAtu1v0 + (1 - du) * bumpAtu0v0;
                float bumpAtV1 = du * bumpAtu1v1 + (1 - du) * bumpAtu0v1;
                float bumpAtU0 = dv * bumpAtu0v1 + (1 - dv) * bumpAtu0v0;
                float bumpAtU1 = dv * bumpAtu1v1 + (1 - dv) * bumpAtu1v0;

                float dDu = mGain * (bumpAtV1 - bumpAtV0);
                float dDv = mGain * (bumpAtU1 - bumpAtU0);

                float u0Ref, u1Ref, v0Ref, v1Ref;
                u0Ref = u0Index * mInvWidth;
                u1Ref = u1Index * mInvWidth;
                v0Ref = v0Index * mInvHeight;
                v1Ref = v1Index * mInvHeight;

                Vector3 Pu0 = g.GetPosition(u0Ref, v);
                Vector3 Pu1 = g.GetPosition(u1Ref, v);
                Vector3 Pv0 = g.GetPosition(u, v0Ref);
                Vector3 Pv1 = g.GetPosition(u, v1Ref);
                Vector3 Pu = Pu1 - Pu0;
                Vector3 Pv = Pv1 - Pv0;

                Vector3 aDir = Vector3.Normalize(Vector3.Cross(Pu, rec.NormalAtIntersect));
                Vector3 bDir = Vector3.Normalize(Vector3.Cross(Pv, rec.NormalAtIntersect));
                Vector3 D = (dDv * aDir) - (dDu * bDir);

                norm = rec.NormalAtIntersect + D;
                norm.Normalize();
            }

            return norm;
        }
Пример #13
0
        /// <summary>
        /// Transparency look up: if mapped, scales Avg(RBG) by transparency
        /// </summary>
        /// <param name="database"></param>
        /// <param name="rec"></param>
        /// <returns></returns>
        public float GetTransparency(SceneDatabase database, IntersectionRecord rec)
        {
            float result = mTransparency.AttributeValue();

            if (mTransparency.IsTextureMapped())
            {
                Vector3 v = mTransparency.AttributeLookup(database, rec);
                result *= ((v.X + v.Y + v.Z) / 3f);
            }
            return(result);
        }
Пример #14
0
 public Vector3 TextureLookup(IntersectionRecord rec, RTGeometry g)
 {
     if (mTexture.NeedUV())
     {
         float u = 0f, v = 0f;
         g.GetUV(rec.IntersectPosition, rec.HitPtBC, ref u, ref v);
         return(mTexture.GetTexile(u, v, rec, g));
     }
     else
     {
         return(mTexture.GetTexile(rec, g));
     }
 }
Пример #15
0
 public Vector3 TextureLookup(IntersectionRecord rec, RTGeometry g)
 {
     if (mTexture.NeedUV())
     {
         float u = 0f, v = 0f;
         g.GetUV(rec.IntersectPosition, rec.HitPtBC, ref u, ref v);
         return mTexture.GetTexile(u, v, rec, g);
     }
     else
     {
         return mTexture.GetTexile(rec, g);
     }
 }
        /// <summary>
        /// UV are values between 0 to 1, maps to texture width/height linearly and returns the
        /// corresponding textile.
        /// </summary>
        /// <param name="u">value between 0 to 1</param>
        /// <param name="v">value between 0 to 1</param>
        /// <param name="rec">IntersectionRecord to be texture mapped</param>
        /// <param name="g">the geometry</param>
        /// <returns></returns>
        public override Vector3 GetTexile(float u, float v, IntersectionRecord rec, RTGeometry g)
        {
            float uVal = u * mURepeat;
            float vVal = v * mVRepeat;

            int uBit = ((int)uVal) % 2;
            int vBit = ((int)vVal) % 2;

            Vector3 c = mColor1;
            if (uBit == vBit)
                c = mColor2;

            return c;
        }
        private void ComputeVisibility(Ray r, IntersectionRecord rec, int exceptGeomIndex)
        {
#if KDTREE
            mKdTree.ComputeVisibility(r, rec, exceptGeomIndex);
#else
            for (int i = 0; i < mSceneDatabase.GetNumGeom(); i++)
            {
                if (i != exceptGeomIndex)
                {
                    RTGeometry g = mSceneDatabase.GetGeom(i);
                    g.Intersect(r, rec);
                }
            }
#endif
        }
        private void ComputeVisibility(Ray r, IntersectionRecord rec, int exceptGeomIndex)
        {
#if KDTREE
            mKdTree.ComputeVisibility(r, rec, exceptGeomIndex);
#else
            for (int i = 0; i < mSceneDatabase.GetNumGeom(); i++)
            {
                if (i != exceptGeomIndex)
                {
                    RTGeometry g = mSceneDatabase.GetGeom(i);
                    g.Intersect(r, rec);
                }
            }
#endif
        }
Пример #19
0
        private bool IntersectWithGeom(Ray ray, IntersectionRecord rec, int exceptGeom)
        {
            bool hitOnce = false;

            if (mGeomList != null)
            {
                foreach (RTGeometry g in mGeomList)
                {
                    if ((g.GetResourceIndex() != exceptGeom) && g.Intersect(ray, rec))
                    {
                        hitOnce = true;
                    }
                }
            }
            return(hitOnce);
        }
        /// <summary>
        /// (x,y,z) is the visible pt, returns solid texture value at x,y,z
        /// </summary>
        /// <param name="rec">IntersectionRecord to be texture mapped</param>
        /// <param name="g">The geometry</param>
        /// <returns></returns>
        public override Vector3 GetTexile(IntersectionRecord rec, RTGeometry g)
        {
            float x = rec.IntersectPosition.X;
            float y = rec.IntersectPosition.Y;
            float z = rec.IntersectPosition.Z;

            float n = ComputeTurbulanceNoise(x, y, z);

            Vector3 v = new Vector3(x, y, z);
            v.Normalize();
            float useU = Vector3.Dot(mDirection, v) + n;
            float theta = useU * mThetaRange;
            float sineV = 0.5f * (((float) Math.Sin(theta)) + 1);

            return (sineV * mColor1) + (1f - sineV) * mColor2;
        }
Пример #21
0
        /// <summary>
        /// (x,y,z) is the visible pt, returns solid texture value at x,y,z
        /// </summary>
        /// <param name="rec">IntersectionRecord to be texture mapped</param>
        /// <param name="g">The geometry</param>
        /// <returns></returns>
        public override Vector3 GetTexile(IntersectionRecord rec, RTGeometry g)
        {
            float x = rec.IntersectPosition.X;
            float y = rec.IntersectPosition.Y;
            float z = rec.IntersectPosition.Z;

            float n = ComputeTurbulanceNoise(x, y, z);

            Vector3 v = new Vector3(x, y, z);

            v.Normalize();
            float useU  = Vector3.Dot(mDirection, v) + n;
            float theta = useU * mThetaRange;
            float sineV = 0.5f * (((float)Math.Sin(theta)) + 1);

            return((sineV * mColor1) + (1f - sineV) * mColor2);
        }
Пример #22
0
        /// <summary>
        /// UV are values between 0 to 1, maps to texture width/height linearly and returns the
        /// corresponding textile.
        /// </summary>
        /// <param name="u">value between 0 to 1</param>
        /// <param name="v">value between 0 to 1</param>
        /// <param name="rec">IntersectionRecord to be texture mapped</param>
        /// <param name="g">the geometry</param>
        /// <returns></returns>
        public override Vector3 GetTexile(float u, float v, IntersectionRecord rec, RTGeometry g)
        {
            float uVal = u * mURepeat;
            float vVal = v * mVRepeat;

            int uBit = ((int)uVal) % 2;
            int vBit = ((int)vVal) % 2;

            Vector3 c = mColor1;

            if (uBit == vBit)
            {
                c = mColor2;
            }

            return(c);
        }
 /// <summary>
 /// UV are values between 0 to 1, maps to texture width/height linearly and returns the
 /// corresponding textile.
 /// </summary>
 /// <param name="u">value between 0 to 1</param>
 /// <param name="v">value between 0 to 1</param>
 /// <param name="rec">IntersectionRecord to be texture mapped</param>
 /// <param name="g">the geometry</param>
 /// <returns></returns>
 /// 
 /// only available to Vista and later
 /// [MethodImpl(MethodImplOptions.Synchronized)]
 public override Vector3 GetTexile(float u, float v, IntersectionRecord rec, RTGeometry g)
 {
     System.Drawing.Color c = System.Drawing.Color.Black;
     if (null != mTextureImage)
     {
         if ((u >= 0) && (u <= 1f) && (v >= 0) && (v <= 1f))
         {
             lock (mTextureImage)
             {
                 int x = (int)(u * (mTextureImage.Width - 1) + 0.5f);
                 int y = (int)(v * (mTextureImage.Height - 1) + 0.5f);
                 y = mTextureImage.Height - y - 1;
                 c = mTextureImage.GetPixel(x, y);
             }
         }
     }
     return ColorToVec(c);
 }
Пример #24
0
 /// <summary>
 /// UV are values between 0 to 1, maps to texture width/height linearly and returns the
 /// corresponding textile.
 /// </summary>
 /// <param name="u">value between 0 to 1</param>
 /// <param name="v">value between 0 to 1</param>
 /// <param name="rec">IntersectionRecord to be texture mapped</param>
 /// <param name="g">the geometry</param>
 /// <returns></returns>
 ///
 /// only available to Vista and later
 /// [MethodImpl(MethodImplOptions.Synchronized)]
 public override Vector3 GetTexile(float u, float v, IntersectionRecord rec, RTGeometry g)
 {
     System.Drawing.Color c = System.Drawing.Color.Black;
     if (null != mTextureImage)
     {
         if ((u >= 0) && (u <= 1f) && (v >= 0) && (v <= 1f))
         {
             lock (mTextureImage)
             {
                 int x = (int)(u * (mTextureImage.Width - 1) + 0.5f);
                 int y = (int)(v * (mTextureImage.Height - 1) + 0.5f);
                 y = mTextureImage.Height - y - 1;
                 c = mTextureImage.GetPixel(x, y);
             }
         }
     }
     return(ColorToVec(c));
 }
Пример #25
0
        /// <summary>
        /// Percentage of the light that is visible from the visiblePt
        /// </summary>
        /// <param name="visiblePt"></param>
        /// <param name="exceptGeomIndex">this geometry can never block the light (geomIndex of the visiblePt)</param>
        /// <param name="database"></param>
        /// <returns></returns>
        public virtual float PercentVisible(Vector3 visiblePt, int exceptGeomIndex, SceneDatabase sceneDatabase)
        {
            IntersectionRecord rec = new IntersectionRecord(DistanceToLight(visiblePt));
            Ray r = Ray.CrateRayFromPtDir(visiblePt, GetNormalizedDirection(visiblePt));

            bool blocked = false;
            int  count   = 0;

            while ((!blocked) && (count < sceneDatabase.GetNumGeom()))
            {
                if (count != exceptGeomIndex)
                {
                    blocked = sceneDatabase.GetGeom(count).Intersect(r, rec);
                }
                count++;
            }
            return(blocked ? 0f : 1f);
        }
        /// <summary>
        /// </summary>
        /// <param name="u">value between 0 to 1</param>
        /// <param name="v">value between 0 to 1</param>
        /// <param name="rec">IntersectionRecord to be texture mapped</param>
        /// <param name="g">the geometry</param>
        /// <returns></returns>
        public override Vector3 GetTexile(float u, float v, IntersectionRecord rec, RTGeometry g)
        {
            float useU = u * mURepeat;
            useU = useU - ((int)useU);
            float useV = v * mVRepeat;
            useV = useV - ((int)useV);

            Vector3 resultColor = mColor1;
            if ((useU > kLowBound) && (useU < kUpBound))
            {
                resultColor = GetGridColor(useU);
            }
            else if ((useV > kLowBound) && (useV < kUpBound))
            {
                resultColor = GetGridColor(useV);
            }

            return resultColor;
        }
Пример #27
0
        /// <summary>
        /// Normal vector lookup, if texture mapped, replaces the intersection record's normal vector!
        /// </summary>
        /// <param name="database"></param>
        /// <param name="rec"></param>
        /// <returns></returns>
        public Vector3 GetNormal(SceneDatabase database, IntersectionRecord rec)
        {
            Vector3 result;

            if (mNormal.IsTextureMapped())
            {
                result = mNormal.AttributeLookup(database, rec);
                if (Vector3.Dot(result, rec.NormalAtIntersect) < 0)
                {
                    result = -result;
                }
                rec.SetNormalAtIntersection(result);
            }
            else
            {
                result = rec.NormalAtIntersect;
            }

            return(result);
        }
Пример #28
0
        public bool FindNearest(Ray ray, IntersectionRecord rec, int exceptGeom)
        {
            float enterD = 0f, exitD = 0f;

            if (!ComputeEntryAndExitSignedDistances(ray, out enterD, out exitD))
            {
                return(false);
            }

            if (IsLeafNode())
            {
                bool hit = IntersectWithGeom(ray, rec, exceptGeom);
                return(hit &&
                       (rec.HitDistance >= enterD) &&
                       (rec.HitDistance <= exitD)
                       );
            }

            Vector3 enterPos = ray.Origin + enterD * ray.Direction;
            Vector3 exitPos  = ray.Origin + exitD * ray.Direction;
            bool    rightHit = false;
            bool    leftHit  = false;

            if (PositionLeftOfSplit(enterPos))
            {
                leftHit = LeftChild.FindNearest(ray, rec, exceptGeom);
                if ((!leftHit) && PositionRightOfSplit(exitPos))
                {
                    rightHit = RightChild.FindNearest(ray, rec, exceptGeom);
                }
            }
            else
            {
                rightHit = RightChild.FindNearest(ray, rec, exceptGeom);
                if ((!rightHit) && PositionLeftOfSplit(exitPos))
                {
                    leftHit = LeftChild.FindNearest(ray, rec, exceptGeom);
                }
            }
            return(leftHit || rightHit);
        }
Пример #29
0
        /// <summary>
        /// Samples the depth map, returns the percentage of samples that is closer to the light than the map
        /// </summary>
        /// <param name="visiblePt"></param>
        /// <param name="visibleObj"></param>
        /// <returns></returns>
        private float SampleDepthMap(Vector3 visiblePt, int visibleObj)
        {
            float samplesTaken = 0f;
            float count        = 0f;

            // intersect a ray with the depthMap to get the intersection position
            Ray r = new Ray(visiblePt, mPosition);
            IntersectionRecord rec = new IntersectionRecord();

            if (mDepthMapGeom.Intersect(r, rec))
            {
                float x = 0, y = 0;
                mDepthMapGeom.GetUV(rec.IntersectPosition, rec.HitPtBC, ref x, ref y);

                int lowX = (int)(x * mRes) - mFilterRes;
                int hiX  = lowX + mFilterRes;
                int lowY = (int)(y * mRes) - mFilterRes;
                int hiY  = lowY + mFilterRes;

                //float distToPt = (visiblePt - mPosition).Length();

                // depth map look up
                for (int i = lowX; i <= hiX; i++)
                {
                    for (int j = lowY; j <= hiY; j++)
                    {
                        if ((i >= 0) && (j >= 0) && (i < mRes) && (j < mRes))
                        {
                            samplesTaken += 1f;
                            if (visibleObj == mGeomID[i][j])
                            {
                                count += 1f;
                            }
                        }
                    }
                }
            }
            return(count /= samplesTaken);
        }
Пример #30
0
        private void computePixelColor(Ray r, ref Vector3 pixelColor, int channel)
        {
            IntersectionRecord rec = new IntersectionRecord();

            // what can we see?
            ComputeVisibility(r, rec, RTCore.kInvalidIndex);

            Vector3 sampleColor = mBgColor;

            if (pixelColor != Vector3.Zero)
            {
                int a = 5;
            }
            // what color should it be?
            if (rec.GeomIndex != RTCore.kInvalidIndex)
            {
                sampleColor = ComputeShading(rec, 0);
            }

            if (channel == SINGLE)
            {
                pixelColor += sampleColor;
            }

            else if (channel == LEFT)
            {
                pixelColor += sampleColor * leftLens;
            }

            else if (channel == RIGHT)
            {
                pixelColor += sampleColor * rightLens;
            }

            //throws off the filters
            // This prevents a yellow background by bringing in the color blue where there are no intersections
            // if (channel != SINGLE && rec.GeomIndex == RTCore.kInvalidIndex)
            //   pixelColor.Z += sampleColor.Z / 2;
        }
Пример #31
0
        /// <summary>
        /// </summary>
        /// <param name="u">value between 0 to 1</param>
        /// <param name="v">value between 0 to 1</param>
        /// <param name="rec">IntersectionRecord to be texture mapped</param>
        /// <param name="g">the geometry</param>
        /// <returns></returns>
        public override Vector3 GetTexile(float u, float v, IntersectionRecord rec, RTGeometry g)
        {
            float useU = u * mURepeat;

            useU = useU - ((int)useU);
            float useV = v * mVRepeat;

            useV = useV - ((int)useV);

            Vector3 resultColor = mColor1;

            if ((useU > kLowBound) && (useU < kUpBound))
            {
                resultColor = GetGridColor(useU);
            }
            else if ((useV > kLowBound) && (useV < kUpBound))
            {
                resultColor = GetGridColor(useV);
            }

            return(resultColor);
        }
        private bool IsBlocked(Vector3 org, Vector3 target, int exceptGeomIndex) 
        {
            Vector3 d = target - org;
            float dist = d.Length();
            IntersectionRecord rec = new IntersectionRecord(dist);
            d /= dist;
            Ray r = Ray.CrateRayFromPtDir(org, d);
#if KDTREE

            mKdTree.ComputeVisibility(r, rec, exceptGeomIndex);
            return (rec.GeomIndex != RTCore.kInvalidIndex);
#else   
            bool blocked = false;
            int count = 0;
            
            while ((!blocked) && (count < mSceneDatabase.GetNumGeom())) {
                if (count != exceptGeomIndex)
                    blocked = mSceneDatabase.GetGeom(count).Intersect(r, rec);
                count++;
            }
            return blocked;
#endif
        }
Пример #33
0
        public void ComputeImage(Object parm)
        {
            int startX, startY, endX, endY, threadID;

            ParseParm(parm, out startX, out startY, out endX, out endY, out threadID);

            // Console.WriteLine("Start: Thread:" + threadID + " - y(" + startY + " " + endY + ")");

            int currentX = startX;
            int currentY = startY;

            while (currentY < endY && currentY < ImageHeight)
            {
                while (currentX < ImageWidth)
                {
                    Vector3 pixelColor    = Vector3.Zero;
                    float   pixelCoverage = 0f;
                    float   pixelDepth    = 0f;

                    for (int i = 0; i < mImageSpec.NumSamplesPerPixel; i++)
                    {
                        float dx;
                        float dy;
                        lock (this)
                        {
                            dx = (float)mRand.NextDouble();
                            dy = (float)mRand.NextDouble();
                        }
                        Vector3 pixelPos = mCamera.GetPixelPosition(currentX + dx, currentY + dy);
                        Ray     r;
                        if (!mOrthoRT)
                        {
                            r = new Ray(mCamera.EyePosition, pixelPos);
                        }
                        else
                        {
                            pixelPos -= 10f * mCamera.ViewDirection;
                            r         = Ray.CrateRayFromPtDir(pixelPos, mCamera.ViewDirection);
                        }

                        // #if RT_PIXEL_DEBUG
                        if ((currentX == 348) && (currentY == 196))
                        {
                            int a = 4;
                        }
                        // #endif

                        if (!mAnaglyph)
                        {
                            computePixelColor(r, ref pixelColor, SINGLE);
                        }
                        else
                        {
                            Ray left = new Ray(mCamera.LeftEyePosition, pixelPos);
                            computePixelColor(left, ref pixelColor, LEFT);
                            Ray right = new Ray(mCamera.RightEyePosition, pixelPos);
                            computePixelColor(right, ref pixelColor, RIGHT);
                        }

                        float sampleCoverage = 0f;
                        float sampleDepth    = 0f;

                        // what coverage and depth?
                        IntersectionRecord rec = new IntersectionRecord();
                        ComputeVisibility(r, rec, RTCore.kInvalidIndex);
                        if (rec.GeomIndex != RTCore.kInvalidIndex)
                        {
                            sampleCoverage = 1f;
                            sampleDepth    = kUseMaxDepth - rec.HitDistance;
                        }
                        pixelCoverage += sampleCoverage;
                        pixelDepth    += sampleDepth;
                    }

                    pixelColor    /= (float)mImageSpec.NumSamplesPerPixel;
                    pixelCoverage /= (float)mImageSpec.NumSamplesPerPixel;
                    pixelDepth    /= (float)mImageSpec.NumSamplesPerPixel;

                    System.Drawing.Color c = ComputeColor(pixelColor); // convert Vector3 (0-1 float) to Color (0 - 255)
                    System.Drawing.Color p = ComputePixelCoverage(pixelCoverage);
                    float useDepth         = pixelDepth / kUseMaxDepth;
                    System.Drawing.Color z = ComputePixelCoverage(useDepth);

                    lock (this)
                    {
                        mResultImage.SetPixel(currentX, currentY, c);
                        mPixelCoverage.SetPixel(currentX, currentY, p);
                        mPixelDepth.SetPixel(currentX, currentY, z);

                        if (mShowPixelInWorld || mDisplayDebugPixels || mDisplayDebugRays)
                        {
                            Vector3            pixelPos    = mCamera.GetPixelPosition(currentX, currentY);
                            Ray                r           = new Ray(mCamera.EyePosition, pixelPos);
                            IntersectionRecord rec         = new IntersectionRecord();
                            Vector3            resultColor = mBgColor;
                            ComputeVisibility(r, rec, RTCore.kInvalidIndex);
                            if (rec.GeomIndex != RTCore.kInvalidIndex)
                            {
                                resultColor = ComputeShading(rec, 0);
                            }

                            mPixelPosition[currentX][currentY]    = pixelPos;
                            mPixelHitDistance[currentX][currentY] = rec.HitDistance;
                            mResultImage.SetPixel(currentX, currentY, ComputeColor(resultColor));
                        }
                    }

                    // next pixel
                    currentX++;
                }

                // next scanline
                currentX = startX;
                currentY++;

                lock (this)
                {
                    if (currentY > mCurrentY)
                    {
                        mCurrentY = currentY;
                    }
                }
            }

            // Console.WriteLine("Start: Thread:" + threadID + " - y(" + startY + " " + endY + ")");

            if (threadID != -1)
            {
                ThreadNextWorkLoad(threadID);
            }
            else
            {
                RTRenderingDone();
            }
        }
Пример #34
0
 private bool IntersectWithGeom(Ray ray, IntersectionRecord rec, int exceptGeom)
 {
     bool hitOnce = false;
     if (mGeomList != null)
     {
         foreach (RTGeometry g in mGeomList)
             if ((g.GetResourceIndex() != exceptGeom) && g.Intersect(ray, rec))
                 hitOnce = true;
     }
     return hitOnce;
 }
 /// <summary>
 /// (x,y,z) is the visible pt, returns solid texture value at x,y,z
 /// </summary>
 /// <param name="rec">IntersectionRecord to be texture mapped</param>
 /// <param name="g">The geometry</param>
 /// <returns></returns>
 public virtual Vector3 GetTexile(IntersectionRecord rec, RTGeometry g)
 {
     return(Vector3.Zero);
 }
        /// <param name="rec">IntersectionRecord to be texture mapped</param>
        /// <param name="g">The geometry</param>
        /// <returns></returns>
        public override Vector3 GetTexile(IntersectionRecord rec, RTGeometry g)
        {
            float noise = ComputeFractalNoise(rec.IntersectPosition.X, rec.IntersectPosition.Y, rec.IntersectPosition.Z);

            return((noise * mColor1) + ((1f - noise) * mColor2));
        }
Пример #37
0
        private const float kDepthImageDist = 1f; // depth map image plane distance from the light source

        private void InitDepthMap(SceneDatabase sceneDatabase)
        {
            if (null != mDepthMap)
            {
                return; // done
            }
            // remember!! mDireciton is L, or a vector from Visible point to the light.
            // Here we want direction from light source towards the scene
            Vector3 useDir = -mDirection;

            // 1. Find a Up direction
            //         guess up direction to be (0, 1, 0), if view direction is also this,
            //         use (1, 0, 0) as view direction
            Vector3 up = Vector3.UnitY;

            if (Math.Abs(Vector3.Dot(up, useDir)) > 0.99999)
            {
                up = Vector3.UnitX;
            }


            // 2. define Orthonormal base
            Vector3 sideV = Vector3.Cross(up, useDir);

            up = Vector3.Cross(useDir, sideV);
            sideV.Normalize();
            up.Normalize();

            // 3. compute the depth map image plane,
            //    define the image plane to be located at ... a distance of kDepthImageDist away
            Vector3 ptOnImage = mPosition + kDepthImageDist * useDir;

            // 4. compute depth map image size
            float halfImageSize = kDepthImageDist * (float)Math.Tan(mOuterAngle / 2f);

            // 5. Compute the 4 vertices the defines the depth map
            Vector3[] v = new Vector3[4];
            v[0] = ptOnImage - halfImageSize * up - halfImageSize * sideV;
            v[1] = ptOnImage - halfImageSize * up + halfImageSize * sideV;
            v[2] = ptOnImage + halfImageSize * up + halfImageSize * sideV;
            v[3] = ptOnImage + halfImageSize * up - halfImageSize * sideV;

            // 6. create a Geometry that represents the map
            // ** Be caureful **!!
            //     RTRectangle uses v[0] as the origin for texture lookup
            //     we _MUST_ follow the same in order to take advante of GetUV() function!
            mDepthMapGeom = new RTRectangle(v);

            // 7. Now allocate memory for the actual map
            mDepthMap = new float[mRes][];
            mGeomID   = new int[mRes][];
            for (int i = 0; i < mRes; i++)
            {
                mDepthMap[i] = new float[mRes];
                mGeomID[i]   = new int[mRes];
            }

            // now, trace rays through each of the pixels in the depth map and record the depth and geomID
            float   pixelSize       = halfImageSize / (0.5f * mRes);
            Vector3 upPixelVector   = pixelSize * up;
            Vector3 sidePixelVector = pixelSize * sideV;

            for (int y = 0; y < mRes; y++)
            {
                Vector3 yDisp = v[0] + (y + 0.5f) * upPixelVector;
                for (int x = 0; x < mRes; x++)
                {
                    Vector3            pixelPos = ((x + 0.5f) * sidePixelVector) + yDisp;
                    Ray                r        = new Ray(mPosition, pixelPos);
                    IntersectionRecord rec      = new IntersectionRecord();

                    for (int i = 0; i < sceneDatabase.GetNumGeom(); i++)
                    {
                        RTGeometry g = sceneDatabase.GetGeom(i);
                        g.Intersect(r, rec);
                    }
                    mDepthMap[x][y] = rec.HitDistance;
                    // closes intersection distance, any object that is
                    // further away from the light than this distance is in the shadow of this light
                    mGeomID[x][y] = rec.GeomIndex;
                    // this object can never be in shadow, becuase it is the closest to the light!
                }
            }
        }
Пример #38
0
 public bool ComputeVisibility(Ray ray, IntersectionRecord rec, int exceptGeom)
 {
     return(mRoot.FindNearest(ray, rec, exceptGeom));
 }
        private void computePixelColor(Ray r, ref Vector3 pixelColor, int channel)
        {
            IntersectionRecord rec = new IntersectionRecord();
            // what can we see?
            ComputeVisibility(r, rec, RTCore.kInvalidIndex);

            Vector3 sampleColor =  mBgColor;
            if (pixelColor != Vector3.Zero)
            {
                int a = 5;
            }
            // what color should it be?
            if (rec.GeomIndex != RTCore.kInvalidIndex)
                sampleColor = ComputeShading(rec, 0);

                if (channel == SINGLE)
                    pixelColor += sampleColor;

                else if (channel == LEFT)
                    pixelColor += sampleColor * leftLens;

                else if (channel == RIGHT)
                    pixelColor += sampleColor * rightLens;

            //throws off the filters
            // This prevents a yellow background by bringing in the color blue where there are no intersections
            // if (channel != SINGLE && rec.GeomIndex == RTCore.kInvalidIndex)
            //   pixelColor.Z += sampleColor.Z / 2;
        }
        public void ComputeImage(Object parm)
        {
            int startX, startY, endX, endY, threadID;
            ParseParm(parm, out startX, out startY, out endX, out endY, out threadID);

            // Console.WriteLine("Start: Thread:" + threadID + " - y(" + startY + " " + endY + ")");

            int currentX = startX;
            int currentY = startY;

            while (currentY < endY && currentY < ImageHeight)
            {
                while (currentX < ImageWidth)
                {
                    Vector3 pixelColor = Vector3.Zero;
                    float pixelCoverage = 0f;
                    float pixelDepth = 0f;

                    for (int i = 0; i < mImageSpec.NumSamplesPerPixel; i++)
                    {
                        float dx;
                        float dy;
                        lock (this)
                        {
                            dx = (float)mRand.NextDouble();
                            dy = (float)mRand.NextDouble();
                        }
                        Vector3 pixelPos = mCamera.GetPixelPosition(currentX + dx, currentY + dy);
                        Ray r;
                        if (!mOrthoRT)
                        {
                            r = new Ray(mCamera.EyePosition, pixelPos);
                        }
                        else
                        {
                            pixelPos -= 10f * mCamera.ViewDirection;
                            r = Ray.CrateRayFromPtDir(pixelPos, mCamera.ViewDirection);
                        }

                        // #if RT_PIXEL_DEBUG
                        if ((currentX == 348) && (currentY == 196))
                        {
                            int a = 4;
                        }
                        // #endif

                        if (!mAnaglyph)
                        {
                            computePixelColor(r, ref pixelColor, SINGLE);
                        }
                        else
                        {
                            Ray left = new Ray(mCamera.LeftEyePosition, pixelPos);
                            computePixelColor(left, ref pixelColor, LEFT);
                            Ray right = new Ray(mCamera.RightEyePosition, pixelPos);
                            computePixelColor(right, ref pixelColor, RIGHT);
                        }

                        float sampleCoverage = 0f;
                        float sampleDepth = 0f;

                        // what coverage and depth?
                        IntersectionRecord rec = new IntersectionRecord();
                        ComputeVisibility(r, rec, RTCore.kInvalidIndex);
                        if (rec.GeomIndex != RTCore.kInvalidIndex)
                        {
                            sampleCoverage = 1f;
                            sampleDepth = kUseMaxDepth - rec.HitDistance;
                        }
                        pixelCoverage += sampleCoverage;
                        pixelDepth += sampleDepth;
                    }

                    pixelColor /= (float)mImageSpec.NumSamplesPerPixel;
                    pixelCoverage /= (float)mImageSpec.NumSamplesPerPixel;
                    pixelDepth /= (float)mImageSpec.NumSamplesPerPixel;

                    System.Drawing.Color c = ComputeColor(pixelColor); // convert Vector3 (0-1 float) to Color (0 - 255)
                    System.Drawing.Color p = ComputePixelCoverage(pixelCoverage);
                    float useDepth = pixelDepth / kUseMaxDepth;
                    System.Drawing.Color z = ComputePixelCoverage(useDepth);

                    lock (this)
                    {
                        mResultImage.SetPixel(currentX, currentY, c);
                        mPixelCoverage.SetPixel(currentX, currentY, p);
                        mPixelDepth.SetPixel(currentX, currentY, z);

                        if (mShowPixelInWorld || mDisplayDebugPixels || mDisplayDebugRays)
                        {
                            Vector3 pixelPos = mCamera.GetPixelPosition(currentX, currentY);
                            Ray r = new Ray(mCamera.EyePosition, pixelPos);
                            IntersectionRecord rec = new IntersectionRecord();
                            Vector3 resultColor = mBgColor;
                            ComputeVisibility(r, rec, RTCore.kInvalidIndex);
                            if (rec.GeomIndex != RTCore.kInvalidIndex)
                            {
                                resultColor = ComputeShading(rec, 0);
                            }

                            mPixelPosition[currentX][currentY] = pixelPos;
                            mPixelHitDistance[currentX][currentY] = rec.HitDistance;
                            mResultImage.SetPixel(currentX, currentY, ComputeColor(resultColor));
                        }
                    }

                    // next pixel
                    currentX++;
                }

                // next scanline
                currentX = startX;
                currentY++;

                lock (this)
                {
                    if (currentY > mCurrentY)
                        mCurrentY = currentY;
                }
            }

            // Console.WriteLine("Start: Thread:" + threadID + " - y(" + startY + " " + endY + ")");

            if (threadID != -1)
                ThreadNextWorkLoad(threadID);
            else
                RTRenderingDone();
        }
Пример #41
0
        /// <summary>
        ///
        /// </summary>
        private Vector3 ComputeShading(IntersectionRecord rec, int generation)
        {
            if (rec.GeomIndex == RTCore.kInvalidIndex)
            {
                return(mBgColor);
            }

            Vector3 resultColor = Vector3.Zero;
            Vector3 V           = -Vector3.Normalize(rec.RayDirection);

            RTMaterial m         = mSceneDatabase.GetMaterial(rec.MaterialIndex);
            Vector3    useNormal = m.GetNormal(mSceneDatabase, rec);

            for (int l = 0; l < mSceneDatabase.GetNumLights(); l++)
            {
                RTLight lgt = mSceneDatabase.GetLight(l);
                resultColor += ShadeRec(V, lgt, rec);
            }

            resultColor += mSceneDatabase.GetMaterial(rec.MaterialIndex).GetAmbient(mSceneDatabase, rec);
            int nextGen = generation + 1;

            // now take care of reflection
            float   reflectivity = m.GetReflectivity(mSceneDatabase, rec);
            Vector3 reflColor    = Vector3.Zero;

            if (mComputeReflection && (reflectivity > 0f) && (generation < mGeneration))
            {
                IntersectionRecord refRec = new IntersectionRecord();
                Vector3            refDir = Vector3.Reflect(rec.RayDirection, useNormal);
                Ray refRay = Ray.CrateRayFromPtDir(rec.IntersectPosition, refDir);
                // Now compute new visibility
                ComputeVisibility(refRay, refRec, rec.GeomIndex);
                if (refRec.GeomIndex != RTCore.kInvalidIndex)
                {
                    reflColor = ComputeShading(refRec, nextGen) * reflectivity;
                }
                else
                {
                    reflColor = mBgColor * reflectivity;
                }
            }


            // now do transparency
            //
            // The following code:
            //     1. only supports refractive index > 1 (from less dense e.g.: air, to more dense: e.g., glass)
            //     2. cannot go from dense material into less dense material (once enter cannot exit)
            //     3. once entered: do not know how to go from one transparent object into another transparent object
            //
            float   transparency = m.GetTransparency(mSceneDatabase, rec);
            Vector3 transColor   = Vector3.Zero;

            if (mComputeReflection && (transparency > 0f) && (generation < mGeneration))
            {
                float   cosThetaI = Vector3.Dot(V, useNormal);
                float   invN      = 1f / m.GetRefractiveIndex;
                float   cosThetaT = (float)Math.Sqrt(1 - ((invN * invN) * (1 - (cosThetaI * cosThetaI))));
                Vector3 transDir  = -((invN * V) + ((cosThetaT - (invN * cosThetaI)) * useNormal));
                Ray     transRay  = Ray.CrateRayFromPtDir(rec.IntersectPosition, transDir);
                // Now compute new visibility
                IntersectionRecord transRec = new IntersectionRecord();
                ComputeVisibility(transRay, transRec, rec.GeomIndex);  // here we assume single layer geometries
                if (transRec.GeomIndex != RTCore.kInvalidIndex)
                {
                    transColor = ComputeShading(transRec, nextGen) * transparency;
                }
                else
                {
                    transColor = mBgColor * transparency;
                }
            }
            resultColor = (1 - transparency - reflectivity) * resultColor + transColor + reflColor;

            return(resultColor);
        }
Пример #42
0
 /// <summary>
 /// Returns status of if Ray intersects with this Geom. If so, details of intersection
 /// is returned in the IntersectionRecord.
 /// </summary>
 /// <param name="ray">Incoming ray.</param>
 /// <param name="record">If intersect, this record has the details.</param>
 /// <returns>T/F: intersect or not.</returns>
 public abstract bool Intersect(Ray ray, IntersectionRecord record);
 /// <summary>
 /// </summary>
 /// <param name="u">value between 0 to 1</param>
 /// <param name="v">value between 0 to 1</param>
 /// <param name="rec">IntersectionRecord to be texture mapped</param>
 /// <param name="g">the geometry</param>
 /// <returns></returns>
 public override Vector3 GetTexile(float u, float v, IntersectionRecord rec, RTGeometry g)
 {
     float useU = u * mRepeat;
     useU = useU - ((int)useU);
     return (useU * mColor2) + (1 - useU) * mColor1;
 }
 /// <summary>
 /// (x,y,z) is the visible pt, returns solid texture value at x,y,z
 /// </summary>
 /// <param name="rec">IntersectionRecord to be texture mapped</param>
 /// <param name="g">The geometry</param>
 /// <returns></returns>
 public virtual Vector3 GetTexile(IntersectionRecord rec, RTGeometry g)
 {
     return Vector3.Zero;
 }
Пример #45
0
        /// <summary>
        /// Intersects the ray, if intersection is closer than the one inside the record,
        /// sets the records with intersection information.
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="record"></param>
        /// <returns></returns>
        public override bool Intersect(Ray ray, IntersectionRecord record)
        {
            float dist = 0f;
            Vector3 hitPt, n;

            n = mNormal;
            if (!RayPlaneIntersection(ray, ref n, mD, ref dist))
                return false;

            /*
             * rectangle behind the ray or there are other closer intersections
             */
            if ((dist < 0) || (dist > record.HitDistance))
                return false;

            hitPt = ray.Origin + (ray.Direction * dist);

            /*
             * Now need to decide inside or outside
             */
            float u, v, w;
            Vector3 v1 = mVertices[1] - hitPt;
            Vector3 v2 = mVertices[2] - hitPt;
            float areaPV1V2 = Vector3.Dot(mNormal, Vector3.Cross(v1, v2));

            u = areaPV1V2 * mInvArea2;
            if ((u < 0f) || (u > 1f))
                return false;

            v1 = mVertices[0] - hitPt;
            float areaPV0V2 = Vector3.Dot(mNormal, Vector3.Cross(v2, v1));
            v = areaPV0V2 * mInvArea2;
            if ((v<0f) || (v>1f))
                return false;

            w = 1 - u - v;
            if (w<0f)
                return false;

            /*
             *  An actual hit
             */
            record.UpdateBC(u, v, w);

            // now if we have per-vertex normal, use it!
            if (null != mNormalAtVertices)
                n = u * mNormalAtVertices[0] + v * mNormalAtVertices[1] + w * mNormalAtVertices[2];

            // flip the normal if seeing the back face
            if (Vector3.Dot(n, ray.Direction) > 0f)
                n = -n;

            record.UpdateRecord(dist, hitPt, n, ray, mMaterialIndex, GetResourceIndex());
            return true;
        }
Пример #46
0
        /// <summary>
        /// Intersects the ray, if intersection is closer than the one inside the record,
        /// sets the records with intersection information.
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="record"></param>
        /// <returns></returns>
        public override bool Intersect(Ray ray, IntersectionRecord record)
        {
            float   dist = 0f;
            Vector3 hitPt, n;

            n = mNormal;
            if (!RayPlaneIntersection(ray, ref n, mD, ref dist))
            {
                return(false);
            }

            /*
             * rectangle behind the ray or there are other closer intersections
             */
            if ((dist < 0) || (dist > record.HitDistance))
            {
                return(false);
            }

            hitPt = ray.Origin + (ray.Direction * dist);

            /*
             * Now need to decide inside or outside
             */
            float   u, v, w;
            Vector3 v1        = mVertices[1] - hitPt;
            Vector3 v2        = mVertices[2] - hitPt;
            float   areaPV1V2 = Vector3.Dot(mNormal, Vector3.Cross(v1, v2));

            u = areaPV1V2 * mInvArea2;
            if ((u < 0f) || (u > 1f))
            {
                return(false);
            }

            v1 = mVertices[0] - hitPt;
            float areaPV0V2 = Vector3.Dot(mNormal, Vector3.Cross(v2, v1));

            v = areaPV0V2 * mInvArea2;
            if ((v < 0f) || (v > 1f))
            {
                return(false);
            }

            w = 1 - u - v;
            if (w < 0f)
            {
                return(false);
            }

            /*
             *  An actual hit
             */
            record.UpdateBC(u, v, w);

            // now if we have per-vertex normal, use it!
            if (null != mNormalAtVertices)
            {
                n = u * mNormalAtVertices[0] + v * mNormalAtVertices[1] + w * mNormalAtVertices[2];
            }

            // flip the normal if seeing the back face
            if (Vector3.Dot(n, ray.Direction) > 0f)
            {
                n = -n;
            }

            record.UpdateRecord(dist, hitPt, n, ray, mMaterialIndex, GetResourceIndex());
            return(true);
        }
Пример #47
0
 /// <summary>
 /// Looks up attribute from the texture table! NO ERROR CHECKINGG! If mTextureIndex is invalid, this function will crash!!
 /// </summary>
 /// <param name="database"></param>
 /// <param name="rec"></param>
 /// <returns></returns>
 public Vector3 AttributeLookup(SceneDatabase database, IntersectionRecord rec)
 {
     return(database.GetTexture(mTextureIndex).TextureLookup(rec, database.GetGeom(rec.GeomIndex)));
 }
        /// <summary>
        /// Intersects the ray, if intersection is closer than the one inside the record,
        /// sets the records with intersection information.
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="record"></param>
        /// <returns></returns>
        public override bool Intersect(Ray ray, IntersectionRecord record)
        {
            float dist= 0f;
            Vector3 hitPt, n;

            n = mNormal;    // because ray/plane intersection may flip the normal!
            if (!RayPlaneIntersection(ray, ref n, mD, ref dist))
                return false;

            /*
             * rectangle behind the ray or there are other closer intersections
             */
            if ((dist < 0) || (dist > record.HitDistance))
                return false;

            hitPt = ray.Origin + (ray.Direction * dist);

            /*
             * Now need to decide inside or outside
             */
            if (!InsidePolygon(hitPt))
                return false;

            record.UpdateRecord(dist, hitPt, n, ray, mMaterialIndex, GetResourceIndex());
            return true;
        }
Пример #49
0
 /// <summary>
 /// Returns status of if Ray intersects with this Geom. If so, details of intersection
 /// is returned in the IntersectionRecord.
 /// </summary>
 /// <param name="ray">Incoming ray.</param>
 /// <param name="record">If intersect, this record has the details.</param>
 /// <returns>T/F: intersect or not.</returns>
 public abstract bool Intersect(Ray ray, IntersectionRecord record);
        /// <summary>
        ///
        /// </summary>
        private Vector3 ComputeShading(IntersectionRecord rec, int generation)
        {
            if (rec.GeomIndex == RTCore.kInvalidIndex)
                return mBgColor;

            Vector3 resultColor = Vector3.Zero;
            Vector3 V = -Vector3.Normalize(rec.RayDirection);

            RTMaterial m = mSceneDatabase.GetMaterial(rec.MaterialIndex);
            Vector3 useNormal = m.GetNormal(mSceneDatabase, rec);

            for (int l = 0; l < mSceneDatabase.GetNumLights(); l++)
            {
                RTLight lgt = mSceneDatabase.GetLight(l);
                resultColor += ShadeRec(V, lgt, rec);
            }

            resultColor += mSceneDatabase.GetMaterial(rec.MaterialIndex).GetAmbient(mSceneDatabase, rec);
            int nextGen = generation + 1;

            // now take care of reflection
            float reflectivity = m.GetReflectivity(mSceneDatabase, rec);
            Vector3 reflColor = Vector3.Zero;
            if ( mComputeReflection && (reflectivity > 0f) && (generation < mGeneration) )
            {
                IntersectionRecord refRec = new IntersectionRecord();
                Vector3 refDir = Vector3.Reflect(rec.RayDirection, useNormal);
                Ray refRay = Ray.CrateRayFromPtDir(rec.IntersectPosition, refDir);
                // Now compute new visibility
                ComputeVisibility(refRay, refRec, rec.GeomIndex);
                if (refRec.GeomIndex != RTCore.kInvalidIndex)
                    reflColor = ComputeShading(refRec, nextGen) * reflectivity;
                else
                    reflColor = mBgColor * reflectivity;
            }

            // now do transparency
            //
            // The following code:
            //     1. only supports refractive index > 1 (from less dense e.g.: air, to more dense: e.g., glass)
            //     2. cannot go from dense material into less dense material (once enter cannot exit)
            //     3. once entered: do not know how to go from one transparent object into another transparent object
            //
            float transparency = m.GetTransparency(mSceneDatabase, rec);
            Vector3 transColor = Vector3.Zero;
            if (mComputeReflection && (transparency > 0f) && (generation < mGeneration))
            {
                float cosThetaI = Vector3.Dot(V, useNormal);
                float invN = 1f / m.GetRefractiveIndex;
                float cosThetaT = (float)Math.Sqrt(1 - ((invN * invN) * (1 - (cosThetaI * cosThetaI))));
                Vector3 transDir = -((invN * V) + ((cosThetaT - (invN * cosThetaI)) * useNormal));
                Ray transRay = Ray.CrateRayFromPtDir(rec.IntersectPosition, transDir);
                // Now compute new visibility
                IntersectionRecord transRec = new IntersectionRecord();
                ComputeVisibility(transRay, transRec, rec.GeomIndex);  // here we assume single layer geometries
                if (transRec.GeomIndex != RTCore.kInvalidIndex)
                    transColor = ComputeShading(transRec, nextGen) * transparency;
                else
                    transColor = mBgColor * transparency;
            }
            resultColor = (1 - transparency - reflectivity) * resultColor + transColor + reflColor;

            return resultColor;
        }
Пример #51
0
        /// <summary>
        /// Intersects the ray with the sphere. If intersection is closer than what is
        /// in the record, updates the record with new intersection information.
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="record"></param>
        /// <returns></returns>
        public override bool Intersect(Ray ray, IntersectionRecord record)
        {
            Vector3 v1 = ray.Origin - mCenter;
            float b = 2f * Vector3.Dot(v1, ray.Direction);
            float c = v1.LengthSquared() - mRadiusSquared;
            float root = b * b - 4 * c;

            if (root < 0f)
                return false;

            root = (float) Math.Sqrt(root);
            float t0 = 0.5f * (-b - root);
            float t1 = 0.5f * (-b + root);

            if ((t0 < 0) && (t1 < 0))
                return false;

            float dist;
            if (t0 < t1)
            {
                if (t0 > 0)
                    dist = t0;
                else
                    dist = t1;
            }
            else
            {
                if (t1 > 0)
                    dist = t1;
                else
                    dist = t0;
            }

            if (dist > record.HitDistance)
                return false;

            // intersection found
            Vector3 pt = ray.Origin + dist * ray.Direction;
            Vector3 n = pt - mCenter;
            record.UpdateRecord(dist, pt, n, ray, mMaterialIndex, GetResourceIndex());

            return true;
        }
Пример #52
0
 public bool ComputeVisibility(Ray ray, IntersectionRecord rec, int exceptGeom)
 {
     return mRoot.FindNearest(ray, rec, exceptGeom);
 }
        /// <summary>
        /// Samples the depth map, returns the percentage of samples that is closer to the light than the map
        /// </summary>
        /// <param name="visiblePt"></param>
        /// <param name="visibleObj"></param>
        /// <returns></returns>
        private float SampleDepthMap(Vector3 visiblePt, int visibleObj)
        {
            float samplesTaken = 0f;
            float count = 0f;

            // intersect a ray with the depthMap to get the intersection position
            Ray r = new Ray(visiblePt, mPosition);
            IntersectionRecord rec = new IntersectionRecord();
            if (mDepthMapGeom.Intersect(r, rec))
            {
                float x = 0, y = 0;
                mDepthMapGeom.GetUV(rec.IntersectPosition, rec.HitPtBC, ref x, ref y);

                int lowX = (int)(x * mRes) - mFilterRes;
                int hiX = lowX + mFilterRes;
                int lowY = (int)(y * mRes) - mFilterRes;
                int hiY = lowY + mFilterRes;

                //float distToPt = (visiblePt - mPosition).Length();

                // depth map look up
                for (int i = lowX; i <=hiX; i++)
                {
                    for (int j = lowY; j <=hiY; j++)
                    {
                        if ((i >=0) && (j>=0) && (i < mRes) && (j < mRes))
                        {
                            samplesTaken += 1f;
                            if (visibleObj == mGeomID[i][j])
                                    count += 1f;
                        }
                    }
                }
            }
            return count /= samplesTaken;
        }
        private int mRes = 128; // depth map resolution is Res x Res

        #endregion Fields

        #region Methods

        private void InitDepthMap(SceneDatabase sceneDatabase)
        {
            if (null != mDepthMap)
                return; // done

            // remember!! mDireciton is L, or a vector from Visible point to the light.
            // Here we want direction from light source towards the scene
            Vector3 useDir = -mDirection;

            // 1. Find a Up direction
            //         guess up direction to be (0, 1, 0), if view direction is also this,
            //         use (1, 0, 0) as view direction
            Vector3 up = Vector3.UnitY;
            if (Math.Abs(Vector3.Dot(up, useDir)) > 0.99999)
                up = Vector3.UnitX;

            // 2. define Orthonormal base
            Vector3 sideV = Vector3.Cross(up, useDir);
            up = Vector3.Cross(useDir, sideV);
            sideV.Normalize();
            up.Normalize();

            // 3. compute the depth map image plane,
            //    define the image plane to be located at ... a distance of kDepthImageDist away
            Vector3 ptOnImage = mPosition + kDepthImageDist * useDir;

            // 4. compute depth map image size
            float halfImageSize = kDepthImageDist * (float)Math.Tan(mOuterAngle/2f);

            // 5. Compute the 4 vertices the defines the depth map
            Vector3[] v = new Vector3[4];
            v[0] = ptOnImage - halfImageSize * up - halfImageSize * sideV;
            v[1] = ptOnImage - halfImageSize * up + halfImageSize * sideV;
            v[2] = ptOnImage + halfImageSize * up + halfImageSize * sideV;
            v[3] = ptOnImage + halfImageSize * up - halfImageSize * sideV;

            // 6. create a Geometry that represents the map
            // ** Be caureful **!!
            //     RTRectangle uses v[0] as the origin for texture lookup
            //     we _MUST_ follow the same in order to take advante of GetUV() function!
            mDepthMapGeom = new RTRectangle(v);

            // 7. Now allocate memory for the actual map
            mDepthMap = new float[mRes][];
            mGeomID = new int[mRes][];
            for (int i = 0; i<mRes; i++) {
                mDepthMap[i] = new float[mRes];
                mGeomID[i] = new int[mRes];
            }

            // now, trace rays through each of the pixels in the depth map and record the depth and geomID
            float pixelSize = halfImageSize / (0.5f * mRes);
            Vector3 upPixelVector = pixelSize * up;
            Vector3 sidePixelVector = pixelSize * sideV;
            for (int y = 0; y < mRes; y++) {
                Vector3 yDisp = v[0] + (y+0.5f) * upPixelVector;
                for (int x = 0; x < mRes; x++) {
                    Vector3 pixelPos = ((x+0.5f) * sidePixelVector) + yDisp;
                    Ray r = new Ray(mPosition, pixelPos);
                    IntersectionRecord rec = new IntersectionRecord();

                    for (int i = 0; i < sceneDatabase.GetNumGeom(); i++)
                    {
                        RTGeometry g = sceneDatabase.GetGeom(i);
                        g.Intersect(r, rec);
                    }
                    mDepthMap[x][y] = rec.HitDistance;
                    // closes intersection distance, any object that is
                    // further away from the light than this distance is in the shadow of this light
                    mGeomID[x][y] = rec.GeomIndex;
                    // this object can never be in shadow, becuase it is the closest to the light!
                }
            }
        }
 /// <param name="rec">IntersectionRecord to be texture mapped</param>
 /// <param name="g">The geometry</param>
 /// <returns></returns>
 public override Vector3 GetTexile(IntersectionRecord rec, RTGeometry g)
 {
     float  noise = ComputeFractalNoise(rec.IntersectPosition.X, rec.IntersectPosition.Y, rec.IntersectPosition.Z);
     return (noise * mColor1) + ((1f - noise) * mColor2);
 }