Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


Shadowmap transparency for multiple objects


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
14 replies to this topic

#1 _6_   Members   -  Reputation: 113

Like
0Likes
Like

Posted 06 January 2014 - 07:01 PM

Hi,

 

I have Shadowmaps working based off of several tutorials around the internet, and have been able to get transparency working by discarding pixels in a texture that have an alpha value.  But this only seems to work on only a single texture sampler which I pass to the shadowmap pixel shader.

 

I'm now trying to work out how I would get my shadows working irrespective of how many textures/models I have in a scene.  I can't quite get my head around how I can do this.  How have others managed to do this?

 

Cheers

6



Sponsor:

#2 _6_   Members   -  Reputation: 113

Like
0Likes
Like

Posted 11 January 2014 - 09:23 PM

Hi,

 

Can I bump this question please.

 

Thanks

6


Edited by _6_, 11 January 2014 - 09:23 PM.


#3 _6_   Members   -  Reputation: 113

Like
0Likes
Like

Posted 28 January 2014 - 06:57 PM

Hmm, no anwser after 300+ views.  I'm sure it's not that complicated so let me re-word the issue I have.

 

The depthmap texture, ( from the lights point-of-view), is created when my pixel shader receives the depth value of a fragment from a vertex shader.  This is all very simple and creates a nice depthmap of my geometry.

 

Next, to create the shadowmap I have a pixelshader which compares the Projected depthMap with the depth from my current Viewposition and accordingly set the pixel as in light or in shadow. 

 

The problem is, at some point, ( either at the creation of the depthMap or shadowMap), I would like to check if the texture fragment has an alpha channel value.  I have been able to do this when I explicitly pass in a texture sampler to the pixel shader, but I don't know how to check for alpha values when there is an unknown number of textures to test.

 

So how do others do this?  I'm just looking for a general direction to go in, not for specific code. Just out of interest, is it best to perform the alpha test when creating the depthMap or at the shadowMap stage.

 

Thanks

6



#4 L. Spiro   Crossbones+   -  Reputation: 19058

Like
1Likes
Like

Posted 28 January 2014 - 09:05 PM

Next, to create the shadowmap

You already created the shadow map. The light’s depth map is the shadow map.  Now you need to find pixels in a shadow or not in a shadow.  This is not “creating the shadow map,” it’s applying the shadow map you just created.
 

but I don't know how to check for alpha values when there is an unknown number of textures to test.

This is why no one has replied. I didn’t have a clue how to even ask for clarification on what this even meant. At least this time it might be a bit clearer as to where you are going wrong since you think making a depth map and making a shadow map are different processes.

 

Step #1: Create the shadow map (write depth values to a depth/float texture).  If the alpha value of the object you are rendering at this time is below a certain threshold, discard it.

Step #2: Apply shadow map using your existing comparison process to determine in or out of shadow.

 

 

That is all there is.

 

 

L. Spiro


Edited by L. Spiro, 28 January 2014 - 09:07 PM.


#5 _6_   Members   -  Reputation: 113

Like
0Likes
Like

Posted 28 January 2014 - 09:52 PM

 

 

Ok, perhaps I have my terminology wrong.  So it sounds like what you're saying is that the depth texture which tells me how far the lighting is reaching, is actually called the shadowMap.  In other words the shadowMap actually stores light depth information.  Kinda makes sense.

 

Now, where you say "If the alpha value of the object you are rendering at this time is below a certain threshold, discard it.".  Yep, I understand that's what I need to do, but the shader is a post process shader so how to I access the texture/sampler belonging to that object? Do I need to declare the sampler at the beginning of the shader file?  If so then what if I have 50 textures with alpha information?

 

Thanks

6



#6 L. Spiro   Crossbones+   -  Reputation: 19058

Like
0Likes
Like

Posted 28 January 2014 - 11:50 PM

Yep, I understand that's what I need to do, but the shader is a post process shader so how to I access the texture/sampler belonging to that object? Do I need to declare the sampler at the beginning of the shader file?

It doesn’t matter if you are using a deferred renderer or what. At the point in time when you create the shadow map, you are rendering object-by-object one at a time.
At that time you have access to alpha values. If not, you need to modify your shaders so that you do.

Shaders used to generate a shadow map are typically custom and are forward-renderred. Opaque objects are drawn first, all with the same shader which simply outputs depth as the color, in a way similar to vec4(depth, 0.0, 0.0, 1.0) (in advanced techniques you will later use vec(depth, ddXderiv, ddYderiv, 1.0) etc., but you can climb that hill once you get there).

When you render translucent objects you need to at least read the alpha from the texture or material (or both) and decide to discard or not.


You make the decision to discard on an object-by-object basis during the creation of the shadow map, so there is no situation in which you have to figure out which sampler to use or X number of textures to potentially sample, etc., unless that single object actually takes 50 textures to render (which simply never is the case).  Creating shadow maps is forward-rendering with simplified shaders.

 

 

L. Spiro



