public static AABB surrounding_box(AABB box0, AABB box1) { Vec3 small = new Vec3(XMath.Min(box0.min.x, box1.min.x), XMath.Min(box0.min.y, box1.min.y), XMath.Min(box0.min.z, box1.min.z)); Vec3 big = new Vec3(XMath.Max(box0.max.x, box1.max.x), XMath.Max(box0.max.y, box1.max.y), XMath.Max(box0.max.z, box1.max.z)); return(new AABB(small, big)); }
// https://developer.download.nvidia.com/cg/atan2.html public static float Atan2(float y, float x) { float t0, t1, t3, t4; t3 = XMath.Abs(x); t1 = XMath.Abs(y); t0 = XMath.Max(t3, t1); t1 = XMath.Min(t3, t1); t3 = 1f / t0; t3 = t1 * t3; t4 = t3 * t3; t0 = -0.013480470f; t0 = t0 * t4 + 0.057477314f; t0 = t0 * t4 - 0.121239071f; t0 = t0 * t4 + 0.195635925f; t0 = t0 * t4 - 0.332994597f; t0 = t0 * t4 + 0.999995630f; t3 = t0 * t3; t3 = (XMath.Abs(y) > XMath.Abs(x)) ? 1.570796327f - t3 : t3; t3 = (x < 0) ? 3.141592654f - t3 : t3; t3 = (y < 0) ? -t3 : t3; return(t3); }
public void RenderPseudoColor(ref WriteableBitmap bmp, short max = -1) { var redBand = 11 - 1; var greenBand = 17 - 1; var blueBand = 38 - 1; double[] minMax = new double[2]; _dataset.GetRasterBand(redBand).ComputeRasterMinMax(minMax, 0); short redMax = (short)(minMax[1]); _dataset.GetRasterBand(greenBand).ComputeRasterMinMax(minMax, 0); short greenMax = (short)(minMax[1]); _dataset.GetRasterBand(blueBand).ComputeRasterMinMax(minMax, 0); short blueMax = (short)(minMax[1]); if (max == -1) { max = XMath.Max(blueMax, Math.Max(redMax, greenMax)); } uint[] data = CalculationWrappers.CalculatePseudoColor(_datasetV.View, redBand, greenBand, blueBand, max); bmp = new WriteableBitmap(new PixelSize(width, height), new Vector(1, 1), Avalonia.Platform.PixelFormat.Rgba8888); using (var buf = bmp.Lock()) { IntPtr ptr = buf.Address; Marshal.Copy((int[])(object)data, 0, ptr, data.Length); } }
public static void CalculateSignatureLengthDerivative(Index2 index, ArrayView3D <float> output, ArrayView3D <byte> input) { var x = index.X; var y = index.Y; if (x == 0) { x = 1; } if (x == input.Width - 1) { x = input.Width - 2; } if (y == 0) { y = 1; } if (y == input.Height - 1) { y = input.Height - 2; } var depth = input.Depth; float xDiffComponentSum = 0; float yDiffComponentSum = 0; for (int i = 0; i < depth; i++) { var val1 = input[x - 1, y, i]; if (val1 < 0) { val1 = 0; } var val2 = input[x + 1, y, i]; if (val2 < 0) { val1 = 0; } var xDiff = val2 - val1; xDiffComponentSum += xDiff * xDiff; val1 = input[x, y - 1, i]; if (val1 < 0) { val1 = 0; } val2 = input[x, y + 1, i]; if (val2 < 0) { val1 = 0; } var yDiff = val2 - val1; yDiffComponentSum += yDiff * yDiff; } var xDiffLength = XMath.Sqrt(xDiffComponentSum); var yDiffLength = XMath.Sqrt(yDiffComponentSum); output[index.X, index.Y, 0] = xDiffLength; output[index.X, index.Y, 1] = yDiffLength; output[index.X, index.Y, 2] = XMath.Max(xDiffLength, yDiffLength); }
public static PicturesData CalculateSignatureLengthDerivative(ArrayView3D <byte> imageView, bool normalize) { PicturesData result = new PicturesData(); var slice = imageView.GetSliceView(0); var picIndex = new Index3(slice.Extent.X, slice.Extent.Y, 3); using (var calcBuffer = GpuContext.Instance.Accelerator.Allocate <float>(picIndex)) using (var byteBuf = GpuContext.Instance.Accelerator.Allocate <byte>(picIndex)) using (var imageBuffer = GpuContext.Instance.Accelerator.Allocate <uint>(picIndex)) { if (normalize) { BCalculateSignatureLengthDerivativeWithNormalizationKernel(slice.Extent, calcBuffer.View, imageView); } else { BCalculateSignatureLengthDerivativeKernel(slice.Extent, calcBuffer.View, imageView); } GpuContext.Instance.Accelerator.Synchronize(); var array = calcBuffer.GetAsArray(); var maxBand1 = array.Take(slice.Extent.Size).Max(); var maxBand2 = array.Skip(slice.Extent.Size).Take(slice.Extent.Size).Max(); //var maxBand3 = array.Skip(slice.Extent.Size * 2).Max(); var maxBand3 = XMath.Max(maxBand1, maxBand2); NormalizeLengthMapKernel(slice.Extent, calcBuffer, 0, maxBand1); GpuContext.Instance.Accelerator.Synchronize(); NormalizeLengthMapKernel(slice.Extent, calcBuffer, 1, maxBand2); GpuContext.Instance.Accelerator.Synchronize(); NormalizeLengthMapKernel(slice.Extent, calcBuffer, 2, maxBand3); GpuContext.Instance.Accelerator.Synchronize(); FloatToByteKernel(calcBuffer.Extent.Size, calcBuffer.AsLinearView(), byteBuf.AsLinearView()); GpuContext.Instance.Accelerator.Synchronize(); result.rawPicture = byteBuf.GetAsArray().Skip(slice.Extent.Size * 2).ToArray(); PinConvertFromByteKernel(slice.Extent.Size, imageBuffer.GetSliceView(0).AsLinearView(), byteBuf.GetSliceView(0).AsLinearView(), 1.0, 0); PinConvertFromByteKernel(slice.Extent.Size, imageBuffer.GetSliceView(1).AsLinearView(), byteBuf.GetSliceView(1).AsLinearView(), 1.0, 0); PinConvertFromByteKernel(slice.Extent.Size, imageBuffer.GetSliceView(2).AsLinearView(), byteBuf.GetSliceView(2).AsLinearView(), 1.0, 0); GpuContext.Instance.Accelerator.Synchronize(); var img = imageBuffer.GetAsArray(); var size = slice.Extent.Size; var buf = new uint[size]; Array.Copy(img, 0, buf, 0, size); result.xPicture = buf; buf = new uint[size]; Array.Copy(img, size, buf, 0, size); result.yPicture = buf; buf = new uint[size]; Array.Copy(img, size * 2, buf, 0, size); result.xyPicture = buf; } return(result); }
public static Vector3 GetGGXMicrofacet(XorShift64Star random, float roughness, Vector3 normal) { float rand1 = random.NextFloat(); float rand2 = random.NextFloat(); Vector3 B = GetPerpendicularVector(normal); Vector3 T = Vector3.Cross(B, normal); float a2 = roughness * roughness; float cosThetaH = XMath.Sqrt(XMath.Max(0f, (1f - rand1) / ((a2 - 1f) * rand1 + 1f))); float sinThetaH = XMath.Sqrt(XMath.Max(0f, 1f - cosThetaH * cosThetaH)); float phiH = rand2 * XMath.PI * 2f; return(T * (sinThetaH * XMath.Cos(phiH)) + B * (sinThetaH * XMath.Sin(phiH)) + normal * cosThetaH); }
public static void AccumulateEdges(Index2 index, ArrayView2D <uint> output, ArrayView2D <byte> pearson, ArrayView2D <byte> canny, ArrayView2D <byte> signLengthByte, ArrayView2D <byte> signLengthShort) { uint r = (uint)XMath.Max(pearson[index] / 3, canny[index]); if (r > 254) { r = 254; } uint g = (uint)(XMath.Max(pearson[index] / 3, signLengthByte[index])); if (g > 254) { g = 254; } uint b = (uint)(XMath.Max(pearson[index] / 3, signLengthShort[index])); if (b > 254) { b = 254; } uint value = (uint)(r + (g << 8) + (b << 16) + (255 << 24)); output[index] = value; }
public bool hit(Ray ray, float tMin, float tMax) { float minV = (min.x - ray.a.x) / ray.b.x; float maxV = (max.x - ray.a.x) / ray.b.x; float t1 = XMath.Max(minV, maxV); float t0 = XMath.Min(minV, maxV); tMin = XMath.Max(t0, tMin); tMax = XMath.Min(t1, tMax); if (tMax <= tMin) { return(false); } minV = (min.y - ray.a.y) / ray.b.y; maxV = (max.y - ray.a.y) / ray.b.y; t1 = XMath.Max(minV, maxV); t0 = XMath.Min(minV, maxV); tMin = XMath.Max(t0, tMin); tMax = XMath.Min(t1, tMax); if (tMax <= tMin) { return(false); } minV = (min.z - ray.a.z) / ray.b.z; maxV = (max.z - ray.a.z) / ray.b.z; t1 = XMath.Max(minV, maxV); t0 = XMath.Min(minV, maxV); tMin = XMath.Max(t0, tMin); tMax = XMath.Min(t1, tMax); if (tMax <= tMin) { return(false); } return(true); }
public static float Schlick(Vector3 nrm, Vector3 dir, float n1, float n2) { float r0 = (n1 - n2) / (n1 + n2); r0 *= r0; float cosI = XMath.Max(Vector3.Dot(-nrm, dir), 0f); if (n1 > n2) { float n = n1 / n2; float sinT2 = n * n * (1f - cosI * cosI); if (sinT2 > 1.0) { return(1f); } cosI = XMath.Sqrt(1f - sinT2); } float x = 1f - cosI; return(r0 + (1f - r0) * x * x * x * x * x); }
static void NearFieldKernel1( Index2 index, // Contains (sample, line) First dimension changes fastest int target_line, // row within the 128 x 128 target patch int target_sample, // column int slope_idx_start, int slope_idx_stop, ArrayView <short> gpu_terrain, ArrayView <float> gpu_range, ArrayView <float> gpu_slope, ArrayView <float> gpu_rise, ArrayView <int> gpu_range_limit) { var flip = -LonFactor; // From ILGPU source code: public int ComputeLinearIndex(Index2 dimension) => Y * dimension.X + X; var rise_idx = index.ComputeLinearIndex(Dimension); var rise = gpu_rise[rise_idx]; var center_line = target_line + index.Y; var center_sample = target_sample + index.X; var center_idx = center_line * TerrainSize + center_sample; var center_height = 0.5f * gpu_terrain[center_idx]; GetVector3d(center_line, center_sample, center_height, out float center_x, out float center_y, out float center_z); center_z *= flip; for (var slope_idx = slope_idx_start; slope_idx < slope_idx_stop; slope_idx++) { var slope = gpu_slope[slope_idx]; // Work out the direction vector var ray_rad = XMath.PI * 2f * slope_idx / cpu_slope_size; // 0 deg in ME frame points toward the earth var ray_cos = XMath.Cos(ray_rad); // varies the line var ray_sin = XMath.Sin(ray_rad); // varies the sample // iterate over the ranges var range_limit = gpu_range_limit[slope_idx]; for (var range_idx = 0; range_idx < range_limit; range_idx++) { var range = gpu_range[range_idx]; var caster_line = center_line + ray_sin * range; var caster_sample = center_sample + ray_cos * range; var x1 = (int)caster_sample; // Calculate the caster point by interpolating between four points from the points array var y1 = (int)caster_line; int x2 = x1 + 1; int y2 = y1 + 1; var q11_idx = y1 * TerrainSize + x1; var q11 = gpu_terrain[q11_idx]; var q12_idx = q11_idx + TerrainSize; var q12 = gpu_terrain[q12_idx]; // First interpolation across rows (line) var q1_line = q11 + (caster_line - y1) * (q12 - q11); var q21_idx = q11_idx + 1; var q21 = gpu_terrain[q21_idx]; var q22_idx = q11_idx + TerrainSize + 1; var q22 = gpu_terrain[q22_idx]; // Second interpolation across rows var q2_line = q21 + (caster_line - y1) * (q22 - q21); // Interpolate across samples and convert to meters var caster_height = q1_line + (caster_sample - x1) * (q2_line - q1_line); caster_height *= 0.5f; GetVector3d(caster_line, caster_sample, caster_height, out float caster_x, out float caster_y, out float caster_z); caster_z *= flip; var dx = caster_x - center_x; var dy = caster_y - center_y; var d = XMath.Sqrt(dx * dx + dy * dy); // horizontal distance in moon radius units var light_ray_height = caster_z - slope * d; // negative slope gets higher as light ray goes toward the center var ray_rise_height = light_ray_height - center_z; // moon radius units var ray_rise_meters = ray_rise_height * 1000f; // Alternative //var dInMeters = d * 1000f; //var deltaHeightInMeters = (caster_z - center_z) * 1000f; //var rise2 = deltaHeightInMeters - dInMeters * slope; rise = XMath.Max(rise, ray_rise_meters); } } gpu_rise[rise_idx] = rise; }
public static void CalculateSignatureLengthDerivativeWithNormalization(Index2 index, ArrayView3D <float> output, ArrayView3D <short> input, short maxValue) { var x = index.X; var y = index.Y; if (x == 0) { x = 1; } if (x == input.Width - 1) { x = input.Width - 2; } if (y == 0) { y = 1; } if (y == input.Height - 1) { y = input.Height - 2; } var depth = input.Depth; int x1ComponentSum = 0; int x2ComponentSum = 0; int y1ComponentSum = 0; int y2ComponentSum = 0; for (int i = 0; i < depth; i++) { var val1 = XMath.Clamp(input[x - 1, y, i], (short)0, maxValue); var val2 = XMath.Clamp(input[x + 1, y, i], (short)0, maxValue); x1ComponentSum += val1 * val1; x2ComponentSum += val2 * val2; val1 = XMath.Clamp(input[x, y - 1, i], (short)0, maxValue); val2 = XMath.Clamp(input[x, y + 1, i], (short)0, maxValue); y1ComponentSum += val1 * val1; y2ComponentSum += val2 * val2; } float x1Length = XMath.Sqrt(x1ComponentSum); float x2Length = XMath.Sqrt(x2ComponentSum); float y1Length = XMath.Sqrt(y1ComponentSum); float y2Length = XMath.Sqrt(y2ComponentSum); float xDiffComponentSum = 0; float yDiffComponentSum = 0; for (int i = 0; i < depth; i++) { var val1 = XMath.Clamp(input[x - 1, y, i], (short)0, maxValue); var val2 = XMath.Clamp(input[x + 1, y, i], (short)0, maxValue); float xDiff = (val2 / x2Length) - (val1 / x1Length); xDiffComponentSum += xDiff * xDiff; val1 = XMath.Clamp(input[x, y - 1, i], (short)0, maxValue); val2 = XMath.Clamp(input[x, y + 1, i], (short)0, maxValue); float yDiff = (val2 / y2Length) - (val1 / y1Length); yDiffComponentSum += yDiff * yDiff; } var xDiffLength = XMath.Sqrt(xDiffComponentSum); var yDiffLength = XMath.Sqrt(yDiffComponentSum); output[index.X, index.Y, 0] = xDiffLength; output[index.X, index.Y, 1] = yDiffLength; output[index.X, index.Y, 2] = XMath.Max(xDiffLength, yDiffLength); }
private static void ColorRay(int index, Ray ray, dFramebuffer framebuffer, dWorldBuffer world, XorShift64Star rng, Camera camera) { Vec3 attenuation = new Vec3(1f, 1f, 1f); Vec3 lighting = new Vec3(); Ray working = ray; bool attenuationHasValue = false; float minT = 0.1f; for (int i = 0; i < camera.maxBounces; i++) { HitRecord rec = GetWorldHit(working, world, minT); if (rec.materialID == -1) { if (i == 0 || attenuationHasValue) { framebuffer.DrawableIDBuffer[index] = -2; } float t = 0.5f * (working.b.y + 1.0f); attenuation *= (1.0f - t) * new Vec3(1.0f, 1.0f, 1.0f) + t * new Vec3(0.5f, 0.7f, 1.0f); break; } else { if (i == 0) { framebuffer.ZBuffer[index] = rec.t; framebuffer.DrawableIDBuffer[index] = rec.drawableID; } ScatterRecord sRec = Scatter(working, rec, rng, world.materials, minT); if (sRec.materialID != -1) { attenuationHasValue = sRec.mirrorSkyLightingFix; attenuation *= sRec.attenuation; working = sRec.scatterRay; } else { framebuffer.DrawableIDBuffer[index] = -1; break; } } for (int j = 0; j < world.lightSphereIDs.Length; j++) { Sphere s = world.spheres[world.lightSphereIDs[j]]; Vec3 lightDir = s.center - rec.p; HitRecord shadowRec = GetWorldHit(new Ray(rec.p, lightDir), world, minT); if (shadowRec.materialID != -1 && (shadowRec.p - rec.p).length() > lightDir.length() - (s.radius * 1.1f)) // the second part of this IF could probably be much more efficent { MaterialData material = world.materials[shadowRec.materialID]; if (material.type != 1) { lightDir = Vec3.unitVector(lightDir); lighting += material.color * XMath.Max(0.0f, Vec3.dot(lightDir, rec.normal)); lighting *= XMath.Pow(XMath.Max(0.0f, Vec3.dot(-Vec3.reflect(rec.normal, -lightDir), ray.b)), material.reflectivity) * material.color; } } } } int rIndex = index * 3; int gIndex = rIndex + 1; int bIndex = rIndex + 2; framebuffer.ColorFrameBuffer[rIndex] = attenuation.x; framebuffer.ColorFrameBuffer[gIndex] = attenuation.y; framebuffer.ColorFrameBuffer[bIndex] = attenuation.z; framebuffer.LightingFrameBuffer[rIndex] = lighting.x; framebuffer.LightingFrameBuffer[gIndex] = lighting.y; framebuffer.LightingFrameBuffer[bIndex] = lighting.z; }
private static float GPUProximalOperator(float x, float lipschitz, float lambda, float alpha) => XMath.Max(x - lambda * alpha, 0.0f) / (lipschitz + lambda * (1 - alpha));