I had based my water terrain on that little sample snippet you posted for me a few months ago. That was building a whole vertex list and calling CoordinateNode.setpoint. I just made it precalculate all those vertices for x, z, and then in the update, just set the Y directly to CoordinateNode.fdPoint.Items[].y
for each vertex. I am now hitting near 30fps in debug mode, which was more like 20fps before. I will make the same change to the texcoords… and then do the same thing for the clouds and speed should no longer feel like a noose tightening on my neck.
Note that you should always call CoordinateNode.fdPoint.Changed
after direct field value manipulation like this. Otherwise results are undefined – we don’t guarantee whether everything related was properly updated, push to GPU etc.
And it is likely that calling CoordinateNode.fdPoint.Changed
will give you back the same performance…
I wonder what is causing such delay for your SetPoint
call. Aside from updating GPU data, it recalculates normal vectors (which doesn’t happen if you directly change Y values), maybe this is is your speedup? It would indicate that in new version you have incorrect lighting. Maybe the solution (correct one, so it would involve using either SetPoint
or CoordinateNode.fdPoint.Changed
) is to provide normal vectors explicitly, and recalculate them on your side? You can likely do it much faster than engine on your side, utilizing the fact that you know you have a regular terrain, not a mesh.
I am calling Changed
, or it doesn’t change anything. It also made the clouds fast enough to update every frame (which makes them too crazy, 1 every 60 frames looks best, you never notice a change but they change) The difference is building all the vertex data vs just modifying the y on the vertex data that is already there. There are over 100 tiles of 101x101 vertices being updated constantly (the water and cloud data updates in work threads, and then the meshes are updated in the main thread). So every clockcycle counts. Zero time spent calculating x, z locations during the update makes a difference. Now there is no calculation… just setting the y from a grid. I went from 20fps debug 30fps release to more like 30fps debug 40fps release (at lot depends on whether the pig is visible).
The following is the code that inits the water vertices. This was basically done every update (only the tile you are looking at updates every frame), now it is just done once per tile. x,z never change.
procedure TWaterTerrainV2.InitVertices;
var Vertices : TVector3List;
step, sz2 : single;
i, j : integer;
vcount : integer;
VertexPtr : ^TVector3;
Vertex : TVector3;
TexCoords : TVector2List;
begin
step := fgridstep;
Vertices := TVector3List.Create;
vcount := fGridCount * fGridCount;
Vertices.Count := vcount;
VertexPtr := Vertices.Ptr(0);
TexCoords := TVector2List.Create;
TexCoords.Capacity := vcount;
sz2 := CellCount * Step * 0.5;
vertex.y := 0;
vertex.z := -sz2;
for i := 0 to fGridCount - 1 do
begin
Vertex.x := -sz2; { world x offset to align tiles }
for j := 0 to fGridCount - 1 do
begin
VertexPtr^ := Vertex;
vertex.x := vertex.x + step;
TexCoords.Add(Vector2(0,0));
inc( vertexptr );
end;
vertex.z := vertex.z + step;
end;
CoordinateNode.SetPoint( Vertices );
TexCoordNode.SetPoint(TexCoords);
Vertices.Free;
TexCoords.Free;
end;
Initializing and freeing and setting all those values takes time! Now it just loops through those and sets the Y value that is already calculated.
I still want more speed. My other older I7 with radeon 470 instead of 580 only get 20fps with release.