コード例 #1
0
ファイル: Raytracer.cs プロジェクト: vsugrob/UnityRaytracer
    public void Render(
        Texture2D outputTexture,
        int resolutionWidth, int resolutionHeight,
        IntRect?rectToRender = null
        )
    {
        if (!rectToRender.HasValue)
        {
            rectToRender = new IntRect(0, 0, -1, -1);
        }

        var rect = rectToRender.Value;

        if (rect.X < 0 || rect.X >= resolutionWidth)
        {
            throw new ArgumentException("rect.X must fall in bounds from 0 to resolutionWidth", "rect.X");
        }

        if (rect.Y < 0 || rect.Y >= resolutionWidth)
        {
            throw new ArgumentException("rect.Y must fall in bounds from 0 to resolutionHeight", "rect.Y");
        }

        if (rect.Width < 0)
        {
            rect.Width = resolutionWidth - rect.X;
        }
        else if (rect.Right > resolutionWidth)
        {
            rect.Right = resolutionWidth;
        }

        if (rect.Height < 0)
        {
            rect.Height = resolutionHeight - rect.Y;
        }
        else if (rect.Bottom > resolutionHeight)
        {
            rect.Bottom = resolutionHeight;
        }

        Camera.aspect = ( float )resolutionWidth / resolutionHeight;
        Counters      = new RaytraceCounters();
        float halfPixelWidth  = 1.0f / resolutionWidth / 2;
        float halfPixelHeight = 1.0f / resolutionHeight / 2;
        float timeStart       = Time.realtimeSinceStartup;

        for (int sy = rect.Y; sy < rect.Bottom; sy++)
        {
            for (int sx = rect.X; sx < rect.Right; sx++)
            {
                Counters.InitialRays++;

                Vector3 viewportPoint = new Vector3(
                    ( float )sx / resolutionWidth + halfPixelWidth,
                    ( float )sy / resolutionHeight + halfPixelHeight,
                    0
                    );
                Ray   ray       = Camera.ViewportPointToRay(viewportPoint);
                var   traceData = new TraceData(Camera.backgroundColor, Counters);
                Color color     = Trace(ray, traceData);

                outputTexture.SetPixel(sx - rect.X, sy - rect.Y, color);
            }
        }

        outputTexture.Apply();
        lastRenderTime = Time.realtimeSinceStartup - timeStart;
        Camera.ResetAspect();
    }
コード例 #2
0
    private void DrawGizmos()
    {
        GizmoSettings.Validate();

        float aspect = ( float )Width / Height;

        if (GizmoSettings.DrawFrustum)
        {
            Matrix4x4 originalMatrix = Gizmos.matrix;
            Gizmos.matrix = Matrix4x4.TRS(transform.position, transform.rotation, transform.localScale);
            Gizmos.color  = Color.gray;

            if (Camera.orthographic)
            {
                float   orthoSize = Camera.orthographicSize * 2;
                Vector3 cubeSize  = new Vector3(
                    orthoSize * aspect,
                    orthoSize,
                    Camera.farClipPlane - Camera.nearClipPlane
                    );

                Vector3 cubePos = new Vector3(
                    0,
                    0,
                    cubeSize.z * 0.5f + Camera.nearClipPlane
                    );

                Gizmos.DrawWireCube(cubePos, cubeSize);
            }
            else
            {
                Gizmos.DrawFrustum(Vector3.zero, Camera.fieldOfView, Camera.farClipPlane, Camera.nearClipPlane, aspect);
            }

            Gizmos.matrix = originalMatrix;
        }

        if (GizmoSettings.DrawTracePaths)
        {
            Camera.aspect = aspect;
            Awake();
            Start();

            float halfPixelWidth  = 1.0f / GizmoSettings.NumPathsX / 2;
            float halfPixelHeight = 1.0f / GizmoSettings.NumPathsY / 2;
            var   counters        = new RaytraceCounters();

            for (int y = 0; y < GizmoSettings.NumPathsY; y++)
            {
                for (int x = 0; x < GizmoSettings.NumPathsX; x++)
                {
                    counters.InitialRays++;

                    Ray ray = Camera.ViewportPointToRay(
                        new Vector3(
                            ( float )x / GizmoSettings.NumPathsX + halfPixelWidth,
                            ( float )y / GizmoSettings.NumPathsY + halfPixelHeight,
                            0
                            )
                        );

                    TraceData traceData = new TraceData(Camera.backgroundColor, counters, recordHistory: true);
                    raytracer.Trace(ray, traceData);

                    var         flatBranches       = traceData.FlattenBranches().ToArray();
                    const float NoHitSegmentLength = 10;                    // TODO: move it to argument of function that draws segments and/or make it come from setting.
#if PERIODIC_UPDATE
                    const float SpiderSpawnRate     = 0.5f;                 // Number of spiders spawning per second.
                    const float SpiderVelocity      = 1;                    // Units per second.
                    const float SpiderLength        = 0.1f;
                    float       spiderSpawnInterval = 1 / SpiderSpawnRate;
#endif

                    foreach (var td in flatBranches)
                    {
                        float segStartDistance = td.StartDistance;

                        foreach (var item in td.History)
                        {
                            Ray   itemRay  = item.Ray;
                            Color rayColor = GizmoSettings.UseCustomColorForPaths ? GizmoSettings.PathsColor : item.Color;
                            Gizmos.color = rayColor;
                            float segEndDistance;

                            if (item.Hit.HasValue)
                            {
                                RaycastHit hit = item.Hit.Value;
                                Gizmos.DrawLine(itemRay.origin, hit.point);
                                segEndDistance = segStartDistance + hit.distance;
                            }
                            else
                            {
                                Gizmos.DrawLine(itemRay.origin, itemRay.GetPoint(NoHitSegmentLength));
                                segEndDistance = segStartDistance + NoHitSegmentLength;
                            }

#if PERIODIC_UPDATE
                            /* Draw marching ants crawling along the rays */

                            /* TODO: I couldn't figure out how to make SceneView update periodically
                             * rather than in response to events. I don't know where from I can call
                             * SceneView.RepaintAll () in order to force scene to update itself as well. */
                            float timeToReachStart = segStartDistance / SpiderVelocity;
                            float timeToReachEnd   = segEndDistance / SpiderVelocity;
                            float segTravelTime    = timeToReachEnd - timeToReachStart;
                            float t = (( float )EditorApplication.timeSinceStartup + timeToReachStart) % spiderSpawnInterval;

                            for ( ; t < segTravelTime; t += spiderSpawnInterval)
                            {
                                Gizmos.color = new Color(1 - rayColor.r, 1 - rayColor.g, 1 - rayColor.b, 1);
                                Vector3 spiderPos = itemRay.GetPoint(t * SpiderVelocity);
                                Gizmos.DrawLine(spiderPos, spiderPos + itemRay.direction * SpiderLength);
                            }
#endif

                            segStartDistance = segEndDistance;
                        }
                    }
                }
            }

            Camera.ResetAspect();
        }
    }
コード例 #3
0
ファイル: Raytracer.cs プロジェクト: vsugrob/UnityRaytracer
 public TraceData(Color backgroundColor, RaytraceCounters counters, bool recordHistory = false)
 {
     this.BackgroundColor = backgroundColor;
     this.Counters        = counters;
     this.RecordHistory   = recordHistory;
 }