Re: terrain ?

Do you have error messages in the Maratis console window ?

Re: terrain ?

No, but for example if I use this like blend texture
I have this (with Normal Specular and shadow map) :
http://img4.hostingpics.net/pics/179081Sanstitre.png
the left corner, full red, should be totally the texture2 left corner, but it's a blend between texture1 and texture2 (more texture1)

Last edited by Alinor (2011-08-24 17:12:33)

Re: terrain ?

The code you used was optimized for using only 4 textures,
the varying variable texCoord was packing the data to use less memory,
so for a 8 textures system there was some modification to do :

(i didn't tested it)

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

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

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

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

attribute vec2 TexCoord0;
attribute vec2 TexCoord1;
attribute vec2 TexCoord2;
attribute vec2 TexCoord3;
attribute vec2 TexCoord4;
attribute vec2 TexCoord5;
attribute vec2 TexCoord6;
attribute vec2 TexCoord7;

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] = (TextureMatrix[0] * vec4(TexCoord0, 1.0, 1.0)).xy;
    texCoord[1] = (TextureMatrix[1] * vec4(TexCoord1, 1.0, 1.0)).xy;
    texCoord[2] = (TextureMatrix[2] * vec4(TexCoord2, 1.0, 1.0)).xy;
    texCoord[3] = (TextureMatrix[3] * vec4(TexCoord3, 1.0, 1.0)).xy;
    texCoord[4] = (TextureMatrix[4] * vec4(TexCoord4, 1.0, 1.0)).xy;
    texCoord[5] = (TextureMatrix[5] * vec4(TexCoord5, 1.0, 1.0)).xy;
    texCoord[6] = (TextureMatrix[6] * vec4(TexCoord6, 1.0, 1.0)).xy;
    texCoord[7] = (TextureMatrix[7] * vec4(TexCoord7, 1.0, 1.0)).xy;
        
    tangent = NormalMatrix * vec4(Tangent, 1.0);
}


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 vec2 texCoord[8];
varying vec4 shadowCoord[3];
varying vec4 position, normal, tangent;

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

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[2]).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);
}

Re: terrain ?

that's perfect !!  Thanks wink

http://img4.hostingpics.net/pics/500776essaie1.png

I'll try now to improve this shaders to blend more textures and to blend normal and specular texture wink

Re: terrain ?

cool,
keep in mind that you are limited to 8 textures,
try to pack the textures as much as you can (for example, using the alpha component of the second texture as blend map, in another texture, use red component for the first specular map and green for the second etc).

Re: terrain ?

Hi, this is an example of a shader that can use to make terrain (derived from Anaël's CustomShaders example) :

1er slot : diffuse texture (1000*1000 pixels or less is good enough)
2em slot : blend texture (black, red, green, blue)
3em slot : normal texture n°1(color associated : black) (example : snow)
4em slot : specular texture n°1(color associated : black)
5em slot : normal texture n°2(color associated : red) (example : grass)
6em slot : specular texture n°2(color associated : red)
7em slot : normal texture n°3(color associated : green) (example : grass n°2)
8em slot : normal texture n°4(color associated : blue) (example : ground)


here an example of a blend texture  :
http://img4.hostingpics.net/pics/307203essaimix.png
and this is the script (cut, past and save in a .vert or .frag file) :
frag shader :

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 vec2 texCoord[8];
varying vec4 shadowCoord[3];
varying vec4 position, normal, tangent;

vec4 texture0 = texture2D(Texture[0], texCoord[0]);                    
vec4 texture1 = texture2D(Texture[1], texCoord[1]);
vec4 texture2 = texture2D(Texture[2], texCoord[2]);
vec4 texture3 = texture2D(Texture[3], texCoord[3]);
vec4 texture4 = texture2D(Texture[4], texCoord[4]);
vec4 texture5 = texture2D(Texture[5], texCoord[5]);
vec4 texture6 = texture2D(Texture[6], texCoord[6]);
vec4 texture7 = texture2D(Texture[7], texCoord[7]);

float calcule_oppose (float red, float green, float blue)
{
    if(red>green)
    {
        if (red>blue)
        {
        return (1.0-red);
        }
        else
        {
        return (1.0-blue);
        }
    }
    else if(green>blue) 
    {
    return (1.0-green);
    }    
    else
    {
    return (1.0-blue);
    }
}

float red = texture1.x;
float green = texture1.y;
float blue = texture1.z;
float oppose = calcule_oppose(red,green,blue);

vec3 diffuse = MaterialEmit;
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((texture2.xyz*(oppose/(red+green+oppose+blue))+ texture4.xyz*(red/(red+green+oppose+blue))+texture6.xyz*(green/(red+green+oppose+blue))+texture7.xyz*(blue/(red+green+oppose+blue)))* 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)
{
    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 + specular*(texture3.xyz*(oppose/(red+green+oppose+blue))+ texture5.xyz*(red/(red+green+oppose+blue))), MaterialOpacity*texture0.w);
    float fogFactor = clamp((FogEnd + position.z) * FogScale, 0.0, 1.0);
    gl_FragColor = mix(FogColor, finalColor, fogFactor);
}

