Jump to content


Photo

Distortion Wave & Ambient Occlusion (baked)


  • Please log in to reply
41 replies to this topic

#1 Phantom107

Phantom107

    Engineer

  • GMC Member
  • 2590 posts
  • Version:GM:Studio

Posted 03 May 2010 - 12:01 PM

Distortion Wave & Ambient Occlusion (Baked)

Hey again 3d users of the GMC,

This example is to display the visual quality achievable if you know how to work with the right tools, and if you have insight in programming with vertexes on the fly.
It includes 2 techniques: Distortion Wave and Ambient Occlusion (Baked).

Distortion Wave

First up is the distortion wave. The distortion wave is basically 2 connected rings of vertexes. The vertexes where the rings meet have offsetted UV coordinates, so will create a very nice distortion when the rings are moving. Since it is built from vertexes it needs a texture. To get this texture I'm using the surface fix by amd24 to render the screen to a surface, then upscale that surface to meet the texture x^2 size requirements.

This technique can also be used in explosion effects, creating a shock wave. That will make the explosion look a lot more impressive. Well, at least I am going to use this for it.
It can also be modified to make heat-haze effects for fire!

Ambient Occlusion (Baked)

This is probably my most favourite effect in the world of computer graphics. Why? Because it creates a great sense of depth in 3d environments that can not be achieved by normal lighting. It's used in commercial games too, for example in Gears of War 2 and Halo Reach. Use it, and your game will look a whole of a lot better!

I find it hard to explain what it is. Wikipedia does a much better job at it:

Ambient occlusion is a shading method used in 3D computer graphics which helps add realism to local reflection models by taking into account attenuation of light due to occlusion. Ambient occlusion attempts to approximate the way light radiates in real life, especially off what are normally considered non-reflective surfaces.
Unlike local methods like Phong shading, ambient occlusion is a global method, meaning the illumination at each point is a function of other geometry in the scene. However, it is a very crude approximation to full global illumination. The soft appearance achieved by ambient occlusion alone is similar to the way an object appears on an overcast day.

Now it is important to note that the Ambient Occlusion I'm using here is baked (pre-rendered) using an external tool. Due to GM's lack of pixel shaders it's not possible to do it realtime in a fast way, but I would prefer baking it in anyway. That's because it still look amazing, and it will require GM a tiny bit of extra performance for a huge graphic improvement!

