private Vector3 DirectLightning(Vector3 point, ResFindShape res, float dist, Light light) { //Create a ray from the shape to the light Ray r2 = new Ray(point, Vector3.Subtract(light.origine, point)); bool seeTheLight = true; foreach (Shape s in m_fastStruct) { float coeff = s.RayIntersect(r2, out res.shape); //If we hit something before the light if (coeff != -1 && coeff < 1) { seeTheLight = false; break; } } if (seeTheLight) { Vector3 powerReceived = Vector3.Multiply(light.power, 1 / (dist * dist)); return(powerReceived); } else { return(new Vector3(0, 0, 0)); } }
private ResFindShape SearchShapeHit(Ray rayon) { ResFindShape res = new ResFindShape(); res.coeff = float.MaxValue; foreach (Shape s in m_fastStruct) { Shape tempShape; float temp = s.RayIntersect(rayon, out tempShape); if (temp != -1 && temp < res.coeff) { res.coeff = temp; res.shape = tempShape; } } return(res); }
private Vector3 SendRay(Ray rFromCam, int cpt = 0) { ResFindShape res = SearchShapeHit(rFromCam); //If we hit a shape if (res.coeff != float.MaxValue && res.shape != null) { cpt++; Vector3 pointOnShape = rFromCam.GetPointAt(res.coeff); // Move hit point slightly on the outside to be sure we're not inside the shape Vector3 normalOnPointOnShape = res.shape.GetNormal(pointOnShape); Vector3 pointOnShapeDecal = Vector3.Add(pointOnShape, Vector3.Multiply(normalOnPointOnShape, 0.5f)); Vector3 indirectLight = new Vector3(0, 0, 0); if (cpt < 10) // Bounce { Vector3 newDir; if (res.shape.material.mat == Materials.Mirror) { //Reflexion direction newDir = Vector3.Add( Vector3.Multiply(2 * -Vector3.Dot(rFromCam.direction, normalOnPointOnShape), normalOnPointOnShape) , rFromCam.direction); indirectLight = res.shape.material.albedo * IndirectLightning(pointOnShapeDecal, newDir, res, cpt); } else if (res.shape.material.mat == Materials.Glass && m_random.Next(2) == 0) { newDir = Vector3.Add( Vector3.Multiply(2 * -Vector3.Dot(rFromCam.direction, normalOnPointOnShape), normalOnPointOnShape) , rFromCam.direction); indirectLight = res.shape.material.albedo * IndirectLightning(pointOnShapeDecal, newDir, res, cpt); } else { newDir = RandomBounce(pointOnShapeDecal); indirectLight = IndirectLightning(pointOnShapeDecal, newDir, res, cpt); } } if (res.shape.material.mat != Materials.Mirror) { Vector3 temp = Vector3.Zero; foreach (Light light in lights) { Vector3 l = Vector3.Subtract(light.origine, pointOnShapeDecal); float dist = l.Length(); l = Vector3.Normalize(l); Vector3 lightEmmited = Vector3.Divide( Vector3.Multiply(res.shape.material.albedo, Math.Max(Math.Min(Vector3.Dot(normalOnPointOnShape, l), 1.0f), 0.0f)) , (float)Math.PI); Vector3 directLight = DirectLightning(pointOnShapeDecal, res, dist, light); temp += Vector3.Add(Vector3.Multiply(lightEmmited, directLight), indirectLight); } return(temp); } else { return(indirectLight); } } return(new Vector3(0.1f, 0.1f, 0.25f)); //Nothing is hit, nothing to return, so return atmosphere value --ATMOSPHERE }
private Vector3 IndirectLightning(Vector3 point, Vector3 dir, ResFindShape res, int cpt) { Ray mirrorRayon = new Ray(point, dir); return(Vector3.Multiply(res.shape.material.albedo, SendRay(mirrorRayon, cpt))); }