In my research about projection, I came to projective texture. I found a lot of material about projective texture on the web but neither of them tells exactly what steps you need to follow to archieve the desired effect. In this post, I will tell in more detail how this works.
Basically, texture projection is a dynamic texture mapping of an object that is changed according to some point of view like a camera or a spot light. It works like projecting a point using the normal world, view and projection matrix but, in this time, projecting a texture coordinate. Below is the shader that accomplish this effect and we will see line by line how it works. So, let’s go.
First of all, we need the texture that will be projected:
texture gDiffuse;
After that, we need to create a sampler. Here there is a trick. The CLAMP mode needs to be used for all adrress. This is because, sometimes, as we will see, the texture coordinate generated can be greater than 1.0.
sampler2D gDiffuseSampler = sampler_state {
Texture = <gDiffuse>;
MagFilter = Linear;
MinFilter = Linear;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
};
Here is view matrix that will do the texture projection.
float4x4 projectorView;
And this is our normal camera matrix, composed by the Word, View and Projection.
float4x4 WorldViewProj;
To facilitate, I created some structs to store the information that will be needed by the shader effect.
struct VSIn
{
float4 position : POSITION0;
float4 texcoord0 : TEXCOORD0;
};
struct VSOut
{
float4 position : POSITION0;
float4 texcoord0 : TEXCOORD0;
};
Here is our main vertex shader. Let’s see how it works:
VSOut mainVS(VSIn input){
First, we create our struct to store the end result computed by the vertex shader.
VSOut output;
In this line, we compute the texture coordinate. We can see here that, to do this, we get the position and multiply by the projectorView, which is a matrix composed of a world, view and a projection but of some other point of view that can be another camera, as is the case of this example. After this multiplication, we said that the position is in homogenius clip space. Points outside the field of view of this projector view will not be rendered, or in other words, will not have texture coordinates.
output.texcoord0 = mul(float4(input.position.xyz, 1.0), projectorView);
Here we compute normally the projected position of this position.
output.position = mul(float4(input.position.xyz, 1.0), WorldViewProj);
And finally return these information
return output;
}
Now let’s see the Fragment Shader.
float4 mainPS(VSOut input) : COLOR {
First of all, we are making a division of all components of texture coordinates by w. It’s is necessary because, as I said before, we are in homogenius clip space. This space is used to do clipping but here we do not need this. So, to get the real position of this vertex we have to make this division. After that we are in normalized clip space. That is, our vertex can go from -1.0 to 1.0. Vertex outside of this range are not showed. Here we have a problem: texture coordinates only can go from 0.0 to 1.0. To solve this, we multiply it by 0.5 and add 0.5. This will do the job.
float4 texcoord = input.texcoord0;
texcoord.x = ((texcoord.x / texcoord.w) * 0.5 ) + 0.5;
texcoord.y = ((texcoord.y / texcoord.w) * -0.5 ) + 0.5;
texcoord.z = ((texcoord.z / texcoord.w) * 0.5 ) + 0.5;
texcoord.w = (texcoord.w / texcoord.w);
Next, we get the texel from the texture normally.
float4 tex = tex2D(gDiffuseSampler, texcoord);
And finally here we return the color. Here there’s another trick. As we are using clamp mode, texture coordinates outside the range from 0.0 to 1.0 will have its color matched to the border of the texture. So, what I did here is make the border of the image transparent, or alfa equals to 0. After that I multiply the texel color from the texture with it’s alpha and added the color of my plane, which in this case is white.
return float4(tex.r * tex.a + (1.0 * (1 – tex.a)),
tex.g + (1.0 * (1 – tex.a)),
tex.b + (1.0 * (1 – tex.a)), 1.0);
}
And is it. Below is an image of this shader applied in a plane using my engine that I’m making in XNA. Here, I used a camera with different field of view. Instead of a plane, it can be applied in whatever object you want.
- A field of view of 30 degrees
- A field of view of 60 degrees
In this shader, I tried to use the tex2Dproj which takes the texture coordinates in homogeneous coordinate space but it doesn’t work for me. If anyone get it’s working please, let me know.
Any comment or question, don’t hesitate to write me.


