Jump to content

Model Transparency


Rick
 Share

Recommended Posts

Was there a way to do model (or csg with a script attached so it doesn't collapse) specific transparency instead of material specific? There are certain instances where I want to fade in/out some models but they'll have the same material as other models that I always want to have shown (ie I don't want transparency of 1 model to affect another with the same material on it).

 

I tried SetColor(Vec4(1, 1, 1, 0)) (alpha set to 0) but that didn't work.

Link to comment
Share on other sites

That's correct. You really can't do transparent surfaces with accurate lighting, because the shadowmap calculation needs a depth value to perform calculations on. You can however do a 50% transparency effect by discarding every other pixel, as the glass shader demonstrates.

 

It would probably be possible to write a really clever shader that did a different discard pattern depending on the alpha value.

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

That's correct. You really can't do a full scale of transparency with lit surfaces, because the shadowmap calculation needs a depth value to perform calculations on.

 

How are games fading models in/out?

 

 

You can however do a 50% transparency effect by discarding every other pixel, as the glass shader demonstrates.

 

But that would be for every model that has it right? For glass sure that would work, but for walls like in my example where only certain wall models need to fade in/out at certain times that wouldn't work right.

 

 

Fading models in/out has to be a pretty common need for various things. Dead bodies that you don't want to clutter up the world with, walls, chests, whatever right.

 

Here is a video of walls fading in which is what I'm trying to do:

 

 

Can we fade (not just discard) with a shader that has this controlled with the alpha value of SetColor() since the Vec4 of SetColor() is model specific?

Link to comment
Share on other sites

Diablo 3 doesn't use a deferred renderer. The shadows are probably just a single projected image with no depth info, which is why it only appears on the floor and isn't self-shadowing, and why only the characters cast any shadows.

 

For a game like this, there are a couple of options:

  • Make the body sink into the ground.
  • Use a puff of particles, or something like the Doom 3 death effect.
  • Leave the bodies there. They're pretty inexpensive to animate.

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

Currently I'm more thinking about the walls than bodies. Just gave bodies as another example. I'm fine with a puff of particles with those, but something like a wall is different. Currently they snap show/hide which works but I guess I have no other options with a deferred renderer? That kind of sucks.

Link to comment
Share on other sites

It's not really that a deferred renderer can't do something a forward renderer can, it's just that it would look out of place not to have dynamic lighting working on the alpha blended object.

 

Personally, I would just design the map so you don't have objects occluding the gameplay areas.

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

I would increase alpha using a noisemap from 0 to 1 and discard.

 

I don't know what that means smile.png

 

It's not really that a deferred renderer can't do something a forward renderer can, it's just that it would look out of place not to have dynamic lighting working on the alpha blended object.

 

That sort of implies that it can't do this requirement though because the requirement is to have dynamic lighting and still allow fading.

 

 

Personally, I would just design the map so you don't have objects occluding the gameplay areas.

 

Having this is sort of a feature in these kinds of games. They all have this and it looks really cool. If shadmar can explain what he means maybe that's an option otherwise snapping in and out will have to do for now. It's not stopping me from continuing on, but if this ever gets far a long I know I'll have to field questions from people asking why it doesn't fade in/out.

Link to comment
Share on other sites

I know what he's talking about and it would probably look really good. Basically you use a noise image, together with an alpha value. For each pixel onscreen, you do a texture lookup on the noise texture in screen space and say "if the noise value is less than the alpha value, discard this pixel". The lower the alpha value, the more pixels are discarded, and the more transparent the surface looks.

  • Upvote 1

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

OK so a noise image would look like:

 

220px-White-noise-mv255-240x180.png

 

Then my model would supply the alpha value for the shader that has this image in some open texture slot.

 

So on the pixel shader it does a texture lookup on the above image and? I'm lost now. What is a noise value? The shades of gray in the noise texture?

 

So like a solid black value is a 1 and a white value is 0 (or reversed if you like), and everything in between has a value between 0 and 1 which relates to the alpha value we send in? Meaning eventually over time when the alpha value is 0 it'll eventually discard all pixels. So in shaders how could we get the color value of the noise texture and relate that to a number between 0-1 (or would it be 0-255)?

 

I think I', understanding the idea now just not sure on how to relate the color value of the noise map to a value the alpha can be compared to.

Link to comment
Share on other sites

Actually, GLSL 4.0 has a rand() function. It would be a lot easier to just use that. Use gl_FragCoord as the input, and if the resulting value is less than your alpha value, discard that pixel.

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

Hmm, wouldn't a rand() function run for each pixel meaning during the time I'm reducing the alpha from 1-0 the same pixel could be discarded and then not discarded, then discarded, etc, over time instead of the constant a noise map would provide? Not sure how that would look vs a constant noise map.

Link to comment
Share on other sites

Hmm, wouldn't a rand() function run for each pixel meaning during the time I'm reducing the alpha from 1-0 the same pixel could be discarded and then not discarded, then discarded, etc, over time instead of the constant a noise map would provide? Not sure how that would look vs a constant noise map.

 

That's what I thought on first reading that, but if the built in rand() function is anything like the first few google results then it will return a the same value for the same input.

 

So on the pixel shader it does a texture lookup on the above image and? I'm lost now. What is a noise value? The shades of gray in the noise texture?

 

Since the noise is greyscale you just take the R G or B value of the pixel and use that as your noise. To get the value of the pixel you need to pass your texture into the shader and look it up the same way it (for example) looks up the diffuse texture.

 

I'm keen to give this a try myself once I get home, will post the results if you haven't got a solution working.

Link to comment
Share on other sites

I would think if they implemented rand() they would have some way to seed it based on time or something, but maybe that's not what we want. I think the rand() way seems way easier but I'm not sure of how to get the color from SetColor() and if I need to include anything for rand(). Those results are using custom made rand() functions and not the GLSL one it seems.

Link to comment
Share on other sites

Since the noise is greyscale you just take the R G or B value of the pixel and use that as your noise. To get the value of the pixel you need to pass your texture into the shader and look it up the same way it (for example) looks up the diffuse texture.

 

This is what I'm thinking, still need to actually test it:

 

float NoiseV = texture(texture4,ex_texcoords0).x; //Lookup the pixel and grab its red (x) value //Assuming texture4 is the noise texture

float InvAlpha = 1-ex_color.a; //Invert range from 0...1 to 1...0 //(Better logic might negate the need for this)
if (InvAlpha==1) InvAlpha = 1.1; //Change 1 to 1.1 so < is true //(Better logic would negate the need for this)

if (NoiseV<InvAlpha) discard; //If the red value of the pixel is less than the alpha value of the model, discard

 

EDIT:

This is what I get from the above code, not sure what to do about the shadow the model casts (I'm not good with shaders but I try where I can)

  • Upvote 6
Link to comment
Share on other sites

I never really thought about the shadow fading out. That's interesting.

 

You can do the exact same thing with the shadow shader. Just copy and paste the animated shadow shader to make a new one, add it to the material, and use the same trick. Because of the shadow blur, your shadow will actually appear to fade smoothly.

 

I've tried to do discards on a sub-pixel basis, which would provide true transparency when MSAA was in use, but for some reason my Nvidia card didn't like the shader logic. I might run it by their driver team some time and ask them to support it.

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

Thanks White, will give this a try when I get home. It looks pretty much what I was expecting. The slower it goes the more noticeable it is as to what is happening, but I bet if it's done fast enough it'll look smoother. In my case with walls I want the shadow to stick around so for me it's not an issue. It's a very neat trick and will work for what I need. Thanks!

 

So pixels can't be made transparent in a shader? It's either there with a given color or it's discarded? I would think if you can discard it and have whatever is behind it still be there, that you could make the pixel semi-transparent too.

Link to comment
Share on other sites

I never really thought about the shadow fading out. That's interesting.

 

You can do the exact same thing with the shadow shader. Just copy and paste the animated shadow shader to make a new one, add it to the material, and use the same trick. Because of the shadow blur, your shadow will actually appear to fade smoothly.

 

How do I actually do it in the shadow shader since it doesn't have a fragment shader just a vertex shader? As far as I know (and I don't know much about shaders) you can't discard during the vertex shader.

 

 

EDIT: Should have tried it before posting. I added a very basic fragment shader to it and it works. biggrin.png

 

 

I copied the fragment from the regular shader and took out everything I didn't need, leaving me with:

#version 400
//Uniforms
uniform sampler2D texture4;//noise map
//Inputs
in vec2 ex_texcoords0;
in vec4 ex_color;
void main(void)
{
   float NoiseV = texture(texture4,ex_texcoords0).x; //Lookup the pixel and grab its red (x) value

   float InvAlpha = 1-ex_color.a; //Invert range from 0...1 to 1...0
   if (InvAlpha==1) InvAlpha = 1.1; //Change 1 to 1.1 so < is true

   if (NoiseV<InvAlpha) discard; //If the red value of the pixel is less than the alpha value of the model, discard
}

 

And added to the vertex part:

//at thte top
in vec2 vertex_texcoords0;
out vec4 ex_color;
out vec2 ex_texcoords0;

//after entitymatrix_ *= animmatrix;
ex_texcoords0 = vertex_texcoords0;
ex_color = vec4(entitymatrix[0][3],entitymatrix[1][3],entitymatrix[2][3],entitymatrix[3][3]);

  • Upvote 2
Link to comment
Share on other sites

@Rick, the final lighting pass needs a depth value. So the lighting will not be correct on the blended pixel, since it should really be the blended result of two different light calculations.

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

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