Jump to content

Plane to hug terrain


Rick
 Share

Recommended Posts

Ah ok. So this is the drop down list when you first create a terrain in the editor. Cool! I'm excited to get this to work. If only I can figure out why UpdateMesh is bombing now.

 

ftp://78.102.70.147/Images/decal6.jpg

 

decal working on extreme places, hehe :D

-= Phenom II X4 965 3.4Ghz - ATI HD5870 - 6 GB DDR3 RAM - Windows 8 Pro 64x=-

Website: http://www.flamewarestudios.com

Link to comment
Share on other sites

@Rick:

Your CreatePatch function creates triangles with vertices that don't exist, hence the access violation.

It should read

"z <= zegs" and "x <= xsegs" like the framewerk function:

TMesh CreatePatch(int xsegs, int zsegs)
{
int x,z;
TMesh mesh;
int count;
TSurface surf;

mesh=CreateMesh();
surf=CreateSurface(mesh);
for(z=0;z<=zsegs;z++)
{
	for(x=0;x<=xsegs;x++)
	{
		count=AddVertex(surf,
					Vec3( (flt)(x)/(flt)(xsegs)-0.5f, 0, (flt)(z)/(flt)(zsegs)-0.5f ),
					Vec3( 0, 1, 0),
					Vec2( (flt)(x)/(flt)(xsegs), 1- (flt)(z)/(flt)(zsegs) ));
		if( (x>0) && (z>0) )
		{
			AddTriangle(surf, count-1, count,         count-xsegs-1);
			AddTriangle(surf, count-1, count-xsegs-1, count-xsegs-2);
		}
	}
}
UpdateMesh(mesh);
return mesh;
}

Link to comment
Share on other sites

That would be due to the resolution of the depth buffer. You can fix that by flipping it from 0-1 to 1-0, since there is more resolution towards 0 floating point than 1 floating point (according to a few documents I have read on Depth Buffer inaccuracies in OpenGL).

 

Also, if you use overlay=1 and zsort=1 in the material file for the decal it should help fix the Z-Fighting.

52t__nvidia.png nVidia 530M cpu.gif Intel Core i7 - 2.3Ghz 114229_30245_16_hardware_memory_ram_icon.png 8GB DDR3 RAM Windows7_Start.gif Windows 7 Ultimate (64x)

-----

IconVisualStudio16.png Visual Studio 2010 Ultimate google-Chrome.png Google Chrome PhotoshopLinkIndicator.png Creative Suite 5 icon28.gif FL Studio 10 MicrosoftOfficeLive.png Office 15

-----

csharp.png Expert cpp.png Professional lua_icon.png Expert BMX Programmer

-----

i-windows-live-messenger-2009.pngskype-icon16.pngaim_online.pnggmail.pngicon_48x48_prism-facebook.pngtunein-web.pngyahoo.giftwitter16.png

Link to comment
Share on other sites

ok Rick, try this :)

 

ftp://78.102.70.147/Data/decalshader.rar

 

you can try it in editor too ;-) works everywhere.

 

There is only one problem. Josh's getting terrain height is wrong, bad interpolation, pehraps Masterxilo can repair it :) he has experience, lol

-= Phenom II X4 965 3.4Ghz - ATI HD5870 - 6 GB DDR3 RAM - Windows 8 Pro 64x=-

Website: http://www.flamewarestudios.com

Link to comment
Share on other sites

  • 2 weeks later...

ok.. i just wrote a shader for terrain decals..

image1

image2

as you can see the vertices of the decal just align to the vertices of the terrain. now you maybe say: but what if i want to move it in smooth steps?

heres the answer:

image3

image4

 

at the pictures you can see the visible areas of my decal.

i create the mesh with its size+1*terrainscale. so i got 2 triangle strips left as a buffer.

when i now move the decal it moves the UV coordinates instead of the vertices until the distance moved is > then 1x terrainscale.

in the pictures the red rectangle is the visible area and the blue one is the invisible.

in picture 2 i moved the "mesh" a bit to the right, top corner. as you can see the mesh didnt really moved, but the visible area did.

when the visible area would leave the mesh, the mesh moves +1xterrainscale.

 

