shader error, too many texture loads

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
esaptonor
Posts: 145
Joined: Sat May 06, 2006 11:59 pm

shader error, too many texture loads

Post by esaptonor »

this is the error i get:

HLSL pixel shader compilation failed:
error X4519: too many texture loads and reads from texcoords

Why can't i access the texture more than once? is there a way around this?
I was just trying to learn shaders, and decided to try blur the screen.

the pixel shader just looks like this:

Code: Select all

struct PS_OUTPUT
{
    float4 RGBColor : COLOR0;  // Pixel color
};


sampler2D tex0;

PS_OUTPUT pixelMain( float2 TexCoord : TEXCOORD0,
                     float4 Position : POSITION,
                     float4 Diffuse  : COLOR0 )
{
   PS_OUTPUT Output;

 float4 up = tex2D(tex0, float2 (TexCoord.x, TexCoord.y+viewport_inv_height));
 float4 down = tex2D(tex0, float2 (TexCoord.x, TexCoord.y-viewport_inv_height));
 float4 left = tex2D(tex0, float2 (TexCoord.x-viewport_inv_width, TexCoord.y));
 float4 right = tex2D(tex0, float2 (TexCoord.x+viewport_inv_width, TexCoord.y));
 float4 upleft = tex2D(tex0, float2 (TexCoord.x-viewport_inv_width, TexCoord.y-viewport_inv_width));
 float4 upright = tex2D(tex0, float2 (TexCoord.x+viewport_inv_width, TexCoord.y-viewport_inv_width));
 float4 downleft = tex2D(tex0, float2 (TexCoord.x-viewport_inv_width, TexCoord.y+viewport_inv_width));
 float4 downright = tex2D(tex0, float2 (TexCoord.x+viewport_inv_width, TexCoord.y+viewport_inv_width));

 float4 centre = (up+down+left+right+upleft+upright+downleft+downright)/8;
 Output.RGBColor = centre;

   return Output;
}

and when i tried deleting the diagonal ones i got a new error:

X4523: cannot map this dependant texture read to ps_1_1

what does that mean?

thanks for your help,
esaptonor
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

i have a remark , may be it is the reason ?

where is the defination of viewport_inv_width in your shader program ?

yuor code does a blur effect so try shearch in the net for ready program that did the blur effect.
esaptonor
Posts: 145
Joined: Sat May 06, 2006 11:59 pm

Post by esaptonor »

the definition for that was at the top of the file, i only posted the pixel shader code.

I found the main problem - i had just copied code, and i didn't realise it but the code i copied was making it compile for ps_1_1, but when i saw that in my program and changed it to ps_2_0 then it worked.

so sorry about this waste of space :oops:
esaptonor
Posts: 145
Joined: Sat May 06, 2006 11:59 pm

Post by esaptonor »

wait, maybe this can turn into a productive piece of space again!

i understand that for a bloom effect i need to run an initial shader that will get the bright areas and make the rest black, make that into a texture to send to my post process shader. How do i do that?
Can i store a new texture with irrlicht and then send this new texture to the post process shader?
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

i understand that for a bloom effect
your shader program takes evry pixel and combine it with it's next one in each direction then calculate the avrage , this is just like the most blur program that i have seen in the net.
i need to run an initial shader that will get the bright areas and make the rest black, make that into a texture to send to my post process shader. How do i do that?
i have done it but with CG for OpenGl but the idea is the same for Dx , the simple way to make the bright areas look like more brighter without effect the darker areas is that
mutiply each pixel with it self then add the reslut to the a blur effect of the pixel , that is all.

here is my CG program so you easlly could convert it to HLSL

Code: Select all

