public static float3 MaxSpace(float3 a, float b) { a.x = DeviceFunction.Max(a.x, b); a.y = DeviceFunction.Max(a.y, b); a.z = DeviceFunction.Max(a.z, b); return(a); }
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 float NewSoftShadow(float3 p, float3 d, float shadowStrength, int iterations, float side, float3 seed, float3 shift, float minDist, float maxDist, float minAngle) { float darkness = 1; float prevDist = float.MaxValue; float dist = minDist / 100; float angle = 1; float totalDist = minDist; float oldNewIntDist = 0; float legLength = 0; while (totalDist < maxDist) { dist = ScaledDE(A(p, M(d, totalDist)), iterations, side, seed, shift); oldNewIntDist = dist * dist / (2 * prevDist); legLength = DeviceFunction.Sqrt(dist * dist - oldNewIntDist * oldNewIntDist); angle = shadowStrength * legLength / DeviceFunction.Max(0, totalDist - oldNewIntDist); darkness = DeviceFunction.Min(darkness, angle); prevDist = dist; totalDist += dist; if (dist < 0) { return(0); } if (darkness < minAngle) { return(0); } } return(darkness); }
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 static float TrapezoidWave(float loc) { return(DeviceFunction.Min(DeviceFunction.Max(DeviceFunction.Abs(loc - 3), 0) - 1, 1)); }