#7 _6_   Members   -  Reputation: 113

Like
0Likes
Like

Posted 30 January 2014 - 08:15 PM

Sorry, I'm still confused.  I've various different things, but nothing seems to be working.

 

At the point where I'm creating the ShadowMap ( aka depthmap) the vertex shader is passing all the vertex data including the depth information to the pixel shader.  At the moment the pixel shader just stores the depth in a 'r32f' texture.  Is it at this point I clip() any alpha values?

 

If so, I'm still not clear how I access the alpha value.  I presume the Vertex Shader can't provide this info because it just processes vertices.  Is there some semantic, ( like COLOR0) I need to use when I'm in the Pixel shader?  I just can't find anything online about how to do this part :(

 

Here is a snippet of my code which shows a shadowMap texture being created, then it is used in ScreenShadOUT_PS as part of the camparison process

///////////////////////////////////////////////////////////
///////////////////////////// Connector Data Struct ///////
///////////////////////////////////////////////////////////

struct OneTexelVertex
 {
    float4 Position	: POSITION;
    float4 color	: COLOR0;
    float2 UV		: TEXCOORD0;
    float4 depth	: TEXCOORD1;
    float4 ViewPosition : TEXCOORD2;
    float4 normal   : NORMAL;	
};


///////////////////////////////////////////////////////////
////////////////////Pass = DepthMap ///////////////////////
///////////////////////////////////////////////////////////
// RTT available in this pass = ScnMap
OneTexelVertex ScreenIN_VS(OneTexelVertex IN) 
{
    OneTexelVertex OUT = (OneTexelVertex)0;
	OUT.Position = mul(IN.Position, gWorld);
	OUT.Position = mul(OUT.Position, gLightView);
	OUT.Position = mul(OUT.Position, gLightOrtho);
	
    OUT.UV = float2(IN.UV.xy + ViewportOffset);
	OUT.depth.x = OUT.Position.z/OUT.Position.w;
	OUT.normal = IN.normal;
    return OUT;
}
float4 ScreenOUT_PS(OneTexelVertex IN) : COLOR
{   
	float depthValue =  IN.depth.x;
	return float4(depthValue,depthValue,depthValue,1.0f);
} 

// RTT Output = ShadowMap
///////////////////////////////////////////////////////////
/////////////// Pass = Shadow /////////////////////////////
///////////////////////////////////////////////////////////
OneTexelVertex ScreenShadIN_VS(OneTexelVertex IN) 
{
    OneTexelVertex OUT = (OneTexelVertex)0;
    OUT.Position = mul(IN.Position, gWorldViewProjection);
	OUT.ViewPosition = mul(IN.Position, gWorld);
	OUT.ViewPosition = mul(OUT.ViewPosition, gLightView);
	OUT.ViewPosition = mul(OUT.ViewPosition, gLightOrtho);
	
    OUT.UV = float2(IN.UV.xy + ViewportOffset);
	OUT.normal = mul(IN.normal, gWorld);
	OUT.normal = normalize(OUT.normal);
    return OUT;
	
}

float4 ScreenShadOUT_PS(OneTexelVertex IN) : COLOR
{
	float depthValue;
	float4 color;
	float3 lightDir;
	float lightIntensity;
	float4 textureColor;
	float2 projectTexCoord;
	float4 projectionColor;	
	color = float4(0.5,0.5,0.5,1);
	lightDir = -gLightDirection;
	lightIntensity = saturate(dot(IN.normal, lightDir));	
	projectTexCoord.x = (IN.ViewPosition.x / IN.ViewPosition.w) /2.0f + 0.5f; 
	projectTexCoord.y = (-IN.ViewPosition.y / IN.ViewPosition.w) /2.0f + 0.5f; 	
	if((saturate(projectTexCoord.x)==projectTexCoord.x)&&(saturate(projectTexCoord.y)==projectTexCoord.y))
	{
		depthValue = tex2D(ShadowMap, projectTexCoord).r;		
		lightDepthValue = IN.ViewPosition.z / IN.ViewPosition.w;		
		lightDepthValue = lightDepthValue - bias;		
		if(lightDepthValue < depthValue)
		{
			if(lightIntensity > 0.0f)
			{
				color = (float4(1, 1, 1,1));// * lightIntensity);
				color = saturate(color);
			}
		}
	}	
	return color;
} 

// RTT Output = ShadowOverlay


#8 phil_t   Crossbones+   -  Reputation: 5620

Like
0Likes
Like

Posted 31 January 2014 - 12:15 AM

I don't even know where to begin....

 


If so, I'm still not clear how I access the alpha value.

 

I'm assuming you are drawing objects that have textures with transparent parts. And in that case, you want to make sure light "shines through" those parts, right?

 

So, when rendering the object to your shadow map, you do your texture sample (exactly like you do when drawing the object during the lighting pass) and discard the pixel at that point based on the alpha value of your object's texture.

 


At the moment the pixel shader just stores the depth in a 'r32f' texture.  Is it at this point I clip() any alpha values?

 

Yes. And if you clip, then the pixel shader won't write the depth to the shadow map. Which is exactly what you want to happen.



#9 _6_   Members   -  Reputation: 113

Like
0Likes
Like

Posted 31 January 2014 - 04:25 AM

Hi Phil,

 

When I apply a shader to an object I know exactly which textures are to be used and only the vertices's for that object are acted on. But during a post process shader, every object vertex in the scene is processed.  I don't have to include every texture sampler for those objects do i?

 

So lets say I have a simple scene with 4 trees and each tree uses a different RGBA texture.  How do I access each of those textures during the shadowmap creation step?  Thats all I'm looking to get answered really.

 

Cheers

6

 

Edit.  Ok, after a bit more reading it sounds like I can access the texture through something like this:

 

sampler2D input : register(s0);


Edited by _6_, 31 January 2014 - 04:59 AM.


#10 phil_t   Crossbones+   -  Reputation: 5620

Like
0Likes
Like

Posted 31 January 2014 - 10:55 AM


But during a post process shader, every object vertex in the scene is processed.

 

A post-process shader generally acts on the entire screen, which is just a bunch of pixels. The only vertices it acts on are the 4 vertices used to draw the full screen quad. The vertices used to draw the original objects aren't relevant anymore. None of this matters though, because:

 


 I don't have to include every texture sampler for those objects do i?

 

Shadow map creation is not a post process shader, so that question doesn't make sense.

 

 


So lets say I have a simple scene with 4 trees and each tree uses a different RGBA texture.  How do I access each of those textures during the shadowmap creation step?  Thats all I'm looking to get answered really.

 

How would you draw though 4 trees normally? 4 separate draw calls, each with a different texture bound. You do the exact same thing when creating the shadow map, except you use a pixel shader that outputs a depth value instead of a color value.



#11 _6_   Members   -  Reputation: 113

Like
0Likes
Like

Posted 31 January 2014 - 01:03 PM

 

Shadow map creation is not a post process shader, so that question doesn't make sense.

 

 

Then thats why I'm having difficulty, because my shadowmap is created as a post process shader.  My shadowmap RTT is declared inside my post process shader and that shader then processes each vertex in the scene. But it sounds like this is wrong and I need to declare the RTT in my program and pass it to every object shader to get updated, then pass the final shadowmap texture to the post process shader.  Is that the way it's meant to work?



#12 L. Spiro   Crossbones+   -  Reputation: 19058

Like
0Likes
Like

Posted 31 January 2014 - 08:03 PM

Then thats why I'm having difficulty, because my shadowmap is created as a post process shader.

No, it’s not. Because that defies the laws of physics. Why do you think you are having so much trouble? Your approach to a very simple problem is so flawed it is literally impossible. By definition, your approach requires an infinite amount of texture units, yet you only have 32 or 64 or so.

That’s the whole reason you started this topic. Because of your misunderstanding you took an impossible approach to the problem. Since you couldn’t figure it out you posted asking how to do it.

The only answer is: Stop trying to put the square peg into the circular hole.


I am not going to repeat my answer. Your line of thinking is so wrong it confused so many people no one even knew how to reply until you posted with a few more details.
Reread my answer until it makes sense. Do not stop rereading as long as you believe your current path makes any form of sense in this universe.


L. Spiro

#13 eppo   Crossbones+   -  Reputation: 3170

Like
0Likes
Like

Posted 01 February 2014 - 03:08 PM


my shadowmap is created as a post process shader

 

You mean it's a render target you render to after you've rendered the scene from the main camera's perspective? Because that would be true. If you're doing forward rendering you would need to have the shadow map ready when you're rendering and lighting the scene, but in a deferred setup you could do it afterwards (before applying lighting).

 

1. Render the scene with colors and all to render target 1 (or MRTs). For models with alpha textures, bind those textures and discard accordingly.

2. Render scene's depth from a light's perspective into render target 2 (shadow map). For models with alpha textures, bind and discard.

3. Apply lighting based on data in g-buffers + shadow map.

 

Forward rendering: first do step 2, then 1 and 3 combined.


Edited by eppo, 01 February 2014 - 03:12 PM.


#14 ankhd   Members   -  Reputation: 1644

Like
0Likes
Like

Posted 03 February 2014 - 08:16 PM

Each mesh gets drawn to the shadow map one at a time. This is the same shadow map. With your tree mesh you want only your leaf and not the quad. So the bit of code you use for your leaf rendering needs to be in your draw to shadow shader.

#15 ankhd   Members   -  Reputation: 1644

Like
0Likes
Like

Posted 04 February 2014 - 01:18 AM

Hello Im home now this is what I do im my shadow fx file

 

void PS(VS_OUT pIn)
{
 float4 diffuse = gDiffuseMap.Sample( gTriLinearSam, pIn.texC );

 // Don't write transparent pixels to the shadow map.
 clip(diffuse.a - 0.15f);
}






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS