Sign in to follow this  
prux

stupid pixel shader

Recommended Posts

hey! Im (would) use DX 8.1 and vertex shader... heres the example:
sampler2D g_samSrcColor;

float4 main( float2 Tex : TEXCOORD0 ) : COLOR0
{
    float4 Color;
    
    Color = tex2D( g_samSrcColor, Tex.xy)*4;
    return Color;
}

technique PostProcess
{
    pass p1
    {
        VertexShader = null;
        PixelShader = compile ps_1_4 main();
    }

}
the samples is "converted" to assembly, because 8.1 doesnt know HLSL language: fxc.exe /nologo /Tps_1_2 /Emain shader.ps > shader.asm
//
// Generated by Microsoft (R) D3DX9 Shader Compiler 9.08.299.0000
//
//   fxc /nologo /Tps_1_2 /Emain shader.ps
//
//
// Parameters:
//
//   sampler2D g_samSrcColor;
//
//
// Registers:
//
//   Name          Reg   Size
//   ------------- ----- ----
//   g_samSrcColor s0       1
//

    ps.1.2
    def c0, 4, 4, 4, 4
    tex t0
    mul r0, t0, c0

// approximately 2 instruction slots used (1 texture, 1 arithmetic)

this currently does nothing... although theres another example: ps.1.0 def c0, 1.0f, 1.0f,1.0f, 1.0f tex t0 sub r0,c0,t0 this works (at least has got effect). Only this example works, this wastebasket doesnt want to work for me!! Any idea why?

Share this post


Link to post
Share on other sites
This may happend due to many reasons, most probably your card is an ATI card and you are trying to run a PS1.2.

Due to lack of standarization on the first PS cards, nVidia video cards are able to handle PS 1.1, 1.2, 1.3 and 2.0 or higher. ATI video cards are able to handle PS 1.4 and 2.0 or higher. So if you try to run a 1.2 shader in an ATI card it may fail

In the other hand, there is no support for PS1.0 in any card. 1.0 was something like the first PS concept by nVidia and was never released in any video card so trying to make a 1.0 shader will probably fail.

That said, I agree with EmptyVoid (a really empty name I must say) and suggest you to move to PS2.0 or higher unless you have a really compelling reason to stay with 1.x shaders.

Luck!
Guimo

Share this post


Link to post
Share on other sites
luckily I found some correction, I can still use it but there are more questions tough.

So, heres an example:

sampler2D g_samSrcColor;
float4 main( float2 Tex : TEXCOORD0 ) : COLOR0
{
float4 Color;

Tex.x = Tex.x * 0.5;
Color = tex2D( g_samSrcColor, Tex.xy);
return Color;
}

technique PostProcess
{
pass p1
{
VertexShader = null;
PixelShader = compile ps_1_4 main();
}
}

it works. Theres a color sample:

Quote:
Color = tex2D( input , Tex.xy)*3;


this also works,

Quote:
Color.r = Color.r / 2;


this too, but WHEN I want to

Quote:
Color.r = Color.r * 2;


the FXC says:

Quote:
shader.ps(18): warning X4704: literal values outside range -1 to 1 are clamped on all ps_1_x shading models


and it dont work :S

Thx the replies! I think I tried to "hard" examples first.

Share this post


Link to post
Share on other sites
Mint látod, a szineket -1 és 1 közé "szorítja", mivel osztásnál egyre inkább a 0 felé halad az érték, ellenben szorzásnál könnyen áteshet ezeken.

Szineket többnyire 0..1 tartományban határozunk meg.

So, understand? :)

Share this post


Link to post
Share on other sites
Minden grafikus API (OpenGL, DX) a szineket float-ként tárolja, 0..1 tartományban, a nagyobb precizitás miatt. Persze te megadhatod 0..255 között (opengl-ben pl. glColor3ub, DX-ben nem tudom), de "belül" úgy is float-ban tárolódik, és ebben a formában is dolgozik vele.

Lehet, nem örülnek itt, hogy magyarul irunk. :D

Share this post


Link to post
Share on other sites
its clear now, but I dont know then how to avoid this... when I mul the whole color (Color = tex2D( input , Tex.xy)*3;) it works, and when just a part of it (Color = tex2D( input , Tex.xy).R*3;) it doesnt?

Share this post


Link to post
Share on other sites
Quote:
Original post by Guimo
Due to lack of standarization on the first PS cards, nVidia video cards are able to handle PS 1.1, 1.2, 1.3 and 2.0 or higher. ATI video cards are able to handle PS 1.4 and 2.0 or higher. So if you try to run a 1.2 shader in an ATI card it may fail


all ATi cards since 8500 were able to run any ps_1_x. The main difference between pre-2_0 generation of ATi (8500, 9000-9200) and nVidia (gf3-4) cards was ps_1_4 profile.

SHKiN

Share this post


Link to post
Share on other sites
Hi

I suggest you either to move to ps_2_0 or throw HLSL away and write ps_1_x in asm, because from my own experience, HLSL compiler often fails to push code into 8/16 asm instructions. It also doesn't use instructions modifiers, such as _x2, _x4, _bx2, _d2, _d4, _sat.

In ps_1_1, ps_1_2, ps_1_3 profiles you can't use values outside of -1..1 range, so you should use modifiers.

Your original code can be rewritten like this:


ps.1.2
tex t0
mov_x4 r0, t0 //result = t0*4


OR you can use ps_1_4 profile, that has -8..8 range.

SHKiN

Share this post


Link to post
Share on other sites
Okay then I see now. So there are two ways:

- DX9 + ps2.0 + HLSL will be easier
- DX8 + ps1.4 + dont trust in HLSL -> ASM compiler, I must write everything on my own

I will use the first way, and when I finished HLSL language, then I switch to assembly :)

Share this post


Link to post
Share on other sites
Hi prux,
ps1.x specification clamps the pixel color values to the -1/1 range only. In fact the color values should be clamped to the 0/1 range only. That is more than enough because it doesnt matter how many strange computations you are doing in the PS, the output is jut a RGBA color, that is, 4 floats in the 0/1 range. This RGBA color will be applied to a single pixel, the pixel which is processed by the shader in that moment.

Also remember that PS1.x is instruction limited so you may quickly hit the PS limits.

In ps2.0 and higher you can get higher values than 1 but unless you are using a floating point color buffer or High Color Range buffer (I guess they are available since p.s.3 only) they will just get lost and clamped to 1 anyway. You will only want to exceed the 0/1 range in other applications like computing vectors.

May I ask what exactly are you trying to do? Maybe a book like ShaderX or ShaderX2 may help to clear this subject. I think its free to download now. Anyway I would suggest you to use PS2 and DX9. PS2 video cards have been around for more than 4 years now so its simple to assume that you will get a nice base to run your game.

Luck!
Guimo

Share this post


Link to post
Share on other sites
Yes you may, I'll tell what's my goal although it might be an other topic:

here are HLSL examples: facewound

the only thing I would change is not using the whole texture but just a rectangle of that. I know I will need to have 2 quads (background ant target) but dont know how to persuade the 2nd rectangle to "read" from an X,Y position... and I dont think this would need a DX9, DX8.1 would be enough

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this