From ccc878280de06568b9fea4bba50301397757d4b8 Mon Sep 17 00:00:00 2001 From: daemyung jang Date: Wed, 30 Mar 2022 18:09:49 +0900 Subject: [PATCH] Summerize Chapter 14: Multipass & Deferred Rendering --- 14-multipass-rendering/README.md | 138 ++++++++++++++++++ .../normalized-device-coordinates.png | Bin 0 -> 26730 bytes .../Shadows/Shadows/Shaders/Composition.metal | 36 +++++ .../Shadows/Shadows/Shaders/Gbuffer.metal | 36 +++++ .../Shadows/Shadows/Shaders/Shadow.metal | 36 +++++ .../texture-coordinates.png | Bin 0 -> 15232 bytes README.md | 1 + 7 files changed, 247 insertions(+) create mode 100644 14-multipass-rendering/README.md create mode 100644 14-multipass-rendering/normalized-device-coordinates.png create mode 100644 14-multipass-rendering/starter/Shadows/Shadows/Shaders/Composition.metal create mode 100644 14-multipass-rendering/starter/Shadows/Shadows/Shaders/Gbuffer.metal create mode 100644 14-multipass-rendering/starter/Shadows/Shadows/Shaders/Shadow.metal create mode 100644 14-multipass-rendering/texture-coordinates.png diff --git a/14-multipass-rendering/README.md b/14-multipass-rendering/README.md new file mode 100644 index 0000000..336273e --- /dev/null +++ b/14-multipass-rendering/README.md @@ -0,0 +1,138 @@ +# Chapter 14: Multipass & Deferred Rendering + +As I read this book, I summarize what I think is wrong. If you think my comments are wrong then please let me know. We can dicuss more and update your opinion. + +## The main pass + +You've reserved the Y coordinate since it's upside down. But why? Because the Y coordinate of the normalized device coordinates and texture coordinates is opposite. + +![](./normalized-device-coordinates.png) + +This is the normalized device coordinates and you can see the Y coordinate is upward. + +![](./texture-coordinates.png) + +This is the texture coordinates and you can see the Y coordinate is downward. + +## The Blit Command Encoder + +This example uses view's bounds size as the drawable size in Renderer.swift but it's right only the content scale is 1. If your system uses HDPI then your system will use the bigger content scale than 1. It can be 2 or 3 depends on your monitor's resolution. In a nutshell view's bounds size can be different from the drawable size when the content scale is not 1. For example the content scale is 2 and view's bounds size is 512x512 then the drawable size would be 1024x1024. This different can make a runtime error. + +In init(metalView:), replace: + +``` +mtkView(metalView, drawableSizeWillChange: metalView.bounds.size) +``` + +With: + +``` +mtkView(metalView, drawableSizeWillChange: metalView.drawableSize) +``` + +## The G-buffer pass + +We use a texture to save the world position. But we don't have to store this information. We can calculate the world position in the composition pass with the inverse view projection matrix and the depth value pass. + +In Composition.metal, add the fragment function: + +``` +fragment float4 compositionFragWithoutPosition(VertexOut in [[stage_in]], + constant FragmentUniforms& fragmentUniforms [[buffer(3)]], + constant Light *lightBuffer [[buffer(2)]], + texture2d albedoTexture [[texture(0)]], + texture2d normalTexture [[texture(1)]], + depth2d depthTexture [[texture(5)]]) { + constexpr sampler s(min_filter::linear, mag_filter::linear); + float4 albedo = albedoTexture.sample(s, in.texCoords); + float3 normal = normalTexture.sample(s, in.texCoords).xyz; + + float4 positionInNdc; + positionInNdc.xy = in.texCoords * 2.0 - 1.0; + positionInNdc.y = positionInNdc.y * -1.0; + positionInNdc.z = depthTexture.sample(s, in.texCoords); + positionInNdc.w = 1.0; + + float4 positionInWorldSpace = fragmentUniforms.inverseViewProjectionMatrix * positionInNdc; + positionInWorldSpace /= positionInWorldSpace.w; + + float3 position = positionInWorldSpace.xyz; + float3 baseColor = albedo.rgb; + float3 diffuseColor = compositeLighting(normal, position, fragmentUniforms, lightBuffer, baseColor); + float shadow = albedo.a; + if (shadow > 0) { + diffuseColor *= 0.5; + } + return float4(diffuseColor, 1); +} + +``` + +This shader isn't perfect but you can understand how to calculate the world position. + +In Renderer.swift, in buildCompositionPipelineState, replace: + +``` +descriptor.fragmentFunction = Renderer.library.makeFunction(name: "compositionFrag") +``` + +With: + +``` +descriptor.fragmentFunction = Renderer.library.makeFunction(name: "compositionFragWithoutPosition") +``` + +In Common.h, add two variables at FragmentUniforms: + +``` +matrix_float4x4 viewProjectionMatrix; +matrix_float4x4 inverseViewProjectionMatrix; +``` + +In renderCompositionPass(renderEncoder:), call these methods before draw: + +``` +fragmentUniforms.viewProjectionMatrix = uniforms.projectionMatrix * uniforms.viewMatrix +fragmentUniforms.inverseViewProjectionMatrix = simd_inverse(fragmentUniforms.viewProjectionMatrix) +renderEncoder.setFragmentBytes(&fragmentUniforms, length: MemoryLayout.stride, index: 3) +renderEncoder.setFragmentTexture(depthTexture, index: 5) +``` + +Instead of saving the position, we can save other valuable information and also can save the memory bandwidth. + + +## The Lighting pass + +We have created the positions buffer and texture coordinates buffer for the composition pass. But we don't have to create these buffers and also can improve a bit of performance. This technique is [Fullscreen triangle](https://wallisc.github.io/rendering/2021/04/18/Fullscreen-Pass.html). + +In Composition.metal, add the vertex function: + +``` +vertex VertexOut compositionFullscreenTriangle(uint id [[vertex_id]]) { + VertexOut out; + + // Generate clip space position. + out.position.x = (float)(id / 2) * 4.0 - 1.0; + out.position.y = (float)(id % 2) * 4.0 - 1.0; + out.position.z = 0.0; + out.position.w = 1.0; + + // Generate texture coordinates. + out.texCoords.x = (float)(id / 2) * 2.0; + out.texCoords.y = 1.0 - (float)(id % 2) * 2.0; + + return out; +} +``` + +In Renderer.swift, in buildCompositionPipelineState, replace: + +``` +descriptor.vertexFunction = Renderer.library.makeFunction(name: "compositionVert") +``` + +With: + +``` +descriptor.vertexFunction = Renderer.library.makeFunction(name: "compositionFullscreenTriangle") +``` diff --git a/14-multipass-rendering/normalized-device-coordinates.png b/14-multipass-rendering/normalized-device-coordinates.png new file mode 100644 index 0000000000000000000000000000000000000000..f26d9d9b602a7ba8651630c4050f304bb784c70a GIT binary patch literal 26730 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%0Da;A^&oCo8moOqH^MX)T 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 literal 0 HcmV?d00001 diff --git a/14-multipass-rendering/starter/Shadows/Shadows/Shaders/Composition.metal b/14-multipass-rendering/starter/Shadows/Shadows/Shaders/Composition.metal new file mode 100644 index 0000000..0cce91e --- /dev/null +++ b/14-multipass-rendering/starter/Shadows/Shadows/Shaders/Composition.metal @@ -0,0 +1,36 @@ +// +/** + * Copyright (c) 2019 Razeware LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, + * distribute, sublicense, create a derivative work, and/or sell copies of the + * Software in any work that is designed, intended, or marketed for pedagogical or + * instructional purposes related to programming, coding, application development, + * or information technology. Permission for such use, copying, modification, + * merger, publication, distribution, sublicensing, creation of derivative works, + * or sale is expressly withheld. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#include +using namespace metal; + + diff --git a/14-multipass-rendering/starter/Shadows/Shadows/Shaders/Gbuffer.metal b/14-multipass-rendering/starter/Shadows/Shadows/Shaders/Gbuffer.metal new file mode 100644 index 0000000..0cce91e --- /dev/null +++ b/14-multipass-rendering/starter/Shadows/Shadows/Shaders/Gbuffer.metal @@ -0,0 +1,36 @@ +// +/** + * Copyright (c) 2019 Razeware LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, + * distribute, sublicense, create a derivative work, and/or sell copies of the + * Software in any work that is designed, intended, or marketed for pedagogical or + * instructional purposes related to programming, coding, application development, + * or information technology. Permission for such use, copying, modification, + * merger, publication, distribution, sublicensing, creation of derivative works, + * or sale is expressly withheld. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#include +using namespace metal; + + diff --git a/14-multipass-rendering/starter/Shadows/Shadows/Shaders/Shadow.metal b/14-multipass-rendering/starter/Shadows/Shadows/Shaders/Shadow.metal new file mode 100644 index 0000000..0cce91e --- /dev/null +++ b/14-multipass-rendering/starter/Shadows/Shadows/Shaders/Shadow.metal @@ -0,0 +1,36 @@ +// +/** + * Copyright (c) 2019 Razeware LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, + * distribute, sublicense, create a derivative work, and/or sell copies of the + * Software in any work that is designed, intended, or marketed for pedagogical or + * instructional purposes related to programming, coding, application development, + * or information technology. Permission for such use, copying, modification, + * merger, publication, distribution, sublicensing, creation of derivative works, + * or sale is expressly withheld. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#include +using namespace metal; + + diff --git a/14-multipass-rendering/texture-coordinates.png b/14-multipass-rendering/texture-coordinates.png new file mode 100644 index 0000000000000000000000000000000000000000..cc38153b8263189f085d5b945b8fb49a9b78c5de GIT binary patch literal 15232 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 RT54s^S=*dOpS