Scrolling heightmap

All topics about ZGameEditor goes here.

Moderator: Moderators

Post Reply
User avatar
Ats
Posts: 603
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Scrolling heightmap

Post by Ats »

Hello,
Today I was playing with noise3 to create a scrolling height map. And while the effect looks cool for water, it visually doesn't work at all for still mountains...

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="Heightmap" ClearColor="0 0 0 1" AmbientLightColor="0.6353 0.6353 0.6353 1" FrameRateStyle="1" ScreenMode="0" CameraPosition="0 100 120" CameraRotation="0.1 0 0" LightPosition="0 0 0" ViewportRatio="3" CustomViewportRatio="1.6667" ClipFar="800" MouseVisible="255" FileVersion="2" AndroidPackageName="com.rado1.PhysicsDemo2">
  <OnLoaded>
    <ZLibrary Comment="Globals">
      <Source>
<![CDATA[// VARIABLES

float TerrainGenOffset;
float Time;]]>
      </Source>
    </ZLibrary>
    <ZExpression Comment="Init">
      <Expression>
<![CDATA[// init random seed
setRandomSeed(getSystemTime());

// create terrain
Time = 0;
TerrainGenOffset = rnd()*100;
@RefreshContent(Component: TerrainMesh);]]>
      </Expression>
    </ZExpression>
  </OnLoaded>
  <OnUpdate>
    <ZExpression>
      <Expression>
<![CDATA[//
Time += App.DeltaTime * 0.8;
@RefreshContent(Component: TerrainMesh);]]>
      </Expression>
    </ZExpression>
  </OnUpdate>
  <OnRender>
    <RenderTransformGroup Name="Ground" Scale="60 60 20" Rotate="-0.25 0 0">
      <Children>
        <UseMaterial Material="TerrainMaterial"/>
        <RenderMesh Mesh="TerrainMesh"/>
      </Children>
    </RenderTransformGroup>
  </OnRender>
  <Lights>
    <Light Position="20 50 20" Color="1 1 0 1" SpotDirection="0 -1 0" SpotCutoff="0"/>
  </Lights>
  <Content>
    <Mesh Name="TerrainMesh">
      <Producers>
        <MeshBox XCount="16" YCount="16" Grid2DOnly="255"/>
        <MeshExpression VertexColors="255">
          <Expression>
<![CDATA[
float h = (1 - cos(v.X * 1.8)) * (noise3(v.X * 4, v.Y * 2 + Time, TerrainGenOffset) * 4.0 + 1.0);
v.Z = h;

c.R = h+0.2;
c.G = h/2;
c.B = h/2;]]>
          </Expression>
        </MeshExpression>
      </Producers>
    </Mesh>
    <Material Name="TerrainMaterial" Shading="1" Color="1 1 1 0.5" SpecularColor="0 0 0 1" EmissionColor="0 0 0 1" DrawBackFace="255"/>
  </Content>
</ZApplication>
How could I manage to make mountains to scroll indefinitely, without that moving effect?
I was thinking of dropping height maps one after another on the Z axis and moving their Z position for real, just like any other objects in my game. But how can I make them connect properly?

Or maybe just one height map, that scroll on Z axis, and when it reaches a certain position, I reset it's Z position and scroll the heightmap as I already do by a certain amount? That seems better...

Also, is @RefreshContent(Component: TerrainMesh); demanding?
User avatar
Ats
Posts: 603
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Scrolling heightmap

Post by Ats »

Here's the second version of my scrolling heigthmap : one single map that moves on Z and get a reset position and an @RefreshContent(Component: TerrainMesh); when it reaches a certain position. But I don't know how to calculate the ration translate / time to make the movement fluid:

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="Heightmap" ClearColor="0 0 0 1" AmbientLightColor="0.6353 0.6353 0.6353 1" FrameRateStyle="1" ScreenMode="0" CameraPosition="0 100 110" CameraRotation="0.1 0 0" LightPosition="0 0 0" ViewportRatio="3" CustomViewportRatio="1.6667" ClipFar="800" MouseVisible="255" FileVersion="2" AndroidPackageName="com.rado1.PhysicsDemo2">
  <OnLoaded>
    <ZLibrary Comment="Globals">
      <Source>
<![CDATA[// VARIABLES

float TerrainGenOffset;
float Time;
float Pos;]]>
      </Source>
    </ZLibrary>
    <ZExpression Comment="Init">
      <Expression>
<![CDATA[// init random seed
setRandomSeed(getSystemTime());

// create terrain
Time = 0;
TerrainGenOffset = rnd()*100;
@RefreshContent(Component: TerrainMesh);

Ground.Translate.X = 0;]]>
      </Expression>
    </ZExpression>
  </OnLoaded>
  <OnUpdate>
    <ZExpression>
      <Expression>
