Differences
This shows you the differences between two versions of the page.
Last revisionBoth sides next revision | |||
1.0.0:water [2023/02/22 14:57] – created - external edit 127.0.0.1 | 1.0.0:water [2023/10/24 14:17] – [Example] admin | ||
---|---|---|---|
Line 135: | Line 135: | ||
<file pascal> | <file pascal> | ||
- | procedure TForm1.CreateWater(const AAssetsPath | + | unit Unit1; |
- | var LTexPath | + | |
+ | interface | ||
+ | |||
+ | uses | ||
+ | System.SysUtils, | ||
+ | System.Types, | ||
+ | System.UITypes, | ||
+ | System.Classes, | ||
+ | System.Variants, | ||
+ | System.IOUtils, | ||
+ | System.Math.Vectors, | ||
+ | FMX.Types, | ||
+ | FMX.Controls, | ||
+ | FMX.Forms, | ||
+ | FMX.Graphics, | ||
+ | FMX.Dialogs, | ||
+ | FMX.Types3D, | ||
+ | FMX.Controls3D, | ||
+ | FMX.Objects3d, | ||
+ | FMX.MaterialSources, | ||
+ | FMX.StdCtrls, | ||
+ | FMX.Controls.Presentation, | ||
+ | Gorilla.DefTypes, | ||
+ | Gorilla.Viewport, | ||
+ | Gorilla.Skybox, | ||
+ | Gorilla.Cube, | ||
+ | Gorilla.Plane, | ||
+ | Gorilla.Terrain, | ||
+ | Gorilla.Terrain.Utils, | ||
+ | Gorilla.Terrain.Algorithm, | ||
+ | Gorilla.Controller.Passes.CustomBlur, | ||
+ | Gorilla.Controller.Passes.Reflection, | ||
+ | Gorilla.Controller.Passes.Refraction, | ||
+ | Gorilla.Controller.Passes.CustomDepth, | ||
+ | Gorilla.Controller.Passes.Environment, | ||
+ | Gorilla.Material.Water, | ||
+ | Gorilla.Material.Lambert, | ||
+ | System.Generics.Collections, | ||
+ | FMX.Edit, FMX.EditBox, | ||
+ | |||
+ | type | ||
+ | TForm1 = class(TForm) | ||
+ | procedure FormCreate(Sender: | ||
+ | private | ||
+ | FGorilla | ||
+ | FLight | ||
+ | FLightPos : Single; | ||
+ | FSkyBox | ||
+ | FTerrain | ||
+ | FTerrainMat : TGorillaLambertMaterialSource; | ||
+ | FWaterPlane : TGorillaPlane; | ||
+ | FWaterMat | ||
+ | FReflection : TGorillaRenderPassReflection; | ||
+ | FRefraction : TGorillaRenderPassRefraction; | ||
+ | FReflectBody : TGorillaCube; | ||
+ | FReflectBodyMat : TGorillaLambertMaterialSource; | ||
+ | public | ||
+ | { Public-Deklarationen } | ||
+ | end; | ||
+ | |||
+ | var | ||
+ | Form1: TForm1; | ||
+ | |||
+ | implementation | ||
+ | |||
+ | {$R *.fmx} | ||
+ | |||
+ | uses | ||
+ | Gorilla.Utils.Math, | ||
+ | Gorilla.Control, | ||
+ | Gorilla.Controller, | ||
+ | Gorilla.Context.Texturing; | ||
+ | |||
+ | procedure TForm1.FormCreate(Sender: TObject); | ||
+ | var LPath : String; | ||
begin | begin | ||
- | | + | |
+ | {$IFDEF MSWINDOWS} | ||
+ | LPath := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) | ||
+ | IncludeTrailingPathDelimiter('assets'); | ||
+ | {$ELSE} | ||
+ | LPath := IncludeTrailingPathDelimiter(TPath.GetHomePath()); | ||
+ | {$ENDIF} | ||
- | /// create | + | // Create |
- | | + | |
- | | + | |
- | | + | |
+ | FGorilla.OnMouseUp := DoOnViewportMouseUp; | ||
+ | FGorilla.FXAA := 0; | ||
+ | |||
+ | // Create a light source | ||
+ | FLight := TLight.Create(FGorilla); | ||
+ | FLight.Parent := FGorilla; | ||
+ | FLight.Name := ' | ||
+ | FLight.LightType := TLightType.Point; | ||
+ | FLight.AbsolutePosition := Vector3D(0, -25, -5); | ||
+ | FLightPos := 0; | ||
+ | |||
+ | // Skybox to have more reflections | ||
+ | FSkyBox := TGorillaSkyBox.Create(FGorilla); | ||
+ | FSkyBox.Parent := FGorilla; | ||
+ | |||
+ | // Terrain with random generation | ||
+ | FTerrain := TGorillaTerrain.Create(FGorilla); | ||
+ | FTerrain.Parent := FGorilla; | ||
+ | fTerrain.BeginUpdate(); | ||
try | try | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | FWaterPlane.SubdivisionsWidth | + | |
- | | + | |
finally | finally | ||
- | | + | |
end; | end; | ||
- | /// create reflection | + | // Create a material for the terrain mesh |
- | | + | FTerrainMat := TGorillaLambertMaterialSource.Create(fTerrain); |
- | | + | FTerrainMat.Parent := FTerrain; |
- | FReflection.Camera | + | TGorillaLambertMaterialSource(FTerrainMat).Texture.LoadFromFile(LPath + ' |
+ | FTerrain.MaterialSource := FTerrainMat; | ||
+ | |||
+ | | ||
+ | FWaterPlane := TGorillaPlane.Create(FGorilla); | ||
+ | FWaterPlane.SetHitTestValue(false); | ||
+ | FWaterPlane.Parent := FGorilla; | ||
+ | FWaterPlane.RotationAngle.X := 90; | ||
+ | FWaterPlane.Width | ||
+ | FWaterPlane.Height := 10; | ||
+ | FWaterPlane.Position.Y := -0.5; | ||
+ | |||
+ | // High resolution for ripple testing - vertex shader modifies it | ||
+ | FWaterPlane.SubdivisionsWidth | ||
+ | FWaterPlane.SubdivisionsHeight := 256; | ||
+ | |||
+ | // Water shader | ||
+ | | ||
+ | | ||
+ | |||
+ | FWaterMat.DisplacementMap.LoadFromFile(LPath + ' | ||
+ | FWaterMat.DisplIntensity := 0.1; | ||
+ | FWaterMat.NormalMap.LoadFromFile(LPath + ' | ||
+ | FWaterMat.DUDVTexture.LoadFromFile(LPath + ' | ||
+ | FWaterMat.SpecularMap.LoadFromFile(LPath + ' | ||
+ | FWaterMat.FoamTexture.LoadFromFile(LPath + ' | ||
+ | FWaterMat.TextureTiling[WATER_TEX_FOAM] := PointF(4, 4); | ||
+ | |||
+ | FWaterMat.ShoreTexture.LoadFromFile(LPath + ' | ||
+ | FWaterMat.TextureTiling[WATER_TEX_SHORE] := PointF(2, 2); | ||
+ | |||
+ | // Link material to the water surface plane | ||
+ | FWaterPlane.MaterialSource := FWaterMat; | ||
+ | |||
+ | // Reflection render pass | ||
+ | FReflection | ||
+ | FReflection.Viewport | ||
+ | |||
+ | // Ignore the water plane, otherwise the rendering might be black | ||
FReflection.IgnoreControl(FWaterPlane); | FReflection.IgnoreControl(FWaterPlane); | ||
FReflection.MirrorSize := FWaterPlane.Width; | FReflection.MirrorSize := FWaterPlane.Width; | ||
| | ||
- | // set the current position of the water plane as mirror | + | // The mirror |
- | // this needs to be updated, if water plane moves | + | // Because displacement mapping is activated, we need to render reflections |
- | FReflection.MirrorPosition := TPoint3D(FWaterPlane.AbsolutePosition); | + | // with the displacement offset |
+ | FReflection.MirrorPosition.Point | ||
+ | Point3D(0, -FWaterMat.DisplIntensity, | ||
+ | |||
+ | // We do not need fullscreen rendering for reflections, | ||
+ | FReflection.ViewportScale := 0.5; | ||
FReflection.Enabled := true; | FReflection.Enabled := true; | ||
- | /// create refraction | + | // Refraction |
- | FRefraction := TGorillaRenderPassRefraction.Create(FViewport); | + | FRefraction := TGorillaRenderPassRefraction.Create(fGorilla); |
- | FRefraction.Viewport := FViewport; | + | FRefraction.Viewport := fGorilla; |
- | FRefraction.IgnoreControl(FWaterPlane); | + | |
+ | // Ignore the water plane, otherwise the rendering might be black | ||
+ | FRefraction.IgnoreControl(fWaterPlane); | ||
+ | |||
+ | // The mirror surface position is important to to render correctly | ||
+ | // Because displacement mapping is activated, we need to render reflections | ||
+ | // with the displacement offset | ||
+ | FRefraction.SurfacePosition.Point := TPoint3D(FWaterPlane.AbsolutePosition) + | ||
+ | Point3D(0, -FWaterMat.DisplIntensity, | ||
+ | |||
+ | // We do not need fullscreen rendering for refractions, | ||
+ | FRefraction.ViewportScale := 0.5; | ||
FRefraction.Enabled := true; | FRefraction.Enabled := true; | ||
- | /// create | + | // Link reflection and refraction render passes to the material |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | FWaterMaterial.FoamTexture.LoadFromFile(LTexPath + ' | + | |
- | /// link reflection | + | // Create a reflective body and material |
- | | + | |
- | | + | |
- | | + | |
+ | FReflectBodyMat.Parent := FReflectBody; | ||
+ | FReflectBodyMat.UseTexture0 := false; | ||
+ | FReflectBody.MaterialSource := FReflectBodyMat; | ||
end; | end; | ||
+ | |||
+ | end. | ||
</ | </ | ||
Next step: [[bokeh|Bokeh]] | Next step: [[bokeh|Bokeh]] |