Topic: terrain ?

Hi there,

You've put alot of work into this, and thx for that, including the more than generous license.

I was wondering if you had any plans of adding terrain support, or if it already exists as a
export from blender possibly ?

Terrain is mandatory for what I'm doing atm.

I checked, but saw no mention of it, unless I missed it.

One last thing..I checked out some docs, but hardly anything is explained.

Solo project I get that, and little time to work fullltime on it no doubt,
but how is anyone to  know where to even start ? wink)



cheers
leebo

Last edited by VeganDev (2011-02-09 03:26:59)

Re: terrain ?

Hi gamemaler,

for now I don't have imediate plan for terrain support, my priority is on tutorials and doc,
you can of course export terrain from blender but it will be static triangles (so less optimized than a terrain algo).

If in Blender you split your mesh in multiple objects and export as 1 mesh it can work good (it will create sub-mesh in the mesh format wich are drawn only if visible).

You can use normal mapping to add visual relief if you want to limit triangles.
You can also bake lighmap in blender and use the texture as Emit texture.


I know it's not easy to know where to start, tutorials are my priority,
I'm trying to find some funds to be able to spend more time but I'm not waiting it to start.

For now, the best is to look at the examples wich are included in the release,
and the links wish are there : http://www.maratis3d.com/?page_id=53

Re: terrain ?

Hi there,

Thanks so much for reply, and I shall indeed give the sub-mesh thing a try.

smile
cheers
gm


anael wrote:

Hi gamemaler,

for now I don't have imediate plan for terrain support, my priority is on tutorials and doc,
you can of course export terrain from blender but it will be static triangles (so less optimized than a terrain algo).

If in Blender you split your mesh in multiple objects and export as 1 mesh it can work good (it will create sub-mesh in the mesh format wich are drawn only if visible).

You can use normal mapping to add visual relief if you want to limit triangles.
You can also bake lighmap in blender and use the texture as Emit texture.


I know it's not easy to know where to start, tutorials are my priority,
I'm trying to find some funds to be able to spend more time but I'm not waiting it to start.

For now, the best is to look at the examples wich are included in the release,
and the links wish are there : http://www.maratis3d.com/?page_id=53

Re: terrain ?

L3DT has a free version of it's terrain tool. It has some really good tools and even has a normal mapping exporting.Don't know how you would export this to Blender/Maratis though.

http://www.bundysoft.com/L3DT/

Re: terrain ?

Hi there,

Indeed, I think terrain will be a great feature for Maratis.

I tried Win32 Maratis version last evening and as gamemaker mentioned, you've put a lot of work into Maratis.
What I understand:
Blender (another very good opensource tools) is used to create objects to be add in the Maratis project after export operation.
So, I think if we want to keep a very hard link with Blender, you have to create maybe Python scripts to export terrain datasets and add adaptive algorithms in Maratis to produce high quality terrain rendering for all the target platforms.

What do you think?

Some useful informations can be found here:
Real-Time Rendering Resources: http://www.realtimerendering.com/
Terrain LOD Published Papers: http://www.vterrain.org/LOD/Papers/


For now, anael is right creating tutorials in first priority because you can't use a new tool without having some best practices.

Last point:
after testing Maratis last evening, I got ideas:

  • logging facility to help debugging (log4cxx ?)

  • unit testing framework (CPP Unit ?)

  • porting to android

How could we help improving general quality, engine and editor?

Thanks your your attention.

Re: terrain ?

Hi,
thanks for the links.
Of course native terrain will be a great support, for now, the way is to create terrain as a mesh,
and as it is not making a so bad result, native terrain support is not on top of the list.

To help improving, the first thing I would like is to see people playing with Maratis and sharing the result in the forum,
to show what is possible and share experience.

Then, what will help is to contribute in the development :

- A Linux port will be very appreciated by users, it can be fast to do for an experimented Linux developer.
Only one class need to be ported, MGuiWindow (window init, input events etc) and maybe a #define/include will need to be added in MGLContext and MALContext.