vert shader :

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

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

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

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

attribute vec2 TexCoord0;
attribute vec2 TexCoord1;
attribute vec2 TexCoord2;
attribute vec2 TexCoord3;
attribute vec2 TexCoord4;
attribute vec2 TexCoord5;
attribute vec2 TexCoord6;
attribute vec2 TexCoord7;

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] = (TextureMatrix[0] * vec4(TexCoord0, 1.0, 1.0)).xy;
    texCoord[1] = (TextureMatrix[1] * vec4(TexCoord1, 1.0, 1.0)).xy;
    texCoord[2] = (TextureMatrix[2] * vec4(TexCoord2, 1.0, 1.0)).xy;
    texCoord[3] = (TextureMatrix[3] * vec4(TexCoord3, 1.0, 1.0)).xy;
    texCoord[4] = (TextureMatrix[4] * vec4(TexCoord4, 1.0, 1.0)).xy;
    texCoord[5] = (TextureMatrix[5] * vec4(TexCoord5, 1.0, 1.0)).xy;
    texCoord[6] = (TextureMatrix[6] * vec4(TexCoord6, 1.0, 1.0)).xy;
    texCoord[7] = (TextureMatrix[7] * vec4(TexCoord7, 1.0, 1.0)).xy;
        
    tangent = NormalMatrix * vec4(Tangent, 1.0);
}

have fun with maratis wink

Last edited by Alinor (2011-08-25 20:34:43)

Re: terrain ?

Just wondering and thx for doing this..

So, as a total non programmer for the most part < learning as I go>, so I simply copy/paste those into the right slots in the Blender<>maratis exporter, for my texture painted terrain, and then place in the correct subDIR's in maratis, and that should then show up correctly in the maratis editor ?

Sorry for posting on such a old thread,,but its relevant now, that I have time to pursue game development.

cheers
gm


Alinor wrote:

