コード例 #1
0
 public override bool FindIntersection(Ray ray, out Intersection intersect)
 {
     //Intersection intersectTmp;
     //if (this.basePrimitive.IntersectPoint(out intersect, ray)) {
     //    if (this.operPrimitive.IntersectPoint(out intersectTmp, ray) && intersectTmp.TMin < intersect.TMin) {
     //        intersect.HitPoint = ray.Origin + ray.Direction * intersectTmp.TMax;
     //        intersect.Normal = this.operPrimitive.NormalOnPoint(intersect.HitPoint);
     //        return true && this.basePrimitive.IsInside(intersect.HitPoint);
     //    } else {
     //        return !this.operPrimitive.IsInside(intersect.HitPoint);
     //    }
     //}
     //return false;
     if (this.basePrimitive.FindIntersection(ray, out intersect)) {
         Intersection intersectTmp;
         if (this.operPrimitive.FindIntersection(ray, out intersectTmp) && intersectTmp.TMin < intersect.TMin) {
             intersectTmp.HitPoint = ray.Origin + ray.Direction * intersectTmp.TMax;
             if (this.basePrimitive.IsInside(intersectTmp.HitPoint)) {
                 intersectTmp.Normal = this.operPrimitive.NormalOnPoint(intersectTmp.HitPoint);
                 intersectTmp.Normal.Flip();
                 //intersectTmp.TMin = intersectTmp.TMax;
                 intersect = intersectTmp;
                 return true;
             } else {
                 //intersect.HitPoint = ray.Origin + ray.Direction * intersect.TMax;
                 //intersect.Normal = this.basePrimitive.NormalOnPoint(intersect.HitPoint);
             }
         }
         return !this.operPrimitive.IsInside(intersect.HitPoint);
     }
     return false;
 }
コード例 #2
0
ファイル: RayTracer.cs プロジェクト: hksonngan/sharptracing
        public override RGBColor Trace(Ray ray, int depth)
        {
            Intersection intersection;
            RGBColor color = this.scene.BackgroundColor;
            if (this.scene.FindIntersection(ray, out intersection)) {
                Material material = intersection.HitPrimitive.Material;
                Shader shader = material.CreateShader(this.scene);
                color = shader.Shade(ray, intersection);
                Ray rRay = new Ray();
                if (depth < this.maxDepth) {
                    float n1 = this.scene.RefractIndex;
                    float n2 = material.RefractIndex;
                    //if (ray.PrevRefractIndex == material.RefractIndex)
                    if (ray.PrevPrimitive == intersection.HitPrimitive) {
                        float temp = n1;
                        n1 = n2;
                        n2 = temp;
                    }
                    float kSpec = material.KSpec;
                    bool specFromRefract = false;
                    float fresnelFactor = 0;
                    if (material.KTrans > 0) {
                        Vector3D T;
                        if (Vector3D.Refracted(intersection.Normal, ray.Direction, out T, n1, n2)) {
                            rRay.Origin = intersection.HitPoint;
                            rRay.Direction = T;

                            //rRay.PrevRefractIndex = material.RefractIndex;
                            rRay.PrevPrimitive = intersection.HitPrimitive;

                            fresnelFactor = Vector3D.FresnelBySchlick(intersection.Normal, ray.Direction, n1, n2);
                            float kTrans = material.KTrans - fresnelFactor;
                            kSpec += fresnelFactor;
                            specFromRefract = true;
                            kTrans = kTrans < 0 ? 0 : kTrans;
                            color += this.Trace(rRay, depth + 1) * kTrans;
                            //float term  = (float)Math.Exp(material.Absorptivity * -intersection.TMin);
                            //color *= term * material.DiffuseColor;
                            //RGBColor transparency = new RGBColor((float)Math.Exp(absorbance.R),
                            //                                     (float)Math.Exp(absorbance.G),
                            //                                     (float)Math.Exp(absorbance.B));
                        }
                    }

                    if (kSpec > 0 || specFromRefract) {
                        rRay.Origin = intersection.HitPoint;
                        rRay.Direction = Vector3D.Reflected(intersection.Normal, ray.Direction);
                        if (!specFromRefract) {
                            //fresnelFactor = Vector3D.FresnelBySchlick(intersection.Normal, ray.Direction, n1, n2);
                            kSpec = material.KSpec + fresnelFactor;
                            rRay.PrevPrimitive = intersection.HitPrimitive;
                        }
                        kSpec = kSpec > 1 ? 1 : kSpec;
                        color += this.Trace(rRay, depth + 1) * kSpec;
                    }
                }
                return color;
            }
            return this.scene.IsEnvironmentMapped ? this.scene.EnvironmentMap.GetColor(ray) : color;
        }
コード例 #3
0
 public override bool FindIntersection(Ray ray, out Intersection intersect)
 {
     Intersection intersectTmp;
     if (this.basePrimitive.FindIntersection(ray, out intersect)) {
         if (this.operPrimitive.FindIntersection(ray, out intersectTmp)) {
             if (intersect.TMin < intersectTmp.TMin) {
                 intersect = intersectTmp;
             }
         }
         return this.basePrimitive.IsInside(intersect.HitPoint) &&
                this.operPrimitive.IsInside(intersect.HitPoint);
     }
     return false;
 }
コード例 #4
0
ファイル: CornellBox.cs プロジェクト: hksonngan/sharptracing
        public override bool FindIntersection(Ray ray, out Intersection intersect)
        {
            intersect = new Intersection();
            intersect.TMin = float.MaxValue;
            Intersection intersection_comp;
            bool hit = false;
            foreach (Primitive hitPrimitive in this.cornellBoxGroup.Values) {
                if (hitPrimitive.FindIntersection(ray, out intersection_comp) && intersection_comp.TMin < intersect.TMin) {
                    intersect = intersection_comp;
                    //if(intersect.Normal * ray.Direction > 0) {
                    //    intersect.Normal.Flip();
                    //}
                    hit = true;
                }
            }

            return hit;
        }
コード例 #5
0
ファイル: SphereMap.cs プロジェクト: hksonngan/sharptracing
 public override RGBColor GetColor(Ray ray)
 {
     Vector3D oc = Point3D.Zero - ray.Origin;
     float l2oc = (oc * oc);
     float tmin = float.PositiveInfinity;
     if (l2oc < this.radius2) {
         // starts inside of the sphere
         float tca = (oc * ray.Direction);
         float l2hc = (this.radius2 - l2oc) / (ray.Direction * ray.Direction) + tca * tca; // division
         tmin = tca + (float) Math.Sqrt(l2hc);
     } else {
         float tca = (oc * ray.Direction);
         if (tca < 0) // points away from the sphere
         {
             return RGBColor.Black;
         }
         float l2hc = (this.radius2 - l2oc) / (ray.Direction * ray.Direction) + (tca * tca); // division
         if (l2hc > 0) {
             tmin = tca - (float) Math.Sqrt(l2hc);
         }
     }
     if (!float.IsPositiveInfinity(tmin)) {
         Point3D hitPoint = ray.Origin + tmin * ray.Direction;
         Vector3D normal = hitPoint.ToVector3D().Normalized;
         double theta = Math.Atan2(-normal.X, normal.Z);
         double temp = -normal.Y;
         double phi = Math.Acos(temp);
         double uCoord = theta * (1.0 / (Math.PI + Math.PI));
         double vCoord = 1.0 - phi * (1.0 / Math.PI);
         if (uCoord < 0.0) {
             uCoord++;
         }
         return this.panorama.GetPixel((float) ((this.panorama.Width - 1) * uCoord),
                                       (float) ((this.panorama.Height - 1) * vCoord));
     }
     return RGBColor.Black;
 }
