locked
Could someone explain this PixelShader to me?

    Question

  • Hey,

    I have picked up an extra project at school, and I am going to try to convert an app from iOS to windows phone 8. The app uses GLSL and the GPU, and so I have been reading up, frantically trying to figure out this HLSL thing. 

    I am starting to understand it - but this example I have been looking at is a little confusing.

    First I should say that I am using the SharpDX libraries - so I can write in C#. This example code is from one of their samples (SharpDX/Samples/Win8/D2DCustomPixelShaderEffect).

    Here is the shader part:

    Texture2D InputTexture : register(t0);
    
    SamplerState InputSampler : register(s0);
    
    cbuffer constants : register(b0)
    {
        float frequency : packoffset(c0.x);
        float phase     : packoffset(c0.y);
        float amplitude : packoffset(c0.z);
        float spread    : packoffset(c0.w);
        float2 center   : packoffset(c1);
    };
    
    float4 main(
        float4 pos      : SV_POSITION,
        float4 posScene : SCENE_POSITION,
        float4 uv0      : TEXCOORD0
        ) : SV_Target
    {
        float2 wave;
    
        float2 toPixel = posScene.xy - center; 
    
        float distance = length(toPixel) * uv0.z;
        float2 direction = normalize(toPixel);
    
        sincos(frequency * distance + phase, wave.x, wave.y);
    
        // Clamps the distance between 0 and 1 and squares the value.
        float falloff = saturate(1 - distance);
        falloff = pow(falloff, 1.0f / spread);
    
        // Calculates new mapping coordinates based on the frequency, center, and amplitude.
        float2 uv2 = uv0.xy + (wave.x * falloff * amplitude) * direction * uv0.zw;
    
        float lighting = lerp(1.0f, 1.0f + wave.x * falloff * 0.2f, saturate(amplitude / 20.0f));
                
        // Resamples the image based on the new coordinates.
        float4 color = InputTexture.Sample(InputSampler, uv2);
        color.rgb *= lighting;
        
        return color;
    }

    I understand the math, as it is basically just c++. The thing that is really throwing me for a loop in this example is the register stuff.

    At the top, they have:

    cbuffer constants : register(b0)
    {
        float frequency : packoffset(c0.x);
        float phase     : packoffset(c0.y);
        float amplitude : packoffset(c0.z);
        float spread    : packoffset(c0.w);
        float2 center   : packoffset(c1);
    };

    So does this mean you want to store that "struct" (cbuffer) in register 0 (like actual register 0 of the computer)? If so, would the registers look like this:

    register 0: | frequency | phase | amplitude | spread |
    register 1: |          center           |--------empty---------|

    Do we need to specify the pack offset? or could we just leave that part off, and it would figure out for itself where the fields should go?

    Can anyone explain this buffer thing to me? Thanks! :)
    Paul

    (Oh, and if you have any hlsl tutorials/simple examples/articles you think are really good, I would not object if you throw them my way! I still don't understand the whole semantics thing completely...)


    pdem


    • Edited by Toadums Friday, October 19, 2012 5:07 PM typo
    Friday, October 19, 2012 5:06 PM

Answers

  • This sample was ported from the original samples included in Windows 8 SDK samples. It is not mandatory to use explicit packing rules for variables inside a constant buffer, unless you need some explicit memory layout. In the previous cases, I don't think that removing them would lead to a different memory layout, as It is basically how things would be packed implicitly.

    For more information, you can have a look at "Packing Rules for Constant Variables" .


    Alexandre Mutel - SharpDX - NShader - Code4k

    Saturday, October 20, 2012 10:03 AM
  • Hi Todums.

    HLSL automatically do addressing for your constant buffers and other variables. there is no need to use register(b0).

    Best Regards.

    Pooya Eimandar


    Best Regards. Pooya Eimandar.

    Sunday, October 21, 2012 9:53 AM

All replies

  • This sample was ported from the original samples included in Windows 8 SDK samples. It is not mandatory to use explicit packing rules for variables inside a constant buffer, unless you need some explicit memory layout. In the previous cases, I don't think that removing them would lead to a different memory layout, as It is basically how things would be packed implicitly.

    For more information, you can have a look at "Packing Rules for Constant Variables" .


    Alexandre Mutel - SharpDX - NShader - Code4k

    Saturday, October 20, 2012 10:03 AM
  • Oh ok, well I'm glad I don't "have" to worry about it. But do I need to specify register(b0)? or does that automatically happen as well?

    pdem

    Saturday, October 20, 2012 4:59 PM
  • Hi Todums.

    HLSL automatically do addressing for your constant buffers and other variables. there is no need to use register(b0).

    Best Regards.

    Pooya Eimandar


    Best Regards. Pooya Eimandar.

    Sunday, October 21, 2012 9:53 AM
  • Awesome, thanks guys! That is one less thing I have to worry about :)

    pdem

    Sunday, October 21, 2012 5:03 PM