Hi, this is an example of a shader that can use to make terrain (derived from Anaël's CustomShaders example) :

1er slot : diffuse texture (1000*1000 pixels or less is good enough)
2em slot : blend texture (black, red, green, blue)
3em slot : normal texture n°1(color associated : black) (example : snow)
4em slot : specular texture n°1(color associated : black)
5em slot : normal texture n°2(color associated : red) (example : grass)
6em slot : specular texture n°2(color associated : red)
7em slot : normal texture n°3(color associated : green) (example : grass n°2)
8em slot : normal texture n°4(color associated : blue) (example : ground)


here an example of a blend texture  :
http://img4.hostingpics.net/pics/307203essaimix.png
and this is the script (cut, past and save in a .vert or .frag file) :
frag shader :

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 vec2 texCoord[8];
varying vec4 shadowCoord[3];
varying vec4 position, normal, tangent;

vec4 texture0 = texture2D(Texture[0], texCoord[0]);                    
vec4 texture1 = texture2D(Texture[1], texCoord[1]);
vec4 texture2 = texture2D(Texture[2], texCoord[2]);
vec4 texture3 = texture2D(Texture[3], texCoord[3]);
vec4 texture4 = texture2D(Texture[4], texCoord[4]);
vec4 texture5 = texture2D(Texture[5], texCoord[5]);
vec4 texture6 = texture2D(Texture[6], texCoord[6]);
vec4 texture7 = texture2D(Texture[7], texCoord[7]);

float calcule_oppose (float red, float green, float blue)
{
    if(red>green)
    {
        if (red>blue)
        {
        return (1.0-red);
        }
        else
        {
        return (1.0-blue);
        }
    }
    else if(green>blue) 
    {
    return (1.0-green);
    }    
    else
    {
    return (1.0-blue);
    }
}

float red = texture1.x;
float green = texture1.y;
float blue = texture1.z;
float oppose = calcule_oppose(red,green,blue);

vec3 diffuse = MaterialEmit;
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((texture2.xyz*(oppose/(red+green+oppose+blue))+ texture4.xyz*(red/(red+green+oppose+blue))+texture6.xyz*(green/(red+green+oppose+blue))+texture7.xyz*(blue/(red+green+oppose+blue)))* 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)
{
    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 + specular*(texture3.xyz*(oppose/(red+green+oppose+blue))+ texture5.xyz*(red/(red+green+oppose+blue))), MaterialOpacity*texture0.w);
    float fogFactor = clamp((FogEnd + position.z) * FogScale, 0.0, 1.0);
    gl_FragColor = mix(FogColor, finalColor, fogFactor);
}

vert shader :

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

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

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

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

attribute vec2 TexCoord0;
attribute vec2 TexCoord1;
attribute vec2 TexCoord2;
attribute vec2 TexCoord3;
attribute vec2 TexCoord4;
attribute vec2 TexCoord5;
attribute vec2 TexCoord6;
attribute vec2 TexCoord7;

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] = (TextureMatrix[0] * vec4(TexCoord0, 1.0, 1.0)).xy;
    texCoord[1] = (TextureMatrix[1] * vec4(TexCoord1, 1.0, 1.0)).xy;
    texCoord[2] = (TextureMatrix[2] * vec4(TexCoord2, 1.0, 1.0)).xy;
    texCoord[3] = (TextureMatrix[3] * vec4(TexCoord3, 1.0, 1.0)).xy;
    texCoord[4] = (TextureMatrix[4] * vec4(TexCoord4, 1.0, 1.0)).xy;
    texCoord[5] = (TextureMatrix[5] * vec4(TexCoord5, 1.0, 1.0)).xy;
    texCoord[6] = (TextureMatrix[6] * vec4(TexCoord6, 1.0, 1.0)).xy;
    texCoord[7] = (TextureMatrix[7] * vec4(TexCoord7, 1.0, 1.0)).xy;
        
    tangent = NormalMatrix * vec4(Tangent, 1.0);
}

have fun with maratis wink

Re: terrain ?

Hi,

- copy/paste the shaders in a text editor, and save two files in your project, par exemple :
    - MyProject/shaders/terrain.vert (vertex shader)
    - MyProject/shaders/terrain.frag (fragment shader)

- in Blender, select the "CustomShader" mode in the Material and link the two whader :
    http://www.maratis3d.com/wp-content/uploads/2011/01/05.jpg

- use the texture slots according to what Alinor said

Re: terrain ?

This blend shader is only useful for terrain with a single diffuse map, and blend several specular and normal map.

At first, I have thought that is the best solution to make complex terrain, but after I changed my mind to a shader who blend :

1 : blend map (use r, g, b and dark compound)
2 : diffuse 1
3 : normal 1
4 : diffuse 2
5 : normal 2
6 : diffuse 3
7 : normal 3
8 : diffuse 4