コード例 #6
0
ファイル: Torus.cs プロジェクト: hksonngan/sharptracing
 public override bool FindIntersection(Ray ray, out Intersection intersect)
 {
     intersect = new Intersection();
     const float A = 1.0f;
     Vector3D viewPosRel = ray.Origin - this.center; // Origin relative to center
     float udotp = (ray.Direction * viewPosRel);
     float B = (udotp + udotp + udotp + udotp);
     float RadiiSqSum = this.majorRadius2 + this.minorRadius2;
     float ucdotp = (this.axisC * viewPosRel);
     float ucdotu = (this.axisC * ray.Direction);
     float pSq = (viewPosRel * viewPosRel);
     float C = B * udotp + (pSq + pSq) - (RadiiSqSum + RadiiSqSum) + 4.0f * this.majorRadius2 * ucdotu * ucdotu;
     float D = 4.0f * ((pSq - RadiiSqSum) * udotp + (this.majorRadius2 + this.majorRadius2) * ucdotp * ucdotu);
     float E = (pSq - (RadiiSqSum + RadiiSqSum)) * pSq + 4.0f * this.majorRadius2 * ucdotp * ucdotp +
               ((this.majorRadius2 - this.minorRadius2) * (this.majorRadius2 - this.minorRadius2));
     float[] roots = {0f, 0f, 0f, 0f};
     int numRoots = EquationSolver.SolveQuartic(A, B, C, D, E, out roots[0], out roots[1], out roots[2],
                                                out roots[3]);
     //if (numRoots > 0)
     //{
     //    Debug.WriteLine(ray.Direction.ToString());
     //}
     //if (numRoots > 0)
     //Debug.Write(String.Format("A={0},B={1},C={2},D={3},E={4} - ", A, B, C, D, E));
     //for (int i = 0; i < numRoots; i++)
     //{
     //    Debug.Write(roots[i] + "|");
     //}
     //if (numRoots > 0)
     //    Debug.Write("\r\n");
     if (numRoots > 0) {
         if (roots[0] > 0.1f) {
             intersect.TMin = roots[0];
             intersect.HitPoint = ray.Origin + intersect.TMin * ray.Direction;
             // Intersection position (not relative to center)
             intersect.HitPrimitive = this;
             // Outward normal
             Vector3D h = intersect.HitPoint - this.center; // Now its the relative point
             float xCoord = h * this.axisA; // forward axis
             float yCoord = h * this.axisB; // rightward axis
             float zCoord = h * this.axisC; // upward axis
             intersect.Normal = this.axisC * -zCoord + h;
             float outNnorm = intersect.Normal.Length;
             intersect.Normal.Normalize();
             intersect.Normal = intersect.Normal * -this.majorRadius + h;
             // Negative point projected to center path of torus
             intersect.Normal.Normalize(); // Fix roundoff error problems
             if (this.material != null && this.material.IsTexturized) {
                 // u - v coordinates
                 double u = Math.Atan2(yCoord, xCoord);
                 u = u * (0.5 / Math.PI) + 0.5;
                 double bVal = outNnorm - this.majorRadius;
                 double v = Math.Atan2(zCoord, bVal);
                 v = v * (0.5 / Math.PI) + 0.5;
                 //int widthTex = this.material.Texture.Width - 1;
                 //int heightTex = this.material.Texture.Height - 1;
                 //this.material.Color = this.material.Texture.GetPixel((int)(u * widthTex), (int)(v * heightTex));
                 intersect.CurrentTextureCoordinate.U = (float) u;
                 intersect.CurrentTextureCoordinate.V = (float) v;
             }
             return true;
         }
     }
     return false;
 }
コード例 #7
0
ファイル: MeshModel.cs プロジェクト: hksonngan/sharptracing
 public override bool FindIntersection(Ray ray, out Intersection intersect)
 {
     intersect = new Intersection();
     if (this.accelerationManager != null && this.accelerationManager.FindIntersection(ray, out intersect)) {
         if (this.shadeType == ShadeType.Phong) {
             MeshTriangle t = (MeshTriangle) intersect.HitPrimitive;
             BarycentricCoordinate bary = t.CurrentBarycentricCoordinate;
             Vector3D v1 = bary.Alpha * t.Vertex1.Normal;
             Vector3D v2 = bary.Beta * t.Vertex2.Normal;
             Vector3D v3 = bary.Gama * t.Vertex3.Normal;
             intersect.Normal = (v1 + v2 + v3);
             intersect.Normal.Normalize();
         }
         if (intersect.Normal * ray.Direction > 0) {
             intersect.Normal.Flip();
         }
         intersect.HitPrimitive = this;
         intersect.HitPrimitive.Material = this.material;
         return true;
     }
     return false;
 }
コード例 #8
0
ファイル: Shader.cs プロジェクト: hksonngan/sharptracing
 //protected virtual bool InShadow(Intersection intersect, Vector3D L) {
 //    if(this.scene.IsShadowActive) {
 //        float len = L.Length;
 //        Ray shadowRay = new Ray(intersect.HitPoint, L);
 //        //foreach(Primitive primitive in this.scene.Primitives) {
 //        if(this.scene.FindIntersection(shadowRay, out intersect)
 //             && intersect.TMin < len) {
 //            return true; //Total Shadow
 //        }
 //        //}
 //    }
 //    return false;
 //}
 protected virtual float ShadowFactor(Intersection intersect, Vector3D L, Light light)
 {
     float shadowFactor = 1; //[0..1] 1 = not in shadow, 0 = total shadow
     if (this.scene.IsShadowActive) {
         Ray shadowRay;
         if (!this.scene.IsSoftShadowActive) {
             float len = L.Length;
             shadowRay = new Ray(intersect.HitPoint, L);
             if (this.scene.FindIntersection(shadowRay, out intersect) && intersect.TMin < len) {
                 shadowFactor = 0; //Total Shadow
             }
         } else {
             AreaLight areaLight = light as AreaLight;
             if (areaLight != null) {
                 Vector3D toRndPointInLight;
                 float reductFactor = 1.0f / this.scene.SoftShadowSamples;
                 for (int i = 0; i < this.scene.SoftShadowSamples; i++) {
                     toRndPointInLight = areaLight.GetRandomPoint() - intersect.HitPoint;
                     shadowRay = new Ray(intersect.HitPoint, toRndPointInLight);
                     if ((intersect.HitPrimitive != null &&
                          intersect.HitPrimitive.FindIntersection(shadowRay, out intersect)) ||
                         this.scene.FindIntersection(shadowRay, out intersect) &&
                         intersect.TMin < toRndPointInLight.Length) {
                         shadowFactor -= reductFactor;
                     }
                 }
             }
         }
     }
     return shadowFactor;
 }
コード例 #9
0
ファイル: Shader.cs プロジェクト: hksonngan/sharptracing
 public abstract RGBColor Shade(Ray ray, Intersection intersection);
コード例 #10
0
ファイル: Cylinder.cs プロジェクト: hksonngan/sharptracing
 public override bool FindIntersection(Ray ray, out Intersection intersect)
 {
     intersect = new Intersection();
     float maxFrontDist = float.MinValue;
     float minBackDist = float.MaxValue;
     HitPrimitive frontType = HitPrimitive.None, backType = HitPrimitive.None; // 0, 1, 2 = top, bottom, side
     // Start with the bounding planes
     float pdotn = (ray.Origin * this.centralAxis) - this.centerDotcentralAxis;
     float udotn = ray.Direction * this.centralAxis;
     if (pdotn > this.halfHeight) {
         if (udotn >= 0.0) {
             return false; // Above top plane pointing up
         }
         // Hits top from above
         maxFrontDist = (this.halfHeight - pdotn) / udotn;
         frontType = HitPrimitive.TopPlane;
         minBackDist = -(this.halfHeight + pdotn) / udotn;
         backType = HitPrimitive.BottomPlane;
     } else if (pdotn < -this.halfHeight) {
         if (udotn <= 0.0) {
             return false; // Below bottom, pointing down
         }
         // Hits bottom plane from below
         maxFrontDist = -(this.halfHeight + pdotn) / udotn;
         frontType = HitPrimitive.BottomPlane;
         minBackDist = (this.halfHeight - pdotn) / udotn;
         backType = HitPrimitive.TopPlane;
     } else if (udotn < 0.0) {
         // Inside, pointing down
         minBackDist = -(this.halfHeight + pdotn) / udotn;
         backType = HitPrimitive.BottomPlane;
     } else if (udotn > 0.0) {
         // Inside, pointing up
         minBackDist = (this.halfHeight - pdotn) / udotn;
         backType = HitPrimitive.TopPlane;
     }
     if (maxFrontDist < 0) {
         return false;
     }
     // Now handle the cylinder sides
     Vector3D v = ray.Origin - this.center;
     float pdotuA = v * this.axisA;
     float pdotuB = v * this.axisB;
     float udotuA = ray.Direction * this.axisA;
     float udotuB = ray.Direction * this.axisB;
     float C = pdotuA * pdotuA + pdotuB * pdotuB - 1.0f;
     float B = (pdotuA * udotuA + pdotuB * udotuB);
     if (C >= 0.0 && B > 0.0) {
         return false; // Pointing away from the cylinder
     }
     B += B; // Double B for final 2.0 factor
     float A = udotuA * udotuA + udotuB * udotuB;
     float alpha1, alpha2; // The roots, in order
     int numRoots = EquationSolver.SolveQuadric(A, B, C, out alpha1, out alpha2);
     if (numRoots == 0) {
         return false; // No intersection
     }
     if (alpha1 > maxFrontDist) {
         if (alpha1 > minBackDist) {
             return false;
         }
         maxFrontDist = alpha1;
         frontType = HitPrimitive.Cylinder;
     }
     if (numRoots == 2 && alpha2 < minBackDist) {
         if (alpha2 < maxFrontDist) {
             return false;
         }
         minBackDist = alpha2;
         backType = HitPrimitive.Cylinder;
     }
     // Put it all together:
     float alpha;
     HitPrimitive hitSurface;
     if (maxFrontDist > 0.0) {
         intersect.HitFromInSide = true; // Hit from outside
         alpha = maxFrontDist;
         hitSurface = frontType;
     } else {
         intersect.HitFromInSide = false; // Hit from inside
         alpha = minBackDist;
         hitSurface = backType;
     }
     if (alpha < 0.01) {
         return false;
     }
     intersect.TMin = alpha;
     intersect.TMax = alpha2;
     // Set v to the intersection point
     intersect.HitPoint = ray.Origin + ray.Direction * alpha;
     intersect.HitPrimitive = this;
     // Now set v equal to returned position relative to the center
     v = intersect.HitPoint - this.center;
     float vdotuA = v * this.axisA;
     float vdotuB = v * this.axisB;
     float uCoord = 0;
     float vCoord = 0;
     switch (hitSurface) {
         case HitPrimitive.TopPlane: // Top surface
             intersect.Normal = this.top.Normal;
             // Calculate U-V values for texture coordinates
             uCoord = 0.5f * (1.0f - vdotuA);
             vCoord = 0.5f * (1.0f + vdotuB);
             break;
         case HitPrimitive.BottomPlane: // Bottom face
             intersect.Normal = this.bottom.Normal;
             // Calculate U-V values for texture coordinates
             uCoord = 0.5f * (1.0f + vdotuA);
             vCoord = 0.5f * (1.0f + vdotuB);
             break;
         case HitPrimitive.Cylinder: // Cylinder's side
             intersect.Normal = ((vdotuA * this.axisA) + (vdotuB * this.axisB));
             intersect.Normal.Normalize();
             // Calculate u-v coordinates for texture mapping (in range[0,1]x[0,1])
             uCoord = (float) (Math.Atan2(vdotuB, vdotuA) / (Math.PI + Math.PI) + 0.5);
             vCoord = ((v * this.centralAxis) + this.halfHeight) * 1.0f / this.height;
             break;
     }
     if (this.material != null && this.material.IsTexturized) {
         //int widthTex = this.material.Texture.Width - 1;
         //int heightTex = this.material.Texture.Height - 1;
         //this.material.Color = this.material.Texture.GetPixel((int)(uCoord * widthTex), (int)(vCoord * heightTex));
         intersect.CurrentTextureCoordinate.U = uCoord;
         intersect.CurrentTextureCoordinate.V = vCoord;
     }
     return true;
 }
