public RGBA_D Shade(Ray ray, Vector3D pos, uint subIdx, out Ray reflection, out Ray refraction, ISceneManager scene) { if (shader != null) return shader.Shade(ray, pos, subIdx, this, scene, out reflection, out refraction); reflection = null; refraction = null; return RGBA_D.Empty; }
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 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(); }
public void QueueDispatch(Ray ray) { throw new System.NotImplementedException(); }