I'll post it, when I'll return to my home wink

Last edited by Alinor (2012-10-08 12:53:49)

Re: terrain ?

Im finally (ugh) getting around to doing this, but having googled on the subject of splitting mesh, all I find is doing 'p' in edit mode, and selecting from menu, but that menu won't apply well, unless I can find a way to apply a different material toeach of those , to be split areas.

So how would I do this for a plane , which has been displaced with a heightmap and is now a actual terrain ?

Thanks anyone wink

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 ?

Hi,

I'll use 'P' in select mode, like you said.
Go to edit mode, in face mode, use the top-view, and the border select tool "B"
select the triangles you want to split, press 'P' > "selection"

You are not forced to split the mesh, but if your terrain is really big, it will be faster.

Re: terrain ?

Ok thanks wink)

cheers
gm


anael wrote:

Hi,

I'll use 'P' in select mode, like you said.
Go to edit mode, in face mode, use the top-view, and the border select tool "B"
select the triangles you want to split, press 'P' > "selection"

You are not forced to split the mesh, but if your terrain is really big, it will be faster.

Re: terrain ?

Any word on this, or should I just try using the shader code as suggested by anael, as in choosing that text file, inside maratis GUI in blender ?

cheers
Gm



Alinor wrote:

This blend shader is only useful for terrain with a single diffuse map, and blend several specular and normal map.

At first, I have thought that is the best solution to make complex terrain, but after I changed my mind to a shader who blend :

1 : blend map (use r, g, b and dark compound)
2 : diffuse 1
3 : normal 1
4 : diffuse 2
5 : normal 2
6 : diffuse 3
7 : normal 3
8 : diffuse 4

I'll post it, when I'll return to my home wink

Re: terrain ?

this may be too much to ask, but i have no idea how to program a shader. is it possible to create a Shader that can be used in blender for terrain painting, something similar to what Alinor Proposed (hope he had returned home safe)

Slot 1 =  Blend Map (Red, Blue, Green, Black)
Slot 2 = Texture Diffuse 1 (Red)
Slot 3 = Texture Normal 1
Slot 4 = Texture Diffuse 2 (Blue)
Slot 5 = Texture Normal 2
Slot 6 = Texture Diffuse 3 (Green)
Slot 7 = Texture Normal 3
Slot 8 = Texture Diffuse 4 (Black/White)

Re: terrain ?

Hi all,

Sorry to bump an old thread, but I thought it would be best to ask in one that's already in-progress (where it's relevant) than to start a whole new one...

I was referred to this thread, from this one that I started recently asking about a related topic.

This info (on multi-texturing using the RGB channels) is quite helpful and definitely something I'll be working on learning, though it's a bit over my head at the moment.

What I'm looking to do, in addition to the multi-texturing/blending, is to allow for the textures on each layer to be tiled. Now, there are a variety of ways to do this. I can do it in the modeler by assigning the textures to a unique UV map that's scaled up several times so the texture is automatically repeated. This requires at least 2 UV sets to be created, though. One would be used for the "tiling" effect and would be scaled up. The other would have to remain at 1:1 scale to be used for the stencil or color map(s).  Alternatively, I can use Blender's "repeat" or "size" options for each texture layer to the same effect.

I don't know if Maratis supports any of  those 3 options, though.

I'm aware that there's a method through GLSL where you can control the tiling of textures across a surface, and I know I've seen it discussed with other game engines (specifically 3DGame Studio), although it related to the terrain system, and not polygon soup meshes. I'm not familiar enough with the topic to know if that would make a difference.

I'm curious if there's a way to achieve this texture tiling via GLSL with Maratis? If so, then I believe I have a 100% solution to what I'm trying to achieve for my project. Just a matter of learning how to use it.

Thanks!

Last edited by Ayulin (2013-04-08 14:56:25)

Re: terrain ?

I'm sure someone will respond who understands what you're after, as this whole talk of tiling has be a tad confused.

A well designed texture, WILL tile, so Im not exactly sure what you are asking wink