the shader i wrote basically does that:

aligns the vertices to the terrain-grid

moves the UV

discards any pixel that has UV > 1 or <0 (can be changed by parsing a max UV value to the shader)

 

the advantage of this system is, that it does all the work on the GPU

that it aligns the decal perfectly to the terrain

that it doesnt need that many vertices.

 

disadvantage:

decals atm cant be rotated

i got some errors with clipping as the mesh's y-coordinate is stored as 0 and so it sometimes doesnt get rendered if you dont look straight down (should be solveable somehow :) )

Link to comment
Share on other sites

sure.. it aint something secret..

 

decal.vert

 

 

Include "abstract::MeshMatrix.vert"

uniform float apptime;
uniform vec2 buffersize;
uniform float meshlayerrange;
uniform float meshlayerheight;
uniform vec3 cameraposition;
uniform float camerazoom;

varying vec3 T,B,N;
varying vec2 texcoord0;
varying vec2 texcoord1;
varying vec3 cubecoord;
varying vec3 vertexposition;
varying vec4 modelvertex;
varying vec4 projectionspace;
varying vec4 refractionspace;
varying vec4 fragcolor;

#ifdef LW_PARALLAXMAP
varying vec3 eyevec;
#endif


void main(void) {

vec4 vertexcameraposition;

Include "abstract::GetMatrix.vert"

fragcolor = gl_Color*color;

modelvertex = gl_Vertex;


mat3 nmat = mat3(mat[0].xyz,mat[1].xyz,mat[2].xyz);

mat[3].y=0.0;

modelvertex = mat * modelvertex;

vec2 posNeu = floor(modelvertex.xz/terrainscale.x)*terrainscale.x;
vec2 move = modelvertex.xz-posNeu;
modelvertex.xz=posNeu;
modelvertex.y += GetTerrainHeight(modelvertex.xz);


vertexposition = modelvertex.xyz;
vertexcameraposition = gl_ModelViewProjectionMatrix * modelvertex;		

texcoord0=gl_MultiTexCoord0.xy-move.xy/2/terrainscale.x;
texcoord1=gl_MultiTexCoord1.xy-move.xy/2/terrainscale.x;


nmat = gl_NormalMatrix * nmat;

N = normalize( nmat * gl_Normal );
#ifdef LW_BUMPMAP
	T = normalize( nmat * gl_MultiTexCoord2.xyz );		
	B = normalize( nmat * gl_MultiTexCoord3.xyz );
#endif

gl_Position = vertexcameraposition;

#ifdef LW_PARALLAXMAP
	modelvertex = gl_ModelViewMatrix * modelvertex;
	mat3 TBN_Matrix;
    	TBN_Matrix[0] = T;
	TBN_Matrix[1] = B;
	TBN_Matrix[2] = N;
	eyevec = vec3(-modelvertex) * TBN_Matrix;
#endif

}

 

 

 

decal.frag

 

 

#extension GL_ARB_draw_buffers : enable

uniform vec3 cameraposition;
uniform vec2 buffersize;
uniform vec2 camerarange;

include "abstract::greyscale.txt"
include "abstract::DepthToZPosition.frag"

#ifdef LW_DETAIL
uniform sampler2D LW_DETAIL;
#endif

#ifdef LW_DIFFUSE
uniform sampler2D LW_DIFFUSE;
#endif

#ifdef LW_SPECULARMAP
uniform sampler2D LW_SPECULARMAP;
#endif

#ifdef LW_BUMPMAP
uniform sampler2D LW_BUMPMAP;
#endif

#ifdef LW_BLOOM
uniform sampler2D LW_BLOOM;
#endif

#ifdef LW_CUBEMAP
uniform samplerCube LW_CUBEMAP;
#endif

#ifdef LW_PARALLAXMAP
uniform sampler2D LW_PARALLAXMAP;
varying vec3 eyevec;
#endif

#ifdef LE_REFRACTION
uniform sampler2D LE_REFRACTION;
uniform sampler2D LE_DEPTHBUFFER;
uniform float refractionstrength = 0.01;
#endif