<![CDATA[//

Pos += App.DeltaTime * 40;
if (Pos >= 16)
{
  Pos -= 16;
  Time += 0.4825; // How to calculate that?
  @RefreshContent(Component: TerrainMesh);
}

Ground.Translate.Z = Pos;]]>
      </Expression>
    </ZExpression>
  </OnUpdate>
  <OnRender>
    <RenderTransformGroup Name="Ground" Scale="60 60 20" Translate="0 0 7.6875" Rotate="-0.25 0 0">
      <Children>
        <UseMaterial Material="TerrainMaterial"/>
        <RenderMesh Mesh="TerrainMesh"/>
      </Children>
    </RenderTransformGroup>
  </OnRender>
  <Lights>
    <Light Position="20 50 20" Color="1 1 0 1" SpotDirection="0 -1 0" SpotCutoff="0"/>
  </Lights>
  <Content>
    <Mesh Name="TerrainMesh">
      <Producers>
        <MeshBox XCount="16" YCount="16" Grid2DOnly="255"/>
        <MeshExpression VertexColors="255">
          <Expression>
<![CDATA[float h = (1 - cos(v.X * 1.8)) * (noise3(v.X * 4, v.Y * 2 + Time, TerrainGenOffset) * 4.0 + 1.0);
v.Z = h;

c.R = h+0.2;
c.G = h/2;
c.B = h/2;]]>
          </Expression>
        </MeshExpression>
      </Producers>
    </Mesh>
    <Material Name="TerrainMaterial" Shading="1" Color="1 1 1 0.5" SpecularColor="0 0 0 1" EmissionColor="0 0 0 1" DrawBackFace="255"/>
  </Content>
</ZApplication>

But now that I think of it, maybe it would be better to have several height maps that scrolls and less @RefreshContent(Component: TerrainMesh); ? I don't know...
User avatar
Kjell
Posts: 1876
Joined: Sat Feb 23, 2008 11:15 pm

Re: Scrolling heightmap

Post by Kjell »

Hi Ats,
Ats wrote: Fri Aug 12, 2022 3:52 pmI don't know how to calculate the ration translate / time to make the movement fluid
That value ( and how you calculate it ) is dependent on what you do in your MeshExpression calculation.
Ats wrote: Fri Aug 12, 2022 3:52 pmBut now that I think of it, maybe it would be better to have several height maps that scrolls and less @RefreshContent(Component: TerrainMesh); ?
Ideally you update ( roughly ) the same amount of vertices each frame, but you'd have to use OpenGL calls for that .. there's no way to do that when using the Mesh & MeshExpression components. However, you can split the terrain up in "slabs" so you only update a fraction of the terrain at a time. Here's a quick example:

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" CameraPosition="16 8 24" CameraRotation="0.0625 -0.125 0" LightPosition="0 1 1" FileVersion="2">
  <OnLoaded>
    <ZExpression>
      <Expression>
<![CDATA[//

for(int i=0; i<16; i++)
{
  Terrain.Position.Z = i;
  createModel(Terrain);
}]]>
      </Expression>
    </ZExpression>
  </OnLoaded>
  <Content>
    <Model Name="Terrain" Rotation="0.75 0 0">
      <Definitions>
        <Variable Name="TerrainPosition" Type="1"/>
        <Mesh Name="TerrainMesh">
          <Producers>
            <MeshBox Scale="8 0.5 1" XCount="15" Grid2DOnly="255"/>
            <MeshExpression>
              <Expression>
<![CDATA[//

V.Z = noise3(V.X, V.Y-TerrainPosition, 0)*2;]]>
              </Expression>
            </MeshExpression>
          </Producers>
        </Mesh>
      </Definitions>
      <OnSpawn>
        <ZExpression>
          <Expression>
<![CDATA[//

TerrainPosition = Terrain.Position.Z;]]>
          </Expression>
        </ZExpression>
      </OnSpawn>
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[//

Terrain.Position.Z += App.DeltaTime;

//

if(Terrain.Position.Z >= 16)
{
  TerrainPosition -= 16;
  Terrain.Position.Z -= 16;
  @RefreshContent(Component: TerrainMesh);
}]]>
          </Expression>
        </ZExpression>
      </OnUpdate>
      <OnRender>
        <UseMaterial Material="TerrainMaterial"/>
        <RenderMesh Mesh="TerrainMesh"/>
      </OnRender>
    </Model>
    <Material Name="TerrainMaterial" Shading="1" Color="0.502 0.502 0.502 1"/>
  </Content>
</ZApplication>
K
User avatar
Ats
Posts: 603
Joined: Fri Sep 28, 2012 10:05 am
Contact:

Re: Scrolling heightmap

Post by Ats »

Nice one. That's clever!
I'm currently plugging all the plains/desert/mountains values for having different kind of reliefs. And it's already looking awesome in the game.
Thanks again :D
Post Reply