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; }
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; }
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; }
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; }
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; }
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; }
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; }
//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; }
public abstract RGBColor Shade(Ray ray, Intersection intersection);
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; }
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; }
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; }
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; }
public override bool FindIntersection(Ray ray, out Intersection intersect) { bool intersects = this.sphereFlakeKDTree.FindIntersection(ray, out intersect); intersect.HitPrimitive = this; return intersects; }
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; }
public abstract RGBColor Trace(Ray ray, int depth);
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; }
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; }
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; }
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; }
/// <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); }
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; }
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; }
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; }
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; }
public abstract bool FindIntersection(Ray ray, out Intersection intersect);
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; //} }
public override bool FindIntersection(Ray ray, out Intersection intersect) { throw new Exception("The method or operation is not implemented."); }
//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; }
public abstract RGBColor GetColor(Ray ray);