TCGShader* cgProg = new TCGShader;

    cgProg->AddToVertexProgram("void main( float4 position          : POSITION,             ");
    cgProg->AddToVertexProgram("           float4 color             : COLOR,                ");
    cgProg->AddToVertexProgram("           float2 texCoord          : TEXCOORD,             ");
    cgProg->AddToVertexProgram("           out float4 oPosition     : POSITION,             ");
    cgProg->AddToVertexProgram("           out float4 oColor        : COLOR,                ");
    cgProg->AddToVertexProgram("           out float2 oTexCoord0    : TEXCOORD0,            ");
    cgProg->AddToVertexProgram("           out float2 oTexCoord1    : TEXCOORD1,            ");
    cgProg->AddToVertexProgram("           out float2 oTexCoord2    : TEXCOORD2,            ");
    cgProg->AddToVertexProgram("           out float2 oTexCoord3    : TEXCOORD3,            ");
    cgProg->AddToVertexProgram("           out float2 oTexCoord4    : TEXCOORD4,            ");
    cgProg->AddToVertexProgram("           uniform float XOffset,                           ");
    cgProg->AddToVertexProgram("           uniform float YOffset,                           ");
    cgProg->AddToVertexProgram("           uniform float4x4 ModelViewProj)                  ");
    cgProg->AddToVertexProgram("{                                                           ");
    cgProg->AddToVertexProgram("       oPosition = mul(ModelViewProj,position);             ");
    cgProg->AddToVertexProgram("       oColor    = color;                                   ");
    cgProg->AddToVertexProgram("       oTexCoord0 = texCoord + float2(XOffset,YOffset);     ");
    cgProg->AddToVertexProgram("       oTexCoord1 = texCoord + float2(XOffset*2,YOffset*2); ");
    cgProg->AddToVertexProgram("       oTexCoord2 = texCoord - float2(XOffset,YOffset);     ");
    cgProg->AddToVertexProgram("       oTexCoord3 = texCoord - float2(XOffset*2,YOffset*2); ");
    cgProg->AddToVertexProgram("       oTexCoord4 = texCoord;                               ");
    cgProg->AddToVertexProgram("}                                                           ");

    cgProg->setVertexProfile(CG_PROFILE_ARBVP1);
    cgProg->CompileVertexProgram("main");
    printf("%s \n", cgProg->GetCompiledVertexProgram());

    cgProg->AddToPixelProgram("void main(  float2 TexCoord0  : TEXCOORD0,            ");
    cgProg->AddToPixelProgram("            float2 TexCoord1  : TEXCOORD1,            ");
    cgProg->AddToPixelProgram("            float2 TexCoord2  : TEXCOORD2,            ");
    cgProg->AddToPixelProgram("            float2 TexCoord3  : TEXCOORD3,            ");
    cgProg->AddToPixelProgram("            float2 TexCoord4  : TEXCOORD4,            ");
    cgProg->AddToPixelProgram("            out float4 color     : COLOR,             ");
    cgProg->AddToPixelProgram("            uniform sampler2D txtr0 : texunit0,       ");
    cgProg->AddToPixelProgram("            uniform sampler2D txtr1 : texunit1)       ");
    cgProg->AddToPixelProgram("{                                                     ");
    cgProg->AddToPixelProgram("       float4 col1 = tex2D(txtr0, TexCoord0) / 2.0f;  ");
    cgProg->AddToPixelProgram("       float4 col2 = tex2D(txtr0, TexCoord1) / 2.0f;  ");
    cgProg->AddToPixelProgram("       float4 col3 = tex2D(txtr0, TexCoord2) / 2.0f;  ");
    cgProg->AddToPixelProgram("       float4 col4 = tex2D(txtr0, TexCoord3) / 2.0f;  ");
    cgProg->AddToPixelProgram("       float4 avg1 = (col1 + col2) / 2.0f;            ");
    cgProg->AddToPixelProgram("       float4 avg2 = (col3 + col4) / 2.0f;            ");
    cgProg->AddToPixelProgram("       float4 blur = avg1 + avg2;                     ");
    cgProg->AddToPixelProgram("       float4 newCol  = tex2D(txtr0, TexCoord4);      ");
    cgProg->AddToPixelProgram("       float4 dark    = newCol * newCol ;             ");
    cgProg->AddToPixelProgram("       color  = dark+blur;                            ");
    cgProg->AddToPixelProgram("}                                                     ");

    cgProg->setPixelProfile(CG_PROFILE_ARBFP1);
    cgProg->CompilePixelProgram("main");
    printf("%s \n", cgProg->GetCompiledPixelProgram());
BTW this effect called GLOW effect
esaptonor
Posts: 145
Joined: Sat May 06, 2006 11:59 pm

Post by esaptonor »

could you explain how it works?
why does multiplying the thing by iteself then adding it to the blur make the dark areas stay dark and the bright areas get more bright?
And does this take into account that only the bright pixels are supposed to be blured?
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

ok i will explain a bit more.

first i want you to know that in shader language you are working with float values ,ie when you get a pixel by useing tex2D you had 4 floating values that represent the red green blue and alpha components of color.

Code: Select all

for each component 
  0.0 means black
  1.0 means white 
  0.5 means gray
so when you mulitplay a floating value that less than 1.0 by itself the result will be more less than the orignal one.

Code: Select all

for Example

    0.01 * 0.01 = 0.0001  --> 0.0001 less than 0.01 

    0.5  * 0.5  = 0.25
that means your pixel will be more darker than the orignal when multiplay by itself.

forget about blur for a moment, what happend if you add 0.25 value to 0.5 value ?
the result will be 0.75 that bigger than orignal 0.5 value.

so when you matiplay values by itself then add it to orignal one the the bright areas look like more brighter without effect the darker areas.

let us take our first example

Code: Select all

