Talk:Lesson 2 - disable effect

From Bo3b's School for Shaderhackers
Jump to: navigation, search

To discuss Lesson 2 - disable effect, please use Add topic in the upper right.

Optimal way to disable an effect

When making a real fix, it might be valuable to consider other factors beyond just the easist way to do it, particularly because in general we'll just copy/paste the code. Let's copy/paste code that works better in all cases.

It's also worth noting that sometimes we need to set the output to all 1 instead, if a PS is used as part of a masking operation. It's rare, but happens.


When we disable an effect using the simplest case, the original shader is still fully executed, but the results thrown away by our last instruction where we assign zero to the output. There's not point in wasting the GPU cycles on stuff that is unused, so we can make it slightly better by making it so that original code is not executed.

Secondly, maybe you or others want to play the game in 2D. The effect is still disabled in 2D, even though it doesn't cause problems there. We can make it so that the disable operation only happens in 3D.


...
//   Texture2D_0              s0       1

    ps_3_0
    def c1, 0, 2, -0.333299994, 9.99999997e-007
...
    dcl_texcoord2_pp v0.xyz
...
    dcl_2d s0
...
    texld r0, v4, s0
    add r1, r0.w, c1.z
...

Would become:

...
//   Texture2D_0              s0       1

    ps_3_0
    def c1, 0, 2, -0.333299994, 9.99999997e-007
def c200, 0, 0, 0.0625, 0
...
    dcl_texcoord2_pp v0.xyz
...
    dcl_2d s0
...
// Check if we are in 3D, and only disable effect if separation==0
texldl r30, c200.z, s0
if_ne  r30.x, c200.x
  mov oC0.rgba, c200.wwww
  ret
endif

    texld r0, v4, s0
    add r1, r0.w, c1.z
...


notes: Not positive this is actually optimal just yet. Need to revisit.

We can switch to Shader Model 4.0, because DX10 video cards have been out for forever (starting with 8800 GTX), and we don't expect anyone to actually only be able to run SM3.0. Switching to SM4.0 allows us to use the discard instruction for simplicity. Consider switching to SM4, at the expense of not matching some other Helix info.



Similar variant for HLSL using 3Dmigoto:

...
void main(
float4 v0 : TEXCOORD0,
float4 v1 : TEXCOORD1,
out float4 o0 : SV_Target0)
{
...
  o0.xyz = HDR_EncodeScale.zzz * r0.xyz;
  o0.w = 1.000000000e+000;
  return;
}

Becomes:

...
void main(
float4 v0 : TEXCOORD0,
float4 v1 : TEXCOORD1,
out float4 o0 : SV_Target0)
{
...
  o0.xyz = HDR_EncodeScale.zzz * r0.xyz;
  o0.w = 1.000000000e+000;

// Disable the effect
o0 = 0;
  return;
}

Trying to understand the 'code'.

Hello!

Just got round to looking at the lesson. I love learning!

You tube: 18:46 to 19.28.

I think I get the second part of the move thing (c1.wwww) but not the first bit, oC0.xyzw. The register? Where did this come from? Have I even asked the question correctly?

The reason I am asking is can I just plonk that line in another game's shader etc?

Thanks!

AndysonofBob

Late answer here

The output register in ASM is the oC0 register, and it will always be oC0 for pixel shaders, as that is how it's defined for the hardware.

There can sometimes be more than one, but there will always be at oC0.

definition of oC0