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(); }
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(); } }
public TraceData(Color backgroundColor, RaytraceCounters counters, bool recordHistory = false) { this.BackgroundColor = backgroundColor; this.Counters = counters; this.RecordHistory = recordHistory; }