public Ray(Ray r) { p = new Vector3(r.p); dir = new Vector3(r.dir); mint = r.mint; maxt = r.maxt; }
public RayContext(Ray _ray) { ray = new Ray(_ray); traceLevel = 0; traceLevelGI = 0; ignoreID = -1; }
public static RayContext createNewContext(RayContext previousContext, Ray newRay) { RayContext newContext = new RayContext(newRay); newContext.traceLevel += previousContext.traceLevel + 1; newContext.scene = previousContext.scene; newContext.ignorePrimitive = previousContext.hitData.hitPrimitive; newContext.m_renderer = previousContext.m_renderer; newContext.ignoreID = previousContext.ignoreID; newContext.m_rndContext = previousContext.m_rndContext.createNew(previousContext.randomIndex, 2); return newContext; }
public override Ray getRay(double x, double y) { double au = System.Math.Tan( 0.0174532925*((fov*0.5)) );// double av = au / aspect; double du = -au + (2.0 * au * x); double dv = -av + (2.0 * av * (1-y)); Ray ray = new Ray(); ray.p.set(pos); Vector3 rayDir = new Vector3(du, dv, -1.0f); ray.dir.x = right.x*rayDir.x + up.x*rayDir.y + forward.x*rayDir.z; ray.dir.y = right.y*rayDir.x + up.y*rayDir.y + forward.y*rayDir.z; ray.dir.z = right.z*rayDir.x + up.z*rayDir.y + forward.z*rayDir.z; return ray; }
public override bool intersect( Ray ray, IntersectionData hitData ) { Vector3 d = ray.dir; Vector3 p = ray.p; //лъчът преминава в локални координати на сферата p = p - center; double A = d * d; double B = 2 * (d * p); double C = (p * p) - (radius * radius); //връщаме лъча в коодинати на сцената p = p + center; double D = (B * B) - (4 * A * C); if (D < 0) return false; else D = System.Math.Sqrt(D); double t0 = (-B - D) / (2 * A); double t1 = (-B + D) / (2 * A); if (t1 < t0) t0 = t1; hitData.hitT = t0; Vector3 wp = p + d * t0; hitData.hitPos = wp; hitData.hitNormal = wp - center; hitData.hitNormal.normalize(); double u = (System.Math.PI + System.Math.Atan2(wp.z - center.z, wp.x - center.x)) / (System.Math.PI * 2); double v = 1.0 - ((System.Math.PI / 2) + System.Math.Asin((wp.y - center.y) / radius)) / System.Math.PI; hitData.textureUVW = new Vector3(u, v, 0); return true; }
public abstract bool intersect( Ray ray, IntersectionData hitData );
public static RayContext startFromPixel(Ray startRay, int pixX, int pixY, Scene _scene, IIntegrator integrator) { RayContext newContext = new RayContext(startRay); newContext.scene = _scene; newContext.m_renderer = integrator; newContext.m_rndContext = new RandomContext(2, 17 * pixX + 73 * pixY); return newContext; }
public static RayContext createNewContextGI(RayContext previousContext, Ray newRay) { RayContext newContext = createNewContext(previousContext, newRay); newContext.traceLevelGI += previousContext.traceLevelGI + 1; return newContext; }
public override bool intersect( Ray ray, IntersectionData hitData ) { Vector3 e1, e2; e1 = v[1] - v[0];// e1 = edge v0 to v1 e2 = v[2] - v[0];// e2 = edge v0 to v2 Vector3 pvec = ray.dir ^ e2;// pvec = cross(dir,e2) double det = e1 * pvec;// determinant = dot(e1,pvec) if (det < 1e-6f && det > -1e-6f) return false; // if det close to zero -> ray lies in the plane double inv_det = 1.0f / det;// inverse determinant Vector3 tvec = ray.p - v[0];// distance v0 to ray origin double u = inv_det * (tvec * pvec);// u = dot(tvec,pvec) / det if (u < -1e-6f || u > (1.0f + 1e-6f)) return false;// if u outside triangle return Vector3 qvec = tvec ^ e1;// qvec = cross(tvec,e1) double t = inv_det * (e2 * qvec);// t = dot(e2,qvec) / det if (t < ray.mint || t > ray.maxt) return false;// return false if t is outside range double uvV = inv_det * (ray.dir * qvec);// v = dot(dir,qvec) / det if (uvV < -1e-6f || (u + uvV) > (1.0f + 1e-6f)) return false;// if v outside triangle return hitData.hitT = t; hitData.hitNormal = e1 ^ e2; hitData.hitNormal.normalize(); hitData.textureUVW = ((1 - u - uvV) * tc[0]) + (u * tc[1]) + (uvV * tc[2]); hitData.shaderID = shaderID; return true; }
public Color3 illuminate(RayContext rayContext, BRDF brdf) { Ray newRay = new Ray(); double invPdf = 0; //във finalColor ще сумираме резултатния цвят Color3 finalColor = new Color3(); //задаваме максималната бройка лъчи //с които ще проследяваме грапави отражения int numSamples = 10; int curSample = 0; //номер на текущ лъч for (curSample = 0; curSample < numSamples; curSample++) { //генерирме двойка случайни числа (ru, rv) double ru = rayContext.getRandom(0, curSample); double rv = rayContext.getRandom(1, curSample); //искаме brdf да конструира лъч използвайки (ru, rv) bool isValidSample = brdf.getSample(rayContext, ru, rv, out newRay.dir, out invPdf); if (!isValidSample) continue; //конструираме нов лъч от текущата точка //и го обвиваме във собствен контекст newRay.p = rayContext.hitData.hitPos; RayContext newContext = RayContext.createNewContext(rayContext, newRay); //извикваме функцията shade, която проследява //лъча в сцената и го осветява rayContext.scene.shade(newContext); double cosT = rayContext.hitData.hitNormal * (newRay.dir); if (cosT < 0.0) cosT *= -1.0; double pdf; Color3 w = new Color3(1, 1, 1); //пресмятаме, каква част от светлината ще отрази BRFD-a w = brdf.eval(rayContext, newRay.dir, out pdf); if (!brdf.isSingular()) { w *= cosT * invPdf; } //добавяме енергията на новия лъч finalColor += newContext.resultColor * w; //if (Double.IsNaN(finalColor.getIntensity())) // break; if (brdf.isSingular()) break; } //сумираме енергията от всички лъчи if (curSample > 0) finalColor *= 1.0 / (double)curSample; return finalColor; }
public bool traceShadowRay(Ray shadowRay, RayContext origContext) { RayContext rayContext = RayContext.createNewContext(origContext, shadowRay); rayContext.ignorePrimitive = origContext.hitData.hitPrimitive; rayContext.isShadowRay = true; return trace(rayContext); }
public LightSample() { color = new Color3(); shadowRay = new Ray(); }