Beispiel #1
0
        public static TraceResult Render(TraceParams parameters, ProgressReportDelegate progressReport = null, float[] backbuffer = null)
        {
            // Allocate backbuffer
            if (ReferenceEquals(backbuffer, null) || backbuffer.Length != (parameters.width * parameters.height * 3))
            {
                backbuffer = new float[parameters.width * parameters.height * 3];
            }

            TraceResult result = new TraceResult()
            {
                parameters = parameters,
                backbuffer = backbuffer
            };

            TraceRuntimeParams runtimeParams = new TraceRuntimeParams();

            runtimeParams.invWidth           = 1.0f / parameters.width;
            runtimeParams.invHeight          = 1.0f / parameters.height;
            runtimeParams.invSamplesPerPixel = 1.0f / parameters.samplesPerPixel;
            runtimeParams.sampleBatchCount   = (int)Mathf.Ceiling(parameters.samplesPerPixel / (float)runtimeParams.batchSize);

            List <TileTraceParameters> traceTiles = new List <TileTraceParameters>();

            for (int y = 0; y < parameters.height; y += parameters.traceTileDimension)
            {
                for (int x = 0; x < parameters.width; x += parameters.traceTileDimension)
                {
                    var tt = new TileTraceParameters()
                    {
                        xStart        = x,
                        yStart        = y,
                        parameters    = parameters,
                        runtimeParams = runtimeParams
                    };

                    tt.xEnd = Math.Min(tt.xStart + parameters.traceTileDimension, parameters.width);
                    tt.yEnd = Math.Min(tt.yStart + parameters.traceTileDimension, parameters.height);
                    traceTiles.Add(tt);
                }
            }

            parameters.tracingProcessor.Trace(traceTiles, ref result, progressReport);
            return(result);
        }
Beispiel #2
0
        public static void TraceTile(TileTraceParameters tile, float[] backbuffer, out long rayCount)
        {
            InitBatchArray(ref _rays);
            InitBatchArray(ref _hits);
            InitBatchArray(ref _localColor);

            Ray[]     rays       = _rays;
            HitInfo[] hits       = _hits;
            Vector3[] localColor = _localColor;
            uint      rndState   = FastRandom.Seed();

            rayCount = 0;

            for (int x = tile.xStart; x < tile.xEnd; x++)
            {
                for (int y = tile.yStart; y < tile.yEnd; y++)
                {
                    Vector3 color = new Vector3(0, 0, 0);
                    // Sample bouncing batches
                    for (int b = 0; b < tile.runtimeParams.sampleBatchCount; b++)
                    {
                        // Calculate batch info
                        int batchStart = b * tile.runtimeParams.batchSize, batchEnd = batchStart + tile.runtimeParams.batchSize;
                        int batchRayCount = Math.Min(batchEnd, tile.parameters.samplesPerPixel);
                        batchRayCount -= batchStart;

                        uint  hitMask = 0;
                        uint  bounces = uint.MaxValue;
                        float u = x * tile.runtimeParams.invWidth, v = y * tile.runtimeParams.invHeight;

                        // Get initial rays
                        tile.parameters.camera.GetRays(u, v, rays, batchRayCount, ref rndState);

                        // Reset local colors
                        for (int i = 0; i < batchRayCount; i++)
                        {
                            localColor[i] = tile.parameters.ambientLight;
                        }

                        Vector3 atten;
                        int     bounceCount = 0;
                        while (bounceCount < tile.parameters.maxBounces && bounces != 0)
                        {
                            tile.parameters.scene.Raycast(rays, hits, 0.01f, tile.parameters.maxDepth, batchRayCount, bounces, ref hitMask, ref rayCount);
                            if (hitMask == 0)
                            {
                                break;
                            }

                            bounces = 0;
                            for (int i = 0; i < batchRayCount; i++)
                            {
                                if (BitHelper.GetBit(ref hitMask, i)) // Did ray hit?
                                {
                                    if (hits[i].material.Scatter(ref hits[i], out atten, ref rays[i], tile.parameters.scene, ref rndState))
                                    {
                                        BitHelper.SetBit(ref bounces, i);
                                    }

                                    localColor[i] *= atten;
                                }
                            }
                            bounceCount++;
                        }

                        for (int i = 0; i < batchRayCount; i++)
                        {
                            color += localColor[i];
                        }
                    }

                    color *= tile.runtimeParams.invSamplesPerPixel;

                    // Write backbuffer
                    int idx = (y * (tile.parameters.width * 3)) + (x * 3);
                    backbuffer[idx]     = color.X;
                    backbuffer[idx + 1] = color.Y;
                    backbuffer[idx + 2] = color.Z;
                }
            }
        }