0.01 * 0.01 + 0.01 = 0.0001 + 0.01 = 0.0101 that is not big deffer from 0.01 so the adding is not effective

    0.5  * 0.5  + 0.5  = 0.25   + 0.5  = 0.75   that is a big deffer from 0.5  so the adding is so effective
0.01 represents darker areas and 0.5 represents brighter areas.

now exchange the adding with orignal by adding with a blur , that give our brighter areas
more realistic look.

hope you got it now , and good luch.
esaptonor
Posts: 145
Joined: Sat May 06, 2006 11:59 pm

Post by esaptonor »

ok that explains that well, thanks a lot, and it certainly does the job of making the bright things brighter, but adding it to the blur is not the way to do it, as it will still make everything blured, - i dont want everything blured, just the bright areas.
For that i am sure i need to somehow run two different shaders. The first one makes a bright texture where all the other pixels that are not bright enough are made black. Then this new texture is used for my blur effect (and the brightening) and it gets added to my scene.

I still need to know how i am supposed to link my bright-texture generating shader and the blur shader together? It needs to take the scene as a texture (like my post process blur shader does) and turn that into a new texture for the post process one to use.

thanks for helping,
esaptonor
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

No, to make certain areas only brighter, you need a "glow mask" which is very similar to the concept of an alpha mask for texture splatting. The glow mask simply tells you where to apply the blur.
Image
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

i have an idea but needs some optimization , it take more calculation in GPU.

1-first get the 4 col that make the blur as you usually do.
2- for each one multiply by itselfe.
3- get the avrage;
4- adding with orignal color

here is the code

Code: Select all

 float4 ocol = tex2D(txtr0, TexCoord0); 
          float4 col1 = tex2D(txtr0, TexCoord0 + x_displacement); 
          float4 col2 = tex2D(txtr0, TexCoord1 - x_displacement); 
          float4 col3 = tex2D(txtr0, TexCoord2 + y_displacement); 
          float4 col4 = tex2D(txtr0, TexCoord3 - y_displacement);
          float4 drkCol1 = col1 * col1;
          float4 drkCol2 = col2 * col2;
          float4 drkCol3 = col3 * col3;
          float4 drkCol4 = col4 * col4;
          float4 avrCol = (drkCol1 +drkCol2 +  drkCol3 +drkCol4) / 4;
          finalcolor = Ocol + avrCol;
 
i did not test it yet , but may be help you.
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

Can i store a new texture with irrlicht and then send this new texture to the post process shader?
Render to texture, for example code look for IRRcinema in the proj annocuments forums.

@Emil

Are you trying to create a high contrast shader to avoid a luminsoity pass?
Sound like a good idea to avoid the exta render target(brightness pass) if contrast is used, this would work nice if whole screen tone mapping is needed.[/quote]
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

yes , my goal is to avoid rendring to Texture ,it takes many FPS
so i thought in making the darking effect in each pixel that feed blur effect.
esaptonor
Posts: 145
Joined: Sat May 06, 2006 11:59 pm

Post by esaptonor »

Is it not possible to make something render twice?

just experimenting again before i look at the irrcinema, i tried doing it myself, but it didn't work.

I had my post process node.
I rendered the scene to its texture, with my blur shader.
I rendered its texture to another texture, with the same shader so that it just blured more.
then i tried to render it to the screen and the screen stayed black. Why is this?

i read about a patch in the irrcinema thread, did it fix this kind of problem?
esaptonor
Posts: 145
Joined: Sat May 06, 2006 11:59 pm

Post by esaptonor »

well i have managed to make an average hdr effect another way.

I have forgotten who i initially downloaded it from, it didn't have any notes on who it came from, but it was called post process filters, it came with normal, black and white, and blur. Well i never got that blur to work which is why i had to write my own, but anyway, i have been using that as my post process node.

I couldn't get anything to work when i tried to copy the irrcinema thing, so instead i just created 4 of the post process filters. The first one did the bright pass second did a blur third did a blur and 4th was the original, and they each rendered to their own texture and the next one took the texture. Similar to your way, but i just couldn't get your way to work :oops:

so now here is what i have done with my super basic knowledge...
the blur doesn't blur much yet, and the overall effect isn't that great. It just makes every pixel brighter than 0.5 more brighter using Emil's method, then blurs only the bright parts.

Image

Image

is that good enough to use?
Ico
Posts: 289
Joined: Tue Aug 22, 2006 11:35 pm

Post by Ico »

Are you talking about this one?
http://irrlicht.sourceforge.net/phpBB2/ ... t=myfilter

I'm using it too at the moment and I found a small memory leak.
It can be fixed by adding a destructor to CBaseFilter:

Code: Select all

   ~CBaseFilter()
   {
	 rt0->drop();
   }
Post Reply