コード例 #11
0
ファイル: CubeMap.cs プロジェクト: hksonngan/sharptracing
 public override RGBColor GetColor(Ray ray)
 {
     if (this.isLoaded) {
         float t;
         Point3D posWS = ray.Origin; // Position where the ray starts in world space
         Vector3D dirWS = ray.Direction; // Direction of the ray in world space
         // Test if ray intersects right plane
         if (dirWS.X > 0) {
             t = (this.xMax - posWS.X) / dirWS.X;
             Point3D p = posWS + dirWS * t;
             if (p.Y <= this.yMax && p.Y >= this.yMin && p.Z >= this.zMin && p.Z <= this.zMax) {
                 float xTex = (-p.Z + this.zMax) / (this.zMax - this.zMin);
                 float yTex = (-p.Y + this.yMax) / (this.yMax - this.yMin);
                 float pixelX = (xTex * (this.xMaxTexture.Width - 1));
                 float pixelY = (yTex * (this.xMaxTexture.Height - 1));
                 return this.xMaxTexture.GetPixel(pixelX, pixelY);
             }
         } else if (dirWS.X < 0) {
             t = (this.xMin - posWS.X) / dirWS.X;
             Point3D p = posWS + dirWS * t;
             if (p.Y <= this.yMax && p.Y >= this.yMin && p.Z >= this.zMin && p.Z <= this.zMax) {
                 float xTex = (p.Z + this.zMax) / (this.zMax - this.zMin);
                 float yTex = (-p.Y + this.yMax) / (this.yMax - this.yMin);
                 float pixelX = (xTex * (this.xMinTexture.Width - 1));
                 float pixelY = (yTex * (this.xMinTexture.Height - 1));
                 //int pixelX = (int)(xTex * (xMinTexture.Width-1));
                 //int pixelY = (int)(yTex * (xMinTexture.Height-1));
                 return this.xMinTexture.GetPixel(pixelX, pixelY);
             }
         }
         if (dirWS.Y > 0) {
             t = (this.yMax - posWS.Y) / dirWS.Y;
             Point3D p = posWS + dirWS * t;
             if (p.X <= this.xMax && p.X >= this.xMin && p.Z >= this.zMin && p.Z <= this.zMax) {
                 float xTex = (p.X + this.xMax) / (this.xMax - this.xMin);
                 float yTex = (p.Z + this.zMax) / (this.zMax - this.zMin);
                 float pixelX = (xTex * (this.yMaxTexture.Width - 1));
                 float pixelY = (yTex * (this.yMaxTexture.Height - 1));
                 return this.yMaxTexture.GetPixel(pixelX, pixelY);
             }
         } else if (dirWS.Y < 0) {
             t = (this.yMin - posWS.Y) / dirWS.Y;
             Point3D p = posWS + dirWS * t;
             if (p.X <= this.xMax && p.X >= this.xMin && p.Z >= this.zMin && p.Z <= this.zMax) {
                 float xTex = (p.X + this.xMax) / (this.xMax - this.xMin);
                 float yTex = (-p.Z + this.zMax) / (this.zMax - this.zMin);
                 float pixelX = (xTex * (this.yMinTexture.Width - 1));
                 float pixelY = (yTex * (this.yMinTexture.Height - 1));
                 return this.yMinTexture.GetPixel(pixelX, pixelY);
             }
         }
         if (dirWS.Z > 0) {
             t = (this.zMax - posWS.Z) / dirWS.Z;
             Point3D p = posWS + dirWS * t;
             if (p.X <= this.xMax && p.X >= this.xMin && p.Y >= this.yMin && p.Y <= this.yMax) {
                 float xTex = (p.X + this.xMax) / (this.xMax - this.xMin);
                 float yTex = (-p.Y + this.yMax) / (this.yMax - this.yMin);
                 float pixelX = xTex * (this.zMaxTexture.Width - 1);
                 float pixelY = yTex * (this.zMaxTexture.Height - 1);
                 return this.zMaxTexture.GetPixel(pixelX, pixelY);
             }
         } else if (dirWS.Z < 0) {
             t = (this.zMin - posWS.Z) / dirWS.Z;
             Point3D p = posWS + dirWS * t;
             if (p.X <= this.xMax && p.X >= this.xMin && p.Y >= this.yMin && p.Y <= this.yMax) {
                 float xTex = (-p.X + this.xMax) / (this.xMax - this.xMin);
                 float yTex = (-p.Y + this.yMax) / (this.yMax - this.yMin);
                 float pixelX = (xTex * (this.zMinTexture.Width - 1));
                 float pixelY = (yTex * (this.zMinTexture.Height - 1));
                 return this.zMinTexture.GetPixel(pixelX, pixelY);
             }
         }
         //throw new Exception("No valid direction for the ray specified.");
     }
     return RGBColor.Black;
 }
コード例 #12
0
        public override RGBColor Shade(Ray ray, Intersection intersection)
        {
            CookTorranceMaterial material = (CookTorranceMaterial) intersection.HitPrimitive.Material;
            RGBColor color = this.Scene.IAmb * material.KAmb; //Contribuicao ambiental
            this.V = -ray.Direction;
            this.N = intersection.Normal;
            this.NV = this.N * this.V;
            foreach (Light light in this.Scene.Lights) {
                //Vetor do ponto para a Luz
                this.L = (light.Position - intersection.HitPoint);
                float shadowFactor = this.ShadowFactor(intersection, this.L, light);
                if (shadowFactor > 0f) {
                    this.L.Normalize();
                    this.lightFactor = light.GetColorFactor(this.L);
                    if (this.lightFactor > 0.0f) {
                        this.NL = this.N * this.L;
                        if (material.KDiff > 0.0f) {
                            if (this.NL > 0) {
                                //Diffuse Term
                                if (material.IsTexturized) {
                                    color += (material.KDiff *
                                              material.Texture.GetPixel(intersection.CurrentTextureCoordinate) *
                                              light.Color * this.NL); //*this.lightFactor;
                                } else {
                                    color += (material.KDiff * material.DiffuseColor * light.Color * this.NL);
                                    //* this.lightFactor;
                                }
                            }
                        }
                        if (material.IsReflective) {
                            this.H = this.L + this.V;
                            this.H.Normalize();
                            this.NH = this.N * this.H;
                            this.VH = this.V * this.H;
                            //verificar se entrando ou saindo...
                            float eta = intersection.HitFromInSide
                                            ? material.RefractIndex * 1 / this.Scene.RefractIndex
                                            : this.Scene.RefractIndex * 1 / material.RefractIndex;
                            this.F = FresnelTerm(this.VH, eta); //* (float)(1/Math.PI);
                            this.D = DistributionTerm(this.NH, material.Roughness);
                            this.G = GeometryOclusionTerm(this.VH, this.NH, this.NL, this.NV);

                            color += ((material.Shiness * this.F * this.D * this.G * light.Color) * (this.NL * this.NV));
                        }
                    }
                    color *= this.lightFactor * shadowFactor;
                }
            }
            return color;
        }
