public bool BeginRecording() { if (m_recording) { return(false); } if (m_shCopy == null) { Debug.LogError("GBufferRecorder: copy shader is missing!"); return(false); } m_recording = true; m_outputDir.CreateDirectory(); if (m_quad == null) { m_quad = fcAPI.CreateFullscreenQuad(); } if (m_matCopy == null) { m_matCopy = new Material(m_shCopy); } var cam = GetComponent <Camera>(); if (m_fbComponents.frameBuffer) { if (m_cbCopyFB == null) { m_rtFB = new RenderTexture(cam.pixelWidth, cam.pixelHeight, 0, RenderTextureFormat.ARGBHalf); m_rtFB.wrapMode = TextureWrapMode.Repeat; m_rtFB.Create(); int tid = Shader.PropertyToID("_TmpFrameBuffer"); m_cbCopyFB = new CommandBuffer(); m_cbCopyFB.name = "GBufferRecorder: Copy FrameBuffer"; m_cbCopyFB.GetTemporaryRT(tid, -1, -1, 0, FilterMode.Point); m_cbCopyFB.Blit(BuiltinRenderTextureType.CurrentActive, tid); m_cbCopyFB.SetRenderTarget(m_rtFB); m_cbCopyFB.DrawMesh(m_quad, Matrix4x4.identity, m_matCopy, 0, 0); m_cbCopyFB.ReleaseTemporaryRT(tid); } cam.AddCommandBuffer(CameraEvent.AfterEverything, m_cbCopyFB); } if (m_fbComponents.GBuffer) { if (m_cbCopyGB == null) { m_rtGB = new RenderTexture[8]; for (int i = 0; i < m_rtGB.Length; ++i) { m_rtGB[i] = new RenderTexture(cam.pixelWidth, cam.pixelHeight, 0, RenderTextureFormat.ARGBHalf); m_rtGB[i].filterMode = FilterMode.Point; m_rtGB[i].Create(); } // clear gbuffer (Unity doesn't clear emission buffer - it is not needed usually) m_cbClearGB = new CommandBuffer(); m_cbClearGB.name = "GBufferRecorder: Cleanup GBuffer"; if (cam.allowHDR) { m_cbClearGB.SetRenderTarget(BuiltinRenderTextureType.CameraTarget); } else { m_cbClearGB.SetRenderTarget(BuiltinRenderTextureType.GBuffer3); } m_cbClearGB.DrawMesh(m_quad, Matrix4x4.identity, m_matCopy, 0, 3); // copy gbuffer m_cbCopyGB = new CommandBuffer(); m_cbCopyGB.name = "GBufferRecorder: Copy GBuffer"; m_cbCopyGB.SetRenderTarget(new RenderTargetIdentifier[] { m_rtGB[0], m_rtGB[1], m_rtGB[2], m_rtGB[3], m_rtGB[4], m_rtGB[5], m_rtGB[6] }, m_rtGB[0]); m_cbCopyGB.DrawMesh(m_quad, Matrix4x4.identity, m_matCopy, 0, 2); } cam.AddCommandBuffer(CameraEvent.BeforeGBuffer, m_cbClearGB); cam.AddCommandBuffer(CameraEvent.BeforeLighting, m_cbCopyGB); if (m_fbComponents.velocity) { if (m_cbCopyVelocity == null) { m_cbCopyVelocity = new CommandBuffer(); m_cbCopyVelocity.name = "GBufferRecorder: Copy Velocity"; m_cbCopyVelocity.SetRenderTarget(m_rtGB[7]); m_cbCopyVelocity.DrawMesh(m_quad, Matrix4x4.identity, m_matCopy, 0, 4); } cam.AddCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, m_cbCopyVelocity); cam.depthTextureMode = DepthTextureMode.Depth | DepthTextureMode.MotionVectors; } } int framerate = m_targetFramerate; if (m_fbComponents.frameBuffer) { m_recorders.Add(new BufferRecorder(m_rtFB, 4, "FrameBuffer", framerate)); } if (m_fbComponents.GBuffer) { if (m_fbComponents.albedo) { m_recorders.Add(new BufferRecorder(m_rtGB[0], 3, "Albedo", framerate)); } if (m_fbComponents.occlusion) { m_recorders.Add(new BufferRecorder(m_rtGB[1], 1, "Occlusion", framerate)); } if (m_fbComponents.specular) { m_recorders.Add(new BufferRecorder(m_rtGB[2], 3, "Specular", framerate)); } if (m_fbComponents.smoothness) { m_recorders.Add(new BufferRecorder(m_rtGB[3], 1, "Smoothness", framerate)); } if (m_fbComponents.normal) { m_recorders.Add(new BufferRecorder(m_rtGB[4], 3, "Normal", framerate)); } if (m_fbComponents.emission) { m_recorders.Add(new BufferRecorder(m_rtGB[5], 4, "Emission", framerate)); } if (m_fbComponents.depth) { m_recorders.Add(new BufferRecorder(m_rtGB[6], 1, "Depth", framerate)); } if (m_fbComponents.velocity) { m_recorders.Add(new BufferRecorder(m_rtGB[7], 2, "Velocity", framerate)); } } foreach (var rec in m_recorders) { rec.Initialize(m_encoderConfigs, m_outputDir); } return(true); }
public bool BeginRecording() { if (m_recording) { return(false); } if (m_shCopy == null) { Debug.LogError("MovieRecorder: copy shader is missing!"); return(false); } if (m_captureTarget == CaptureTarget.RenderTexture && m_targetRT == null) { Debug.LogError("MovieRecorder: target RenderTexture is null!"); return(false); } m_outputDir.CreateDirectory(); if (m_quad == null) { m_quad = fcAPI.CreateFullscreenQuad(); } if (m_matCopy == null) { m_matCopy = new Material(m_shCopy); } var cam = GetComponent <Camera>(); if (cam.targetTexture != null) { m_matCopy.EnableKeyword("OFFSCREEN"); } else { m_matCopy.DisableKeyword("OFFSCREEN"); } m_numVideoFrames = 0; // create scratch buffer { int targetWidth = cam.pixelWidth; int targetHeight = cam.pixelHeight; int captureWidth = targetWidth; int captureHeight = targetHeight; if (m_resolutionWidth > 0) { captureWidth = m_resolutionWidth; captureHeight = (int)((float)m_resolutionWidth / ((float)targetWidth / (float)targetHeight)); } else if (m_resolutionWidth < 0) { int div = System.Math.Abs(m_resolutionWidth); captureWidth = targetWidth / div; captureHeight = targetHeight / div; } if (m_encoderConfigs.format == MovieEncoder.Type.MP4) { captureWidth = (captureWidth + 1) & ~1; captureHeight = (captureHeight + 1) & ~1; } m_scratchBuffer = new RenderTexture(captureWidth, captureHeight, 0, RenderTextureFormat.ARGB32); m_scratchBuffer.wrapMode = TextureWrapMode.Repeat; m_scratchBuffer.Create(); } // initialize encoder { int targetFramerate = 60; if (m_framerateMode == FrameRateMode.Constant) { targetFramerate = m_targetFramerate; } string outPath = m_outputDir.GetFullPath() + "/" + DateTime.Now.ToString("yyyyMMdd_HHmmss"); m_encoderConfigs.Setup(m_scratchBuffer.width, m_scratchBuffer.height, 3, targetFramerate); m_encoder = MovieEncoder.Create(m_encoderConfigs, outPath); if (m_encoder == null) { EndRecording(); return(false); } } // create command buffer { int tid = Shader.PropertyToID("_TmpFrameBuffer"); m_cb = new CommandBuffer(); m_cb.name = "MovieRecorder: copy frame buffer"; if (m_captureTarget == CaptureTarget.FrameBuffer) { m_cb.GetTemporaryRT(tid, -1, -1, 0, FilterMode.Bilinear); m_cb.Blit(BuiltinRenderTextureType.CurrentActive, tid); m_cb.SetRenderTarget(m_scratchBuffer); m_cb.DrawMesh(m_quad, Matrix4x4.identity, m_matCopy, 0, 0); m_cb.ReleaseTemporaryRT(tid); } else if (m_captureTarget == CaptureTarget.RenderTexture) { m_cb.SetRenderTarget(m_scratchBuffer); m_cb.SetGlobalTexture("_TmpRenderTarget", m_targetRT); m_cb.DrawMesh(m_quad, Matrix4x4.identity, m_matCopy, 0, 1); } } cam.AddCommandBuffer(CameraEvent.AfterEverything, m_cb); m_recording = true; Debug.Log("MovieMRecorder: BeginRecording()"); return(true); }
public bool BeginRecording() { if (m_recording) { return(false); } if (m_shCopy == null) { Debug.LogError("ImageSequenceRecorder: copy shader is missing!"); return(false); } if (m_captureTarget == CaptureTarget.RenderTexture && (m_targetRT == null || m_targetRT.Length == 0)) { Debug.LogError("ImageSequenceRecorder: target RenderTexture is empty!"); return(false); } ValidateContext(); if (m_ctx == null) { return(false); } m_ctx.Initialize(this); m_recording = true; m_outputDir.CreateDirectory(); if (m_quad == null) { m_quad = fcAPI.CreateFullscreenQuad(); } if (m_matCopy == null) { m_matCopy = new Material(m_shCopy); } var cam = GetComponent <Camera>(); if (m_captureTarget == CaptureTarget.FrameBuffer) { if (m_fbComponents.frameBuffer) { if (m_cbCopyFB == null) { m_rtFB = new RenderTexture(cam.pixelWidth, cam.pixelHeight, 0, RenderTextureFormat.ARGBHalf); m_rtFB.wrapMode = TextureWrapMode.Repeat; m_rtFB.Create(); int tid = Shader.PropertyToID("_TmpFrameBuffer"); m_cbCopyFB = new CommandBuffer(); m_cbCopyFB.name = "ImageSequenceRecorder: Copy FrameBuffer"; m_cbCopyFB.GetTemporaryRT(tid, -1, -1, 0, FilterMode.Point); m_cbCopyFB.Blit(BuiltinRenderTextureType.CurrentActive, tid); m_cbCopyFB.SetRenderTarget(m_rtFB); m_cbCopyFB.DrawMesh(m_quad, Matrix4x4.identity, m_matCopy, 0, 0); m_cbCopyFB.ReleaseTemporaryRT(tid); } cam.AddCommandBuffer(CameraEvent.AfterEverything, m_cbCopyFB); } if (m_fbComponents.GBuffer) { if (m_cbCopyGB == null) { m_rtGB = new RenderTexture[8]; for (int i = 0; i < m_rtGB.Length; ++i) { m_rtGB[i] = new RenderTexture(cam.pixelWidth, cam.pixelHeight, 0, RenderTextureFormat.ARGBHalf); m_rtGB[i].filterMode = FilterMode.Point; m_rtGB[i].Create(); } // clear gbuffer (Unity doesn't clear emission buffer - it is not needed usually) m_cbClearGB = new CommandBuffer(); m_cbClearGB.name = "ImageSequenceRecorder: Cleanup GBuffer"; if (cam.allowHDR) { m_cbClearGB.SetRenderTarget(BuiltinRenderTextureType.CameraTarget); } else { m_cbClearGB.SetRenderTarget(BuiltinRenderTextureType.GBuffer3); } m_cbClearGB.DrawMesh(m_quad, Matrix4x4.identity, m_matCopy, 0, 3); // copy gbuffer m_cbCopyGB = new CommandBuffer(); m_cbCopyGB.name = "ImageSequenceRecorder: Copy GBuffer"; m_cbCopyGB.SetRenderTarget(new RenderTargetIdentifier[] { m_rtGB[0], m_rtGB[1], m_rtGB[2], m_rtGB[3], m_rtGB[4], m_rtGB[5], m_rtGB[6] }, m_rtGB[0]); m_cbCopyGB.DrawMesh(m_quad, Matrix4x4.identity, m_matCopy, 0, 2); } cam.AddCommandBuffer(CameraEvent.BeforeGBuffer, m_cbClearGB); cam.AddCommandBuffer(CameraEvent.BeforeLighting, m_cbCopyGB); if (m_fbComponents.velocity) { if (m_cbCopyVelocity == null) { m_cbCopyVelocity = new CommandBuffer(); m_cbCopyVelocity.name = "ImageSequenceRecorder: Copy Velocity"; m_cbCopyVelocity.SetRenderTarget(m_rtGB[7]); m_cbCopyVelocity.DrawMesh(m_quad, Matrix4x4.identity, m_matCopy, 0, 4); } cam.AddCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, m_cbCopyVelocity); cam.depthTextureMode = DepthTextureMode.Depth | DepthTextureMode.MotionVectors; } } } else if (m_captureTarget == CaptureTarget.RenderTexture) { if (m_cbCopyRT == null) { m_rtScratch = new RenderTexture[m_targetRT.Length]; for (int i = 0; i < m_rtScratch.Length; ++i) { var rt = m_targetRT[i]; m_rtScratch[i] = new RenderTexture(rt.width, rt.height, 0, rt.format); m_rtScratch[i].Create(); } m_cbCopyRT = new CommandBuffer(); m_cbCopyRT.name = "ImageSequenceRecorder: Copy Targets"; for (int i = 0; i < m_targetRT.Length; ++i) { m_cbCopyRT.SetRenderTarget(m_rtScratch[i]); m_cbCopyRT.SetGlobalTexture("_TmpRenderTarget", m_targetRT[i]); m_cbCopyRT.DrawMesh(m_quad, Matrix4x4.identity, m_matCopy, 0, 1); } GetComponent <Camera>().AddCommandBuffer(CameraEvent.AfterEverything, m_cbCopyRT); } } return(true); }