First I created a scene. The scene consists of 2 models, the Temple and the Holy Relic. I made them both in Google Sketchup. The Temple was designed by myself, but I copied the Holy Relic from a design made by Nintendo. Gamecube players will probably recognize it. (It's featured in my all-time favourite game.)

After creating the models, I exported them to OBJ. Then I loaded them in Lith Unwrap to create an UV-map for them. The thing with baking Ambient Occlusion is that every triangle needs to have it's own unique place on the texture, because all triangles are shaded differently. I used the "face" mapping function to let Lith Unwrap automatically seperated all triangles nicely on the texture. I scaled the entire mapping down a bit to stay away from the edges, and I was all set to go. I exported the UV-mapped model to OBJ.

This is where the Ambient-Occlusion tool comes into play. It's called xNormal and can be found here. In this tool you just drag in the OBJ model to both the High-Poly Mesh and Low-Poly Mesh sections, select export location, define rendering options and click the "Generate Maps" button. It's that simple.
The time needed for rendering can and probably will take awhile depending your rendering options.

I now had the OBJ model and Ambient Occlusion texture for the model. Now to get the model in GM, I used GMModelFix by icuurd12b42 to convert to d3d. When I loaded both the d3d model and texture in GM I noticed the Ambient Occlusion map was not placed on the model as it should be. When this happens just flip the Ambient Occlusion texture image vertically!

Here's a screenshot of the result. It doesn't use any GM lighting at all, it's all in the texture!

Posted Image

The Holy Relic pulsates some kind of magical forcefield...

Posted Image


Someone is using dark magic on the Relic, making the forcefield go crazy!

Posted Image

Here's the download. It also includes an EXE for the people who want to try it out directly.

http://host-a.net/Ph.....n (Baked).zip

Controls in the example:
  • Move around using WASD
  • Change height with QE
  • Look around with the mouse
  • Hold space to reign fear upon your minions
Enjoy!

- Phantom107
  • 0

#2 RamboFox

RamboFox

    Tainted Fortune

  • New Member
  • 992 posts

Posted 03 May 2010 - 12:06 PM

Those screenshots look incredibly tasty~

OH WOW, that was much more than I expected! Shockwave ring distortion in 3d - nice!
And you've made me a believer of ambient occlusion :blink:

Edited by RamboFox, 03 May 2010 - 12:13 PM.

  • 0

#3 Tepi

Tepi

    GMC Member

  • Global Moderators
  • 4201 posts
  • Version:GM8.1

Posted 03 May 2010 - 12:35 PM

Baking the lighting into the texture allows you to do pretty wild things. Not only ambient occlusion but also radiosity, caustics and of course shadows all with the quality only limited by the size of the texture. Thanks for introducing xNormal. It seems really useful.

But the disortion wave... man. It looks incredibly good! It's fast too: it ran the average of about 80 fps even on my machine, which is pretty damn impressive. The wave shape also looked incredibly high quality: I wasn't able to spot the edges of its triangles. Now you have made some nice examples before but this is my absolute favourite. Great job, man. :blink:
  • 0

#4 Endorel

Endorel

    GMC Member

  • Banned Users
  • 191 posts

Posted 03 May 2010 - 02:33 PM

Looks nice, but needs texturing. That is why I would like to discuss multi-texturing verses it's hack.

Multi-Texturing: call model once > scroll through every triangle once > rasterize pixels without repeating loops but draw the pixel twice (with different textures, UVs, and colors) for every step
Hack: call the model X times (with different textures, vertex colors and UVs) > scroll through every triangle X times > draw every pixel X times

Concept Modeling:

Multi-Texturing
for("every triangle")
{
for("each texture") "put the UVs and colors into a buffer"
for("every pixel")
{
for("each texture") "access the buffer and draw the pixel"
}
}


Hack
for("each texture")
for("each triangle")
for("each pixel")
{
"draw the pixel"
}

Which is faster? I would say that the Hack is actually faster. But hey, what do I know?

Edited by Endorel, 03 May 2010 - 03:13 PM.


#5 Phantom107

Phantom107

    Engineer

  • GMC Member
  • 2590 posts
  • Version:GM:Studio

Posted 03 May 2010 - 03:22 PM

If anything, I'd pre-bake the generated AO onto the texture directly using a function in xNormal, or just use GIMP.

But if you want actual multi-texturing, there would be some very interesting possibilies.

1. Instead of drawing anything twice, use the surface fix. Just paint the default texture on a surface, then paint all the other effects on top of it.
Then use as texture for the model.

2. First do a surface-render of the scene with the default texture. Then surface-render the AO and finally, using an ortho projection,
draw the scene render with the AO render on top of it, using an extended blend mode.

Edited by Phantom107, 03 May 2010 - 03:22 PM.

  • 0

#6 Endorel

Endorel

    GMC Member

  • Banned Users
  • 191 posts

Posted 03 May 2010 - 03:35 PM

The benefit of multi-texturing is that you can repeat a texture while using a light map. The light map doesn't need to be super large for it to have a high quality texture underneath it.

1. Instead of drawing anything twice, use the surface fix. Just paint the default texture on a surface, then paint all the other effects on top of it.
Then use as texture for the model.

What if some one's VRAM sucks?

2. First do a surface-render of the scene with the default texture. Then surface-render the AO and finally, using an ortho projection,
draw the scene render with the AO render on top of it, using an extended blend mode.

That is hard to understand. Why would I use an ortho projection?

Edited by Endorel, 03 May 2010 - 03:53 PM.


#7 Chhaaiinnssaaww

Chhaaiinnssaaww

    GMC Member

  • GMC Member
  • 584 posts

Posted 03 May 2010 - 03:39 PM

The effect looks really nice :blink:
  • 0

#8 Phantom107

Phantom107

    Engineer

  • GMC Member
  • 2590 posts
  • Version:GM:Studio

Posted 03 May 2010 - 03:52 PM

What if some one's VRAM sucks?

Then they should not play games. I understand you want as much compatability as possible, but you need to put the bar somewhere.
It's like trying to break the world speed record in a go-kart.

Anyhow, this will not be much of a problem if the game only has 128x128, 256x256 and 512x512 textures in it.

That is hard to understand. Could you expand on the setup detail? How would it work?

You've seen my glow example right? Well it's the same more or less.

1. Render the scene to a surface using the default colorized textures.
2. Render the scene to a surface again, but this time using the pre-rendered Ambient Occlusion maps.
3. Initiate the ortho projection for 2d drawing.
4. Draw surface 1.
5. Draw surface 2, but using an extended blend mode. I don't know which it was exactly, but it needs to only draw the gray/black tints and not draw any of the white.
  • 0

#9 Endorel

Endorel

    GMC Member

  • Banned Users
  • 191 posts

Posted 03 May 2010 - 03:58 PM

I would go with method 2. Okay, quick make another example! :blink:

#10 Phantom107

Phantom107

    Engineer

  • GMC Member
  • 2590 posts
  • Version:GM:Studio

Posted 03 May 2010 - 04:10 PM

I would go with method 2. Okay, quick make another example! :blink:

I don't think so, first you were laughing at me with your supposedly good UGE engine and now you asking for an example...?

You will see it... in my game. :D
  • 0

#11 Endorel

Endorel

    GMC Member

  • Banned Users
  • 191 posts

Posted 03 May 2010 - 04:16 PM

Okay then I'll make an example. :blink:

#12 Newly Discovered

Newly Discovered

    Harmonious Genius

  • New Member
  • 2467 posts
  • Version:GM8

Posted 03 May 2010 - 06:27 PM

looks great phantom! the AO is weird, but it looks like it's just the uv mapping.
the distortion is great. 46fps seeing everything and 49 fps seeing nothing. not the fastest, but it works.
good job!

and endorel...good luck?
how long have you been using GM? you look to be a relatively new member.

Edited by Newly Discovered, 03 May 2010 - 06:28 PM.

  • 0

#13 Phantom107

Phantom107

    Engineer

  • GMC Member
  • 2590 posts
  • Version:GM:Studio

Posted 03 May 2010 - 07:01 PM

I have a request for the people who are experienced in working with modeling converters for GM. (icuurd12b42?)
All other users wanting to use AO probably would like this too...

In the AO generating process all the triangles need to be nicely divided on a texture, since every triangle has a different AO shading on it.
Currently I'm using Lith Unwrap to do that for me but it doesn't do a good job at automatically mapping all triangles.
What I would really like to have is a program that could UV-map a loaded model like this:

Posted Image

That would make the AO generating process a whole lot easier, and provide better quality AO because it's mapped so perfectly!

Edited by Phantom107, 03 May 2010 - 07:02 PM.

  • 0

#14 D1g1talAli3n

D1g1talAli3n

    BoyGenius

  • New Member
  • 963 posts
  • Version:GM8

Posted 03 May 2010 - 07:59 PM

Wow. What is this? Like a super surface fix effects-streak? :D
Once again, good job! Can't wait to see what next eye-candy you come up with! :blink:
  • 0

#15 Tepi

Tepi

    GMC Member

  • Global Moderators
  • 4201 posts
  • Version:GM8.1

Posted 03 May 2010 - 08:18 PM

@Phantom107:
Yeah, I noticed your current UV map sucks. :blink:

I'm not sure if there is a program to make an UV map like that, but you certainly could code one yourself. The basic method would be to read all the model data three vertices at a time (requires the model to use trianglelist and be triangulated), and set their texels according to the current values of three counter variables. Two counter variables would be the UV coordinates of the current grid cell, and the third would be a boolean value stating which triangle the current one is from the two that make up the cell. After this would be done, you would have gathered all the data and you could write it all back to the model file.

In pseudo code you'd do:
open_file_for_reading();
var xx, yy, zz, uu, vv, U, V, T, s, n;
U = 0;	V = 0;	T = 0;
s = 0.1;  //separation
n = file_get_number_of_lines()/3;  // number of triangles
n = floor( sqrt(n) );  //Number of cells per side
for (i=0; eof; i+=1)
 {
	xx[i] = file_read_x();
	yy[i] = file_read_y();
	zz[i] = file_read_z();
	nx[i] = file_read_nx();
	...

	if T
	 {
		 uu[i,0] = (U + s)/n;
		 vv[i,0] = (V + s)/n;
		 uu[i,1] = (U + s)/n;
		 vv[i,1] = (V + 1 - s)/n;
		 uu[i,2] = (U + 1 - s)/n;
		 vv[i,2] = (V + 1 - s)/n;
	 }
	else
	 {
		 uu[i,0] = (U + s)/n;
		 vv[i,0] = (V + s)/n;
		 uu[i,1] = (U + 1 - s)/n;
		 vv[i,1] = (V + s)/n;
		 uu[i,2] = (U + 1 - s)/n;
		 vv[i,2] = (V + 1 - s)/n;
	 }
	if T
	 {
		T = 0;
		if U < n
		 U += 1;
		else
		{
		V += 1;
		U = 0;
		}
	 }
	else
	 T = 1;
 }
file_close();

file_open_for_writing();
<write all the array data>
file_close();
I hope I didn't forget anything significant.

EDIT: Screwed up the loop... editing...
EDIT2: Yeah, I believe it's ok now.
EDIT3: Man indenting the code is hard in this editor.
EDIT4: Now I officially hate the editor. The hell with this you are able to understand the code without proper indentation.

Edited by Tepi, 03 May 2010 - 08:39 PM.

  • 0

#16 Robert3DG+

Robert3DG+

    VR Games

  • GMC Member
  • 1848 posts
  • Version:GM:Studio

Posted 03 May 2010 - 08:55 PM

D:

This is amazing! The shockwave effect alone is worth the price of admission.

I'd love to see you tackle a faux environment mapping effect using surface-fix :blink:
  • 1

#17 Phantom107

Phantom107

    Engineer

  • GMC Member
  • 2590 posts
  • Version:GM:Studio

Posted 03 May 2010 - 09:08 PM

This is amazing! The shockwave effect alone is worth the price of admission.

Which is...free? Haha. :mellow:

I'd love to see you tackle a faux environment mapping effect using surface-fix :D

I've actually been thinking of something like it, but I eventually gave up, mainly because I'm using GM OGRE with DirectX 9 for my game and environment mapping is a built-in feature. Sorry. :blink:

edit

Oh more more thing. For everyone wanting to have a closer look on how I made the shockwave, just hold control!

Edited by Phantom107, 03 May 2010 - 09:19 PM.

  • 0

#18 Desert Dog

Desert Dog

    GMC Member

  • Global Moderators
  • 6409 posts
  • Version:Unknown

Posted 03 May 2010 - 10:25 PM

You really know what your doing. :blink: Another super cool example! *thumbs up*
  • 0

#19 B Factory LLC

B Factory LLC

    We're awesome!!

  • New Member
  • 511 posts

Posted 03 May 2010 - 11:33 PM

Cool. Will look.
  • 0

#20 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • Global Moderators
  • 14389 posts
  • Version:GM:Studio

Posted 04 May 2010 - 01:28 AM

Phantom, you can make a little gm app and use gmmodelex.dll to load the model, you will have access to all the vertices, uv and the likes to implement tepi's code.

model = GMModelEx_ModelCreateFromFile("tmp.d3d");
or
model = GMModelEx_ModelImport(see argrs for .obj);
points = GMModelEx_ModelGetNumPoints(model);
facets = points/3;
i = 0;
j = 0;
repeat(facets)
{
u1 = GMModelEx_ModelGetPointU(model, i)
v1 = GMModelEx_ModelGetPointU(model, i)
i+=1;
u2 = GMModelEx_ModelGetPointU(model, i)
v2 = GMModelEx_ModelGetPointU(model, i)
i+=1;
u3 = GMModelEx_ModelGetPointU(model, i)
v3 = GMModelEx_ModelGetPointU(model, i)
i+=1;
////////////////
//fiddle with uv

//fiddle with uv
////////////////
GMModelEx_ModelSetPointUV(model, j, u1, v1)
j+=1;
GMModelEx_ModelSetPointUV(model, j, u2, v2)
j+=1;
GMModelEx_ModelSetPointUV(model, j, u3, v3)
j+=1;
}
GMModelEx_ModelSave(model,"newfile.d3d", 0 /*no color, no alpha*/)
GMModelEx_ModelDestroy(model)

Edited by icuurd12b42, 04 May 2010 - 01:29 AM.

  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users