To use tex2Dproj you’ll need to multiply texcoord by the following matrix:
float off = 0.5 + (0.5 / projTexSize);
Matrix texAdjust
= new Matrix(0.5f,0.0f,0.0f,0.0f,
0.0f,-0.5f,0.0f,0.0f,
0.0f,0.0f,1.0f, 0.0f,
off,off,0.0f,1.0f);
You can multiply this against projectorView and then do a single matrix multiply in the pixel shader:
float4 tex = tex2D(gDiffuseSampler, texcoord*projectorView);
Hi Anon,
Thanks for your hint but you still use tex2D in the final right?
Sorry, my error, should have been tex2Dproj:
float4 tex = tex2Dproj(gDiffuseSampler, texcoord*projectorView);
Hi José. Just to say hello.
Hi Erick!
I really liked this post. Can I copy?
Thank in advance.
Sincerely, Your Reader.
Hi Timur,
You can copy that but please give me the credits where you use it.
Thanks!
Thank you!
I think you are thinking like sukrat, but I think you should cover the other side of the topic in the post too…
I am amazed with it. It is a good thing for my research. Thanks
I am unable to understand this post. But well some points are useful for me.
Wow! Thank you!
I always wanted to write in my site something like that. Can I take part of your post to my blog?
Of course, I will add backlink?
Sincerely, Your Reader
Yes, you can take part of it!
Cool site, love the info.
Great site…keep up the good work.
Great site…keep up the good work.
Cool site, love the info.
Wow! Its imposible… I’m realy shocked :/
Hey good stuff…keep up the good work!
This site rocks!
Cool site, love the info. I do a lot of research online on a daily basis and for the most part, people lack substance but, I just wanted to make a quick comment to say I’m glad I found your blog. Thanks,
A definite great read…
-Bill-Bartmann
Thank you much for that great post.
Great site…keep up the good work. I read a lot of blogs on a daily basis and for the most part, people lack substance but, I just wanted to make a quick comment to say I’m glad I found your blog. Thanks,
A definite great read…:)
-Bill-Bartmann
I don’t know If I said it already but …Great site…keep up the good work.
I read a lot of blogs on a daily basis and for the most part, people lack substance but, I just wanted to make a quick comment to say I’m glad I found your blog. Thanks,
A definite great read..
-Bill-Bartmann
Hey, I read a lot of blogs on a daily basis and for the most part, people lack substance but, I just wanted to make a quick comment to say GREAT blog!…..I”ll be checking in on a regularly now….Keep up the good work!
Super site….where’s the blog roll?
I don’t usually reply to posts but I will in this case, great info…I will add a backlink and bookmark your site. Keep up the good work!
Hey, I read a lot of blogs on a daily basis and for the most part, people lack substance but, I just wanted to make a quick comment to say GREAT blog!…..I”ll be checking in on a regularly now….Keep up the good work!
Generally I do not post on blogs, but I would like to say that this post really forced me to do so, Excellent post!
Your blog is so informative … ..I just bookmarked you….keep up the good work!!!!
Your site was extremely interesting, especially since I was searching for thoughts on this subject last Thursday.
I am really glad I found this blog. Great Job!
I was going to write a similar blog concerning this topic, you beat me to it. You did a nice job!
I was lucky enough to find your website through google. I have been searching all day for this information, Thank You.
Your blog is so informative … ..I just bookmarked you….keep up the good work!!!!
I‘m sure many of you are like me and one of the first things you do in the morning is head here and check out the new post. Along with seeing the new posts, I’m also always checking out the blog roll rss feed and watching them grow, or shrink sometimes. In one of my past …but all in all excellent site. Keep it up!
Hello, it really interesting, thanks
Hey, I really enjoy your blog. I have a blog too in a totally unrelated field (Online Stock Trading) but I like to check in here on a regular basis, just to see what’s going on and it’s always interesting to say the least. It’s always entertaining what people have to say.
Hey Buddy,
Nice site. Some interesting and informative posts man
I know, I am creeping,lol. Hopefully I can produce something like this myself. Who did you get your templates from?
Hopefully some of you people could help me out somewhat here. I am looking for someone who I was reliably told used to be a member on here. They used to use the name ‘webwizardthree’.
You see I am looking to start my own website on beauty related goods for goods such as: nonlaser tooth whitener (hence the where did you get your templates from,lol) but am having realllll difficulty getting hold of dropshippers for these goods. I had been in touch with this guy but my PC got stolen and unfortunately had all my contact details on it (I know, I know, should have backed it up
)
So if you folks have heard or seen anything of him could you pm me please? Failing that maybe one of you folks knows someone?
Also, which hosting do you use as I keep being told bad stories about the host I am thinking of placing my site with. Plus any other helpful tips you can give re starting up my website would be most useful and gratefully appreciated.
I do hope that someone has helpful knowledge about this
Thanks Pal,
I enjoyed reading your blog.
Thanks alot for the great read.
Great blog. Can’t wait to start my own blog.
Usually I don’t leave a comment but I wanted to let you know that I really like your site.
Thanks for this info. Additional discussions similar to this topic can be found at the World’s Largest Forum.
I’m new to your blog and i really appreciate the nice posts and great layout.,.,~,
Thanks for the great post on your blog, it really gives me an insight on this topic.*~,”.
Wow, I love these… thanks for sharing
All the best, Aaron
check my site
I love to visit your web-blog, the themes are nice.’-,~:
Great blog post and nice discussion among the comments.`-*`.
Man that was very entertaining and at the same time informative.,-*–
I bookmared your site a couple of days ago coz your blog impresses me.-,;~.
Hello Thank u for a very fresh idea. I am wondering why i have never though of this as well. I will definately try to use your blog for getting some more fresh info!
Thanks!
Regards, Aron
here’s my site too
This is a good blog. Keep up all the work. I too love blogging and expressing my opinions. Thanks