Jump to content

crack in earth


Rick
 Share

Recommended Posts

So I have this idea for an ability in my game. The character will select a target and slam his first on the ground. It will then create a crack in the earth that starts at the character and go to the target. Here is how I'm thinking of doing it and I'm just curious of how other people would handle this.

 

The crack in the earth would just be a texture. It would be a pretty small crack so I figure an artist would be able to make it look like it has some kind of depth. I would make a plane that would scale to the attacker to the target. I would then use the terrain hugging on the plane to make it

fit the terrain. I'm wondering though how to make the crack look like it's traveling from the star to the finish. I could scale the plane over a few frames until it reaches it's goal and the texture on it would need to stay the same size (not scale with the terarin) and be repeatable with seamless transition from start to end. Does that seem like the way to go about this or am I missing something?

Link to comment
Share on other sites

I was thinking about that also, but I don't think that would give the correct visual. Plus wouldn't I need to deal with transparency over the part of the terrain that's the crack hasn't reached yet because I wouldn't want that part to have anything on it (or let the ground show through).

 

The visual thing I'm thinking is if I move the texture "forward" towards the target it wouldn't look like it would if it was real because if the ground would start to split right by your feet that first cracking part would be done and not change again, but if I was moving the texture "forward" the part by my feet would always seem to be changing as the texture is moving. The crack will have bends and turns in it. That's why I was thinking of just growing the plane and having the texture stay the same. The texture by my feet and beyond wouldn't be changing at all and that would be the effect for something like this.

Link to comment
Share on other sites

There is no doubt in my mind that most anything can be done with shaders. Unfortunately I don't know shader programming and if I ever want to actually complete a game I'm not going to have time to get into shader programming. Maybe I'll mess around with it a little here and there, but for now I'm not going to delay the project to learn shader programming. I wish I had more time to dig into it though because I know it's powerful. Maybe someone should create an easier wrapper around shader programming. Kind of like a library on top of the different shader languages.

Link to comment
Share on other sites

OK, so I'm really close. I have a growing plane that has a crack texture that reaches the mouse destination over time. I just need to figure out how to make the texture not scale with the plane and it will be perfect (minus my crappy programmer art).

 

The crappy part about this is that the real-time updating of the plane to hug the terrain drops my FPS from 88 to 33 :). Whisper where are you with the shader solution for this?

Link to comment
Share on other sites

I use this, something Master posted, but if I put this after the scale and call it each frame I basically get 0 FPS. It also freezes my game for a few seconds if I call this only once. The plane that I create has 64 x & z segments so not sure if that's the reason. Although it requires a high number of segments to be able to hug the terrain correctly.

 

void EarthQuake::_ScaleMesh(TEntity mesh, TVec2 uvscale, TVec2 center = Vec2(0,0))
{
for (int iSurf = 1; iSurf <= CountSurfaces(mesh); iSurf++)
   {
       TSurface surface = GetSurface(mesh, iSurf);
       for (int iVert = 0; iVert < CountVertices(surface); iVert++)
       {
           for (int texcset = 0; texcset < 2; texcset++)
           {
               TVec2 uv = (GetVertexTexCoords(surface, iVert, texcset) - center) * uvscale + center;
               SetVertexTexCoords(surface, iVert, uv, texcset);
           }
       }
   }
   UpdateMesh(mesh);
}

 

 

How can I get the texture to not scale with the mesh and instead just tile?

Link to comment
Share on other sites

In the pixel shader, find where the texcoord is read and multiply the x or y component by the scaling factor. If you make a texcoord bigger, that means more repeats.

 

Find this line in mesh.frag:

vec2 texcoord=texcoord0;// only use this because of parallax mapping

 

And do something like this:

texcoord.y *= fragcolor.w

 

Then use the entity alpha color to store the scaling factor for an instance of the mesh.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

So doing this real-time in code is pretty much not an option because of the speed I assume?

 

Also, this seems to be kind of hardcoded in the mat file if I need to change the alpha to determine the value. How do programs like 3DWS handle this sort of thing? If I apply a texture onto a block in 3DWS it tiles itself. If I extend that block no matter how long the new area of the block is just tiled with the same texture. That's the sort of effect I'm looking for. As my plane is growing I want the texture to just repeat over and over again no matter how scaled it gets.

Link to comment
Share on other sites

Here is a video that shows the effect I'm looking for

 

So notice that as I'm scaling the mesh the texture just repeats itself indefinitely. That's what I'm after. When a part of the crack in the earth is established it doesn't change, only it's tail grows but the existing parts stay put.

 

So this is from 3DWS. If I could duplicate that, everything would be perfect.

Link to comment
Share on other sites

As I said above, a shader is the most correct way to do this. You can also modify the mesh texture coordinates. This will be slightly slower, but with such a small mesh it won't really matter. This is how 3D World Studio adjusts texture coordinates.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

As I said above, a shader is the most correct way to do this. You can also modify the mesh texture coordinates. This will be slightly slower, but with such a small mesh it won't really matter. This is how 3D World Studio adjusts texture coordinates.

 