There are specific applications you can get/buy that do this, tiling ,and do it well, then again textures are by their nature, tileable 'enough'.

I saw your screenshot, and I used to go that confusing 'stencil' way, but I find its largely unnecessary, unless it has something to do with your tiling needs  ? I've got no idea on that front, as I'm barely just at the point I am with blender to even to multitexturing in the first place.

I am simply doing the whole unwrapping of my mesh, adding a new image in UVmap section , and then I simply just add all the textures I want to work with in the add texture area of blender ( next to new material of course),and then I go into the 'texture paint' , and add new textures ( using texdraw ) as I need them using the >Textures section. It works perfectly and I do not have to worry about stencils , and it exports into Maratis just perfect, without the need of any fancy shaders,and using 'pacman' from Maratis editor has it working just fine,and it looks like it does in blender.

Re: terrain ?

gamemaker wrote:

I'm sure someone will respond who understands what you're after, as this whole talk of tiling has be a tad confused.

A well designed texture, WILL tile, so Im not exactly sure what you are asking wink

There are specific applications you can get/buy that do this, tiling ,and do it well, then again textures are by their nature, tileable 'enough'.

I saw your screenshot, and I used to go that confusing 'stencil' way, but I find its largely unnecessary, unless it has something to do with your tiling needs  ? I've got no idea on that front, as I'm barely just at the point I am with blender to even to multitexturing in the first place.

I am simply doing the whole unwrapping of my mesh, adding a new image in UVmap section , and then I simply just add all the textures I want to work with in the add texture area of blender ( next to new material of course),and then I go into the 'texture paint' , and add new textures ( using texdraw ) as I need them using the >Textures section. It works perfectly and I do not have to worry about stencils , and it exports into Maratis just perfect, without the need of any fancy shaders,and using 'pacman' from Maratis editor has it working just fine,and it looks like it does in blender.

Hey there.. Thanks for the response!

To clarify what I mean by "tiling", I could also say (and maybe should have said) "repeating across a surface". Basically, you can have the texture repeat a certain number of times across the UV surface.  So, when you have a seamless tiling texture, it will repeat across the surface as many times as you need it to, in much the same way you'd tile a texture across a heightmap terrain.

Here's a shot taken inside Blender where I have the texture(s) repeating across the surface. You can see how sharp/crisp the textures remain, and they'd remain just as sharp/crisp no matter how large the surface is that I'm tiling them across. That's two different texture layers blended via a stencil texture which I can paint directly on the mesh in Blender. The repeating textures just "flow" right on across the surface.

