Ejemplo n.º 1
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;
                }
            }
        }