コード例 #13
0
ファイル: Sphere.cs プロジェクト: hksonngan/sharptracing
        public override bool FindIntersection(Ray ray, out Intersection intersect)
        {
            intersect = new Intersection();
            // geometric solution
            Vector3D L = this.center - ray.Origin;
            float tca = L * ray.Direction;
            if (tca < 0) return false;
            float d2 = L * L - tca * tca;
            if (d2 > radius2) return false;
            float thc = (float)Math.Sqrt(radius2 - d2);
            float t0 = tca - thc;
            float t1 = tca + thc;
            intersect.TMin = t0;
            intersect.TMax = t1;
            intersect.HitPoint = ray.Origin + ray.Direction * intersect.TMin;
            intersect.Normal = intersect.HitPoint - this.center;
            intersect.HitPrimitive = this;
            intersect.Normal.Normalize();

            if (this.material != null && this.material.IsTexturized)
            {
                double uCoord, vCoord;
                double theta = Math.Atan2(-intersect.Normal.X, intersect.Normal.Z);
                double temp = -intersect.Normal.Y;
                double phi = Math.Acos(temp);
                uCoord = theta * (1.0 / (Math.PI + Math.PI));
                vCoord = 1.0 - phi * (1.0 / Math.PI);
                if (uCoord < 0.0)
                {
                    uCoord++;
                }
                intersect.CurrentTextureCoordinate.U = (float)uCoord;
                intersect.CurrentTextureCoordinate.V = (float)vCoord;
                //int w = this.material.Texture.Width;
                //int h = this.material.Texture.Height;
                //this.material.Color = this.material.Texture.GetPixel((int)(w * uCoord), (int)(h * vCoord));
            }
            return true;
        }
コード例 #14
0
ファイル: SphereFlake.cs プロジェクト: hksonngan/sharptracing
 public override bool FindIntersection(Ray ray, out Intersection intersect)
 {
     bool intersects = this.sphereFlakeKDTree.FindIntersection(ray, out intersect);
     intersect.HitPrimitive = this;
     return intersects;
 }
コード例 #15
0
 public override RGBColor Trace(Ray ray, int depth)
 {
     Intersection intersection;
     if (this.scene.FindIntersection(ray, out intersection)) {
         Material material = intersection.HitPrimitive.Material;
         Shader shader = material.CreateShader(this.scene);
         RGBColor color = shader.Shade(ray, intersection);
         Ray rRay = new Ray();
         if (depth < 5) {
             if (material.IsReflective) {
                 rRay.Origin = intersection.HitPoint;
                 rRay.Direction = Vector3D.Reflected(intersection.Normal, ray.Direction);
                 color += this.indirectEnlightenment.IrradianceEstimate(intersection.HitPoint,
                                                                        intersection.Normal, this.IrradianceArea,
                                                                        this.IrradiancePhotonNumber);
                 //color += this.Trace(rRay, depth + 1) * material.KSpec;
                 this.Trace(rRay, depth + 1);
             }
             if (material.IsTransparent) {
                 Vector3D T;
                 //float eta = intersection.HitFromInSide
                 //                ? material.RefractIndex * 1 / this.scene.RefractIndex
                 //                : this.scene.RefractIndex * 1 / material.RefractIndex;
                 //float eta = this.scene.RefractIndex * 1 / material.RefractIndex;
                 float eta = (ray.PrevRefractIndex.IsEqual(material.RefractIndex))
                                 ? material.RefractIndex * 1 / this.scene.RefractIndex
                                 : this.scene.RefractIndex * 1 / material.RefractIndex;
                 if (Vector3D.Refracted(intersection.Normal, ray.Direction, out T, eta)) {
                     rRay.Origin = intersection.HitPoint;
                     rRay.Direction = T;
                     rRay.PrevRefractIndex = material.RefractIndex;
                     color += this.indirectEnlightenment.IrradianceEstimate(intersection.HitPoint,
                                                                            intersection.Normal,
                                                                            this.IrradianceArea,
                                                                            this.IrradiancePhotonNumber);
                     this.Trace(rRay, depth + 1); //* material.KTrans
                 }
             }
         }
         return color;
     }
     return this.scene.IsEnvironmentMapped ? this.scene.EnvironmentMap.GetColor(ray) : this.scene.BackgroundColor;
 }
コード例 #16
0
ファイル: RayCasting.cs プロジェクト: hksonngan/sharptracing
 public abstract RGBColor Trace(Ray ray, int depth);
コード例 #17
0
ファイル: BoundBox.cs プロジェクト: hksonngan/sharptracing
 public bool Intersect(Ray ray, ref float ltmin, ref float ltmax)
 {
     ltmin = float.MaxValue;
     ltmax = float.MaxValue;
     float tmin, tmax, tymin, tymax, tzmin, tzmax;
     if (ray.InvertedDirection.X >= 0) {
         tmin = (this.pMin.X - ray.Origin.X) * ray.InvertedDirection.X;
         tmax = (this.pMax.X - ray.Origin.X) * ray.InvertedDirection.X;
     } else {
         tmin = (this.pMax.X - ray.Origin.X) * ray.InvertedDirection.X;
         tmax = (this.pMin.X - ray.Origin.X) * ray.InvertedDirection.X;
     }
     if (ray.InvertedDirection.Y >= 0) {
         tymin = (this.pMin.Y - ray.Origin.Y) * ray.InvertedDirection.Y;
         tymax = (this.pMax.Y - ray.Origin.Y) * ray.InvertedDirection.Y;
     } else {
         tymin = (this.pMax.Y - ray.Origin.Y) * ray.InvertedDirection.Y;
         tymax = (this.pMin.Y - ray.Origin.Y) * ray.InvertedDirection.Y;
     }
     if ((tmin > tymax) || (tymin > tmax)) {
         return false;
     }
     if (tymin > tmin) {
         tmin = tymin;
     }
     if (tymax < tmax) {
         tmax = tymax;
     }
     if (ray.InvertedDirection.Z >= 0) {
         tzmin = (this.pMin.Z - ray.Origin.Z) * ray.InvertedDirection.Z;
         tzmax = (this.pMax.Z - ray.Origin.Z) * ray.InvertedDirection.Z;
     } else {
         tzmin = (this.pMax.Z - ray.Origin.Z) * ray.InvertedDirection.Z;
         tzmax = (this.pMin.Z - ray.Origin.Z) * ray.InvertedDirection.Z;
     }
     if ((tmin > tzmax) || (tzmin > tmax)) {
         return false;
     }
     if (tzmin > tmin) {
         tmin = tzmin;
     }
     if (tzmax < tmax) {
         tmax = tzmax;
     }
     if ((tmin < ltmin) && (tmax > 0)) {
         ltmin = tmin;
         ltmax = tmax;
         return true;
     }
     return false;
 }
コード例 #18
0
ファイル: BoundBox.cs プロジェクト: hksonngan/sharptracing
 public bool Intersect(Ray ray, out float t)
 {
     t = float.PositiveInfinity;
     //if (this.IsEmpty)
     //{
     //    return false;
     //}
     float tmin, tmax, tymin, tymax, tzmin, tzmax;
     float oX = ray.Origin.X, oY = ray.Origin.Y, oZ = ray.Origin.Z;
     float inv_dX = ray.InvertedDirection.X, inv_dY = ray.InvertedDirection.Y, inv_dZ = ray.InvertedDirection.Z;
     if (ray.InvertedDirection.X >= 0) {
         tmin = (this.pMin.X - oX) * inv_dX;
         tmax = (this.pMax.X - oX) * inv_dX;
     } else {
         tmin = (this.pMax.X - oX) * inv_dX;
         tmax = (this.pMin.X - oX) * inv_dX;
     }
     if (ray.InvertedDirection.Y >= 0) {
         tymin = (this.pMin.Y - oY) * inv_dY;
         tymax = (this.pMax.Y - oY) * inv_dY;
     } else {
         tymin = (this.pMax.Y - oY) * inv_dY;
         tymax = (this.pMin.Y - oY) * inv_dY;
     }
     if ((tmin > tymax) || (tymin > tmax)) {
         return false;
     }
     if (tymin > tmin) {
         tmin = tymin;
     }
     if (tymax < tmax) {
         tmax = tymax;
     }
     if (ray.InvertedDirection.Z >= 0) {
         tzmin = (this.pMin.Z - oZ) * inv_dZ;
         tzmax = (this.pMax.Z - oZ) * inv_dZ;
     } else {
         tzmin = (this.pMax.Z - oZ) * inv_dZ;
         tzmax = (this.pMin.Z - oZ) * inv_dZ;
     }
     if ((tmin > tzmax) || (tzmin > tmax)) {
         return false;
     }
     if (tzmin > tmin) {
         tmin = tzmin;
     }
     if (tzmax < tmax) {
         tmax = tzmax;
     }
     t = tmin;
     return true;
 }
