Terrain Height Manipulation

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


IndieGuy11
Halfling
Posts: 50
Joined: Fri May 19, 2017 8:09 pm
x 2

Terrain Height Manipulation

Post by IndieGuy11 »

We want to start experimenting with Terrain Manipulation (changing the vertices position up and down, etc, etc) like other editors can do (unreal).

What are some examples or tutorials we can look at to give us an idea how we can do this within Ogre.

We understand it will be something we have to make (not an issue) but an idea of where to start would be helpful.

For example, should we use Ogre Terrain? Or should we just use normal meshes connected together to be able to manipulate them, etc, etc. We want maximum flexibility (performance is a must)

Thank you!
Last edited by IndieGuy11 on Mon Sep 11, 2017 4:25 pm, edited 3 times in total.
User avatar
Kohedlo
Orc
Posts: 435
Joined: Fri Nov 27, 2009 3:34 pm
Location: Ukraine, Sumy
x 32
Contact:

Re: Terrain Height Manipulation

Post by Kohedlo »

i use Ogre Editable Terrain Manager.

this terrain and collection tools can dynamically in game paint, decorate and lift terrain that is lod parts.

Image
Large
c++ game developer.
current project: Imperial Game Engine 2.5
Image
IndieGuy11
Halfling
Posts: 50
Joined: Fri May 19, 2017 8:09 pm
x 2

Re: Terrain Height Manipulation

Post by IndieGuy11 »

Hey Thanks!

Is this OETM part of the Ogre 2.1 SDK?

We want something home-brewed to be able to enable functionality how we want.

I would be interested in how dark_sylinc would go about it! :D
User avatar
Zonder
Ogre Magi
Posts: 1168
Joined: Mon Aug 04, 2008 7:51 pm
Location: Manchester - England
x 73

Re: Terrain Height Manipulation

Post by Zonder »

I'd suggest looking into doing the editing GPU side not CPU. Scape is an older project which does this. http://ogre3d.org/forums/viewtopic.php?f=11&t=68026

As I recollect doesn't the 2.1 terrain sample just process height maps on the GPU?
There are 10 types of people in the world: Those who understand binary, and those who don't...
IndieGuy11
Halfling
Posts: 50
Joined: Fri May 19, 2017 8:09 pm
x 2

Re: Terrain Height Manipulation

Post by IndieGuy11 »

I dont see a 2.1 Terrain Sample!

WOW!!!!! Looks good. Something we can consider!
xrgo
OGRE Expert User
OGRE Expert User
Posts: 1148
Joined: Sat Jul 06, 2013 10:59 pm
Location: Chile
x 168

Re: Terrain Height Manipulation

Post by xrgo »

IndieGuy11 wrote:I dont see a 2.1 Terrain Sample!
It's called Tutorial_Terra, but I am not sure how easy would be to make it realtime-editable since it loads the texture at the begining
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: Terrain Height Manipulation

Post by dark_sylinc »

Editing the terrain should be straightforward.
The heightmap data is stored in Terra::m_heightMapTex which is a TexturePtr and can be obtained via Terra::getHeightMapTex.

Like xrgo said, editing in the GPU would be much faster (and probably easier) than editing in the CPU.
Alternatively the data could be edited from the CPU by modifying Terra::m_heightMap

There are a couple observations:
  • Editing GPU side would mean m_heightMapTex would probably need to be created with TU_RENDERTARGET (or use a separate clone of the texture with TU_RENDERTARGET, and then blit/copy the data from this clone to m_heightMapTex, all GPU side)
  • Editing GPU would mean at some point you need to read back contents from GPU (doesn't have to be immediate) so that m_heightMap is updated (otherwise Terra::getHeightAt won't work properly)
  • The values in m_heightMapTex and m_heightMap aren't in the same space/range. See Terra::createHeightmap how the values from the texture get transformed when writing to m_heightMap. It's:

    Code: Select all

    const float maxValue = powf( 2.0f, (float)image.getBPP() ) - 1.0f;
    const float invMaxValue = 1.0f / maxValue;
    m_heightMap[y * m_width + x] = (data[y * m_width + x] * invMaxValue) * m_height
    If you modify from CPU and need to update the GPU, obviously you should do the inverse of these operations.
  • Normals would need to be regenerated. Right now Terra::createNormalTexture performs both creation and update; but if it is split in two, it could perform update without having to recreate resources (performance optimization).
  • m_skirtSize needs to be updated to avoid showing "cracks" between LOD transitions. m_skirtSize is calculated via an heuristic based on heightmap data. If the m_skirtSize is too small, the artifacts become visible. If m_skirtSize is too high, you may have an unnecessary performance degradation. Probably for real time editing something much faster than recalculating m_skirtSize every time you edit the terrain would be to just use a conservatively large value and pay the performance price for real time editing.
