Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Last revisionBoth sides next revision
renderpass [2020/01/09 14:06] – [Rendering Method] adminrenderpass [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); override;
 +      procedure DoInitialize(); override;
 +    public
 +  end;
 +
 +  TMyRenderPassMaterialSource = class(TGorillaRenderPassMaterialSource)
 +    protected
 +      function CreateMaterial() : TMaterial; override;
 +    public
 +  end;
 +</file>
 +
 +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 =
 +    'attribute vec3 a_Position;' +
 +    '' +
 +    'uniform mat4 _ModelViewProjMatrix;' +
 +    '' +
 +    'varying vec4 v_position;' +
 +    '' +
 +    'void main( void ){' +
 +    '  vec4 fvPosition = vec4(a_Position.x, a_Position.y, a_Position.z, 1.0);' +
 +    '  v_position = _ModelViewProjMatrix * fvPosition;' +
 +    '  gl_Position = v_position;' +
 +    '}';
 +
 +  ResourceString SOURCE_FS =
 +    'varying vec4 v_position;' +
 +    '' +
 +    'void main( void ){' +
 +    '  gl_FragColor = v_position;' +
 +    '}';
 +
 +procedure TMyRenderPassMaterial.DoInitialize();
 +var LOGLBytes : TArray<Byte>;
 +begin
 +  LOGLBytes := TEncoding.ASCII.GetBytes(SOURCE_VS);
 +  FVertexShader := TShaderManager.RegisterShaderFromData('MyRenderPass.fvs', TContextShaderKind.VertexShader, '', [
 +    TContextShaderSource.Create(TContextShaderArch.GLSL,
 +      LOGLBytes,
 +      [
 +      TContextShaderVariable.Create('ModelViewProjMatrix', TContextShaderVariableKind.Matrix, 0, 4)
 +      ]
 +    )
 +  ]);
 +
 +  LOGLBytes := TEncoding.ASCII.GetBytes(SOURCE_FS);
 +  FPixelShader := TShaderManager.RegisterShaderFromData('MyRenderPass.fps', TContextShaderKind.PixelShader, '', [
 +    TContextShaderSource.Create(TContextShaderArch.GLSL,
 +      LOGLBytes,
 +      []
 +    )
 +  ]);
 +end;
 +
 +{ TMyRenderPassMaterial }
 +
 +procedure TMyRenderPassMaterial.DoApply(const Context: TContext3D);
 +begin
 +  // activate shaders
 +  Context.SetShaders(FVertexShader, FPixelShader);
 +  // set model view projection matrix
 +  TCustomContextOpenGL(Context).SetShaderVariable('ModelViewProjMatrix', Context.CurrentModelViewProjectionMatrix, true);
 +end;
 +
 +{ TMyRenderPassMaterialSource }
 +
 +function TMyRenderPassMaterialSource.CreateMaterial() : TMaterial;
 +begin
 +  Result := TMyRenderPassMaterial.Create(Self);
 +end;
 +</file>
 +
 +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;
 +</file>
  
 ===== Start / End ===== ===== Start / End =====
Line 67: Line 170:
           [TRenderTarget.Color_0, TRenderTarget.Depth],            [TRenderTarget.Color_0, TRenderTarget.Depth], 
           TAlphaColorF.Create(0, 0, 0, 0), 0, 0);           TAlphaColorF.Create(0, 0, 0, 0), 0, 0);
-        FFBO.Bind();+           
 +        // prepare framebufferobject for multiple render targets
         FFBO.Prepare([TRenderTarget.Color_0, TRenderTarget.Depth]);                 FFBO.Prepare([TRenderTarget.Color_0, TRenderTarget.Depth]);        
       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), when state is "TRenderPassEventState.OnPassBegin": We do this all in the render-pass callback method (DoOnRenderPass), when state is "TRenderPassEventState.OnPassBegin":
Line 217: Line 321:
       FFBO.Clear(Point(AContext.Width, AContext.Height),        FFBO.Clear(Point(AContext.Width, AContext.Height), 
         LTarget, TAlphaColorF.Create(0, 0, 0, 0), 0, 0);         LTarget, TAlphaColorF.Create(0, 0, 0, 0), 0, 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;
 </file> </file>
Line 284: Line 382:
   * function GetProjectionMatrix(const AContext : TContext3D) : TMatrix3D;   * function GetProjectionMatrix(const AContext : TContext3D) : TMatrix3D;
  
-===== 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); override; 
-      procedure DoInitialize(); override; 
-    public 
-  end; 
- 
-  TMyRenderPassMaterialSource = class(TGorillaRenderPassMaterialSource) 
-    protected 
-      function CreateMaterial() : TMaterial; override; 
-    public 
-  end; 
-</file> 
- 
-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 = 
-    'attribute vec3 a_Position;' + 
-    '' + 
-    'uniform mat4 _ModelViewProjMatrix;' + 
-    '' + 
-    'varying vec4 v_position;' + 
-    '' + 
-    'void main( void ){' + 
-    '  vec4 fvPosition = vec4(a_Position.x, a_Position.y, a_Position.z, 1.0);' + 
-    '  v_position = _ModelViewProjMatrix * fvPosition;' + 
-    '  gl_Position = v_position;' + 
-    '}'; 
- 
-  ResourceString SOURCE_FS = 
-    'varying vec4 v_position;' + 
-    '' + 
-    'void main( void ){' + 
-    '  gl_FragColor = v_position;' + 
-    '}'; 
- 
-procedure TMyRenderPassMaterial.DoInitialize(); 
-var LOGLBytes : TArray<Byte>; 
-begin 
-  LOGLBytes := TEncoding.ASCII.GetBytes(SOURCE_VS); 
-  FVertexShader := TShaderManager.RegisterShaderFromData('MyRenderPass.fvs', TContextShaderKind.VertexShader, '', [ 
-    TContextShaderSource.Create(TContextShaderArch.GLSL, 
-      LOGLBytes, 
-      [ 
-      TContextShaderVariable.Create('ModelViewProjMatrix', TContextShaderVariableKind.Matrix, 0, 4) 
-      ] 
-    ) 
-  ]); 
- 
-  LOGLBytes := TEncoding.ASCII.GetBytes(SOURCE_FS); 
-  FPixelShader := TShaderManager.RegisterShaderFromData('MyRenderPass.fps', TContextShaderKind.PixelShader, '', [ 
-    TContextShaderSource.Create(TContextShaderArch.GLSL, 
-      LOGLBytes, 
-      [] 
-    ) 
-  ]); 
-end; 
- 
-{ TMyRenderPassMaterial } 
- 
-procedure TMyRenderPassMaterial.DoApply(const Context: TContext3D); 
-begin 
-  // activate shaders 
-  Context.SetShaders(FVertexShader, FPixelShader); 
-  // set model view projection matrix 
-  TCustomContextOpenGL(Context).SetShaderVariable('ModelViewProjMatrix', Context.CurrentModelViewProjectionMatrix, true); 
-end; 
- 
-{ TMyRenderPassMaterialSource } 
- 
-function TMyRenderPassMaterialSource.CreateMaterial() : TMaterial; 
-begin 
-  Result := TMyRenderPassMaterial.Create(Self); 
-end; 
-</file> 
- 
-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; 
-</file> 
  
 ===== How to use ===== ===== How to use =====
Line 398: Line 394:
 FMyRenderPass.Enabled := true; FMyRenderPass.Enabled := true;
 </file> </file>
 +
 +Next step: [[shadows|Shadows]]