- The other thing will be for an iOS and Android developer to share some code to link Maratis-Engine into a iOS or Android context. A simpler imageLoader and soundLoader will maybe need to be added for iOS, as it is not compatible LGPL (for DevIL and libsndfile).

- Helping doing a "one clic" project publishing : converting xml to binary, automatically copying project files + MaratisPlayer. And if iOS and Android port is done, automatically compiling app.


Another thing about using and playing with Maratis, the way the game plugin works, you have full access to the SDK (engine) in c++, you can use render to texture, draw triangles manually etc. If you really need a special feature, like LOD or adaptive terrain, if you have a developer in your team or if you are developer yourself, you can render terrain with your own code (using virtual MGame::draw()). So your game is having the feature you need, and you can then decide to share this code, to be included by default in the engine. that's why I'm saying the first thing to help is to try playing with it and doing game or demos.

I will try to make more examples to show how to use custom code inside a game plugin.

Thank you,
Anaël.

Re: terrain ?

Hey there,

my project is an FPS and i will make grass, but i dont know how?
Help, please!

Áron

Last edited by csaron92 (2011-03-02 13:02:47)

Re: terrain ?

Here is a free terrain making tool that allows you to create the terrain, texture it and place models such as rocks , tree's ect. You can export to obj so blender should be able to use this.

http://www.pnp-terraincreator.com/

Re: terrain ?

Kurtz wrote:

Here is a free terrain making tool that allows you to create the terrain, texture it and place models such as rocks , tree's ect. You can export to obj so blender should be able to use this.

http://www.pnp-terraincreator.com/

The trouble with this, is that its not free, and the free 'version' is rather limited. I have no idea what '3x3' even means,
does anyone ? It's a option anyway, but the other limitations are also very subpar.

cheers
gm

Re: terrain ?

As Kurtz suggested, have you tried L3DT ?
http://www.bundysoft.com/L3DT/

Its a really good terrain generator, can export to obj + texture and also have an
internal mesh decimator who let you choose how much polys u want at export

Otherwise, i found these tools :

Nem's Mega 3D Terrain Generator (free)
(Modeling is easy but setting up textures can be painful)
http://nemesis.thewavelength.net/index.php?p=8

Terragen Classic (free-limited version)
(Can export to OBJ using a plugin)
http://www.planetside.co.uk/content/view/16/28/