コード例 #19
0
ファイル: BoundBox.cs プロジェクト: hksonngan/sharptracing
 public bool Intersect(Ray ray)
 {
     //if (this.IsEmpty) {
     //    return false;
     //}
     float tmin, tmax, tymin, tymax, tzmin, tzmax;
     float oX = ray.Origin.X, oY = ray.Origin.Y, oZ = ray.Origin.Z;
     float inv_dX = ray.InvertedDirection.X, inv_dY = ray.InvertedDirection.Y, inv_dZ = ray.InvertedDirection.Z;
     if (inv_dX > 0) {
         tmin = (this.pMin.X - oX) * inv_dX;
         tmax = (this.pMax.X - oX) * inv_dX;
     } else {
         tmin = (this.pMax.X - oX) * inv_dX;
         tmax = (this.pMin.X - oX) * inv_dX;
     }
     if (inv_dY > 0) {
         tymin = (this.pMin.Y - oY) * inv_dY;
         tymax = (this.pMax.Y - oY) * inv_dY;
     } else {
         tymin = (this.pMax.Y - oY) * inv_dY;
         tymax = (this.pMin.Y - oY) * inv_dY;
     }
     if ((tmin > tymax) || (tymin > tmax)) {
         return false;
     }
     if (tymin > tmin) {
         tmin = tymin;
     }
     if (tymax < tmax) {
         tmax = tymax;
     }
     if (inv_dZ > 0) {
         tzmin = (this.pMin.Z - oZ) * inv_dZ;
         tzmax = (this.pMax.Z - oZ) * inv_dZ;
     } else {
         tzmin = (this.pMax.Z - oZ) * inv_dZ;
         tzmax = (this.pMin.Z - oZ) * inv_dZ;
     }
     if ((tmin > tzmax) || (tzmin > tmax)) {
         return false;
     }
     if (tzmin > tmin) {
         tmin = tzmin;
     }
     if (tzmax < tmax) {
         tmax = tzmax;
     }
     return true;
 }
コード例 #20
0
ファイル: PhongShader.cs プロジェクト: hksonngan/sharptracing
        public override RGBColor Shade(Ray ray, Intersection intersection)
        {
            Material material = intersection.HitPrimitive.Material;
            RGBColor color = this.Scene.IAmb * material.KAmb; //Contribuicao ambiental
            this.V = -ray.Direction;

            //{
            //    Vector3D n = intersection.Normal;
            //    int noisetype = 2;
            //    double f0 = F(n[0], n[1], n[2], noisetype),
            //            fx = F(n[0] + .0001, n[1], n[2], noisetype),
            //            fy = F(n[0], n[1] + .0001, n[2], noisetype),
            //            fz = F(n[0], n[1], n[2] + .0001, noisetype);
            //    // SUBTRACT THE FUNCTION'S GRADIENT FROM THE SURFACE NORMAL
            //    n[0] -= (float)((fx - f0) / .0001);
            //    n[1] -= (float)((fy - f0) / .0001);
            //    n[2] -= (float)((fz - f0) / .0001);
            //    n.Normalize();
            //    //intersection.HitPrimitive.Material.Color = new RGBColor(n[0], n[1], n[2]);
            //    intersection.Normal = n;
            //}
            this.N = intersection.Normal;

            //if(material.IsTexturized){
            //    this.N = BumpNormal(intersection.HitPrimitive.Material.Texture, intersection);
            //    intersection.Normal = this.N;
            //} else{
            //    this.N = intersection.Normal;
            //}

            //this.NV = this.N * this.V;
            foreach (Light light in this.Scene.Lights) {
                this.L = (light.Position - intersection.HitPoint);
                float shadowFactor = this.ShadowFactor(intersection, this.L, light);
                if (shadowFactor > 0f) {
                    this.L.Normalize();
                    this.lightFactor = light.GetColorFactor(this.L);
                    if (this.lightFactor > 0.0f) {
                        this.NL = this.N * this.L;
                        if (material.KDiff > 0.0f) {
                            if (this.NL > 0) {
                                //Diffuse Term
                                if (material.IsTexturized) {
                                    color += (material.KDiff *
                                              material.Texture.GetPixel(intersection.CurrentTextureCoordinate) *
                                              light.Color * this.NL) * this.lightFactor * shadowFactor;
                                } else {
                                    color += (material.KDiff * material.DiffuseColor * light.Color * this.NL) *
                                             this.lightFactor * shadowFactor;
                                }
                            }
                        }
                        if (material.IsReflective) {
                            this.R = (2 * this.NL * this.N) - this.L;
                            this.R.Normalize();
                            this.RV = this.R * this.V;
                            if (this.RV > 0) {
                                //Specular Term
                                color += (material.KSpec * material.SpecularColor * light.Color *
                                          (float) Math.Pow(this.RV, material.Shiness)) * this.lightFactor * shadowFactor;
                            }
                        }
                        //color *= lightFactor * shadowFactor;
                    }
                }
            }

            return color;
        }
コード例 #21
0
ファイル: Polygon.cs プロジェクト: hksonngan/sharptracing
 /// <summary>
 /// Calculates the distance from a ray to the polygon.
 /// </summary>
 /// <param name="ray">The ray to trace</param>
 /// <param name="intersect"></param>
 /// <returns>The distance from the ray to the polygon, or negative if no intersection</returns>
 public override bool FindIntersection(Ray ray, out Intersection intersect)
 {
     intersect = new Intersection();
     //t = -(N • Ro + D) / (N • Rd)
     //Vector3D origin = ray.Origin.ToVector3D();
     float NRd = this.normal * ray.Direction;
     if (NRd.NearZero()) {
         return false;
     }
     float t = -(this.normal * ray.Origin.ToVector3D() + this.d) / NRd;
     if (t < 0.01f) {
         return false;
     }
     intersect.Normal = this.normal;
     intersect.HitPoint = ray.Origin + (t * ray.Direction);
     intersect.HitPrimitive = this;
     intersect.TMin = t;
     return this.PointIsInPolygon(intersect.HitPoint);
 }
コード例 #22
0
        public override Ray CreateRayFromScreen(float x, float y)
        {
            float du = -this.au + ((2.0f * this.au * x) * 1f / (this.resX));
            float dv = -this.av + ((2.0f * this.av * y) * 1f / (this.resY));
            Ray ray = new Ray(this.eye, this.basis.Transform(new Vector3D(du, dv, -1)));

            //Ray ray = new Ray(eye, this.basis.W + this.basis.U * x + this.basis.V * y);

            ray.Direction = ray.Direction * focalDistance;

            double r2 = new Random().NextDouble() * lensRadius;
            double r = Math.Sqrt(r2);

            double theta = new Random().NextDouble() * 2 * Math.PI;

            double xD = r * Math.Sin(theta);
            double yD = r * Math.Cos(theta);

            Vector3D lensU = this.basis.U * (float)(xD * lensRadius);
            Vector3D lensV = this.basis.V * (float)(yD * lensRadius);

            ray.Direction = ray.Direction - (lensU + lensV);
            ray.Origin = ray.Origin + (lensU + lensV);

            ray.Direction.Normalize();

            return ray;
        }
