Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionLast revisionBoth sides next revision | ||
renderpass [2020/01/09 14:07] – [Render-Pass Material] admin | renderpass [2020/01/09 14:24] – [How to use] admin | ||
---|---|---|---|
Line 31: | Line 31: | ||
In the next step you have to decide, if a **one-for-all material shader** should be used //or// the **object specific material shaders**. | In the next step you have to decide, if a **one-for-all material shader** should be used //or// the **object specific material shaders**. | ||
Because sometimes you want the full scene just to be rendered from another perspective (like reflection) or you want to store a specific value (like the depth-value in shadow mapping) in the FBO. | Because sometimes you want the full scene just to be rendered from another perspective (like reflection) or you want to store a specific value (like the depth-value in shadow mapping) in the FBO. | ||
+ | |||
+ | ===== Render-Pass Material ===== | ||
+ | |||
+ | To create an individual material shader for your render-pass you need to extend **TGorillaRenderPassMaterialSource** and **TGorillaRenderPassMaterial**. | ||
+ | |||
+ | <file pascal> | ||
+ | uses | ||
+ | FMX.Types3D, | ||
+ | FMX.Materials, | ||
+ | FMX.MaterialSources, | ||
+ | Gorilla.Controller; | ||
+ | | ||
+ | TMyRenderPassMaterial = class(TGorillaRenderPassMaterial) | ||
+ | protected | ||
+ | procedure DoApply(const Context: TContext3D); | ||
+ | procedure DoInitialize(); | ||
+ | public | ||
+ | end; | ||
+ | |||
+ | TMyRenderPassMaterialSource = class(TGorillaRenderPassMaterialSource) | ||
+ | protected | ||
+ | function CreateMaterial() : TMaterial; override; | ||
+ | public | ||
+ | end; | ||
+ | </ | ||
+ | |||
+ | Here you can have a look at this example of a render-pass material implementation. | ||
+ | |||
+ | Notice: No multiple targets used here. We just write to default output buffer by gl_FragColor. | ||
+ | |||
+ | <file pascal> | ||
+ | uses | ||
+ | Gorilla.Context.GLES; | ||
+ | | ||
+ | ResourceString SOURCE_VS = | ||
+ | ' | ||
+ | '' | ||
+ | ' | ||
+ | '' | ||
+ | ' | ||
+ | '' | ||
+ | 'void main( void ){' + | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | ResourceString SOURCE_FS = | ||
+ | ' | ||
+ | '' | ||
+ | 'void main( void ){' + | ||
+ | ' | ||
+ | ' | ||
+ | |||
+ | procedure TMyRenderPassMaterial.DoInitialize(); | ||
+ | var LOGLBytes : TArray< | ||
+ | begin | ||
+ | LOGLBytes := TEncoding.ASCII.GetBytes(SOURCE_VS); | ||
+ | FVertexShader := TShaderManager.RegisterShaderFromData(' | ||
+ | TContextShaderSource.Create(TContextShaderArch.GLSL, | ||
+ | LOGLBytes, | ||
+ | [ | ||
+ | TContextShaderVariable.Create(' | ||
+ | ] | ||
+ | ) | ||
+ | ]); | ||
+ | |||
+ | LOGLBytes := TEncoding.ASCII.GetBytes(SOURCE_FS); | ||
+ | FPixelShader := TShaderManager.RegisterShaderFromData(' | ||
+ | TContextShaderSource.Create(TContextShaderArch.GLSL, | ||
+ | LOGLBytes, | ||
+ | [] | ||
+ | ) | ||
+ | ]); | ||
+ | end; | ||
+ | |||
+ | { TMyRenderPassMaterial } | ||
+ | |||
+ | procedure TMyRenderPassMaterial.DoApply(const Context: TContext3D); | ||
+ | begin | ||
+ | // activate shaders | ||
+ | Context.SetShaders(FVertexShader, | ||
+ | // set model view projection matrix | ||
+ | TCustomContextOpenGL(Context).SetShaderVariable(' | ||
+ | end; | ||
+ | |||
+ | { TMyRenderPassMaterialSource } | ||
+ | |||
+ | function TMyRenderPassMaterialSource.CreateMaterial() : TMaterial; | ||
+ | begin | ||
+ | Result := TMyRenderPassMaterial.Create(Self); | ||
+ | end; | ||
+ | </ | ||
+ | |||
+ | You than have to overwrite the CreateMaterialSource() method and create your material source. | ||
+ | In case you'd like to use the element specific material shaders, return nil in the CreateMaterialSource() method. | ||
+ | |||
+ | <file pascal> | ||
+ | function TMyRenderPass.CreateMaterialSource() : TGorillaRenderPassMaterialSource; | ||
+ | begin | ||
+ | result := TMyRenderPassMaterialSource.Create(Self); | ||
+ | end; | ||
+ | </ | ||
===== Start / End ===== | ===== Start / End ===== | ||
Line 67: | Line 170: | ||
[TRenderTarget.Color_0, | [TRenderTarget.Color_0, | ||
TAlphaColorF.Create(0, | TAlphaColorF.Create(0, | ||
- | FFBO.Bind(); | + | |
+ | // prepare framebufferobject for multiple render targets | ||
FFBO.Prepare([TRenderTarget.Color_0, | FFBO.Prepare([TRenderTarget.Color_0, | ||
end; | end; | ||
Line 73: | Line 177: | ||
OnPassEnd: | OnPassEnd: | ||
begin | begin | ||
- | AContext.SetCameraMatrix(FPrevCamView); | + | AContext.SetCameraMatrix(FPrevCamView); |
- | + | ||
- | FFBO.Unbind(); | + | |
end; | end; | ||
end; | end; | ||
Line 203: | Line 305: | ||
To use a render target from the framebuffer object, we need to clear it on each rendering step. | To use a render target from the framebuffer object, we need to clear it on each rendering step. | ||
After that, we have to activate it for shader usage by the Prepare() method. | After that, we have to activate it for shader usage by the Prepare() method. | ||
+ | The prepare method will activate all supplied render targets for shader computation. | ||
+ | If you forget to execute prepare() only the default target Color_0 will be available for computation. | ||
We do this all in the render-pass callback method (DoOnRenderPass), | We do this all in the render-pass callback method (DoOnRenderPass), | ||
Line 217: | Line 321: | ||
FFBO.Clear(Point(AContext.Width, | FFBO.Clear(Point(AContext.Width, | ||
LTarget, TAlphaColorF.Create(0, | LTarget, TAlphaColorF.Create(0, | ||
- | | ||
- | // bind again the framebuffer object | ||
- | FFBO.Bind(); | ||
| | ||
// activate the specific render target buffer for shader | // activate the specific render target buffer for shader | ||
Line 234: | Line 335: | ||
begin | begin | ||
[...] | [...] | ||
- | | ||
- | // unbind framebuffer object | ||
- | FFBO.Unbind(); | ||
end; | end; | ||
</ | </ | ||
Line 296: | Line 394: | ||
FMyRenderPass.Enabled := true; | FMyRenderPass.Enabled := true; | ||
</ | </ | ||
+ | |||
+ | Next step: [[shadows|Shadows]] |