Jump to content
  • Advertisement
Sign in to follow this  
kobingo

Projective texturing in HLSL (water reflection)

This topic is 4601 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey, I want to project a texture to create a water reflection and have managed to do this with the FFP. But now I want to manipulate the pixels (with a pixelshader) on the water surface to make it look like its moving (so it looks like real water). Is it so, that if I want to use a pixelshader I also need to project my texture in a vertexshader? (I must forget about my working FFP projective texture?.. or can I do it any other way?). I don't really understand how to project a texture using a vertexshader in HLSL. What values does my vertexshader need? What does it look like? If anyone could show me a sample of projective texturing in HLSL it would be great. I have searched the forums but haven't find any good ones that ONLY shows projective texturing in HLSL... Thanks in advance!

Share this post


Link to post
Share on other sites
Advertisement
this can be acheived easily enough:

first in your vertex shader do this...
first mul your Input vertex postion with the worldspace projection matrix
and set the value to a float4 called pPos

then, having defined an output float3 called 'project', output these values:
Out.project.x = 0.5 * (pPos.w + pPos.x);
Out.project.y = 0.5 * (pPos.w - pPos.y);
Out.projectr.z = pPos.w;

now in your pixel shader before you sample your texture caluculate the final coords like this:

float2 projcoord=(In.project.xy / In.project.z);

then just sample your texture like:
float4 reflect=Tex2d(reflectsampler,projcoord);

or you can offet these coords with a normal map or whatever to make waves..just sample a normal map:

EDIT: use regular texture coords for the bump map
float4 bump=Tex2d(bumpsampler,In.Tex.xy);
float2 wavecoords = projcoord + (bump.xy * 0.2f) ; //bias it with a scale
float4 reflect=Tex2d(reflectsampler,wavecoords);

[Edited by - Matt Aufderheide on May 8, 2006 6:28:36 AM]

Share this post


Link to post
Share on other sites
Thanks for the reply. I couldn't get it to work... This is what my shader looks like now:

float4x4 worldViewProj : WorldViewProjection;
float4x4 world : World;
float4x4 worldInverseTranspose : WorldInverseTranspose;
float4x4 viewInverse : ViewInverse;

texture diffuseTexture : Diffuse
<
string ResourceName = "default_color.dds";
>;

struct vertexInput {
float3 position : POSITION;
float3 normal : NORMAL;
float4 diffuseColor : COLOR0;
float4 texCoordDiffuse : TEXCOORD0;
};

struct vertexOutput {
float4 pos : POSITION;
float4 project : TEXCOORD0;
};

vertexOutput VS_TransformAndTexture(vertexInput IN)
{
vertexOutput OUT;

OUT.pos = mul(float4(IN.position.xyz , 1.0), worldViewProj);

float4 pPos = mul(IN.position, worldViewProj);

OUT.project.x = 0.5 * (pPos.w + pPos.x);
OUT.project.y = 0.5 * (pPos.w - pPos.y);
OUT.project.z = pPos.w;
OUT.project.w = 0; // ??

return OUT;
}

sampler TextureSampler = sampler_state
{
texture = <diffuseTexture>;
};

float4 PS_Textured( vertexOutput IN): COLOR
{
float2 projcoord = (IN.project.xy / IN.project.z);
float4 reflect = tex2D(TextureSampler, projcoord);
return reflect;
}

technique textured
{
pass p0
{
VertexShader = compile vs_2_0 VS_TransformAndTexture();
PixelShader = compile ps_2_0 PS_Textured();
}
}


In my code I'm setting the values like this:

effect.SetTechnique("textured");
effect.SetValue("diffuseTexture", billboard.Texture[0]);
effect.SetValue("worldViewProj", Screen.Device.Transform.World * Screen.Device.Transform.View * Screen.Device.Transform.Projection);


I'm not that good at shaders yet, maybe you can explain whats wrong with it?

Share this post


Link to post
Share on other sites
Quote:
Original post by kobingo

vertexOutput OUT;

OUT.pos = mul(float4(IN.position.xyz , 1.0), worldViewProj);

float4 pPos = mul(IN.position, worldViewProj);

OUT.project.x = 0.5 * (pPos.w + pPos.x);
OUT.project.y = 0.5 * (pPos.w - pPos.y);
OUT.project.z = pPos.w;
OUT.project.w = 0; // ??


I don´t know if this is the source of your problem, but OUT.pos is already what Matt referred to as pPos. Furthermore I´m not sure whether

float4 pPos = mul(IN.position, worldViewProj)

would use 0 or 1 as w-coordinate, but it will definitely assume a w-coordinate, as you need a 4-dimensional vector to perform that multiplication and IN.position is only a 3-dimensional vector.

So I would just use the calculated OUT.pos to calculate OUT.project, because I think the w-coordinate in that multiplication should be 1. I´d change that code snippet to:

vertexOutput OUT;

OUT.pos = mul(float4(IN.position.xyz , 1.0), worldViewProj);

// float4 pPos = mul(IN.position, worldViewProj);

OUT.project.x = 0.5 * (OUT.pos.w + OUT.pos.x);
OUT.project.y = 0.5 * (OUT.pos.w - OUT.pos.y);
OUT.project.z = OUT.pos.w;


OUT.project should only be float3, as there is no need for the fourth component.

Hope that helps.
Good luck!

Share this post


Link to post
Share on other sites
Matches is correct..and normally I would just define the input position as a float4 right at the start to avoid any goofiness..

so you just do this:
{//inputs
float4 inPos: POSITION,
....
}

float4 pPos=mul(inPos,matWorldViewProj);
Out.pos=pPos;

Out.project.x = 0.5 * (pPos.w + pPos.x);
Out.project.y = 0.5 * (pPos.w - pPos.y);
Out.project.z = pPos.w;

or of ourse you can operate using the Out.pos if you want, but i dont like operating on my outs for some reason..

(btw see my edit for the bump map sampling..)

Share this post


Link to post
Share on other sites
Thanks alot, that worked! :-) Now I must experiment with the pixelshader to get it to look like waves...

Share this post


Link to post
Share on other sites
When I added this:

float4 bump=tex2D(NormalSampler,IN.project.xy);
float2 wavecoords = projcoord + (bump.xy * 0.2f) ; //bias it with a scale
reflect=tex2D(TextureSampler,wavecoords);

I got some weird effects, parts of the texture look correct while others didn't. It seemed like it wasn't really projected correctly anymore... Any ideas?

Also, what do you mean by "bias it with a scale"?

Share this post


Link to post
Share on other sites
When I change the line:
float4 bump=tex2D(NormalSampler,IN.project.xy);
to this:
float4 bump=tex2D(NormalSampler,projcoord);

I looks a little bit better, but still a bit weird... Can anyone spot the error?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!