TL;DR version: Editing requires modifying the contents of Terra::m_heightMapTex (GPU side), Terra::m_heightMap (CPU side) and the normal maps (just call Terra::createNormalTexture when you're done editing, but take in mind createNormalTexture could be optimized). m_skirtSize also needs to be updated or just set it to a large value and forget about it (for real time editing).
IndieGuy11
Halfling
Posts: 50
Joined: Fri May 19, 2017 8:09 pm
x 2

Re: Terrain Height Manipulation

Post by IndieGuy11 »

Wow! Thanks.

We have a direction now, and how we could go about it. We will let you know how things go!

Cheers!
User avatar
Zonder
Ogre Magi
Posts: 1168
Joined: Mon Aug 04, 2008 7:51 pm
Location: Manchester - England
x 73

Re: Terrain Height Manipulation

Post by Zonder »

Ah good I was correct and it's mainly GPU based. I don't think an editor should require the GetHeightAt (it's doing that GPU side for editing). I suppose if you used this as an example of real time terrain deformation then you would need to pull it back.
There are 10 types of people in the world: Those who understand binary, and those who don't...
IndieGuy11
Halfling
Posts: 50
Joined: Fri May 19, 2017 8:09 pm
x 2

Re: Terrain Height Manipulation

Post by IndieGuy11 »

Zonder wrote:Ah good I was correct and it's mainly GPU based. I don't think an editor should require the GetHeightAt (it's doing that GPU side for editing). I suppose if you used this as an example of real time terrain deformation then you would need to pull it back.

I Think
Yes, its passing the vector float for the heightmap to the GPU (still have to look where this is happening), and GPU is calculating everything and reading it back.


So, if we wanted a pure GPU Based on, we would directly manipulate the vertex at mouse position (depending on the size of manipulation) with either an increase or decrease. Atleast thats what I would want to do.
IndieGuy11
Halfling
Posts: 50
Joined: Fri May 19, 2017 8:09 pm
x 2

Re: Terrain Height Manipulation

Post by IndieGuy11 »

Ive been looking over this sample, and I think I see where you update the renderable position, assuming its doing it at: void TerrainCell::uploadToGpu( uint32 * RESTRICT_ALIAS gpuPtr ) const

One question I have is, how can the Renderable objects know their location? I assume the GPU is calculating this in the sample. But I just want to be clear. We have one Moveable Object, and then we have arrays of renderables, and each renderable gets a shader pass that updates the information (location, uv, etc, etc).

So, is there anyway to set the Position without using GPU? My very basic first test is to store all these renderables into an array, and then store the height for them in an array, and update each renderable's height based on the float array (exactly how the sample does it). However, could the same be done with their positon(just like the height)?

Thanks! Hope I was clear.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: Terrain Height Manipulation

Post by dark_sylinc »

The height is data driven, but the XZ position is not. The system assumes all vertices are uniformly distributed like a 2D grid and generates them on the fly in vertex shader.

In code (simplified) it does something like:

Code: Select all

Pos.x = renderableOffset.x + floor( vertexIndex / maxVerticesPerRow ) * renderableScale.x;
Pos.z = renderableOffset.z + mod( vertexIndex, maxVerticesPerRow ) * renderableScale.z;
What we communicate to the GPU via uploadToGpu is the offset, scale and maxVerticesPerRow.
But the individual xz positions of each vertex cannot be modified arbitrarily because they're defined by a mathematical formula and there's no RAM allocated for them in neither CPU or GPU.
IndieGuy11
Halfling
Posts: 50
Joined: Fri May 19, 2017 8:09 pm
x 2

Re: Terrain Height Manipulation

Post by IndieGuy11 »

Hello,

Thanks for the reply. Ive been looking more and more into this, and it seems like I would have to implement my own HLMS (like the sample does). At first, this was not really clear! :)

Just so I am not totally confused, and this may sound like a strange question ... but is there anyway to set my own Vertex and Fragment shaders, and set my own input variables? For example, I was thinking I could give the renderables a QueID, and then pass a texture, fragment and vertex shader to them, and push my own variables like a global float map, and change things on the fly using a simple lookup ID in an array. But Maybe this is not possible! I am a bit new to this so the ideas are just ideas without any knowhow of whats possible.

Reading this: http://www.ogre3d.org/forums/viewtopic.php?f=2&t=85410
It seems like a no (but that was a long time ago).

If not, ill go ahead and get something basic working with: http://www.ogre3d.org/forums/viewtopic. ... 79#p519340

And then after I learn the systems Ill feel a bit more comfortable using the Tera code.
IndieGuy11
Halfling
Posts: 50
Joined: Fri May 19, 2017 8:09 pm
x 2

Re: Terrain Height Manipulation

Post by IndieGuy11 »

Hello, hate to be asking so many questions, and I do apologize, I am putting my time in and trying to learn from the samples. (its not super obvious whats going on)

Code: Select all

void TerrainCell::uploadToGpu( uint32 * RESTRICT_ALIAS gpuPtr ) const
    {
        //uint32 rows = (m_sizeZ + (1u << m_lodLevel) - 1u) >> m_lodLevel;
        VertexArrayObject *vao = mVaoPerLod[VpNormal][0];

        //uvec4 numVertsPerLine
        gpuPtr[0] = m_verticesPerLine;
        gpuPtr[1] = m_lodLevel;
        gpuPtr[2] = vao->getPrimitiveCount() / m_verticesPerLine - 2u;
        gpuPtr[3] = *reinterpret_cast<uint32*>( &m_parentTerra->m_skirtSize );

        //ivec4 xzTexPosBounds
        ((int32*RESTRICT_ALIAS)gpuPtr)[4] = m_gridX;
        ((int32*RESTRICT_ALIAS)gpuPtr)[5] = m_gridZ;
        ((int32*RESTRICT_ALIAS)gpuPtr)[6] = m_parentTerra->m_width - 1u;
        ((int32*RESTRICT_ALIAS)gpuPtr)[7] = m_parentTerra->m_depth - 1u;

        ((float*RESTRICT_ALIAS)gpuPtr)[8]  = m_parentTerra->m_terrainOrigin.x;
        ((float*RESTRICT_ALIAS)gpuPtr)[9]  = m_parentTerra->m_terrainOrigin.y;
        ((float*RESTRICT_ALIAS)gpuPtr)[10] = m_parentTerra->m_terrainOrigin.z;
        ((float*RESTRICT_ALIAS)gpuPtr)[11] = m_parentTerra->m_invWidth;

        ((float*RESTRICT_ALIAS)gpuPtr)[12] = m_parentTerra->m_xzRelativeSize.x;
        ((float*RESTRICT_ALIAS)gpuPtr)[13] = m_parentTerra->m_height;
        ((float*RESTRICT_ALIAS)gpuPtr)[14] = m_parentTerra->m_xzRelativeSize.y;
        ((float*RESTRICT_ALIAS)gpuPtr)[15] = m_parentTerra->m_invDepth;
    }
What is this doing? What shader is it using? Is it a cuda program, or a opencl program? It be nice to get the file its using so I can compare and trace back how its working.

Also:

Code: Select all

const HlmsCache* HlmsTerra::createShaderCacheEntry( uint32 renderableHash,
                                                            const HlmsCache &passCache,
                                                            uint32 finalHash,
                                                            const QueuedRenderable &queuedRenderable )
...
GpuProgramParametersSharedPtr vsParams = retVal->pso.vertexShader->getDefaultParameters();
        vsParams->setNamedConstant( "heightMap", 0 );
I assume its slot 0, but what does this actually mean? Any materials on this online about shader programming would help clear it up. Where is it being set in code for the texture to use this? I am new to shader programming, so this may be my confusion, but does the GPU automatically put the texture information here? For example inside:

GpuNormalMapper_ps.hlsl:

Code: Select all

Texture2D<float> heightMap;

struct PS_INPUT
{
	float2 uv0 : TEXCOORD0;
};
There is also other things being set in this function, that im a bit unclear on, for example ...

Code: Select all

psParams->setNamedConstant( "terrainNormals", 1 );
psParams->setNamedConstant( "terrainShadows", 2 );
psParams->setNamedConstant( "f3dGrid",      3 );
psParams->setNamedConstant( "f3dLightList", 4 );
psParams->setNamedConstant( "textureMaps[" + StringConverter::toString( i ) + "]", texUnit++ );
psParams->setNamedConstant( "texEnvProbeMap", texUnit++ );
Again, where is this being used? Is this using the generic HLSL files? Which files.


I understand where these are being set:

Code: Select all

float4 main
(
	PS_INPUT inPs,
	uniform float2 heightMapResolution,
	uniform float3 vScale
) : SV_Target
{
Inside: void Terra::createNormalTexture(void)

Code: Select all

GpuProgramParametersSharedPtr psParams = pass->getFragmentProgramParameters();
        psParams->setNamedConstant( "heightMapResolution", Vector4( static_cast<Real>( m_width ),
                                                                    static_cast<Real>( m_depth ),
                                                                    1, 1 ) );
        psParams->setNamedConstant( "vScale", vScale );
After clearing this up, I will be really close to understanding the system better. Starting from ground 0, since there is no other examples that are basic, so basics I must learn!

Thanks for your time.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: Terrain Height Manipulation

Post by dark_sylinc »

Yeah, unfortunately I haven't yet find the time to prepare a simple series of Hlms introduction samples.
IndieGuy11 wrote:

Code: Select all

void TerrainCell::uploadToGpu( uint32 * RESTRICT_ALIAS gpuPtr ) const
    {
        //uint32 rows = (m_sizeZ + (1u << m_lodLevel) - 1u) >> m_lodLevel;
        VertexArrayObject *vao = mVaoPerLod[VpNormal][0];

        //uvec4 numVertsPerLine
        gpuPtr[0] = m_verticesPerLine;
        gpuPtr[1] = m_lodLevel;
        gpuPtr[2] = vao->getPrimitiveCount() / m_verticesPerLine - 2u;
        gpuPtr[3] = *reinterpret_cast<uint32*>( &m_parentTerra->m_skirtSize );

        //ivec4 xzTexPosBounds
        ((int32*RESTRICT_ALIAS)gpuPtr)[4] = m_gridX;
        ((int32*RESTRICT_ALIAS)gpuPtr)[5] = m_gridZ;
        ((int32*RESTRICT_ALIAS)gpuPtr)[6] = m_parentTerra->m_width - 1u;
        ((int32*RESTRICT_ALIAS)gpuPtr)[7] = m_parentTerra->m_depth - 1u;

        ((float*RESTRICT_ALIAS)gpuPtr)[8]  = m_parentTerra->m_terrainOrigin.x;
        ((float*RESTRICT_ALIAS)gpuPtr)[9]  = m_parentTerra->m_terrainOrigin.y;
        ((float*RESTRICT_ALIAS)gpuPtr)[10] = m_parentTerra->m_terrainOrigin.z;
        ((float*RESTRICT_ALIAS)gpuPtr)[11] = m_parentTerra->m_invWidth;

        ((float*RESTRICT_ALIAS)gpuPtr)[12] = m_parentTerra->m_xzRelativeSize.x;
        ((float*RESTRICT_ALIAS)gpuPtr)[13] = m_parentTerra->m_height;
        ((float*RESTRICT_ALIAS)gpuPtr)[14] = m_parentTerra->m_xzRelativeSize.y;
        ((float*RESTRICT_ALIAS)gpuPtr)[15] = m_parentTerra->m_invDepth;
    }

What is this doing? What shader is it using? Is it a cuda program, or a opencl program? It be nice to get the file its using so I can compare and trace back how its working.[/code]
Technically, all it does is fill a buffer that resides in GPU memory.
This buffer could be used by any shader, but TerrainCell::uploadToGpu gets called from within HlmsTerra::fillBuffersFor, and like a couple lines above it says in all caps :lol: :

Code: Select all

//---------------------------------------------------------------------------
//                          ---- VERTEX SHADER ----
//---------------------------------------------------------------------------
So yeah, that buffer is mostly meant for the vertex shader (although the pixel shader could be able to see it just fine, and use it as well).

The pointer we pass is "currentMappedConstBuffer" which comes from mCurrentMappedConstBuffer, and that's a buffer shared by multiple instances which gets reset when it gets full (we grab a new buffer) or with every preparePassHash call.

In terms of shader code, it corresponds to Samples/Media/Hlms/Terra/GLSL/Structs_piece_vs_piece_ps.glsl

Code: Select all

struct CellData
{
	//.x = numVertsPerLine
	//.y = lodLevel
	//.z = vao->getPrimitiveCount() / m_verticesPerLine - 2u
	//.w = skirtY (float)
	uvec4 numVertsPerLine;
	ivec4 xzTexPosBounds;		//XZXZ
	vec4 pos;		//.w contains 1.0 / xzTexPosBounds.z
	vec4 scale;		//.w contains 1.0 / xzTexPosBounds.w
};

layout_constbuffer(binding = 2) uniform InstanceBuffer
{
	CellData cellData[256];
} instance;
You will see the data we fill in uploadToGpu corresponds to one entry in CellData.
Why 256? Because we could have just 1; but that would mean we have to rebind the const buffer too often for each offset (increasing CPU overhead); and we don't have more than 256 because const buffers have a max limit of 64kb but some OpenGL cards have a 16kb limit for unknown reasons, and each entry in the array is 64 bytes. So 256 * 64 = 16384 (16kb)

If we've rendered more than 256 cells, we grab a new const buffer, start from 0 again and keep rendering.
IndieGuy11 wrote: Also:

Code: Select all

const HlmsCache* HlmsTerra::createShaderCacheEntry( uint32 renderableHash,
                                                            const HlmsCache &passCache,
                                                            uint32 finalHash,
                                                            const QueuedRenderable &queuedRenderable )
...
GpuProgramParametersSharedPtr vsParams = retVal->pso.vertexShader->getDefaultParameters();
        vsParams->setNamedConstant( "heightMap", 0 );
I assume its slot 0, but what does this actually mean? Any materials on this online about shader programming would help clear it up. Where is it being set in code for the texture to use this? I am new to shader programming, so this may be my confusion, but does the GPU automatically put the texture information here?
Textures are bound to "slots". OpenGL offers up to 31 slots, Direct3D offers up to 128; although for various reasons Ogre limits it to 16 slots (this restriction is getting fixed in Ogre 2.2).

From C++ we need to bind a texture to a particular slot, and the shader needs to read the texture from that same slot; otherwise it will be looking in the wrong place and bad thing would happen (from API errors, to glitches, to system errors).

We need to set both the texture and the shader to slot 0.

Ogre binds the texture to slot 0 when it performs this:

Code: Select all

*commandBuffer->addCommand<CbTexture>() =
        CbTexture( [b]0[/b], true, terraObj->getHeightMapTex().get() );
The 0 stands for the slot 0.

In OpenGL the shader is set to slot 0 from C++ here:

Code: Select all

GpuProgramParametersSharedPtr vsParams = retVal->pso.vertexShader->getDefaultParameters();
        vsParams->setNamedConstant( "heightMap", 0 );
In Direct3D, the shader code is the one responsible for setting the slot:

Code: Select all

Texture2D<float> heightMap: register(t0);
For example inside:
IndieGuy11 wrote: GpuNormalMapper_ps.hlsl:

Code: Select all

Texture2D<float> heightMap;

struct PS_INPUT
{
	float2 uv0 : TEXCOORD0;
};
GpuNormalMapper_ps is not part of the Hlms that renders the terrain; therefore it's not controlled by HlmsTerra.
It is a low level material, and thus the settings are handled by the material script in Samples/Media/2.0/scripts/materials/Tutorial_Terrain/GpuNormalMapper.material (and also by GpuNormalMapper.compositor)
I think there's some C++ handling as well, but it's not done inside the HlmsTerra class. HlmsTerra only handles the rendering.
The GpuNormalMapper is a shader to generate normals which is only ran at initialization (since normals never change unless the heightmap were to change).
IndieGuy11 wrote: There is also other things being set in this function, that im a bit unclear on, for example ...

Code: Select all

psParams->setNamedConstant( "terrainNormals", 1 );
psParams->setNamedConstant( "terrainShadows", 2 );
psParams->setNamedConstant( "f3dGrid",      3 );
psParams->setNamedConstant( "f3dLightList", 4 );
psParams->setNamedConstant( "textureMaps[" + StringConverter::toString( i ) + "]", texUnit++ );
psParams->setNamedConstant( "texEnvProbeMap", texUnit++ );
Again, where is this being used? Is this using the generic HLSL files? Which files.
Check the files inside Samples/Media/Hlms/Terra.
You tell from C++ HlmsTerra to look there on initialization:

Code: Select all

Ogre::Archive *archiveTerra = Ogre::ArchiveManager::getSingletonPtr()->load(
                [b]dataFolder + "Hlms/Terra/" + shaderSyntax[/b],
                "FileSystem", true );
Ogre::HlmsTerra *hlmsTerra = OGRE_NEW Ogre::HlmsTerra( archiveTerra, &library );
Btw, the template files may be a little hard to see what's going; so it's better to first study the generated shader files (which should be dumped in the same folder where the .exe is located e.g. something like 84654123_PixelShader.glsl and _VertexShader.glsl) to understand how the final working version looks like, and then analyze the templates to see how it's being generated.
IndieGuy11
Halfling
Posts: 50
Joined: Fri May 19, 2017 8:09 pm
x 2

Re: Terrain Height Manipulation

Post by IndieGuy11 »

Hey dark_sylinc,

Thank you for taking the time and doing this for all of us.

I ripped apart the Terra Example, and right now im getting some custom shaders to work (very basic). Since I have a better understanding of the process!

Once I can get something working, ill post my example so hopefully others can benfit, and add any corrections!

In the meantime, hopefully we get those introductory examples! :D :D :D :D

Cheers!
IndieGuy11
Halfling
Posts: 50
Joined: Fri May 19, 2017 8:09 pm
x 2

Re: Terrain Height Manipulation

Post by IndieGuy11 »

Hello! Thanks again for the continued support and helpful insights. I know you are busy with other things (as we all are), so whenever you have time, Id appreciate some insight! :)

Code: Select all

D3D11 device cannot Clear State
Error Description:ID3D11DeviceContext::DrawIndexedInstanced: Draw cannot be invoked while a bound Resource is currently mapped. The Vertex Shader Constant Buffer at slot (2) is still mapped.
I keep getting this issue, Ive been trying to get something barebones working by using the Terra Sample as a base, and trying to have something barebones like this guy does: http://www.ogre3d.org/forums/viewtopic. ... 79#p519340 -- Everything compiles but I get this issue.

Getting insight why this would be happening(more detail and possible reasons) would help a lot. I assume its because my shader code is wrong. But its hard to know whats wrong when trying to hack together the sample.

Also, ive noticed in the Terra Sample:

Code: Select all

onst HlmsCache* HlmsTerra::createShaderCacheEntry( uint32 renderableHash,
                                                            const HlmsCache &passCache,
                                                            uint32 finalHash,
                                                            const QueuedRenderable &queuedRenderable )
    {
        const HlmsCache *retVal = Hlms::createShaderCacheEntry( renderableHash, passCache, finalHash,
                                                                queuedRenderable );

        if( mShaderProfile == "hlsl" )
        {
            mListener->shaderCacheEntryCreated( mShaderProfile, retVal, passCache,
                                                mSetProperties, queuedRenderable );
            return retVal; //D3D embeds the texture slots in the shader.
        }
createShaderCacheEntry will always return from mShaderProfile (because Im using DX11). Could you explain a bit more in detail what this comment means, and why opengl needs to be different: "//D3D embeds the texture slots in the shader."

Thanks! We are almost there! ^_^
Lax
Hobgoblin
Posts: 583
Joined: Mon Aug 06, 2007 12:53 pm
Location: Saarland, Germany
x 50

Re: Terrain Height Manipulation

Post by Lax »

Hi all,

I'm sorry for asking... but does anyone got deforming/painting terra working and is willing to share some code?

Best Regards
Lax

http://www.lukas-kalinowski.com/Homepage/?page_id=1631
Please support Second Earth Technic Base built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd1 ... b97b79be62

Nucleartree
Kobold
Posts: 28
Joined: Tue Apr 04, 2017 9:10 pm
Location: Cardiff, UK
x 16

Re: Terrain Height Manipulation

Post by Nucleartree »

Hi.

I recently followed Dark_Sylinc's advice in this thread to implement editable terrain for my level editor. You can find the code here https://gitlab.com/edherbert/southsea/t ... rain/terra

It has some caveats:
  • Currently only supports Ogre 2.1. I don't have time right now to update it to 2.2, although that should happen soon!
  • Is entirely cpu based. I needed to be able to undo and redo terrain edits and I thought this would get complex if it was done on the gpu. I do hope to be able to update it in future.
  • To my knowledge it only works with opengl (because that's all I've tested it with).
It edits fine in real time so I don't feel like I need to change it because of efficiency. It makes use of this sort of thing:

Code: Select all

v1::HardwarePixelBufferSharedPtr pixelBufferBuf = m_heightMapTex->getBuffer(0, 0);
const Ogre::PixelBox &pixBox =
pixelBufferBuf->lock(Ogre::Image::Box(0, 0, pixelBufferBuf->getWidth(), pixelBufferBuf->getHeight()), Ogre::v1::HardwareBuffer::HBL_NORMAL);

Ogre::uint16* pDest = static_cast<Ogre::uint16*>(pixBox.data);

size_t pitch = pixBox.rowPitch;
for(int y = 0; y < m_heightMapTex->getHeight(); y++){
    for(int x = 0; x < m_heightMapTex->getWidth(); x++){
        *pDest++ = 0;
    }
}

pixelBufferBuf->unlock();
I know the pixel box and buffer stuff has changed in 2.2 but hopefully this helps you. Maybe if you check back in a year I'll have changed it!
Lax
Hobgoblin
Posts: 583
Joined: Mon Aug 06, 2007 12:53 pm
Location: Saarland, Germany
x 50

Re: Terrain Height Manipulation

Post by Lax »

Hi Nucleartree,

thanks for sharing :D !

Code: Select all

Currently only supports Ogre 2.1. I don't have time right now to update it to 2.2, although that should happen soon!
Yeah that would be gread, Ogre2.2 is totally fast due to its texture streaming, so its worth porting everything to Ogre2.2.
It edits fine in real time so I don't feel like I need to change it because of efficiency.
I see it the same way, its an editing feature, as long as its possible to do in realtime, thats fine.

I will orientate on your implementation and try to introduce it to my NOWA-Engine.

Best Regards
Lax

http://www.lukas-kalinowski.com/Homepage/?page_id=1631
Please support Second Earth Technic Base built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd1 ... b97b79be62

Lax
Hobgoblin
Posts: 583
Joined: Mon Aug 06, 2007 12:53 pm
Location: Saarland, Germany
x 50

Re: Terrain Height Manipulation

Post by Lax »

Hi folks,

I just wanted to show my progress with terra deforming and splatting. I'm using Ogre2.2. It is still not finished.

http://www.lukas-kalinowski.com/Homepag ... terra1.mp4

Especially I'm having crashes, as soon as I use a detail normal map.

Code: Select all

13:35:21: OGRE EXCEPTION(-2147467259:RenderingAPIException): Cannot compile D3D11 high-level shader 700000008PixelShader_ps Errors:
C:\Users\lukas\Documents\GameEngineDevelopment\bin\Debug\700000008PixelShader_ps.hlsl(1070,41-50): error X3004: undeclared identifier 'geomNormal'
 in D3D11HLSLProgram::compileMicrocode at C:\Users\lukas\Documents\GameEngineDevelopment\external\Ogre2.2SDK\RenderSystems\Direct3D11\src\OgreD3D11HLSLProgram.cpp (line 569)
13:35:21: High-level program 700000008PixelShader_ps encountered an error during loading and is thus not supported.
OGRE EXCEPTION(-2147467259:RenderingAPIException): Cannot compile D3D11 high-level shader 700000008PixelShader_ps Errors:
C:\Users\lukas\Documents\GameEngineDevelopment\bin\Debug\700000008PixelShader_ps.hlsl(1070,41-50): error X3004: undeclared identifier 'geomNormal'
 in D3D11HLSLProgram::compileMicrocode at C:\Users\lukas\Documents\GameEngineDevelopment\external\Ogre2.2SDK\RenderSystems\Direct3D11\src\OgreD3D11HLSLProgram.cpp (line 569)
13:35:21: OGRE EXCEPTION(-2147467259:RenderingAPIException): Cannot compile D3D11 high-level shader 700000009PixelShader_ps Errors:
C:\Users\lukas\Documents\GameEngineDevelopment\bin\Debug\700000009PixelShader_ps.hlsl(1070,41-50): error X3004: undeclared identifier 'geomNormal'
 in D3D11HLSLProgram::compileMicrocode at C:\Users\lukas\Documents\GameEngineDevelopment\external\Ogre2.2SDK\RenderSystems\Direct3D11\src\OgreD3D11HLSLProgram.cpp (line 569)
13:35:21: High-level program 700000009PixelShader_ps encountered an error during loading and is thus not supported.
OGRE EXCEPTION(-2147467259:RenderingAPIException): Cannot compile D3D11 high-level shader 700000009PixelShader_ps Errors:
C:\Users\lukas\Documents\GameEngineDevelopment\bin\Debug\700000009PixelShader_ps.hlsl(1070,41-50): error X3004: undeclared identifier 'geomNormal'
 in D3D11HLSLProgram::compileMicrocode at C:\Users\lukas\Documents\GameEngineDevelopment\external\Ogre2.2SDK\RenderSystems\Direct3D11\src\OgreD3D11HLSLProgram.cpp (line 569)
I think, terra has never been tested with normal maps, as in the "TerraExampleMaterial" no normal maps are used.

Best Regards
Lax

http://www.lukas-kalinowski.com/Homepage/?page_id=1631
Please support Second Earth Technic Base built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd1 ... b97b79be62

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: Terrain Height Manipulation

Post by dark_sylinc »

Ouch!

That must been a porting error from 2.1

I'll take a look when I get some time for it. Apologies for the problem
Lax
Hobgoblin
Posts: 583
Joined: Mon Aug 06, 2007 12:53 pm
Location: Saarland, Germany
x 50

Re: Terrain Height Manipulation

Post by Lax »

Hi,
I'll take a look when I get some time for it. Apologies for the problem
ok thanks!

I just wanted to report another issue.

Code: Select all

Ogre::Image2::scale
Does also crash, I tried several approaches in order to scale a terrain brush, but without success.

Best Regards
Lax

http://www.lukas-kalinowski.com/Homepage/?page_id=1631
Please support Second Earth Technic Base built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd1 ... b97b79be62

Lax
Hobgoblin
Posts: 583
Joined: Mon Aug 06, 2007 12:53 pm
Location: Saarland, Germany
x 50

Re: Terrain Height Manipulation

Post by Lax »

Hi dark_sylinc,
Ouch!

That must been a porting error from 2.1

I'll take a look when I get some time for it. Apologies for the problem
I just tested terra with newest Ogre2.2 version and It seems as if the normal maps functionality is still faulty as I'm still getting a runtime crash because of PixelShader.

Another small thing:

In OgreHlmsTerraDatablock.cpp mDetailsOffsetScale is an array of 4 elements, but

Code: Select all

setDetailMapOffsetScale
can be called up to index 7. think this is wrong.

Code: Select all

void HlmsTerraDatablock::setDetailMapOffsetScale( uint8 detailMap, const Vector4 &offsetScale )
    {
        assert( detailMap < 8 );
        bool wasDisabled = mDetailsOffsetScale[detailMap] == Vector4( 0, 0, 1, 1 );

        mDetailsOffsetScale[detailMap] = offsetScale;

        if( wasDisabled != (mDetailsOffsetScale[detailMap] == Vector4( 0, 0, 1, 1 )) )
        {
            flushRenderables();
        }

        scheduleConstBufferUpdate();
    }
Best Regards
Lax

http://www.lukas-kalinowski.com/Homepage/?page_id=1631
Please support Second Earth Technic Base built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd1 ... b97b79be62

Nickak2003
Goblin
Posts: 272
Joined: Thu Jun 10, 2004 4:19 am
x 26

Re: Terrain Height Manipulation

Post by Nickak2003 »

Terra normal map code is broke, it I corrected it in my app though, I will make a post. It was broke in earlier versions I used , too.

What I had to do was add shader code, add c++ code. The terra code doesn't have any tangents, which to my knowledge are necessary. The terra shader code itself is syntax broken, and as far as I can tell, feature broken, not referencing a tangent map. I added a tangent map texture and reference it in the terra shader.

example:
Post Reply