コード例 #23
0
ファイル: Cone.cs プロジェクト: hksonngan/sharptracing
 public override bool FindIntersection(Ray ray, out Intersection intersect)
 {
     intersect = new Intersection();
     float maxFrontDist = float.NegativeInfinity;
     float minBackDist = float.PositiveInfinity;
     HitSide frontType = HitSide.None, backType = HitSide.None; // 0, 1 = base, side
     float viewPosdotCtr = ray.Origin * this.centralAxis;
     float udotuCtr = ray.Direction * this.centralAxis;
     if (viewPosdotCtr > (this.apexDotCenterAxis) && udotuCtr >= 0.0f) {
         return false; // Above the cone's apex
     }
     // Start with the bounding base plane
     float pdotnCap = this.baseNormal * ray.Origin;
     float udotnCap = this.baseNormal * ray.Direction;
     if (pdotnCap > this.coefBasePlane) {
         if (udotnCap >= 0.0f) {
             return false; // Above (=outside) base plane, pointing away
         }
         maxFrontDist = (this.coefBasePlane - pdotnCap) / udotnCap;
         frontType = HitSide.BottomPlane;
     } else if (pdotnCap < this.coefBasePlane) {
         if (udotnCap > 0.0f) {
             // Below (=inside) base plane, pointing towards the plane
             minBackDist = (this.coefBasePlane - pdotnCap) / udotnCap;
             backType = HitSide.BottomPlane;
         }
     }
     // Now handle the cone's sides
     Vector3D v = ray.Origin - this.apex;
     float pdotuCtr = v * this.centralAxis;
     float pdotuA = v * this.axisA;
     float pdotuB = v * this.axisB;
     // udotuCtr already defined above
     float udotuA = ray.Direction * this.axisA;
     float udotuB = ray.Direction * this.axisB;
     float C = pdotuA * pdotuA + pdotuB * pdotuB - pdotuCtr * pdotuCtr;
     float B = (pdotuA * udotuA + pdotuB * udotuB - pdotuCtr * udotuCtr);
     B += B;
     float A = udotuA * udotuA + udotuB * udotuB - udotuCtr * udotuCtr;
     float alpha1, alpha2; // The roots, in order
     int numRoots = EquationSolver.SolveQuadric(A, B, C, out alpha1, out alpha2);
     if (numRoots == 0) {
         return false; // No intersection
     }
     bool viewMoreVertical = (A < 0.0f);
     if (viewMoreVertical) {
         // View line leaves and then enters the cone
         if (alpha1 < minBackDist && pdotuCtr + alpha1 * udotuCtr <= 0.0f) {
             if (alpha1 < maxFrontDist) {
                 return false;
             }
             minBackDist = alpha1;
             backType = HitSide.Cone;
         } else if (numRoots == 2 && alpha2 > maxFrontDist && pdotuCtr + alpha2 * udotuCtr <= 0.0f) {
             if (alpha2 > minBackDist) {
                 return false;
             }
             maxFrontDist = alpha2;
             frontType = HitSide.Cone;
         }
     } else {
         // view line enters and then leaves
         if (alpha1 > maxFrontDist) {
             if (pdotuCtr + alpha1 * udotuCtr > 0.0f) {
                 return false; // Enters dual cone instead
             }
             if (alpha1 > minBackDist) {
                 return false;
             }
             maxFrontDist = alpha1;
             frontType = HitSide.Cone;
         }
         if (numRoots == 2 && alpha2 < minBackDist) {
             if (pdotuCtr + alpha2 * udotuCtr > 0.0f) {
                 return false; // Is leaving dual cone instead
             }
             if (alpha2 < maxFrontDist) {
                 return false;
             }
             minBackDist = alpha2;
             backType = HitSide.Cone;
         }
     }
     // Put it all together:
     float alpha;
     HitSide hitSurface = HitSide.None;
     if (maxFrontDist > 0.0f) {
         alpha = maxFrontDist;
         hitSurface = frontType;
     } else {
         alpha = minBackDist;
         hitSurface = backType;
     }
     if (alpha < 0.0) {
         return false;
     }
     intersect.TMin = alpha;
     // Set v to the intersection point
     intersect.HitPoint = ray.Origin + intersect.TMin * ray.Direction;
     intersect.HitPrimitive = this;
     // Now set v equal to returned position relative to the apex
     v = intersect.HitPoint - this.apex;
     float vdotuA = v * this.axisA;
     float vdotuB = v * this.axisB;
     float vdotuCtr = v * this.centralAxis;
     switch (hitSurface) {
         case HitSide.BottomPlane: // Base face
             intersect.Normal = this.baseNormal;
             if (this.material != null && this.material.IsTexturized) {
                 // Calculate U-V values for texture coordinates
                 vdotuA /= vdotuCtr; // vdotuCtr is negative
                 vdotuB /= vdotuCtr;
                 vdotuA = 0.5f * (1.0f - vdotuA);
                 vdotuB = 0.5f * (1.0f - vdotuB);
                 //int widthTex = this.material.Texture.Width - 1;
                 //int heightTex = this.material.Texture.Height - 1;
                 //this.material.Color =
                 //    this.material.Texture.GetPixel((int)(vdotuB * widthTex), (int)(vdotuA * heightTex));
                 intersect.CurrentTextureCoordinate.U = vdotuB;
                 intersect.CurrentTextureCoordinate.V = vdotuA;
             }
             break;
         case HitSide.Cone: // Cone's side
             intersect.Normal = vdotuA * this.axisA;
             intersect.Normal += vdotuB * this.axisB;
             intersect.Normal -= vdotuCtr * this.centralAxis;
             intersect.Normal.Normalize();
             if (this.material != null && this.material.IsTexturized) {
                 // Calculate u-v coordinates for texture mapping (in range[0,1]x[0,1])
                 float uCoord = (float) (Math.Atan2(vdotuB, vdotuA) / (Math.PI + Math.PI) + 0.5);
                 float vCoord = (vdotuCtr + this.height) / this.height;
                 //int widthTex = this.material.Texture.Width - 1;
                 //int heightTex = this.material.Texture.Height - 1;
                 //this.material.Color =
                 //    this.material.Texture.GetPixel((int)(uCoord * widthTex), (int)(vCoord * heightTex));
                 intersect.CurrentTextureCoordinate.U = uCoord;
                 intersect.CurrentTextureCoordinate.V = vCoord;
             }
             break;
     }
     return true;
 }
コード例 #24
0
ファイル: Ellipsoid.cs プロジェクト: hksonngan/sharptracing
 public override bool FindIntersection(Ray ray, out Intersection intersect)
 {
     intersect = new Intersection();
     Vector3D v = ray.Origin - this.center;
     float pdotuA = v * this.axisA;
     float pdotuB = v * this.axisB;
     float pdotuC = v * this.axisC;
     float udotuA = ray.Direction * this.axisA;
     float udotuB = ray.Direction * this.axisB;
     float udotuC = ray.Direction * this.axisC;
     float C = (pdotuA * pdotuA) + (pdotuB * pdotuB) + (pdotuC * pdotuC) - 1.0f;
     float B = (pdotuA * udotuA + pdotuB * udotuB + pdotuC * udotuC);
     if (C > 0.0f && B >= 0.0f) {
         return false; // Pointing away from the ellipsoid
     }
     B += B; // Double B to get final factor of 2.
     float A = (udotuA * udotuA) + (udotuB * udotuB) + (udotuC * udotuC);
     float alpha1, alpha2;
     int numRoots = EquationSolver.SolveQuadric(A, B, C, out alpha1, out alpha2);
     if (numRoots == 0) {
         return false;
     }
     if (alpha1 > 0.01f) {
         // Found an intersection from outside.
         intersect.TMin = alpha1;
         intersect.TMax = alpha2;
         intersect.HitFromInSide = false;
     } else if (numRoots == 2 && alpha2 > 0.01f) {
         // Found an intersection from inside.
         intersect.TMin = alpha2;
         intersect.TMax = alpha1;
         intersect.HitFromInSide = true;
     } else {
         return false; // Both intersections behind us (should never get here)
     }
     // Calculate intersection position
     intersect.HitPoint = ray.Origin + intersect.TMin * ray.Direction;
     intersect.Normal = intersect.HitPoint - this.center; // Now v is the relative position
     float vdotuA = intersect.Normal * this.axisA;
     float vdotuB = intersect.Normal * this.axisB;
     float vdotuC = intersect.Normal * this.axisC;
     intersect.Normal = vdotuA * this.axisA + vdotuB * this.axisB + vdotuC * this.axisC;
     intersect.Normal.Normalize();
     intersect.HitPrimitive = this;
     if (this.material != null && this.material.IsTexturized) {
         double uCoord = Math.Atan2(-vdotuB, vdotuA) * (1.0 / (Math.PI + Math.PI));
         double vCoord = 1.0 - Math.Cos(-vdotuC) * (1.0 / Math.PI);
         if (uCoord < 0.0) {
             uCoord++;
         }
         //int widthTex = this.material.Texture.Width - 1;
         //int heightTex = this.material.Texture.Height - 1;
         //this.material.Color = this.material.Texture.GetPixel((int)(uCoord * widthTex), (int)(vCoord * heightTex));
         intersect.CurrentTextureCoordinate.U = (float) uCoord;
         intersect.CurrentTextureCoordinate.V = (float) vCoord;
     }
     return true;
 }
