public RGBA_D Shade(Ray ray, Vector3D hitPoint, uint subIdx, IOpticalSceneObject obj, ISceneManager scene, out Ray reflection, out Ray refraction) { RGBA_D color = RGBA_D.Empty; // needed? // normal.Normalize(); Vector3D normal = obj.GetNormal(hitPoint, subIdx); //color.R = normal.X * 255; //color.G = normal.Y * 255; //color.B = normal.Z * 255; //color.A = 255; //refraction = null; //reflection = null; //return color; /*double len = (ray.Origin - hitPoint).Length(); * len -= 2; * color.R = color.G = color.B = len * 42.5;*/ foreach (Light light in scene.Lights) { Vector3D lv = light.Position - hitPoint; lv.Normalize(); // deal with light ray first (diffuse) if (true)//ray.TraceRayToLight(hitPoint, light.Position)) { // light pixel double cost = Vector3D.GetCosAngle(lv, normal); Vector3D vRefl = Vector3D.Reflect(-lv, normal); vRefl.Normalize(); double cosf = Vector3D.GetCosAngle(ray.DirectionUV, vRefl); double result1 = Math.Max(0, cost) * 255; double result2 = Math.Pow(Math.Max(0, cosf), shininess) * 255; double luminosity = light.LuminosityForPoint(hitPoint); double r = ((clr.R * diffuse * light.Clr3D.X * result1) + (light.Clr3D.X * result2)) * luminosity; double g = ((clr.G * diffuse * light.Clr3D.Y * result1) + (light.Clr3D.Y * result2)) * luminosity; double b = ((clr.B * diffuse * light.Clr3D.Z * result1) + (light.Clr3D.Z * result2)) * luminosity; color.R += r; color.G += g; color.B += b; } } // add ambient double alpha = 1 - transmission; color.R += (diffuse * scene.Ambient.R + (clr.R * emmissive)) * 255; //color.R *= alpha; color.G += (diffuse * scene.Ambient.G + (clr.G * emmissive)) * 255; //color.G *= alpha; color.B += (diffuse * scene.Ambient.B + (clr.B * emmissive)) * 255; //color.B *= alpha; color.A = alpha * 255; // blend texture (if any) /*if (texture != null) * { * Vector2D tCoord = obj.GetTexCoord(hitPoint, subIdx); * // clamp for now * if (tCoord.X < 0) * tCoord.X = 0; * if (tCoord.Y < 0) * tCoord.Y = 0; * if (tCoord.X > 1) * tCoord.X = 1; * if (tCoord.Y > 1) * tCoord.Y = 1; * * int tX = (int)(tCoord.X * (texture.Width - 1)); * int tY = (int)(tCoord.Y * (texture.Height - 1)); * * Color tClr = ((Bitmap)texture).GetPixel(tX, tY); * color.R = (color.R + tClr.R) / 2; * color.G = (color.G + tClr.G) / 2; * color.B = (color.B + tClr.B) / 2; * }*/ if (ray.Intensity > 0) { /*if (this.reflection > 0) * { * Vector3D refl = Vector3D.Reflect(ray.DirectionUV, normal); * reflection = new Ray(hitPoint, refl, ray.Intensity * this.reflection, ray.Length, ray.MaxLength, ray.scene); * } * else*/ reflection = null; /*if (transmission > 0) * refraction = new Ray(hitPoint, Vector3D.Normalize(Vector3D.Refract(1, 1.33, -ray.DirectionUV, normal)), ray.Intensity * transmission, ray.Length, ray.MaxLength, ray.scene); * else*/ refraction = null; } else { reflection = refraction = null; } ray.Intensity = 0; return(color); }
public static double GetCosAngle(Vector3D v1, Vector3D v2) { /* incident angle // inters pt (i) double ix, iy, iz; ix = px+t*vx; iy = py+t*vy; iz = pz+t*vz; // normal at i double nx, ny, nz; nx = ix - cx; ny = iy - cy; nz = iz - cz; */ v1.Normalize(); v2.Normalize(); // cos(t) = (v.w) / (|v|.|w|) double n = (v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z); double d = (modv(v1) * modv(v2)); if (Math.Abs(d) < 1.0E-10) return 0; return n / d; }
public void Trace() { // project into scene as inital rejection test if (scene.TestForContents(view, area, maxLength)) { // sub-divide task area until all 4 are positive for matches if (!divide) { // no divisions so run the task immediately // just run all rays here for now double xScale = 0.5 / view.Area.Width; //area.Width; double yScale = 0.5 / view.Area.Height; //area.Height; double yIdx = -0.25 + (xScale * 0.5) + (yScale * area.Top); double filterShiftX = xScale * 0.5; double filterShiftY = yScale * 0.5; for (int y = area.Top; y < area.Bottom; y++) { double xIdx = -0.25 + (yScale * 0.5) + (xScale * area.Left); for (int x = area.Left; x < area.Right; x++) { Vector3D offset = ((view.XUV * xIdx) + (view.YUV * yIdx)); Vector3D rayDir = offset + view.Direction; rayDir.Normalize(); Ray ray = new Ray(view.Centre, rayDir, 1, 0, maxLength, scene); RGBA_D value = ray.Trace(ray); // do anti-alias pass/pixel // TODO: Do more if on left and/or top edge RGBA_D aaValue = RGBA_D.Empty; if (frameData.AALayer != null) { offset = ((view.XUV * (xIdx + filterShiftX)) + (view.YUV * (yIdx + filterShiftY))); rayDir = offset + view.Direction; rayDir.Normalize(); ray = new Ray(view.Centre, rayDir, 1, 0, maxLength, scene); aaValue = ray.Trace(ray); if (aaValue != RGBA_D.Empty) { int index = ((y + 1) * (frameData.Width + 2)) + (x + 1); lock (frameData) { // pack to bytes float val = ((byte)aaValue.R | (byte)aaValue.G << 8 | (byte)aaValue.B << 16 | (byte)value.A << 24); frameData.AALayer[index] = val; } } } value.Normalize(); aaValue.Normalize(); if (value != RGBA_D.Empty) { // write to frame buffer int index = (y * frameData.Width) + x; lock (frameData) { // pack to bytes float val = ((byte)value.R | (byte)value.G << 8 | (byte)value.B << 16 | (byte)value.A << 24); frameData.Data[index] = val; } } /*else * { * int index = (y * frameData.Width) + x; * lock (frameData) * { * // pack to bytes * float val = ((byte)area.Left /2 | (byte)area.Top /2 << 8 | (byte)0 << 16 | (byte)255 << 24); * frameData.Data[index] = val; * } * }*/ xIdx += xScale; } yIdx += yScale; } // pass AA area on to control // just create group outline for now /*for (int x = area.Left; x < area.Right; x++) * { * lock (frameData) * { * // pack to bytes * frameData.Data[x] = (255 | (byte)0 << 255 | (byte)0 << 255 | (byte)255 << 24); * } * } * int index2 = view.Area.Width * (area.Height - 1); * for (int x = area.Left; x < area.Right; x++) * { * lock (frameData) * { * // pack to bytes * frameData.Data[index2 + x] = (255 | (byte)0 << 255 | (byte)0 << 255 | (byte)255 << 24); * } * }*/ dispatch.RaysTraced(area.Width * area.Height); } else { SubDivideTask(area, maxLength, 0); } } dispatch.ExecutionComplete(); }