void InitAndClearBuffer(Camera camera, RenderLoop renderLoop) { // We clear only the depth buffer, no need to clear the various color buffer as we overwrite them. // Clear depth/stencil and init buffers { var cmd = new CommandBuffer(); cmd.name = "InitGBuffers and clear Depth/Stencil"; // Init buffer // With scriptable render loop we must allocate ourself depth and color buffer (We must be independent of backbuffer for now, hope to fix that later). // Also we manage ourself the HDR format, here allocating fp16 directly. // With scriptable render loop we can allocate temporary RT in a command buffer, they will not be release with ExecuteCommandBuffer // These temporary surface are release automatically at the end of the scriptable renderloop if not release explicitly int w = camera.pixelWidth; int h = camera.pixelHeight; cmd.GetTemporaryRT(s_CameraColorBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Default); cmd.GetTemporaryRT(s_CameraDepthBuffer, w, h, 24, FilterMode.Point, RenderTextureFormat.Depth); m_gbufferManager.InitGBuffers(w, h, cmd); cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer)); cmd.ClearRenderTarget(true, false, new Color(0, 0, 0, 0)); renderLoop.ExecuteCommandBuffer(cmd); cmd.Dispose(); } // TEMP: As we are in development and have not all the setup pass we still clear the color in emissive buffer and gbuffer, but this will be removed later. // Clear HDR target { var cmd = new CommandBuffer(); cmd.name = "Clear HDR target"; cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer)); cmd.ClearRenderTarget(false, true, new Color(0, 0, 0, 0)); renderLoop.ExecuteCommandBuffer(cmd); cmd.Dispose(); } // Clear GBuffers { var cmd = new CommandBuffer(); cmd.name = "Clear GBuffer"; // Write into the Camera Depth buffer cmd.SetRenderTarget(m_gbufferManager.GetGBuffers(cmd), new RenderTargetIdentifier(s_CameraDepthBuffer)); // Clear everything // TODO: Clear is not required for color as we rewrite everything, will save performance. cmd.ClearRenderTarget(false, true, new Color(0, 0, 0, 0)); renderLoop.ExecuteCommandBuffer(cmd); cmd.Dispose(); } // END TEMP }
void RenderDebugViewMaterial(CullResults cull, Camera camera, RenderLoop renderLoop) { // Render Opaque forward { var cmd = new CommandBuffer { name = "DebugView Material Mode Pass" }; cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer)); cmd.ClearRenderTarget(true, true, new Color(0, 0, 0, 0)); renderLoop.ExecuteCommandBuffer(cmd); cmd.Dispose(); Shader.SetGlobalInt("_DebugViewMaterial", (int)debugParameters.debugViewMaterial); RenderOpaqueRenderList(cull, camera, renderLoop, "DebugViewMaterial"); } // Render GBUffer opaque { Vector4 screenSize = ComputeScreenSize(camera); m_DebugViewMaterialGBuffer.SetVector("_ScreenSize", screenSize); m_DebugViewMaterialGBuffer.SetFloat("_DebugViewMaterial", (float)debugParameters.debugViewMaterial); // m_gbufferManager.BindBuffers(m_DeferredMaterial); // TODO: Bind depth textures var cmd = new CommandBuffer { name = "GBuffer Debug Pass" }; cmd.Blit(null, new RenderTargetIdentifier(s_CameraColorBuffer), m_DebugViewMaterialGBuffer, 0); renderLoop.ExecuteCommandBuffer(cmd); cmd.Dispose(); } // Render forward transparent { RenderTransparentRenderList(cull, camera, renderLoop, "DebugViewMaterial"); } // Last blit { var cmd = new CommandBuffer { name = "Blit DebugView Material Debug" }; cmd.Blit(s_CameraColorBuffer, BuiltinRenderTextureType.CameraTarget); renderLoop.ExecuteCommandBuffer(cmd); cmd.Dispose(); } }
void FinalPass(RenderLoop renderLoop) { // Those could be tweakable for the neutral tonemapper, but in the case of the LookDev we don't need that const float blackIn = 0.02f; const float whiteIn = 10.0f; const float blackOut = 0.0f; const float whiteOut = 10.0f; const float whiteLevel = 5.3f; const float whiteClip = 10.0f; const float dialUnits = 20.0f; const float halfDialUnits = dialUnits * 0.5f; // converting from artist dial units to easy shader-lerps (0-1) var tonemapCoeff1 = new Vector4((blackIn * dialUnits) + 1.0f, (blackOut * halfDialUnits) + 1.0f, (whiteIn / dialUnits), (1.0f - (whiteOut / dialUnits))); var tonemapCoeff2 = new Vector4(0.0f, 0.0f, whiteLevel, whiteClip / halfDialUnits); m_FinalPassMaterial.SetVector("_ToneMapCoeffs1", tonemapCoeff1); m_FinalPassMaterial.SetVector("_ToneMapCoeffs2", tonemapCoeff2); m_FinalPassMaterial.SetFloat("_EnableToneMap", debugParameters.enableTonemap ? 1.0f : 0.0f); m_FinalPassMaterial.SetFloat("_Exposure", debugParameters.exposure); var cmd = new CommandBuffer { name = "FinalPass" }; // Resolve our HDR texture to CameraTarget. cmd.Blit(s_CameraColorBuffer, BuiltinRenderTextureType.CameraTarget, m_FinalPassMaterial, 0); renderLoop.ExecuteCommandBuffer(cmd); cmd.Dispose(); }
void RenderDeferredLighting(Camera camera, RenderLoop renderLoop) { if (debugParameters.useForwardRenderingOnly) { return; } // Bind material data m_LitRenderLoop.Bind(); var invViewProj = GetViewProjectionMatrix(camera).inverse; m_DeferredMaterial.SetMatrix("_InvViewProjMatrix", invViewProj); var screenSize = ComputeScreenSize(camera); m_DeferredMaterial.SetVector("_ScreenSize", screenSize); // m_gbufferManager.BindBuffers(m_DeferredMaterial); // TODO: Bind depth textures var cmd = new CommandBuffer { name = "Deferred Ligthing Pass" }; cmd.Blit(null, new RenderTargetIdentifier(s_CameraColorBuffer), m_DeferredMaterial, 0); renderLoop.ExecuteCommandBuffer(cmd); cmd.Dispose(); }
public void Draw(RenderLoop loop, Camera camera) { if (camera.clearFlags != CameraClearFlags.Skybox) { return; } var mat = RenderSettings.skybox; if (mat == null) { return; } var cmd = new CommandBuffer { name = "Skybox" }; var looksLikeSixSidedShader = true; looksLikeSixSidedShader &= (mat.passCount == 6); // should have six passes //looksLikeSixSidedShader &= !mat.GetShader()->GetShaderLabShader()->HasLightingPasses(); if (looksLikeSixSidedShader) { Debug.LogWarning("Six sided skybox not yet supported."); } else { if (mesh == null) { CreateMesh(); } var dist = camera.farClipPlane * 10.0f; var world = Matrix4x4.TRS(camera.transform.position, Quaternion.identity, new Vector3(dist, dist, dist)); var skyboxProj = SkyboxHelper.GetProjectionMatrix(camera); cmd.SetProjectionAndViewMatrices(skyboxProj, camera.worldToCameraMatrix); cmd.DrawMesh(mesh, world, mat); cmd.SetProjectionAndViewMatrices(camera.projectionMatrix, camera.worldToCameraMatrix); } loop.ExecuteCommandBuffer(cmd); cmd.Dispose(); }
void RenderForwardUnlit(CullResults cullResults, Camera camera, RenderLoop renderLoop) { // Bind material data m_LitRenderLoop.Bind(); var cmd = new CommandBuffer { name = "Forward Unlit Pass" }; cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer)); renderLoop.ExecuteCommandBuffer(cmd); cmd.Dispose(); RenderOpaqueRenderList(cullResults, camera, renderLoop, "ForwardUnlit"); RenderTransparentRenderList(cullResults, camera, renderLoop, "ForwardUnlit"); }
//--------------------------------------------------------------------------------------------------------------------------------------------------- private void RenderShadowSplit(ref ShadowSliceData slice, Vector3 lightDirection, Matrix4x4 proj, Matrix4x4 view, ref RenderLoop loop, DrawShadowsSettings settings) { var commandBuffer = new CommandBuffer { name = "ShadowSetup" }; // Set viewport / matrices etc commandBuffer.SetViewport(new Rect(slice.atlasX, slice.atlasY, slice.shadowResolution, slice.shadowResolution)); //commandBuffer.ClearRenderTarget (true, true, Color.green); commandBuffer.SetGlobalVector("g_vLightDirWs", new Vector4(lightDirection.x, lightDirection.y, lightDirection.z)); commandBuffer.SetProjectionAndViewMatrices(proj, view); // commandBuffer.SetGlobalDepthBias (1.0F, 1.0F); loop.ExecuteCommandBuffer(commandBuffer); commandBuffer.Dispose(); // Render loop.DrawShadows(ref settings); }
void RenderGBuffer(CullResults cull, Camera camera, RenderLoop renderLoop) { if (debugParameters.useForwardRenderingOnly) { return; } // setup GBuffer for rendering var cmd = new CommandBuffer { name = "GBuffer Pass" }; cmd.SetRenderTarget(m_gbufferManager.GetGBuffers(cmd), new RenderTargetIdentifier(s_CameraDepthBuffer)); renderLoop.ExecuteCommandBuffer(cmd); cmd.Dispose(); // render opaque objects into GBuffer RenderOpaqueRenderList(cull, camera, renderLoop, "GBuffer"); }
//--------------------------------------------------------------------------------------------------------------------------------------------------- // Render shadows //--------------------------------------------------------------------------------------------------------------------------------------------------- void RenderPackedShadows(RenderLoop loop, CullResults cullResults, ref ShadowOutput packedShadows) { var setRenderTargetCommandBuffer = new CommandBuffer(); setRenderTargetCommandBuffer.name = "Render packed shadows"; setRenderTargetCommandBuffer.GetTemporaryRT(m_ShadowTexName, m_Settings.shadowAtlasWidth, m_Settings.shadowAtlasHeight, k_DepthBuffer, FilterMode.Bilinear, RenderTextureFormat.Shadowmap, RenderTextureReadWrite.Linear); setRenderTargetCommandBuffer.SetRenderTarget(new RenderTargetIdentifier(m_ShadowTexName)); setRenderTargetCommandBuffer.ClearRenderTarget(true, true, Color.green); loop.ExecuteCommandBuffer(setRenderTargetCommandBuffer); setRenderTargetCommandBuffer.Dispose(); VisibleLight[] visibleLights = cullResults.visibleLights; var shadowSlices = packedShadows.shadowSlices; // Render each light's shadow buffer into a subrect of the shared depth texture for (int lightIndex = 0; lightIndex < packedShadows.shadowLights.Length; lightIndex++) { int shadowSliceCount = packedShadows.shadowLights[lightIndex].shadowSliceCount; if (shadowSliceCount == 0) { continue; } Profiler.BeginSample("Shadows.GetShadowCasterBounds"); Bounds bounds; if (!cullResults.GetShadowCasterBounds(lightIndex, out bounds)) { Profiler.EndSample(); return; } Profiler.EndSample(); Profiler.BeginSample("Shadows.DrawShadows"); Matrix4x4 proj; Matrix4x4 view; var lightType = visibleLights[lightIndex].lightType; var lightDirection = visibleLights[lightIndex].light.transform.forward; var shadowNearClip = visibleLights[lightIndex].light.shadowNearPlane; int shadowSliceIndex = packedShadows.GetShadowSliceIndex(lightIndex, 0); if (lightType == LightType.Spot) { var settings = new DrawShadowsSettings(cullResults, lightIndex); bool needRendering = cullResults.ComputeSpotShadowsMatricesAndCullingPrimitives(lightIndex, out view, out proj, out settings.splitData); SetupShadowSplitMatrices(ref packedShadows.shadowSlices[shadowSliceIndex], proj, view); if (needRendering) { RenderShadowSplit(ref shadowSlices[shadowSliceIndex], lightDirection, proj, view, ref loop, settings); } } else if (lightType == LightType.Directional) { Vector3 splitRatio = m_Settings.directionalLightCascades; for (int s = 0; s < 4; ++s) { packedShadows.directionalShadowSplitSphereSqr[s] = new Vector4(0, 0, 0, float.NegativeInfinity); } for (int s = 0; s < shadowSliceCount; ++s, shadowSliceIndex++) { var settings = new DrawShadowsSettings(cullResults, lightIndex); var shadowResolution = shadowSlices[shadowSliceIndex].shadowResolution; bool needRendering = cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(lightIndex, s, shadowSliceCount, splitRatio, shadowResolution, shadowNearClip, out view, out proj, out settings.splitData); packedShadows.directionalShadowSplitSphereSqr[s] = settings.splitData.cullingSphere; packedShadows.directionalShadowSplitSphereSqr[s].w *= packedShadows.directionalShadowSplitSphereSqr[s].w; SetupShadowSplitMatrices(ref shadowSlices[shadowSliceIndex], proj, view); if (needRendering) { RenderShadowSplit(ref shadowSlices[shadowSliceIndex], lightDirection, proj, view, ref loop, settings); } } } else if (lightType == LightType.Point) { for (int s = 0; s < shadowSliceCount; ++s, shadowSliceIndex++) { var settings = new DrawShadowsSettings(cullResults, lightIndex); bool needRendering = cullResults.ComputePointShadowsMatricesAndCullingPrimitives(lightIndex, (CubemapFace)s, 2.0f, out view, out proj, out settings.splitData); SetupShadowSplitMatrices(ref shadowSlices[shadowSliceIndex], proj, view); if (needRendering) { RenderShadowSplit(ref shadowSlices[shadowSliceIndex], lightDirection, proj, view, ref loop, settings); } } } Profiler.EndSample(); } }