Aside from getting clearer/crisper results, I also have the ability to increase or decrease the number of repetitions across the surface by scaling the UV for each texture layer up or down as needed/desired.  In that picture, I believe I have each of the two textures repeating about 10-12 times across the object (they're fairly large texture images).

Another benefit to that approach is that I can use seamless textures that are, maybe 512x512 which would be pretty small in file-size (esp. using DDS format). The only large image is the stencil/blendmap, which can be 2048x2048, or even 1024 x 1024, without concern for loss of too much detail because it's just a grayscale image and there's no texture detail to worry about. So, you can get a lot of detail for relatively low memory cost.

Painting a UV texture directly, as you describe, is the approach I'm using for objects that are smaller and don't require as much pixel density to maintain their level of detail. For larger objects, though, such as large stretches of ground, or large cliff-sides, etc, I feel the multitexture approach, with repeating textures is the best way to go.

I've tried the direct texture-painting approach that you describe, but I'm never really happy with the results. I don't like how the texture "shrinks" or "grows" depending on how close or far you are from the object while painting. Although, it has its uses if you're painting a rather homogeneous texture and want to paint over anything that would betray a repeating/tiling texture. For things with fine detail that you want to keep consistent (like in my screenshot with the dirt and small plants), it's really not ideal.

Not sure if that helped at all lol.. but there you go.

Last edited by Ayulin (2013-04-08 20:24:05)

Re: terrain ?

Yes , it all makes total sense. I need to do some of that myself and get less stretching, because my current project actually is a island terrain,and atm though the modeling is adequate,the texturing leaves me unhappy.

I'm far from a blender guru so I clearly need to do some more research. I truly had no idea that direct texturing had that effect vs stencil maps inbetween each. I often wondered why blender offered the two modes. I wish there was ONE interface for all of it to lessen the confusion. Come on in our IRC channel sometimes,and maybe we can discuss some of these design techniques and help each other and maratis in the process.

I goofed up early on in design of my island ,and the stretching in one specific area is nasty,so I need to redo my unwrap I guess,,,I really hate to as I like my desin mostly as is, but no pain no gain I suppose ;0-0

Cheers
Gm

Re: terrain ?

Hey there, GM...

Yeah, I hear ya. I have a normal baked UV map that I've tested out. It works. I just don't like how much detail is lost. If I were to go that way with my texturing on larger objects, I'd have to make sure the textures I'm using aren't quite as "granular" in their detail, but are a bit more homogeneous.

If you're going to use the blendmap approach, I'd go with the RGB Blendmap approach described in this thread. That gives you access to more textures per object, since it's based on color (R, G, B and Black) and not just black or white. I'm going to use that approach myself. I just need to learn how to use the GLSL scripts myself. I'm entirely Right-brained, so figuring out anything to do with programming is an uphill battle for me. But I'll figure it out.

And I know there's a way to control the tiling/repeating of the textures through GLSL as well. I just need to find it.

Re: terrain ?

The RBG blendmap is normally working good, you can use each component to mix different textures and you can use tiling.

Just to clarify, there is two ways to tile your texture :

- directly in the uv (by scaling your uv down)

- or/and by using the texture size (from the doc) :

http://www.maratis3d.com/wp-content/uploads/2011/01/10.jpg


Be also sure that your texture is in repeat mode :
http://www.maratis3d.com/wp-content/uploads/2011/01/09.jpg

Re: terrain ?

@Auylin,Anael,

Thx anael for reminder about repeating textures, as I definitely need some of that on mine as they are far too stretched atm, even looking at them from the distance wink

To Auylin, I shall indeed try the RGBB as noted in this thread. I also want to mirror the fact that Im a much better artist and creative person, than programmer ( definitely right brain here too ), but hopefully as you noted, I can progress as I learn the finer details of programming and apply them for experience. Im sure you will find this to be true as well, that I have over time found I enjoy programming more than I thought I would  so it becomes easier as I go. Thankfully lua makes this learning curve a lot easier at least for scripting.

P.s.-When you referred to the stencil/blendmap in one of your prior posts above , and then mentioned their large sizes, were you referring to the heightmap you used for displacement, as that's what it sure sounds like; just wanted to make sure it was that and not something else, as if it's something else I have no idea what you meant by that reference of blendmap.

Re: terrain ?

anael wrote:

The RBG blendmap is normally working good, you can use each component to mix different textures and you can use tiling.

Just to clarify, there is two ways to tile your texture :

- directly in the uv (by scaling your uv down)

- or/and by using the texture size (from the doc) :

http://www.maratis3d.com/wp-content/uploads/2011/01/10.jpg


Be also sure that your texture is in repeat mode :
http://www.maratis3d.com/wp-content/uploads/2011/01/09.jpg


Oh that's excellent! So Maratis does support Blender's "repeat" functionality then? That's sweet! That means I don't have to use two UV sets tongue. Beautiful!

Okay, well I've been in "documentation and logo/site design mode" for my project since the end of this weekend, but I'm definitely going to dive more into this soon. It's fun being the only person covering all aspects at the beginning of a project. A ton of work.. but fun... except for the documentation part. I hate documentation.

PS: I don't know if anyone else has this issue, but for some reason, the first time I submit a post I've typed up, most of it gets chopped off. I have to edit the post and then re-submit it for it to show the whole thing. Very odd.

Last edited by Ayulin (2013-04-09 12:10:35)

Re: terrain ?

gamemaker wrote:

@Auylin,Anael,

Thx anael for reminder about repeating textures, as I definitely need some of that on mine as they are far too stretched atm, even looking at them from the distance wink

To Auylin, I shall indeed try the RGBB as noted in this thread. I also want to mirror the fact that Im a much better artist and creative person, than programmer ( definitely right brain here too ), but hopefully as you noted, I can progress as I learn the finer details of programming and apply them for experience. Im sure you will find this to be true as well, that I have over time found I enjoy programming more than I thought I would  so it becomes easier as I go. Thankfully lua makes this learning curve a lot easier at least for scripting.

P.s.-When you referred to the stencil/blendmap in one of your prior posts above , and then mentioned their large sizes, were you referring to the heightmap you used for displacement, as that's what it sure sounds like; just wanted to make sure it was that and not something else, as if it's something else I have no idea what you meant by that reference of blendmap.


Ahh, so you can relate to the challenge of wrapping your head around coding then. Nice! Seems, though, that you have a better grasp on programming than I do. I have books on C++, Python, Java, and a few others... and I can't make progress with any of them. I get into the first couple chapters and it all just goes completely over my head. I don't know why. Maybe I'm making it more difficult than it actually is for myself? No idea. I just can't seem to grasp it, though I've tried. It would make my life a lot easier if I knew how to implement things myself, rather than having to hope I can find an engine that does it for me, or hope someone else could help me with doing so, which is a stretch. In my experience, professionally and personally, programmers tend to be protective of what they know. I say this having been good friends with two programmers for many years. One was happy to share whatever they knew, the other was like "No I won't share or explain my code! Learn it yourself!".

As for the stencil map, yes, that's what I was referring to with large sizes. Because the blend map is only controlling what is hidden or shown, and doesn't provide any color/detail itself, you can tend to get away with a lower resolution image than you might if you were using a single image map. Of course, using a higher resolution stencil map allows you to paint in finer details, which might be preferable, but I've yet to see a situation where that's been *super* important.

Look at it like this... If you're using a single image as a UV Map that covers the entire model, the only way you can maintain a high level of pixel density/image resolution is by using really large images (4096x4096, etc). Those can eat up quite a bit of memory when they start adding up.

For a system that uses a stencil map, or a color map (both serve the same function, just in different ways), you can be using individual tiling textures that are maybe 512x512, and then a single color/stencil map that controls their visibility/blending on the object. And that color/blend map can be 1024x1024, or maybe even 512x512 if you're using it in an area that doesn't require a lot of fine blending.

I just find that you can get far more detail with a significantly lower memory cost using the blend-map approach, than you could using the UV map approach.

Now that's in terms of file size and memory cost. I don't know what the cost is in terms of processing overhead to tile the image layers and blend them, versus just laying a single UV image over an object. I'm sure the processing cost is higher, but how much higher? I don't know. Considering many games I've played use the tiled texture/blendmap approach, I'm assuming it's not very significant.

Edit: I had a thought after posting this. When you're setting up these materials via the texture blend scripts, is Blender, or Maratis for that matter, loading the textures into memory for each individual object? Or, is it just referencing the images on disk, so it only has to load them once? I'm thinking in terms of efficiency when you have many objects using the same textures. For example, in my current prototype project, many of the objects are going to use the same textures (grass, dirt, stone, etc). So, instead of the textures being loaded up for each object using them, if they could be sorta "pre-loaded" into memory, and then simply referenced for each object using them, I imagine that would save a lot of memory as well. It's kind of a form of instancing, essentially.

Last edited by Ayulin (2013-04-09 14:04:41)

Re: terrain ?

yes same textures are only once in memory, it is the same for mesh files, sounds, fonts...

Re: terrain ?

So Ayulin, you are saying that to save memory I should try using 512 textures, and making the stencils inbetween each texture 1024, correct ?

thx
Gm