I agree the shader would be the most correct but it's something I'm not familiar with and don't want to spend the time to learn at this moment. I just want to get a finished product and then later I can go back and work on speeding certain areas up.

 

So how would one go about modifying the texture coordinates to get this result? The code I have above seems to modify the texture coordinates but it doesn't seem to give the results that 3DWS is giving.

Link to comment
Share on other sites

So I wrote this little test program, but I still can't see what the relationship between the mesh scale vs the texture scale to get it to work right. It's almost as if I need the texture size and keep it scaled to that size no matter what the size of the model, so it'll tile itself at the same size all the time

 

//	====================================================================
//	This file was generated by Leadwerks C++/LEO/BlitzMax Project Wizard
//	Written by Rimfrost Software
//	http://www.rimfrost.com 
//	====================================================================

#include "engine.h"
#define PI 3.14

void ScaleTexture(TEntity mesh, TVec2 uvscale, TVec2 center = Vec2(0,0))
{
       for (int iSurf = 1; iSurf <= CountSurfaces(mesh); iSurf++)
   {
       TSurface surface = GetSurface(mesh, iSurf);
       for (int iVert = 0; iVert < CountVertices(surface); iVert++)
       {
           for (int texcset = 0; texcset < 2; texcset++)
           {
               TVec2 uv = (GetVertexTexCoords(surface, iVert, texcset) - center) * uvscale + center;
               SetVertexTexCoords(surface, iVert, uv, texcset);
           }
       }
   }
   UpdateMesh(mesh);
}

int main( int argn, char* argv[] )
{
Initialize() ;
RegisterAbstractPath("C:/Leadwerks Engine SDK");
SetAppTitle( "Test05" ) ;
Graphics( 800, 600 ) ;
AFilter() ;
TFilter() ;

TWorld	world;
TBuffer gbuffer;
TCamera camera;
TMesh	ground;
TLight	light;
TMaterial material;

world = CreateWorld() ;
if (!world) {
	MessageBoxA(0,"Error","Failed to create world.",0);
	return Terminate();
}

gbuffer=CreateBuffer(GraphicsWidth(),GraphicsHeight(),BUFFER_COLOR|BUFFER_DEPTH|BUFFER_NORMAL);

camera=CreateCamera();
PositionEntity(camera,Vec3(0, 15, 0));
RotateEntity(camera, Vec3(90, 0, 0));

float FOV = 60;
CameraZoom(camera, 1.0f / tan((FOV * (PI/180))/2.0f));

material=LoadMaterial("abstract::grid.mat");

ground=CreateCube();
ScaleEntity(ground,Vec3(1,1,1));
PositionEntity(ground,Vec3(0,0,0));
PaintEntity(ground,material);

light=CreateDirectionalLight();
RotateEntity(light,Vec3(45,45,45));

float xScale = .5;
float zScale = .5;

// Game loop
while( !KeyHit() && !AppTerminate() )
{
	if(KeyHit(KEY_A))
	{
		xScale += .5;
		ScaleEntity(ground, Vec3(xScale, 1, zScale));
	}
	if(KeyHit(KEY_W))
	{
		zScale += .5;
		ScaleEntity(ground, Vec3(xScale, 1, zScale));
	}

	//ScaleTexture(ground, Vec2(xScale, zScale));
	//ScaleTexture(ground, Vec2(xScale, zScale));

	if(KeyHit(KEY_NUMADD))
		ScaleTexture(ground, Vec2(.5, .5));
	if(KeyHit(KEY_NUMSUBTRACT))
		ScaleTexture(ground, Vec2(1.5, 1.5));

	// Update timing and world
	UpdateAppTime();
	UpdateWorld(AppSpeed()) ;

	// Render
	SetBuffer(gbuffer);
	RenderWorld();
	SetBuffer(BackBuffer());
	RenderLights(gbuffer);

	// Send to screen
	Flip(0) ;
}

// Done
return Terminate() ;
}

Link to comment
Share on other sites

another way would be:

1) create the full mesh (with 100% size)..

-apply the UV's so it fits when its 100% grown

2) create a shader which makes the crack visible depending on a variable you later parse to the shader..

 

something like

 

if(texcoord.x<size)

outputcolor.a=0.0;

 

where size is a float that goes from 0 to the max. U value

 

now all you have to do is update the size parameter depending on how fast you want your crack to grow..

so you dont have to update any mesh, and you could add something like a little alpha blending at the end of the crack.

 

€: if you dont use the color of the mesh you could just for instance use the color.a value as the size, so you just have to change the color of the mesh at runtime..

Link to comment
Share on other sites

I like that idea even better, because I only need to call the terrain hugging code once after the plane is scaled instead of each frame as it's being scaled. That'll speed things up a ton.

 

I'll test that shader you wrote on this tonight and let you know how it goes. I'm excited for this because it's the last piece to this kick wonderful person ability ;)

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...