コード例 #25
0
ファイル: Box.cs プロジェクト: hksonngan/sharptracing
        public override bool FindIntersection(Ray ray, out Intersection intersection)
        {
            intersection = new Intersection();
            float tNear = float.NegativeInfinity, tFar = float.PositiveInfinity, t1, t2;
            float oX = ray.Origin.X, oY = ray.Origin.Y, oZ = ray.Origin.Z;
            float inv_dX = ray.InvertedDirection.X, inv_dY = ray.InvertedDirection.Y, inv_dZ = ray.InvertedDirection.Z;
            float temp;
            //Sides hitSide = Sides.None;
            //bool x = false, y = false, z = false;

            #region X

            if (ray.Direction.X.NearZero()) {
                if ((oX < this.vLow.X || oX > this.vHigh.X)) {
                    return false;
                }
            } else {
                t1 = (this.vLow.X - oX) * inv_dX;
                t2 = (this.vHigh.X - oX) * inv_dX;

                if (t1 > t2) {
                    temp = t1;
                    t1 = t2;
                    t2 = temp;
                }
                //    hitSide = Sides.Right;
                //} else{
                //    hitSide = Sides.Left;
                //}
                if (t1 > tNear) {
                    tNear = t1;
                }
                if (t2 < tFar) {
                    tFar = t2;
                }
                if (tNear > tFar || tFar < 0.1f) {
                    return false;
                }
            }

            #endregion

            #region Y

            if (ray.Direction.Y.NearZero()) {
                if ((oY < this.vLow.Y || oY > this.vHigh.Y)) {
                    return false;
                }
            } else {
                t1 = (this.vLow.Y - oY) * inv_dY;
                t2 = (this.vHigh.Y - oY) * inv_dY;

                if (t1 > t2) {
                    temp = t1;
                    t1 = t2;
                    t2 = temp;
                }
                //    hitSide = Sides.Top;
                //} else{
                //    hitSide = Sides.Bottom;
                //}
                if (t1 > tNear) {
                    tNear = t1;
                    //y = true;
                }
                if (t2 < tFar) {
                    tFar = t2;
                }
                if (tNear > tFar || tFar < 0.1f) {
                    return false;
                }
            }

            #endregion

            #region Z

            if (ray.Direction.Z.NearZero()) {
                if ((oZ < this.vLow.Z || oZ > this.vHigh.Z)) {
                    return false;
                }
            } else {
                t1 = (this.vLow.Z - oZ) * inv_dZ;
                t2 = (this.vHigh.Z - oZ) * inv_dZ;

                if (t1 > t2) {
                    temp = t1;
                    t1 = t2;
                    t2 = temp;
                }
                //    hitSide = Sides.Back;
                //} else{
                //    hitSide = Sides.Front;
                //}
                if (t1 > tNear) {
                    tNear = t1;
                }
                if (t2 < tFar) {
                    tFar = t2;
                }
                if (tNear > tFar || tFar < 0.1f) {
                    return false;
                }
            }

            #endregion

            intersection.TMin = tNear;
            intersection.TMax = tFar;
            //if (tNear > 0.00001f)
            //{
            //    intersection.TMin = tNear;
            //    intersection.TMax = tFar;
            //}
            //else
            //{
            //    intersection.TMin = tFar;
            //    intersection.TMax = tNear;
            //}
            //if (intersection.TMin < 0.01f) {
            //    return false;
            //}
            intersection.HitPoint = (ray.Origin + (intersection.TMin * ray.Direction));
            intersection.HitPrimitive = this;

            //switch (hitSide)
            //{
            //    case Sides.Left:
            //        intersection.Normal.X = -1.0f;
            //        break;
            //    case Sides.Right:
            //        intersection.Normal.X = 1.0f;
            //        break;
            //    case Sides.Top:
            //        intersection.Normal.Y = 1.0f;
            //        break;
            //    case Sides.Bottom:
            //        intersection.Normal.Y = -1.0f;
            //        break;
            //    case Sides.Front:
            //        intersection.Normal.Z = -1.0f;
            //        break;
            //    case Sides.Back:
            //        intersection.Normal.Z = 1.0f;
            //        break;
            //}

            #region Calculo da Normal

            Sides hitSide = Sides.None;
            if (MathUtil.NearZero(intersection.HitPoint.X - this.vLow.X, 0.01)) {
                intersection.Normal.X = -1;
                hitSide = Sides.Left;
            } else if (MathUtil.NearZero(intersection.HitPoint.X - this.vHigh.X, 0.01)) {
                intersection.Normal.X = 1;
                hitSide = Sides.Right;
            } else if (MathUtil.NearZero(intersection.HitPoint.Y - this.vLow.Y, 0.01)) {
                intersection.Normal.Y = -1;
                hitSide = Sides.Bottom;
            } else if (MathUtil.NearZero(intersection.HitPoint.Y - this.vHigh.Y, 0.01)) {
                intersection.Normal.Y = 1;
                hitSide = Sides.Top;
            } else if (MathUtil.NearZero(intersection.HitPoint.Z - this.vLow.Z, 0.01)) {
                intersection.Normal.Z = -1;
                hitSide = Sides.Back;
            } else if (MathUtil.NearZero(intersection.HitPoint.Z - this.vHigh.Z, 0.01)) {
                intersection.Normal.Z = 1;
                hitSide = Sides.Front;
            }
            //if ((intersection.HitPoint.Z > this.vLow.Z - 0.0001f && intersection.HitPoint.Z < this.vLow.Z + 0.0001f))
            //{
            //    intersection.Normal.Z = -1;
            //}
            //else if ((intersection.HitPoint.Z > this.vHigh.Z - 0.0001f && intersection.HitPoint.Z < this.vHigh.Z + 0.0001f))
            //{
            //    intersection.Normal.Z = 1;
            //}
            //else if ((intersection.HitPoint.X > this.vLow.X - 0.0001f
            //         && intersection.HitPoint.X < this.vLow.X + 0.0001f))
            //{
            //    intersection.Normal.X = -1;
            //}
            //else if ((intersection.HitPoint.X > this.vHigh.X - 0.0001f
            //         && intersection.HitPoint.X < this.vHigh.X + 0.0001f))
            //{
            //    intersection.Normal.X = 1;
            //}
            //else if ((intersection.HitPoint.Y > this.vLow.Y - 0.0001f
            //         && intersection.HitPoint.Y < this.vLow.Y + 0.0001f))
            //{
            //    intersection.Normal.Y = -1;
            //}
            //else if ((intersection.HitPoint.Y > this.vHigh.Y - 0.0001f
            //         && intersection.HitPoint.Y < this.vHigh.Y + 0.0001f))
            //{
            //    intersection.Normal.Y = 1;
            //}

            #endregion

            //Vector3D normal = Vector3D.Zero;
            //switch (hitSide)
            //{
            //    case Sides.Left:
            //        normal.X = -1.0f;
            //        break;
            //    case Sides.Right:
            //        normal.X = 1.0f;
            //        break;
            //    case Sides.Top:
            //        normal.Y = 1.0f;
            //        break;
            //    case Sides.Bottom:
            //        normal.Y = -1.0f;
            //        break;
            //    case Sides.Front:
            //        normal.Z = -1.0f;
            //        break;
            //    case Sides.Back:
            //        normal.Z = 1.0f;
            //        break;
            //}
            //if(normal == intersection.Normal){
            //    Console.WriteLine("------");
            //}

            if (this.material != null && this.material.IsTexturized) {
                float u = 0, v = 0;
                switch (hitSide) {
                    case Sides.Left:
                    case Sides.Right:
                        u = (this.topCoefABC - (intersection.HitPoint * this.normalABC)) * this.inv_TopBottomABC;
                        v = ((intersection.HitPoint * this.normalABD) - this.bottomCoefABD) * this.inv_TopBottomABD;
                        if (intersection.Normal.X.IsEqual(1.0)) {
                            u = 1 - u;
                        }
                        break;
                    case Sides.Top:
                    case Sides.Bottom:
                        u = ((intersection.HitPoint * this.normalACD) - this.bottomCoefACD) * this.inv_TopBottomACD;
                        v = (this.topCoefABC - (intersection.HitPoint * this.normalABC)) * this.inv_TopBottomABC;
                        if (intersection.Normal.Y.IsEqual(-1.0)) {
                            u = 1 - u;
                        }
                        break;
                    case Sides.Front:
                    case Sides.Back:
                        u = ((intersection.HitPoint * this.normalACD) - this.bottomCoefACD) * this.inv_TopBottomACD;
                        v = ((intersection.HitPoint * this.normalABD) - this.bottomCoefABD) * this.inv_TopBottomABD;
                        if (intersection.Normal.Z.IsEqual(1.0)) {
                            u = 1 - u;
                        }
                        break;
                }
                intersection.CurrentTextureCoordinate.U = u;
                intersection.CurrentTextureCoordinate.V = v;
                //int widthTex = this.material.Texture.Width - 1;
                //int heightTex = this.material.Texture.Height - 1;
                //this.material.Color = this.material.Texture.GetPixel((int)(u * widthTex), (int)((v) * heightTex));
            }
            return true;
        }
コード例 #26
0
ファイル: Primitive.cs プロジェクト: hksonngan/sharptracing
 public abstract bool FindIntersection(Ray ray, out Intersection intersect);