#ifdef LW_POMMAP
vec3 vLightTS=vec3(0.577,0.577,0.577);
varying vec3 eyevec;
float depthP = .15;
float nMinSamples = 20;
float nMaxSamples = 50;	
#endif

#ifdef LW_MESHLAYER
varying float vegetationfade;
#endif

#ifdef LW_ALPHABLEND
uniform sampler2D LW_ALPHABLEND_INCOMINGCOLOR;
uniform sampler2D LW_ALPHABLEND_INCOMINGNORMAL;
#endif

varying vec3 vertexposition;
varying vec3 T,B,N;
varying vec2 texcoord0;
varying vec2 texcoord1;
varying vec3 cubecoord;
varying vec4 modelvertex;
varying vec4 fragcolor;

float fOcclusionShadow = 1.0;

uniform sampler2D texture14;
uniform float terrainsize;
uniform vec3 terrainscale;
uniform float bumpscale;
uniform float specular;
uniform float gloss;

//Terrain color map
uniform sampler2D texture12;

void main(void) {

vec4 diffuse = fragcolor;
vec3 normal;
float shininess = 0.0;
vec2 texcoord=texcoord0;// only use this because of parallax mapping
float selfillumination = 0.0;	

vec2 terraincoord;
float terrainresolution;

if(texcoord0.x>1 || texcoord0.x<0 || texcoord0.y<0 || texcoord0.y>1) // For greater UV values then 1 just pass a variable to the shader and check if UV > the variable..
	discard;
#ifdef LW_PARALLAXMAP
	texcoord += (texture2D(LW_PARALLAXMAP,texcoord).x * 0.04 - 0.036) * normalize(eyevec).xy;
#endif

#ifdef LW_POMMAP
	// for POM, the heightmap is in the alpha of the diffuse so save ur diffuse with DXT5 I chose this because the alpha of DXT5 is higher precision
	Include "abstract::POM.frag"
#endif

#ifdef LW_DIFFUSE
	diffuse *= texture2D(LW_DIFFUSE,texcoord);//*fOcclusionShadow;
#endif

#ifdef LW_ALPHATEST
	if (diffuse.w<0.5) {
		discard;
	}
#endif


normal = N;

#ifdef LW_BUMPMAP

	//Use terrain normals
	terraincoord=vec2(vertexposition.x,-vertexposition.z) / terrainsize + 0.5;
	terrainresolution = terrainsize / terrainscale.x;
	terraincoord += 0.5 / terrainresolution;
	vec3 worldNormal = ((texture2D(texture14,terraincoord).xyz - 0.5) * 2.0).xyz;
	normal = normalize(gl_NormalMatrix*worldNormal);

	#ifdef LW_DETAIL
		normal += texture2D(LW_DETAIL,texcoord * 4.0).xyz * 2.0 - 1.0;
	#endif
	normal.z /= bumpscale;
	normal = T * normal.x + B * normal.y + N * normal.z;
	normal = normalize(normal);
	#ifdef LW_SPECULAR
		shininess = bumpcolor.a*specular;//*fOcclusionShadow
	#endif
	#ifdef LW_SPECULARMAP
		shininess = texture2D(LW_SPECULARMAP,texcoord).x*specular;//*fOcclusionShadow
	#endif

#else
	normal=normalize(normal);
#endif


#ifdef LW_TERRAINCOLOR
	//Use terrain color
	terraincoord=vec2(vertexposition.x,-vertexposition.z) / terrainsize + 0.5;
	terrainresolution = terrainsize / terrainscale.x;
	terraincoord.x -= 0.5 / terrainresolution;
	//terraincoord.y += 0.5 / terrainresolution;
	vec4 terraincolor = texture2D(texture12,terraincoord);
	diffuse = vec4( greyscale(diffuse.xyz) * 2.0 * terraincolor.xyz,diffuse.w);

	#ifdef LW_MESHLAYER
		float temp_w=diffuse.w;
		diffuse = diffuse * (1.0-vegetationfade) + terraincolor * vegetationfade;
		diffuse.w=temp_w;
	#endif

	shininess = terraincolor.w;
#endif

#ifdef LE_REFRACTION
	diffuse.a=0.25;
	vec4 refractionvector = vec4( gl_FragCoord.x/buffersize.x, gl_FragCoord.y/buffersize.y, gl_FragCoord.z, 1.0 );
	vec4 refractionvector2 = refractionvector + refractionstrength * vec4(normal,0.0);		
	if (gl_FragCoord.z<DepthToZPosition(texture2DProj(LE_DEPTHBUFFER,refractionvector2).x)) {
		refractionvector=refractionvector2;
	}
	vec4 transparency = texture2DProj(LE_REFRACTION,refractionvector);
	diffuse = transparency * diffuse;
#endif

vec3 adjustednormal = normal*0.5+0.5;
float adjustedgloss = gloss;
//Diffuse
gl_FragData[0] = diffuse;	

//Normal
#ifdef LW_FULLBRIGHT
	gl_FragData[1] = vec4(1.0,1.0,1.0,diffuse.w);
#else
	gl_FragData[1] = vec4(adjustednormal,diffuse.w);
#endif

//Bloom
#ifdef LW_BLOOM
	gl_FragData[3] = texture2D(LW_BLOOM,texcoord) * fragcolor;
#else
	gl_FragData[3] = vec4(0,0,0,diffuse.w);
#endif

shininess=clamp(shininess,0,1)*0.5;

gl_FragData[2]=vec4(shininess,gloss,0.0,diffuse.w);




/*
float c;
float temp;
temp=adjustednormal.x*100.0;
c=int(temp);
temp=adjustednormal.y*100.0;
c+=int(temp)/100.0;
temp=adjustednormal.z*100.0;
c+=int(temp)/100.0/100.0;
gl_FragData[1].x = c;
*/
}

 

 

 

