public static float CubeDE(float3 p, float3 c, float di) { float3 o = S(p, c); float d = DeviceFunction.Max(DeviceFunction.Abs(o.x), DeviceFunction.Max(DeviceFunction.Abs(o.y), DeviceFunction.Abs(o.z))); return(d - di / 2); }
public static Matrix Phansalkar(Matrix input, int radius) { var width = input.Width; var height = input.Height; var data = (float[])input; var result = (float[])new Matrix(width, height); var p = 2.5f; var q = 10; var k = 0.15; var r = 0.4; var dimension = GetKernelDimension(height); Gpu.Default.Launch(KernelBuilder(tid => { var index = tid * width; for (var x = 0; x < width; x++) { var sum = 0f; var count = 0; for (var ky = -radius; ky <= radius; ky++) { var py = tid + ky; var pindex = py * width; for (var kx = -radius; kx <= radius; kx++) { var px = x + kx; if (px >= 0 && px < width && py >= 0 && py < height) { sum += data[pindex + px] / byte.MaxValue; count++; } } } var mean = sum / count; var variance = DeviceFunction.Abs(sum / count - mean); var deviation = DeviceFunction.Sqrt(variance / count); var threshold = mean * (1f + p * DeviceFunction.Exp(-q * mean) + k * (deviation / r - 1)); result[index + x] = data[index + x] / byte.MaxValue > threshold ? byte.MaxValue : 0; } }, height), new LaunchParam(dimension, dimension)); return(new Matrix(width, height, result)); }
public static void MarchRay(deviceptr <float3> directions, deviceptr <byte> pixelValues, float3 camera, float3 light, float2 cols, float minDist, float maxDist, int maxstep, int bytes, int width, int iterations, float side, float3 seed, float3 shift, float shadowStrength, float ambientOccStrength) { int i = blockIdx.x * blockDim.x + threadIdx.x; int j = blockIdx.y * blockDim.y + threadIdx.y; int h = Index(i, j, width); float3 p = camera; int stepnum = 0; float dist = minDist + 1; float totalDist = 0; while (totalDist < maxDist && dist > minDist) { dist = ScaledDE(p, iterations, side, seed, shift); p = A(p, M(directions[h], dist)); totalDist += dist; stepnum++; if (stepnum == maxstep) { break; } } float brightness = 0; if (DeviceFunction.Abs(dist) <= minDist) { float3 off = S(light, p); float lightVectorLength = L(off); off = D(off, lightVectorLength); float shadow = 1; float diffuseCalculated = 0; float normalAngle = O(off, Normal(p, iterations, side, seed, shift, minDist)); if (normalAngle > 0) { shadow = NewSoftShadow(p, off, shadowStrength, iterations, side, seed, shift, minDist, lightVectorLength, 0.01f); diffuseCalculated = DeviceFunction.Max(cols.y * shadow * normalAngle, 0); } brightness += diffuseCalculated + cols.x / (1 + stepnum * ambientOccStrength); brightness = DeviceFunction.Min(DeviceFunction.Max(brightness, 0), 1); float col = Orbit(p, iterations, side, seed, shift); pixelValues[h * 3] = (byte)(Blue(col) * brightness * byte.MaxValue); pixelValues[h * 3 + 1] = (byte)(Green(col) * brightness * byte.MaxValue); pixelValues[h * 3 + 2] = (byte)(Red(col) * brightness * byte.MaxValue); } else { pixelValues[h * 3] = 0; pixelValues[h * 3 + 1] = 0; pixelValues[h * 3 + 2] = 0; } }
private static void SampleKernel(GpuShapeInfo shape, GpuSpaceInfo space, Matrix transformation, float maxDistance, bool revert) { var start = space.Bounds.Length * (blockIdx.x * blockDim.x + threadIdx.x) / blockDim.x / gridDim.x; var end = space.Bounds.Length * (blockIdx.x * blockDim.x + threadIdx.x + 1) / blockDim.x / gridDim.x; var inversedTransformation = transformation.Inverse(); for (int voxelIndex = start; voxelIndex < end; voxelIndex++) { var voxel = space.Voxels.Get(voxelIndex); var spaceCoordinates = space.Bounds.At(voxelIndex); var spacePosition = spaceCoordinates.AsVertex(); var shapePosition = transformation * spacePosition; var shapeCoordinates = DiscreteCoordinates.Floor(shapePosition); for (int partIndex = 0; partIndex < 8; partIndex++) { var partCoordinates = shapeCoordinates.Move(partIndex % 2, (partIndex >> 1) % 2, (partIndex >> 2) % 2); var warpedPartCoordinates = shape.Bounds.Warp(partCoordinates); ref var cell = ref shape.Voxels[shape.Bounds.Index(warpedPartCoordinates)]; var distance = Vector.Between(warpedPartCoordinates.AsVertex(), cell.NearestIntersection).Length; var normal = Vector.Between( spacePosition, inversedTransformation * (shapePosition + cell.Normal) ).Normalize() * (revert ? -1 : 1); var weight = DeviceFunction.Max(0f, 1f - distance / maxDistance); var factor = (1 - DeviceFunction.Abs(partCoordinates.X - shapePosition.X)) * (1 - DeviceFunction.Abs(partCoordinates.Y - shapePosition.Y)) * (1 - DeviceFunction.Abs(partCoordinates.Z - shapePosition.Z)); voxel.Weight += weight * factor; voxel.Normal += normal * factor * weight; } space.Voxels.Set(voxelIndex, voxel); }
public double Loss(BufferField target) { int area = Area; int width = Width; int height = Height; var sb = Buffer; var tb = target.Buffer; var diff = new double[Length]; if (GPU != null) { GPU.For(0, Length, n => { int c = (int)(n / area); int i = n - c * area; int y = (int)(i / width); int x = i - y * width; diff[n] = DeviceFunction.Abs(sb[c][x, y] - tb[c][x, y]); }); } return(diff.Sum() / Area); }
public static float3 AbsSpaceZ(float3 p) { return(new float3(p.x, p.y, DeviceFunction.Abs(p.z))); }
public static float3 AbsSpaceX(float3 p) { return(new float3(DeviceFunction.Abs(p.x), p.y, p.z)); }
public static float TrapezoidWave(float loc) { return(DeviceFunction.Min(DeviceFunction.Max(DeviceFunction.Abs(loc - 3), 0) - 1, 1)); }
public static double VectorLength(double x1, double y1, double x2, double y2) { return(DeviceFunction.Sqrt((DeviceFunction.Abs(x2 - x1) * DeviceFunction.Abs(x2 - x1)) + (DeviceFunction.Abs(y2 - y1) * DeviceFunction.Abs(y2 - y1)))); }