EarthSculptor (free-limited version)
(haven't tried this one)
http://www.earthsculptor.com/index.htm

HemaHema (free)
(haven't tried this one)
http://reinerstileset.4players.de/hemahemaE.html

Visual Terrain Maker (free)
(haven't tried this one)
http://www.ungsoft.com/vtm/index.html

Terrain Texture Generator (free)
(load an heightmap and set textures - for me, results were decent but far from perfect)
http://www.saschawillems.de/?page_id=92

TexGen (free)
(load an heightmap and set textures - not worked for me)
http://www.3drad.com/forum/index.php?topic=4128.0

Last edited by Vegas (2011-04-26 16:02:58)

Re: terrain ?

I'm a bit surprised that Blender isn't considered as sufficient for terrain making. It probably depends of the wished size, though.

Create a plane, subdivide it depending of your needs, then restrict the deformation to the z axis, and use the sculpt tool to deform it.
As a result of the Yo Frankie project there is still a shader for blending and painting three different textures on the terrain.
And, depending of the size of the terrain, you can seperate it as different meshes as anael suggested.
Only his suggestion makes a difference in rendering the terrain in the engine at the moment.

Re: terrain ?

I'm also finding Blender quite efficient for terrain making, with sculpting and normal baking it's very powerful. You can also create your own shader to deal with multiple textures and even bake shadows.

Re: terrain ?

Achim Luebbeke wrote:

I'm a bit surprised that Blender isn't considered as sufficient for terrain making. It probably depends of the wished size, though.

Create a plane, subdivide it depending of your needs, then restrict the deformation to the z axis, and use the sculpt tool to deform it.
As a result of the Yo Frankie project there is still a shader for blending and painting three different textures on the terrain.
And, depending of the size of the terrain, you can seperate it as different meshes as anael suggested.
Only his suggestion makes a difference in rendering the terrain in the engine at the moment.

You mention yo frankie for assistance, but do not say where to get this 'shader' from .

Please elaborate a bit wink

thx
gm

Last edited by VeganDev (2011-05-11 15:43:21)

Re: terrain ?

This is what I had in mind:
http://www.wonderhowto.com/how-to-do-re … sl-377669/
I was wrong while remembering, that you could combine three textures, sadly you can combine only two textures in the way shown in the video. You need(!) three textures, but one of them is for the blending.
The version of blender that is used in the video seems to be 2.48, at least it is not 2.49b, the version that I still use from time to time.
The shader should come with blender. Hope it helps.

Re: terrain ?

Can I use stencil map for maratis? One time I tried and my terrain was without texture...

Re: terrain ?

You can use a "CustomShader" Material, and write your own glsl shader,
to blend multiple textures in glsl, using 2 or 3 textures as sources, and one texture used as blending texture.

Here is a very basic fragment shader blending 2 textures :


uniform sampler2D Texture[8];
varying vec2 texCoord[3];

void main(void)
{
    vec4 texture0 = texture2D(Texture[0], texCoord[0]); // first textures               
    vec4 texture1 = texture2D(Texture[1], texCoord[1]); // second texture
    vec4 texture2 = texture2D(Texture[2], texCoord[2]); // blend texture

    float interp = texture2.x; // use the red component
    float invInterp = 1.0 - interp;

    gl_FragColor = texture0*invInterp + texture1*interp;
}

Re: terrain ?

If it's any help , the same process for 2.5x :

http://www.cgmasters.net/category/free- … texturing/

Re: terrain ?

Hi all,

First off, thanks Vegas so much, for 2.5 video, that was quite curteous wink

Is there anyway to sneak 5 textures +1a ?
I was playing guild wars with a friend, and they seem to have at least that many.

No offense meant as reference, just hoping to eek out as much artistic flow as I can.

cheers
gm




Vegas wrote:

If it's any help , the same process for 2.5x :

http://www.cgmasters.net/category/free- … texturing/

Last edited by VeganDev (2011-06-14 22:57:00)

Re: terrain ?

When writing a custom shader, you can use up to 8 textures in total.
For example, you can write a shader using 4 terrain textures + 1 blending texture,
while using each component (R, G, B, A) of the blending texture to blend each terrain texture.

But it's highly possible that a game like guild war is splitting the geometry according to texture use for performance,
mixing A+B in one area, A+C in another etc...

Re: terrain ?

anael wrote:

When writing a custom shader, you can use up to 8 textures in total.

That's why you used a 8 case array ?

anael wrote:

uniform sampler2D Texture[8];
varying vec2 texCoord[3];

but where must we put the textures ? in blender texture slots ? if it's right, the blend texture is on the first slot and the others the followers ?

if I import the CustomShader in a .txt in blender, is that work ?

and it is possible to make the same trick with normal/specular map ?

Re: terrain ?

For Maratis shaders, uniform sampler2D Texture[8]; correspond to the texture slots of the Material.

but where must we put the textures ? in blender texture slots ? if it's right, the blend texture is on the first slot and the others the followers ?

For example, but you can do it in the order you want.

if I import the CustomShader in a .txt in blender, is that work ?

A shader written for Maratis will not be previewed in Blender, it can be adapted but Blender don't use the exact same technique.

and it is possible to make the same trick with normal/specular map ?

You can. For example uses the slots like that :

0:normalMap
1:specularMap
2:blendMap
3:blendA
4:blendB
5:blendC
6:blendD

In your shader you will get the texture data like that :

vec4 normalMap = texture2D(Texture[0], texCoord[0]);
vec4 specularMap = texture2D(Texture[1], texCoord[1]);
vec4 blendMap = texture2D(Texture[2], texCoord[2]);
etc

Re: terrain ?

I was just wondering , does this sub-mesh code require the entire mesh and all subs be loaded into ram or does it just stream as needed< drawn if visible > ?

gm

Last edited by VeganDev (2011-06-23 01:35:45)

Re: terrain ?

the full mesh is loaded, but each sub-mesh is only drawn if visible

Re: terrain ?

I actually have a terrain tutorial coming up for Maratis using blender. It won't cover sub-meshes. But will show a very quick and basic way to create terrain for Maratis.

Re: terrain ?

Hi, I try to transform the standardDSEN shaders (of the customShaders Example) so that it can blend two textures or more on a mesh, but I didn't succeed completely.
could you help me to improve these scripts :

uniform bool AlphaTest;
uniform vec4 FogColor;
uniform float FogEnd;
uniform float FogScale;

uniform vec3 MaterialEmit;
uniform float MaterialShininess;
uniform float MaterialOpacity;

uniform vec4 LightPosition[4];
uniform vec3 LightDiffuseProduct[4];
uniform vec3 LightSpecularProduct[4];
uniform vec3 LightSpotDirection[4];
uniform float LightConstantAttenuation[4];
uniform float LightQuadraticAttenuation[4];
uniform float LightSpotCosCutoff[4];
uniform float LightSpotExponent[4];
uniform bool LightActive[4];

uniform sampler2D LightShadowMap[3];
uniform bool LightShadow[3];
uniform float LightShadowBias[3];
uniform float LightShadowBlur[3];

uniform sampler2D Texture[8];
uniform sampler2D RandTexture;

varying vec4 texCoord[8];
varying vec4 shadowCoord[3];
varying vec4 position, normal, tangent;

vec4 texture0 = texture2D(Texture[0], texCoord[0].xy);                    
vec4 texture1 = texture2D(Texture[1], texCoord[0].zw);
vec4 texture3 = texture2D(Texture[3], texCoord[1].zw);

vec3 diffuse = MaterialEmit*texture3.xyz;
vec3 specular = vec3(0.0, 0.0, 0.0);

vec3 nor = normalize(normal.xyz);
vec3 bi = normalize(-cross(normal.xyz, tangent.xyz));
vec3 tan = normalize(tangent.xyz);

vec3 bump = normalize(texture2D(Texture[2], texCoord[1].xy).xyz * 2.0 - 1.0);

vec3 N = normalize(tan*bump.x + bi*bump.y + nor*bump.z);
vec3 E = normalize(-position.xyz);


float lookup(vec4 shadCoord, sampler2D shadMap, vec2 offSet)
{
    float distanceFromLight = texture2D(shadMap, shadCoord.xy + offSet).z;
    return step(shadCoord.z, distanceFromLight);
}            
                                
float computeShadow(bool shad, vec4 shadCoord, sampler2D shadMap, float shadBias, float shadBlur)
{
    float shadow = 1.0;
    if(shad)
    {
        vec4 shadowCoordinateWdivide = shadCoord;
        shadowCoordinateWdivide.z -= shadBias;

        shadowCoordinateWdivide /= shadowCoordinateWdivide.w;
         
        float blur = (shadBlur*0.01);
        vec4 rand = texture2D(RandTexture, (shadowCoordinateWdivide.xy)*(500.0/(shadBlur+1.0)))*2.0 - 1.0;
        
        vec2 d = rand.xy;
        d = normalize(d)*blur;
                                
        vec2 dp = vec2(d.y, -d.x);
        
        shadow = lookup(shadowCoordinateWdivide, shadMap, rand.zw*blur);
        shadow += lookup(shadowCoordinateWdivide, shadMap,  d);
        shadow += lookup(shadowCoordinateWdivide, shadMap, -d);
        shadow += lookup(shadowCoordinateWdivide, shadMap,  dp);
        shadow += lookup(shadowCoordinateWdivide, shadMap, -dp);
        shadow *= 0.2;

    }                
    return shadow;
}
                                
void computeLight(vec3 lightPosition, float constantAttenuation, float quadraticAttenuation, vec3 lightDiffuse, vec3 lightSpecular, vec3 spotDir, float spotCos, float spotExp, bool shad, vec4 shadCoord, sampler2D shadMap, float shadBias, float shadBlur)
{
    vec3 lightDir = lightPosition - position.xyz;
    vec3 L = normalize(lightDir);

    float lambertTerm = max(dot(N, L), 0.0);
    if(lambertTerm > 0.0)
    {
        if(spotCos > 0.0)
        {
            float spot = dot(spotDir, -L);
            
            if(spot > spotCos)
            {
                float shadow = computeShadow(shad, shadCoord, shadMap, shadBias, shadBlur);
                                
                spot = clamp(pow(spot, spotExp), 0.0, 1.0);
                                
                float lightDirLength2 = dot(lightDir, lightDir);
                float attenuation = (spot / (constantAttenuation + (lightDirLength2 * quadraticAttenuation)))*shadow;

                diffuse = diffuse + (lightDiffuse * lambertTerm * attenuation);

                vec3 S = normalize(E + L);
                float spec = pow(max(dot(S, N), 0.0), MaterialShininess) * attenuation;
                specular = specular + (lightSpecular * spec);
            }
        }
        else
        {
            float lightDirLength2 = dot(lightDir, lightDir);
            float attenuation = (1.0 / (constantAttenuation + (lightDirLength2 * quadraticAttenuation)));

            diffuse = diffuse + (lightDiffuse * lambertTerm * attenuation);

            vec3 S = normalize(E + L);
            float spec = pow(max(dot(S, N), 0.0), MaterialShininess) * attenuation;
            specular = specular + (lightSpecular * spec);
        }
    }
}

void computeLightNoShadow(vec3 lightPosition, float constantAttenuation, float quadraticAttenuation, vec3 lightDiffuse, vec3 lightSpecular, vec3 spotDir, float spotCos, float spotExp)
{
    vec3 lightDir = lightPosition - position.xyz;
    vec3 L = normalize(lightDir);

    float lambertTerm = max(dot(N, L), 0.0);
    if(lambertTerm > 0.0)
    {
        if(spotCos > 0.0)
        {
            float spot = dot(spotDir, -L);
            
            if(spot > spotCos)
            {            
                spot = clamp(pow(spot, spotExp), 0.0, 1.0);
                                
                float lightDirLength2 = dot(lightDir, lightDir);
                float attenuation = (spot / (constantAttenuation + (lightDirLength2 * quadraticAttenuation)));

                diffuse = diffuse + (lightDiffuse * lambertTerm * attenuation);

                vec3 S = normalize(E + L);
                float spec = pow(max(dot(S, N), 0.0), MaterialShininess) * attenuation;
                specular = specular + (lightSpecular * spec);
            }
        }
        else
        {
            float lightDirLength2 = dot(lightDir, lightDir);
            float attenuation = (1.0 / (constantAttenuation + (lightDirLength2 * quadraticAttenuation)));

            diffuse = diffuse + (lightDiffuse * lambertTerm * attenuation);

            vec3 S = normalize(E + L);
            float spec = pow(max(dot(S, N), 0.0), MaterialShininess) * attenuation;
            specular = specular + (lightSpecular * spec);
        }
    }
}


void main(void)
{
    vec4 texture6 = texture2D(Texture[5], texCoord[5]); // blend texture                
        vec4 texture7 = texture2D(Texture[6], texCoord[6]); // second texture
    float interp = texture6.x; // use the red component
        float invInterp = 1.0 - interp;


    if(LightActive[0])
    {
        computeLight(
            LightPosition[0].xyz,
            LightConstantAttenuation[0],
            LightQuadraticAttenuation[0],
            LightDiffuseProduct[0],
            LightSpecularProduct[0],
            LightSpotDirection[0],
            LightSpotCosCutoff[0],
            LightSpotExponent[0],
            LightShadow[0],
            shadowCoord[0],
            LightShadowMap[0],
            LightShadowBias[0],
            LightShadowBlur[0]
        );

        if(LightActive[1])
        {
            computeLight(
                LightPosition[1].xyz,
                LightConstantAttenuation[1],
                LightQuadraticAttenuation[1],
                LightDiffuseProduct[1],
                LightSpecularProduct[1],
                LightSpotDirection[1],
                LightSpotCosCutoff[1],
                LightSpotExponent[1],
                LightShadow[1],
                shadowCoord[1],
                LightShadowMap[1],
                LightShadowBias[1],
                LightShadowBlur[1]
            );

            if(LightActive[2])
            {
                computeLight(
                    LightPosition[2].xyz,
                    LightConstantAttenuation[2],
                    LightQuadraticAttenuation[2],
                    LightDiffuseProduct[2],
                    LightSpecularProduct[2],
                    LightSpotDirection[2],
                    LightSpotCosCutoff[2],
                    LightSpotExponent[2],
                    LightShadow[2],
                    shadowCoord[2],
                    LightShadowMap[2],
                    LightShadowBias[2],
                    LightShadowBlur[2]
                );

                if(LightActive[3])
                {
                    computeLightNoShadow(
                        LightPosition[3].xyz,
                        LightConstantAttenuation[2],
                        LightQuadraticAttenuation[3],
                        LightDiffuseProduct[3],
                        LightSpecularProduct[3],
                        LightSpotDirection[3],
                        LightSpotCosCutoff[3],
                        LightSpotExponent[3]
                    );
                }
            }
        }
    }

    vec4 finalColor = vec4(diffuse*(texture0.xyz*invInterp + texture7.xyz*interp) + specular*texture1.xyz, MaterialOpacity*texture0.w);
    float fogFactor = clamp((FogEnd + position.z) * FogScale, 0.0, 1.0);
    gl_FragColor = mix(FogColor, finalColor, fogFactor);
}

I didn't touch the standartDSEN.vert file, maybe I should have done it ...

attribute vec3 Vertex;
attribute vec3 Normal;
attribute vec3 Tangent;
attribute vec3 Color;

uniform bool LightShadow[3];
uniform mat4 LightShadowMatrix[3];

uniform mat4 TextureMatrix[4];
uniform mat4 ModelViewMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 NormalMatrix;
uniform mat4 ProjModelViewMatrix;

varying vec4 texCoord[2];
varying vec4 shadowCoord[3];
varying vec4 position, normal, tangent;

attribute vec2 TexCoord0;
attribute vec2 TexCoord1;
attribute vec2 TexCoord2;
attribute vec2 TexCoord3;

void main(void)
{
    if(LightShadow[0]) shadowCoord[0] = LightShadowMatrix[0] * vec4(Vertex, 1.0);
    if(LightShadow[1]) shadowCoord[1] = LightShadowMatrix[1] * vec4(Vertex, 1.0);
    if(LightShadow[2]) shadowCoord[2] = LightShadowMatrix[2] * vec4(Vertex, 1.0);

    normal = NormalMatrix * vec4(Normal, 1.0);
    position = ModelViewMatrix * vec4(Vertex, 1.0);
    gl_Position = ProjModelViewMatrix * vec4(Vertex, 1.0);
    texCoord[0].xy = (TextureMatrix[0] * vec4(TexCoord0, 1.0, 1.0)).xy;
    texCoord[0].zw = (TextureMatrix[1] * vec4(TexCoord1, 1.0, 1.0)).xy;
    texCoord[1].xy = (TextureMatrix[2] * vec4(TexCoord2, 1.0, 1.0)).xy;
    texCoord[1].zw = (TextureMatrix[3] * vec4(TexCoord3, 1.0, 1.0)).xy;
        
    tangent = NormalMatrix * vec4(Tangent, 1.0);
}

Last edited by Alinor (2011-08-24 10:29:04)