i pretty much just copied the mesh.vert and mesh.frag and made some changes..

also didnt test it with parallax and bumpmap, etc..

Link to comment
Share on other sites

Thanks for getting those out so quick!

 

So I created a .mat file (see below) which uses you shader but it is causing LE to crash when the material loads. I looked in the log and it doesn't give any info on why it died. But here is my .mat file.

 

texture0="abstract::decal.dds" 
blend=1 
depthmask=1 
depthtest=1 
overlay=1 
zsort=1 
cullface=1 
castshadows=0 
shader="abstract::decal.vert","abstract::decal.frag" 
shadowshader="abstract::mesh_shadow.vert",""

 

Are you just creating a mesh and applying the material to the mesh, or are you loading a .gmf?

 

If you create a mesh what is the minimum number of verts do I need, or is that handled in the shader?

 

Also, what is the difference between the shader you've done vs what wh1sp3r did?

 

And finally, how do you get LE to go into wiremesh mode? I'm using Gamelib and have tried to use "game.engine.SetWireframe(true)" with no luck. Any suggestions?

 

Thanks,

 

Blue

Link to comment
Share on other sites

Thanks for getting those out so quick!

 

So I created a .mat file (see below) which uses you shader but it is causing LE to crash when the material loads. I looked in the log and it doesn't give any info on why it died. But here is my .mat file.

 

texture0="abstract::decal.dds" 
blend=1 
depthmask=1 
depthtest=1 
overlay=1 
zsort=1 
cullface=1 
castshadows=0 
shader="abstract::decal.vert","abstract::decal.frag" 
shadowshader="abstract::mesh_shadow.vert",""

where's the sense of setting castshadows=0 and then defining a shadowshader?

why it crashes? i dont know...

Are you just creating a mesh and applying the material to the mesh, or are you loading a .gmf?

 

If you create a mesh what is the minimum number of verts do I need, or is that handled in the shader?

yes.. i am creating a mesh.

the minimum should be 9 i guess (otherwise the shader doesnt make sense..

3 in each direction, so you got a 1x1 field for rendering your decal.

Also, what is the difference between the shader you've done vs what wh1sp3r did?

I have to admit.. i dont know what whisper "did"??

And finally, how do you get LE to go into wiremesh mode? I'm using Gamelib and have tried to use "game.engine.SetWireframe(true)" with no luck. Any suggestions?

Wireframe(1);

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...