コード例 #27
0
ファイル: Quadric.cs プロジェクト: hksonngan/sharptracing
 public override bool FindIntersection(Ray ray, out Intersection intersect)
 {
     intersect = new Intersection();
     Vector3D rayDir = ray.Direction;
     Point3D rayPoint = ray.Origin;
     //this->boundingBox->intersect(line, point, normal, u, v);
     //if(!(*point))
     //{
     //    *point = 0;
     //    *normal = 0;
     //    return;
     //}
     //@see: http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter4.htm
     float Aq_1 = this.a * (rayDir.X * rayDir.X);
     float Aq_2 = this.b * (rayDir.Y * rayDir.Y);
     float Aq_3 = this.c * (rayDir.Z * rayDir.Z);
     float Aq_4 = this.d * rayDir.X * rayDir.Y;
     float Aq_5 = this.e * rayDir.X * rayDir.Z;
     float Aq_6 = this.f * rayDir.Y * rayDir.Z;
     float Bq_1 = 2 * this.a * rayPoint.X * rayDir.X;
     float Bq_2 = 2 * this.b * rayPoint.Y * rayDir.Y;
     float Bq_3 = 2 * this.c * rayPoint.Z * rayDir.Z;
     float Bq_4 = this.d * ((rayPoint.X * rayDir.Y) + (rayPoint.Y * rayDir.X));
     float Bq_5 = this.e * rayPoint.X * rayDir.Z;
     float Bq_6 = this.f * ((rayPoint.Y * rayDir.Z) + (rayDir.Y * rayPoint.Z));
     float Bq_7 = this.g * rayDir.X;
     float Bq_8 = this.h * rayDir.Y;
     float Bq_9 = this.i * rayDir.Z;
     float Cq_1 = this.a * (rayPoint.X * rayPoint.X);
     float Cq_2 = this.b * (rayPoint.Y * rayPoint.Y);
     float Cq_3 = this.c * (rayPoint.Z * rayPoint.Z);
     float Cq_4 = this.d * rayPoint.X * rayPoint.Y;
     float Cq_5 = this.e * rayPoint.X * rayPoint.Z;
     float Cq_6 = this.f * rayPoint.Y * rayPoint.Z;
     float Cq_7 = this.g * rayPoint.X;
     float Cq_8 = this.h * rayPoint.Y;
     float Cq_9 = this.i * rayPoint.Z;
     float Aq = Aq_1 + Aq_2 + Aq_3 + Aq_4 + Aq_5 + Aq_6;
     float Bq = Bq_1 + Bq_2 + Bq_3 + Bq_4 + Bq_5 + Bq_6 + Bq_7 + Bq_8 + Bq_9;
     float Cq = Cq_1 + Cq_2 + Cq_3 + Cq_4 + Cq_5 + Cq_6 + Cq_7 + Cq_8 + Cq_9 + this.j;
     //quadratic equation:   Aqt² + Bqt + Cq = 0
     float t, t0, t1, tMin, tMax;
     if (EquationSolver.SolveQuadric(Aq, Bq, Cq, out t0, out t1) == 0) {
         return false;
     }
     tMin = (float) Math.Min(t0, t1);
     tMax = (float) Math.Max(t0, t1);
     if (tMin > 0.01f) {
         t = tMin;
     } else if (tMax > 0.01f) {
         t = tMax;
     } else {
         return false;
     }
     Point3D tempP = rayPoint + rayDir * t;
     //if (!this.boundBox.IsInside(tempP) && tMax > 0)
     //{
     //    tempP = rayPoint + rayDir * tMax;
     //}
     //bool isInsideBox = this->boundingBox->checkCollision(Box(tempP.getX(), tempP.getY(), tempP.getZ(),
     //														 tempP.getX(), tempP.getY(), tempP.getZ()));
     //if(!isInsideBox && t == tMin && tMax > 0)
     //{
     //    tempP = (*rayPoint) + ((*rayDir) * tMax);
     //    isInsideBox = this->boundingBox->checkCollision(Box(tempP.getX(), tempP.getY(), tempP.getZ(),
     //                                                         tempP.getX(), tempP.getY(), tempP.getZ()));
     //}
     //if(isInsideBox)
     //{
     //*point = new Point(tempP.getX(), tempP.getY(), tempP.getZ());
     //calculating normal
     float nX1 = 2 * this.a * tempP.X;
     float nX2 = this.d * tempP.Y;
     float nX3 = this.e * tempP.Z;
     float nY1 = 2 * this.b * tempP.Y;
     float nY2 = this.d * tempP.X;
     float nY3 = this.f * tempP.Z;
     float nZ1 = 2 * this.c * tempP.Z;
     float nZ2 = this.e * tempP.X;
     float nZ3 = this.f * tempP.Y;
     float normalX = nX1 + nX2 + nX3 + this.g;
     float normalY = nY1 + nY2 + nY3 + this.h;
     float normalZ = nZ1 + nZ2 + nZ3 + this.i;
     intersect.Normal = new Vector3D(normalX, normalY, normalZ);
     intersect.Normal.Normalize();
     intersect.HitPoint = tempP;
     intersect.HitPrimitive = this;
     intersect.TMin = t;
     return true;
     //}
 }
コード例 #28
0
 public override bool FindIntersection(Ray ray, out Intersection intersect)
 {
     throw new Exception("The method or operation is not implemented.");
 }
コード例 #29
0
        //From http://jgt.akpeters.com/papers/GuigueDevillers03/ray_triangle_intersection.html
        public bool FindIntersection(Ray ray, out Intersection intersect)
        {
            intersect = new Intersection();
            Vector3D vect0, vect1, nvect;
            float det, inv_det;

            vect0 = this.Vertex2.Position - this.Vertex1.Position;
            vect1 = this.Vertex3.Position - this.Vertex1.Position;
            Vector3D normalNonNormalized = vect0 ^ vect1;

            /* orientation of the ray with respect to the triangle's normal,
               also used to calculate output parameters*/
            det = -(ray.Direction * normalNonNormalized);
            #if TEST_CULL
            /* define TEST_CULL if culling is desired */
            if (det < MathUtil.Epsilon) return false;

            /* calculate vector from ray origin to this.vertex1 */
            vect0 = this.Vertex1.Position - ray.Origin;
            /* vector used to calculate u and v parameters */
            nvect = ray.Direction ^ vect0;

            /* calculate vector from ray origin to this.vertex2*/
            vect1 = this.Vertex2.Position - ray.Origin;
            /* calculate unnormalized v parameter and test bounds */
            float v = -(vect1 * nvect);

            if (v < 0.0 || v > det) return false;

            /* calculate vector from ray origin to this.vertex3*/
            vect1 = this.Vertex3.Position - ray.Origin;
            /* calculate unnormalized v parameter and test bounds */
            float u = vect1 * nvect;

            if (u < 0.0 || u + v > det) return false;

            /* calculate unormalized t parameter */
            float t = -(vect0 * normalNonNormalized);

            inv_det = 1.0f / det;
            /* calculate u v t, ray intersects triangle */
            u = u * inv_det;
            v = v * inv_det;
            t = t * inv_det;

            #else
            /* the non-culling branch */

            /* if determinant is near zero, ray is parallel to the plane of triangle */
            if (det.NearZero()) {
                return false;
            }

            /* calculate vector from ray origin to this.vertex1 */
            vect0 = this.Vertex1.Position - ray.Origin;

            /* normal vector used to calculate u and v parameters */
            nvect = ray.Direction ^ vect0;

            inv_det = 1.0f / det;
            /* calculate vector from ray origin to this.vertex2*/
            vect1 = this.Vertex2.Position - ray.Origin;

            /* calculate v parameter and test bounds */
            float v = -(vect1 * nvect) * inv_det;

            if (v < 0.0f || v > 1.0f) {
                return false;
            }

            /* calculate vector from ray origin to this.vertex3*/
            vect1 = this.Vertex3.Position - ray.Origin;
            /* calculate v parameter and test bounds */
            float u = (vect1 * nvect) * inv_det;

            if (u < 0.0f || u + v > 1.0f) {
                return false;
            }

            /* calculate t, ray intersects triangle */
            float t = -(vect0 * normalNonNormalized) * inv_det;
            #endif

            //if (t < 100)
            //    return false;
            // return 1;

            //if (t < 100) //FIXME: the correct is t < 0, but dont work, why? tell me you! =P
            //{
            //    return false;
            //}
            if (t >= 0) {
                intersect.TMin = t;
                intersect.Normal = Vector3D.Normal(this.Vertex1.Position, this.Vertex2.Position, this.Vertex3.Position);
                intersect.HitPoint = ray.Origin + (t * ray.Direction);
                this.CurrentBarycentricCoordinate = new BarycentricCoordinate(1.0f - (u + v), u, v);
                intersect.HitPrimitive = this;
                return true;
            }
            return false;
        }
コード例 #30
0
 public abstract RGBColor GetColor(Ray ray);