Viewport

The 2D/3D Firemonkey components (TButton, TLabel, …) are still compatible with Gorilla3D. But instead of using a TViewport3D or TForm3D, we need to drag at first the TGorillaViewport onto our form.

Creating a Gorilla3D Viewport at design-time

You can find the viewport at designtime in the toolbar under:

Gorilla3D > TGorillaViewport.

Simply drag it onto your form or create it at runtime by the following method.

CAUTION: Gorilla3D is not compatible with TForm3D and TViewport3D!

Creating a viewport at runtime

If you need to create the Gorilla3D viewport at runtime, you can do it the following way:

Form1.pas
uses
  System.UITypes, // on elder IDE versions FMX.UITypes
  Gorilla.Viewport;
 
// in our form (TForm1) we added a field named "FGorilla"
procedure TForm1.FormCreate(Sender: TObject);
begin
  FGorilla := TGorillaViewport.Create(Self);
  FGorilla.Parent := Form1;
  FGorilla.Color  := TAlphaColorRec.Black;
end;

Rendering-Pipeline

Since v0.8.1.x we've changed the default rendering pipeline of the TGorillaViewport. The pipeline is responsible for rendering all render passes and the main scene itself. It computes transparency by using Weighted-Blended-Order-Independent-Transparency (WBOIT) rendering mechanism.

Read more: Transparency

Rendering-Order

Render-Cycle

A render-cycle is the process of rendering everything needed for a frame.

  1. all pre-processing render passes (represented by instances of TGorillaRenderPassController)
  2. main render pass
  3. all post-processing render passes (represented by instances of TGorillaRenderPassController)

Render-Pass

A render pass is a closed unit for rendering specific elements or some kind of effect, inside of a step of the render-cycle.

  1. all opaque objects (not transparent)
  2. all transparent objects (rendered into separated buffers)
  3. compositing opaque and transparent render result

Read more: Renderpasses

Frame-Rate

Requesting FrameRate (FPS)

Currently it is not possible to retrieve an actual framerate, but the TGorillaViewport provides an estimated framerate value.

Simply setup a timer and request those value every 100 milliseconds.

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Self.Caption := Format('Gorilla 3D - %n FPS', [FGorilla.FPS]);
end;

Notice

The estimated framerate measures the time a complete render cycle needs, including all objects, render passes and the main pass itself. Based on this value we compute the possible frames per second for the last interval. So Gorilla3D FPS value is only an orientation for you and the possible performance of your application.

Animation-Framerate (TAnimation): Because skin- and skeleton animation extends basic Firemonkey TAnimation. Therefore animations are limited to 30 FPS for rendering.

UseFixedFrameRate

FrustumCulling

The viewing frustum is a geometric representation of the volume visible to the virtual camera. Naturally, objects outside this volume will not be visible in the final image, so they are discarded.

Source:https://en.wikipedia.org/wiki/Hidden-surface_determination#View_frustum_culling

This is a great boost to the performance of your application, when only objects will be rendered that would be visible. The FrustumCulling property enables or disables the functionality in general.

But you can activate/deactivate it for each derived type of TGorillaControl, by setting:

GorillaCube1.FrustumCullingCheck := false;

If FrustumCullingCheck is set to FALSE, it will always be rendered, wether it's inside or outside of the view frustum.

Take care, that the frustum culling may affect render-passes, where a different view matrix is used.

HighRes

The High-Resolution property is currently only useful on Android platform. When activating higher resolution, than context size for rendering will be increased by device display scaling factor.

Otherwise the size of the viewport will be used for rendering. Deactivated HighRes property could lead to a more rastarized result, but is faster in rendering.

Fog

The viewport provides a classic render effect as basis implementation. Fog computation is a very popular element larger scenes when hiding elements in far distance, and making a scene disappear.

PropertyValueDescription
Fog True/False Enable or disable fog computation
FogMode TGorillaFogMode Get or set fog computation mode. Allowed modes are: linear, exp and exp2.
FogDensity Single Get or set density of computed fog.
FogStart Single Get or set lower limit of fog by distance.
FogEnd Single Get or set upper limit of fog by distance.
FogColor TAlphaColorF Get or set fog color.

Fog computation is a global scene effect over each visible element of the scene. Due to necessary shader operations this is only allowed for derived types of TGorillaDefaultMaterialSource.

This means the fog effect will not work for default FMX materials.

Optimization

In Firemonkey every time you change a visual property of a component, for example the position of a TCube, FMX will throw an event to update the viewport.

Cube1.Position.X := Cube1.Position.X + 0.1;
Cube1.Position.Y := Cube1.Position.Y + 0.2;
Cube1.Position.Z := Cube1.Position.Z + 0.3;

As you can imagine this is very slow, especially when you did not expected an update on changing the x, y and z value of a position.

Therefor the TGorillaViewport provides an optimization mechanism. Encapsulate those operations into BeginUpdate and EndUpdate to perform only one update command on the viewport renderer.

  FGorilla.BeginUpdate();
  try
    Cube1.Position.X := Cube1.Position.X + 0.1;
    Cube1.Position.Y := Cube1.Position.Y + 0.2;
    Cube1.Position.Z := Cube1.Position.Z + 0.3;  
  finally
    FGorilla.EndUpdate();
  end;

In case you need explicit render instructions, you can suppress updates completely, by calling EndUpdateWithoutInvalidate instead of EndUpdate.

  FGorilla.BeginUpdate();
  try
    Cube1.Position.X := Cube1.Position.X + 0.1;
    Cube1.Position.Y := Cube1.Position.Y + 0.2;
    Cube1.Position.Z := Cube1.Position.Z + 0.3;  
  finally
    FGorilla.EndUpdateWithoutInvalidate();
  end;

But you have to update viewport yourself by calling:

  FGorilla.Invalidate();

Shaders

Since v0.8.0 rendering pipeline was optimized due to unnecessary render instructions. An update limitation was implemented, that not every property change leads to a new rendering. Besides that you may use a shader / material which updates itself by time. The TGorillaWaterMaterialSource is an example. Waves are generated by a timevalue, but it will only update on re-rendering.

Here we need an explicit render instruction. Like you may already know from other Delphi components the TGorillaViewport supports the “Invalidate” method to tell Gorilla3D to re-render. Call this method constantly in a TTimer or by synchronized thread to update water material.

Next step: Loading models