Perfil de PetriDark Codex StudiosFotosBlogListasMás ![]() | Ayuda |
|
30 abril Transmittance Part IIOk, I started making the Transmittance shader, and this is how far I got:
Here we can see a green glass ball absorbing the pixels behind it, and before the rays hit our eyes( camera ) the color is absorbed based on how long/far it travels trough the sphere. This effect is mostly a post process effect, where I use two depth maps to find out how thick the object is. This is done by first rendering the sphere's backfaces into one depth buffer, and then rendering the spheres frontbuffer into another buffer; taking the difference of these two textures will give me the thickness of the object. If you take a look at the spikeball, it contains some artifacts. This is because of the way I find the depth of the object. There are many ways of getting these look better and I will get back to this later! ;) Then, I use Beer-Lambert's law to compute the amount of light absortion: XNA Shader Programming - Tutorial 13, Alpha mappingXNA Shader Programming
Tutorial 13 - Alpha mapping Welcome to another tutorial in the XNA Shader Programming series. Today we are going to look at a simple, but important shader: The Alpha map!
The Alpha map is very usefull when you want to render a 3D object where some parts are transparent and other parts are solid. This could be a window with some cracks on it, making the cracks solid and the rest transparent! There are many other places you can use alpha maps, like thin/thick ice, skin, flowers, insect wings, and wherever you want to mix solid and transparent part!
Executable + Source can be downloaded from the end of the tutorial Alpha Mapping
The general idea is to introduce an other texture we can use in our shaders, the alpha map. This texture will be a grayscale texture, where the black parts means the object is fully transparent, a shade of gray means its a mid thing of transparent and solid, and white means it will be 100% solid.
You can think of the grayscale texture as a texture that contains how solid an object is, stored as a grayscale color that represents a percent. A color of 0.0( Black ) means its 0% solid. A color of 0.5( gray ) means its 50% solid, and 1.0( white ) means its 100% solid.
So our shader can contain two textures: the ColorMap that represents the objects color, and a AlphaMap that represents the objects opacity.
Implementing the Shader
In this tutorial, im just using the Diffuse Shader, and making that shader support Alpha Mapping. This could be any shader you want so feel free to implement this in your own shaders!
First of all, the shaders need two textures:
Let us start by adding these to the shader:
Here we calculate the diffuse color as we usually do, and put it in color. Our technique for todays lesson looks like this: As you can see, we set AlphaBlendEnable to true, and use det SrcAlpha/InvSrcAlpha as the blending function. This means that we use the alphachannel to make things transparent. Using the shader I have also added an overlay texture named m_Overlay. This is used to render the overlay in front of the whole screen, using the alpha values found in a .PNG file. These alpha values can be set by using Photoshop or many other picture editor programs.
NOTE: YouTube - XNA Shader programming, Tutorial 13 - Alpha mapping Download: Executable + Source 29 abril TransmittanceI had a request on writing a tutorial about Alpha maps using shaders, and this tutorial will be written tomorrow. But after yesterdays workshop, I had some thoughts about transparent objects, reflection and refraction.
We usually code a transparent object the following way: Set the color of the object to a desired color, and use blending/aplha to make the pixels located behind the object( relative to the camera ) get the color of the blended object + it's normal pixel color. This works well in many cases, but what if I have a glassball I want to make transparent?
I could just make the whole sphere transparant using blending/alpha, but this would make it look rather flat. We all know that in the real world, all light-rays hitting a transparent object ( say a yellow glass sphere ) will be reflected and refracted. The refracted light will go through the object, and based on how far the light-ray travels before going out of on the opposite side, the more it will get the color of the transparent object its passing, in the case, yellow.
If the light goes trough a really thick part of the sphere, it will get much more affected of its color than a ray that just passes the side of it:
In this picture, lightrays outside the sphere is green. Once they are inside, the vector is red, and then green again when going out from the object. The longer the rays are inside( the length of the vector ), the more will the ray get colored by the object it's transmitting.
So, in our shader, we want to modify the color all pixels we see trough our sphere, with the spheres color and thickness. I have a few challenges including how to find out how thick a object is at each given point and how the formula for coloring transmitting rays will work, but got an idea.
I will write this shader using DirectX 10, but once I get it working, I'll write an XNA tutorial about it, so you can implement the same effect in your applications!
Anyway, this is for tomorrow. This evening went in the air on a NNUG user group about Silverlight and WPF, and some final reading before taking the MCTS Distributed Applications exam tomorrow. XNA as a target platform for Balder3DI had a meeting with Einar Ingebrigtsen yesterday about Balder and our goals for release 1.
So, after the meeting, I started on making XNA as a taget platform for Balder. I have a few challenges on getting it up correctly but I'll keep you guys updated on my progress, as well as posting some screenshots! So, stay tuned :)
If you want to know more about Balder and see it in action, take a look at the Balder page on codeplex. 28 abril Todays workshop went great!Today I had the "Rendering the ocean" workshop with 6 students from Hamar, Norway.
We started the session with making the waves, and then moved one with detaild waves, reflection and refraction.
The discussed algorithm was also implemented into their game engine. We got most of it in today, and they got enough knowledge on how to implement the rest. All in all, todays session was great and we all learned a lot.
I will add todays session in my Tutorial TODO list, but it will take some time before we are getting there as I have to prioritize other tutorials.
If you and your team want to learn anything specific, don't hesitate to contact anyone i game camp and we will see what we can do! Chairman of Game CampI'm now officially the Chariman of Game Camp!
We are still the same crew and the same persons in the steering grop as before, but we promise you new english content to www.gamecamp.no, frequent news, updates and a new web design. We will also hold user groups, presentations and workshops so stay tuned! :)
Our first goal is to finish todays workshop, and start the (hopefully) monthly mini-events @ NITH. Remember, you are all welcome to these events, not only NITH students.
We will soon post more information about this on gamecamp.no!
Polish translation of XNA Shader Tutorial 1.A polish version of my XNA Shader Tutorial 1 can be found on the following URL:
The author have, with permission from me, translated my tutorial into polish. So, if your polish, you should check out http://xna.com.pl/ for information about XNA on polish! Workshop on Ocean rendering todayI'm having a Workshop on "How to implement the ocean" for a few students who are creating a XNA game for Dream-Build-Play 2009. In this workshop I will talk about reflection, refraction, cube mapping and how to model/generate waves using a vertex/pixel shader, including foam generating on top of big waves!
The students who are attending to todays workshop are acctually traveling from OPIM, Hamar, almost 200km, to learn what they want. This is really cool! :)
I will also try and write a tutorial about this session later, so you who cannot come to the workshop can get something from it. There are many students who have used the opportunity to use me as their mentor during their projects, and asking me for help and workshops. If you and your team want to learn anything specific, please send me an e-mail and I will gladly try to set up a workshop either physical or over a live meeting/web cast. New version of GS360 in PlayTestI have uploaded the new version of Grill Simulator 360, and its available at XNA creators club.
If you want to test the game, please register there and check the Grill Simulator 360 post under Play Test.
I would like to take a moment to thank everybody who have been testing my game this far. Your feedback is really apprechiated, and makes the game complete and bug-free ;) 27 abril Balder 3DEinar Ingebrigtsen has made a huge job on revitalizing Balder, a 3D engine with Silverlight as one of it's target platforms.
Einar invited me to join the development team, and I seaid yes. So, now I'm a part of it all :)
We got plans on impementing support for many different platforms, making Balder3D a cross-platform engine, including XNA. Right now I'm busy on implementing the lighting functionality, making things shine! It's quite a challange, but thats what we like, ain't it? ;)
More information, a live demo( you will need Silverlight installed ) and a screenshot can be seen on Einar Ingebrigtsens blog: Revitalizing Balder
You can find the project on CodePlex/Balder. Grill Simulator 360Grill Simulator is still under PlayTest. I have only delivered the game to PlayTest one time, but I guess its time to upload a new version.
I tried to fix some issues with the save and load functions, but it was hard without a memory unit for the XBox360. So, I got one from the shop this other day have tried to get everything I can on saving and loading bugs.
In this new version, I have fixed quite many minor bugs. Also, I made it possible to turn off the ingame music, playing SFX only, so now you can listen to your own music in game :)
Other changes:
- Made it a bit easier to navigate the game
- Added a bigger, better and more complete in-game tutorial
- You can now use all the controlers to play the game, not only the one in slot 1.
- Added a few more items and clothes
- More robust Save/Load rutines
- New in-game music on the way
I would like to recommend every developer on the XBox360 to get a 2nd hardrive or at least a memory unit in order to fully debug and fix the bugs that one might encounter when writing the save/load functionality for your game.
Here is a short picture slideshow from previos versions of Grill Simulator:
1 - PocketPC 2003 version
Windows version, using C++/DirectX 9.0 And finally, Grill Simulator 360 for XBox 360:
What's Grill Simulator?
Teknofil 2009I went to a technology fair in Oslo Spektrum this weekend, named Teknofil 2009. It was pretty cool, not as good as last time I was there but they had a nice gameing area there, with XBox games, Wii games and Ps3 games on the big screen, and many competitions.
Most of the stands was pretty basic, but I got myself a cable TV decoder from Canal Digital so now I can, finally, look at HD channels ;)
Also, now I know I want a new Pioneer TV, so I can play Grill Simulator on a bigger screen ;P Silverlight presentation for AvanadeI'm having a 2h Silverlight presenation @ Avanade, Fornebu, 08:00-10:00 on May 7th, so if you are working at Avanade and want to learn how easy it is to get started with Silverlight 2, feel free to take a visit :)
Breakfast will be served. :) Windows 7 RCYou want to get your hands on Windows 7? Well, if you are a MSDN Subscriber, you can get it April 30th and if your a regular user, you can get it May 5th. :)
Looking forward for the RC version..
More information:
24 abril The Gathering 2009Just wanted to share some pictures taken at The Gathering 2009 :)
An ocean of computers.. over 5000 ;)
From left to right: Steffen aka. kroz, Egil aka. higen, Petri aka. digitalerr0r( yeah me :P ),Thomas aka. sabotender, Stian aka. Gifster, Lars aka. RawBacon and Paul aka. MadeInPixels. Egil and me suffers from .. too little sleep and too much coding but im happy with this years The Gathering, we had lots of fun, and won some prizes :)
Me coding some last minute( those last minutes went on for 9 hours, after most of the group went to sleep :P ) changes in the democode. Sabotender is making faces in the background.
After many hours at the stand, im ready to do some more coding and getting our demo done. 22 abril XNA Shader Programming - Tutorial 12, Post process NoiseXNA Shader Programming
Tutorial 12 - Post process, Noise/Distortion
This tutorial builds on Tutorial 9, post process wiggling. If you haven't read that yet, you should in order to fully understand what's going on here.
The source-code and binaries can be found in the end of the tutorial.
Noise/Distortion
In this tutorial, we are going to add some Noise/Distortion to our scene.
To add some noise/distortion to your scenes, we must add a distortion value to out texture coordinates, and when modified, we must use the new texture coordinate to look up into a texture sampler.
We also want to animate the noise, so we would need a timer that will affect the distortion amount, and we must have a value that indicats how much we want to distort our image, and a seed that will be used in the distortion algorithm.
Implementing the shader
Now, let's implement this little shader!
First of all, we need to declare some global variables in our shader:
// This will use the texture bound to the object( like from the sprite batch ).
sampler ColorMapSampler : register(s0); // A timer to animate our shader
float fTimer; // the amount of distortion
float fNoiseAmount; // just a random starting number
int iSeed; ColorMapSampler is our rendered scene, fTimer is our timer, fNoiseAmount is a value that indicates how much the scene will be distorted. A value between 0.001 to 0.5 is pretty good, and lastly, our seed value that will be used when calculating the noise.
Next, we need to add some logic to our pixel shader. First of all, we need to calculate our noise factor:
float NoiseX = iSeed * fTimer * sin(Tex.x * Tex.y+fTimer);
NoiseX=fmod(NoiseX,8) * fmod(NoiseX,4); This is just a "random" math formula that takes our seed, timer and the texture coordinates to make the random value different between our pixels. Feel free to play with this in order to archive differnt effects.
We are also using a new function here: fmod(x,y).
This function returns the floating-point reminder of x diveided by y.
Next, we need to calculate how much the distortion will affect each x and y component. We want these to be slightly different to make it look a little randomized:
float DistortX = fmod(NoiseX,fNoiseAmount);
float DistortY = fmod(NoiseX,fNoiseAmount+0.002); Now, we got what we need to create our new texture coordinates:
float2 DistortTex = float2(DistortX,DistortY);
And, lastly, use the new distrot texture coordinate with the old texture coordinate to end up with a slightly distorted texture coordinate:
float4 Color=tex2D(ColorMapSampler, Tex+DistortTex);
This is our post process shader: // A timer to animate our shader // the amount of distortion // just a random starting number // Noise // Use our distortion factor to compute how much it will affect each return Color; technique PostProcess NOTE: YouTube - XNA Shader programming, Tutorial 12 - Pixel distortion post process Download: Executable + Source
XNA Shader Programming - Tutorial 11, Post process GrayscaleXNA Shader Programming
Tutorial 11 - Post process, Grayscale
This tutorial builds on Tutorial 9, post process wiggling. If you haven't read that yet, you should in order to fully understand what's going on here.
The source-code and binaries can be found in the end of the chapter.
Grayscale Image
In order to make a black and white image/scene, we will need to convert our colored SceneTexture to a nagative one. This is done in a post process pixel shader.
A black and white image consist of only pixels with a shade of gray, so our shader must somehow take a color, and make it to a shade of gray. There is a few ways of doing this, and Im going to show you two of them.
1. Average color
One way of doing this is to take the three color channels, add them together and devide the result on 3. This gives us the average color, and we set all components of our color to this average color:
Color.rgb = (Color.r + Color.g + Color.b)/3; This will result in a pixel with all components set to the same value. It gives a pretty good result, but if you look closely, it's incorrect! Let's take a look on an other method of doing this. 2. Grayscale intensity
The eye is more sensitive to one color component, green, than towards the others and so on. One of the most common ways of converting an image to grayscale is to use a set of values that describe the grayscales intensity/weight for each of the three color components:
g = 0.3 R + 0.59 G + 0.11 B
This will convert our grayscale image correctly, and can be implemented in the shader like this:
Color.rgb = dot(Color.rgb, float3(0.3, 0.59, 0.11)); I have added this figure as a comparison on the two different grayscale methods. It's a little hard to see in this example but it can be seen in a more colorful scene, or one that contains more green. Implementing the shader We have seen how to convert a color to grayscale. I'v also added the shaders for both methods, so you can see the whole picture without having to download the example.
1. Average color sampler ColorMapSampler : register(s0); float4 PixelShader(float2 Tex: TEXCOORD0) : COLOR // Keep our alphachannel at 1. technique PostProcess
2. Grayscale intensity sampler ColorMapSampler : register(s0); float4 PixelShader(float2 Tex: TEXCOORD0) : COLOR // Keep our alphachannel at 1. technique PostProcess NOTE: Thats about it, if you have any inputs on this one, please leave a comment, or send me an e-mail on petriw(at)gmail(dot)com YouTube - XNA Shader programming, Tutorial 11 - Grayscale postprocess Download: Executable + Source
21 abril XNA Shader Programming - Tutorial 10, Post process NegativeXNA Shader Programming
Tutorial 10 - Post process, negative
This tutorial builds on Tutorial 9, post process wiggling. If you haven't read that yet, you should in order to fully understand what's going on here.
The source-code and binaries can be found in the end of the chapter.
Negative Image
This shader is also very simple, but, I got a lot of questions about this so I decided I wanted to write a short tutorial on it.. and it's really short ;)
To get the color from a texture sampler, you usually do this: float4 Color = tex2D(ColorMapSampler, Tex);
To get the negative color, you simply subracts each channel on Color with one, or, simply:
float4 ColorInverse = 1.0f - tex2D(ColorMapSampler, Tex); And, thats it!
Implementing the shader
Let's start by implementing the shader. Its pretty short so I'll just add the code:
sampler ColorMapSampler : register(s0);
// Negative image
float4 PixelShader(float2 Tex: TEXCOORD0) : COLOR { float4 Color = 1.0f - tex2D(ColorMapSampler, Tex); // Keep our alphachannel at 1. Color.a = 1.0f; return Color; } technique PostProcess
{ pass P0 { // A post process shader only needs a pixel shader. PixelShader = compile ps_2_0 PixelShader(); } } First, we subtract the color from our sampler, from 1.0f to get the inverse.
But, when doing this, we are inverting the Alpha channel as well. If this is what you want, go ahead, but if you want to keep the alpha-values from the original image, you must set it back to what it was, or set it to something manually.
In this case, we want the image to have the alpha of 1.0, so we set the a component of Color to 1.0, making our image fully opque if we have shading enabled.
Thats it for this tutorial. I'll keep adding some post process effects during the next days so keep comming back :)
NOTE:
You might have noticed that I have not used effect.commitChanges(); in this code. If you are rendering many objects using this shader, you should add this code in the pass.Begin() part so the changed will get affected in the current pass, and not in the next pass. This should be done if you set any shader paramteres inside the pass. Download: Executable + Source XNA Shader Programming - Tutorial 9, Post process wiggleXNA Shader Programming
Tutorial 9 - Post process wiggling
Welcome to the 9th tutorial in my Shader Programming series. Today we are going to look at a pretty simple but cool post process effect!
It's hard to see the result in the image, so you should download the example and take a look at the result so you understand what we are about to make.
The source-code and binaries can be found on the bottom of this article.
Post processing?
Post processing is really just about applying an effect, or a combination of effects to a image/frame/video to make it look more polished, or to have a certain effect. A post process effect can be looked at as a filter the scene is going trough.
In this case, we are rendering a scene to a texture and applying a wiggling effect to the scene. This makes the scene look like it's "underwater". To make this happen, we need to modify our texture coordinate vector using some sort of a circle movement, and then use the modified texture coordinate to look up the color in our ColorMapSampler! Take this image for example:
The green points are just some example texture coordinates, and based on a timer, we can circulate this point around. Doing this on all texture coordinates will give us the wiggling effect we want!
The scene in our example contains a backdrop rendered using SpriteBatch, and a 3D model using our Diffuse shader from Tutorial 2. This scene is rendered into a texture, and that texture is used to render the scene. When rendering it, we apply our post process shader.
So, all in all, we got two shaders. One for the in-scene object, and one that will be used as the post process shader.
Implementing the shader
The post process shader only needs one shader, the pixel shader. To make the shader dynamic, we will need to implement a timer.
float fTimer; This timer will be set from the application, and will be used in our sin/cos movment of every texture coordinate, making them move around! :) We also need the ColorMap texture for the shader, containing our scene and is updated every frame. Now, we got what we need for our shader! Lets take a look at our short pixel shader function: float4 PixelShader(float2 Tex: TEXCOORD0) : COLOR
float4 Color = tex2D(ColorMapSampler, Tex); This shader simply takes the X and Y component of the current Texture Coordinate, Tex, and moves them around in a circle. the fTimer+Tex.x in the sin loop is there so the coordinate moves based on the timer, pluss the Tex.x to make the circle different for every step in the X-direction. We do the same thing with Y.
If we had used sin(fTimer)/cos(fTimer) in stead of including Tex.x/Tex.y, all texture coordinates would have been moving in the exact same circles. You should try this, and play around with the parameters so you fully understand why we are doing this.
Finally, we will need our technique, named PostProcess:
technique PostProcess Implementing the shader
It's pretty simple to add our shader to whatever scene we want! Just render the scene into a texture:
RenderTarget2D Now, we must display the scenetexture, and applying the post process effect: And thats it! We got a very simple, but pretty cool post process effect. You should play around with the shader so implement your own post process effects. Try editing the circle each texture coordinate moves in! U guess you can come up with a quite cool distortion effect ;)
NOTE: Good luck! 20 abril Common mistakes when using XNAJust wanted to spend a few minutes on some regular questions I get.
1: SpriteBatch and SaveState
First of all, the SaveState on the sprite batch.
When you are using the Begin() method of the SpriteBatch class, it will set some of the render/device states to different values. Once you call the End() method of the SpriteBatch object, the render states will not, by default, be restored. This can result in some wierd artifacts that makes your 3D models( if you render 3D and 2D ) look wierd, especially considering the UV-coordinates.
This can lead to a lot of frustration, but luckily, the solution to this is pretty simple:
spriteBatch.Begin( SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.SaveState);spriteBatch.Draw(texture, new Rectangle(0, 0, 200, 200), Color.White); spriteBatch.End(); Here we use the SaveStateMode.SaveState to sve the state of our device. Once we call End(), the state that was saved in Begin will be restored!
2: AudioEngine, playing music is randomly crashing!??
Just got one comment on this one. Did you remember to update your AudioEngine instance? Say your instance is named audio, this problem can most of the time be solved by just calling this function from your Update loop:
audio.Update();
I will update this post with more soon! |
|
|