https://github.com/mozilla/gecko-dev
Raw File
Tip revision: 4de65ed647cfede012c65e5b42268b52a3c32ff3 authored by seabld on 31 January 2013, 03:42:17 UTC
Added tag SEAMONKEY_2_16b3_RELEASE for changeset FIREFOX_19_0b4_BUILD1. CLOSED TREE a=release
Tip revision: 4de65ed
ShadersD2D.fx
// We store vertex coordinates and the quad shape in a constant buffer, this is
// easy to update and allows us to use a single call to set the x, y, w, h of
// the quad.
// The QuadDesc and TexCoords both work as follows:
// The x component is the quad left point, the y component is the top point
// the z component is the width, and the w component is the height. The quad
// are specified in viewport coordinates, i.e. { -1.0f, 1.0f, 2.0f, -2.0f }
// would cover the entire viewport (which runs from <-1.0f, 1.0f> left to right
// and <-1.0f, 1.0f> -bottom- to top. The TexCoords desc is specified in texture
// space <0, 1.0f> left to right and top to bottom. The input vertices of the
// shader stage always form a rectangle from {0, 0} - {1, 1}
cbuffer cb0
{
    float4 QuadDesc;
    float4 TexCoords;
    float4 MaskTexCoords;
    float4 TextColor;
}

cbuffer cb1
{
    float4 BlurOffsetsH[3];
    float4 BlurOffsetsV[3];
    float4 BlurWeights[3];
    float4 ShadowColor;
}

cbuffer cb2
{
    float3x3 DeviceSpaceToUserSpace;
    float2 dimensions;
    // Precalculate as much as we can!
    float3 diff;
    float2 center1;
    float A;
    float radius1;
    float sq_radius1;
}

struct VS_OUTPUT
{
    float4 Position : SV_Position;
    float2 TexCoord : TEXCOORD0;
    float2 MaskTexCoord : TEXCOORD1;
};

struct VS_RADIAL_OUTPUT
{
    float4 Position : SV_Position;
    float2 MaskTexCoord : TEXCOORD0;
    float2 PixelCoord : TEXCOORD1;
};

struct PS_TEXT_OUTPUT
{
    float4 color;
    float4 alpha;
};

Texture2D tex;
Texture2D mask;

sampler sSampler = sampler_state {
    Filter = MIN_MAG_MIP_LINEAR;
    Texture = tex;
    AddressU = Clamp;
    AddressV = Clamp;
};

sampler sWrapSampler = sampler_state {
    Filter = MIN_MAG_MIP_LINEAR;
    Texture = tex;
    AddressU = Wrap;
    AddressV = Wrap;
};

sampler sMirrorSampler = sampler_state {
    Filter = MIN_MAG_MIP_LINEAR;
    Texture = tex;
    AddressU = Mirror;
    AddressV = Mirror;
};

sampler sMaskSampler = sampler_state {
    Filter = MIN_MAG_MIP_LINEAR;
    Texture = mask;
    AddressU = Clamp;
    AddressV = Clamp;
};

sampler sShadowSampler = sampler_state {
    Filter = MIN_MAG_MIP_LINEAR;
    Texture = tex;
    AddressU = Border;
    AddressV = Border;
    BorderColor = float4(0, 0, 0, 0);
};

RasterizerState TextureRast
{
  ScissorEnable = True;
  CullMode = None;
};

BlendState ShadowBlendH
{
  BlendEnable[0] = False;
  RenderTargetWriteMask[0] = 0xF;
};

BlendState ShadowBlendV
{
  BlendEnable[0] = True;
  SrcBlend = One;
  DestBlend = Inv_Src_Alpha;
  BlendOp = Add;
  SrcBlendAlpha = One;
  DestBlendAlpha = Inv_Src_Alpha;
  BlendOpAlpha = Add;
  RenderTargetWriteMask[0] = 0xF;
};

BlendState bTextBlend
{
  AlphaToCoverageEnable = FALSE;
  BlendEnable[0] = TRUE;
  SrcBlend = Src1_Color;
  DestBlend = Inv_Src1_Color;
  BlendOp = Add;
  SrcBlendAlpha = Src1_Alpha;
  DestBlendAlpha = Inv_Src1_Alpha;
  BlendOpAlpha = Add;
  RenderTargetWriteMask[0] = 0x0F; // All
};

VS_OUTPUT SampleTextureVS(float3 pos : POSITION)
{
    VS_OUTPUT Output;
    Output.Position.w = 1.0f;
    Output.Position.x = pos.x * QuadDesc.z + QuadDesc.x;
    Output.Position.y = pos.y * QuadDesc.w + QuadDesc.y;
    Output.Position.z = 0;
    Output.TexCoord.x = pos.x * TexCoords.z + TexCoords.x;
    Output.TexCoord.y = pos.y * TexCoords.w + TexCoords.y;
    Output.MaskTexCoord.x = pos.x * MaskTexCoords.z + MaskTexCoords.x;
    Output.MaskTexCoord.y = pos.y * MaskTexCoords.w + MaskTexCoords.y;
    return Output;
}

VS_RADIAL_OUTPUT SampleRadialVS(float3 pos : POSITION)
{
    VS_RADIAL_OUTPUT Output;
    Output.Position.w = 1.0f;
    Output.Position.x = pos.x * QuadDesc.z + QuadDesc.x;
    Output.Position.y = pos.y * QuadDesc.w + QuadDesc.y;
    Output.Position.z = 0;
    Output.MaskTexCoord.x = pos.x * MaskTexCoords.z + MaskTexCoords.x;
    Output.MaskTexCoord.y = pos.y * MaskTexCoords.w + MaskTexCoords.y;

    // For the radial gradient pixel shader we need to pass in the pixel's
    // coordinates in user space for the color to be correctly determined.

    Output.PixelCoord.x = ((Output.Position.x + 1.0f) / 2.0f) * dimensions.x;
    Output.PixelCoord.y = ((1.0f - Output.Position.y) / 2.0f) * dimensions.y;
    Output.PixelCoord.xy = mul(float3(Output.PixelCoord.x, Output.PixelCoord.y, 1.0f), DeviceSpaceToUserSpace).xy;
    return Output;
}

float4 SampleTexturePS( VS_OUTPUT In) : SV_Target
{
    return tex.Sample(sSampler, In.TexCoord);
};

float4 SampleMaskTexturePS( VS_OUTPUT In) : SV_Target
{
    return tex.Sample(sSampler, In.TexCoord) * mask.Sample(sMaskSampler, In.MaskTexCoord).a;
};

float4 SampleRadialGradientPS(VS_RADIAL_OUTPUT In, uniform sampler aSampler) : SV_Target
{
    // Radial gradient painting is defined as the set of circles whose centers
    // are described by C(t) = (C2 - C1) * t + C1; with radii
    // R(t) = (R2 - R1) * t + R1; for R(t) > 0. This shader solves the
    // quadratic equation that arises when calculating t for pixel (x, y).
    //
    // A more extensive derrivation can be found in the pixman radial gradient
    // code.
 
    float2 p = In.PixelCoord;
    float3 dp = float3(p - center1, radius1);

    // dpx * dcx + dpy * dcy + r * dr
    float B = dot(dp, diff);

    float C = pow(dp.x, 2) + pow(dp.y, 2) - sq_radius1;

    float det = pow(B, 2) - A * C;

    if (det < 0) {
      return float4(0, 0, 0, 0);
    }

    float sqrt_det = sqrt(abs(det));

    float2 t = (B + float2(sqrt_det, -sqrt_det)) / A;

    float2 isValid = step(float2(-radius1, -radius1), t * diff.z);

    if (max(isValid.x, isValid.y) <= 0) {
      return float4(0, 0, 0, 0);
    }

    float upper_t = lerp(t.y, t.x, isValid.x);

    float4 output = tex.Sample(aSampler, float2(upper_t, 0.5));
    // Premultiply
    output.rgb *= output.a;
    // Multiply the output color by the input mask for the operation.
    output *= mask.Sample(sMaskSampler, In.MaskTexCoord).a;
    return output;
};

float4 SampleRadialGradientA0PS( VS_RADIAL_OUTPUT In, uniform sampler aSampler ) : SV_Target
{
    // This simpler shader is used for the degenerate case where A is 0,
    // i.e. we're actually solving a linear equation.

    float2 p = In.PixelCoord;
    float3 dp = float3(p - center1, radius1);

    // dpx * dcx + dpy * dcy + r * dr
    float B = dot(dp, diff);

    float C = pow(dp.x, 2) + pow(dp.y, 2) - pow(radius1, 2);

    float t = 0.5 * C / B;

    if (-radius1 >= t * diff.z) {
      return float4(0, 0, 0, 0);
    }

    float4 output = tex.Sample(aSampler, float2(t, 0.5));
    // Premultiply
    output.rgb *= output.a;
    // Multiply the output color by the input mask for the operation.
    output *= mask.Sample(sMaskSampler, In.MaskTexCoord).a;
    return output;
};

float4 SampleShadowHPS( VS_OUTPUT In) : SV_Target
{
    float outputStrength = 0;

    outputStrength += BlurWeights[0].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[0].x, In.TexCoord.y)).a;
    outputStrength += BlurWeights[0].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[0].y, In.TexCoord.y)).a;
    outputStrength += BlurWeights[0].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[0].z, In.TexCoord.y)).a;
    outputStrength += BlurWeights[0].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[0].w, In.TexCoord.y)).a;
    outputStrength += BlurWeights[1].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[1].x, In.TexCoord.y)).a;
    outputStrength += BlurWeights[1].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[1].y, In.TexCoord.y)).a;
    outputStrength += BlurWeights[1].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[1].z, In.TexCoord.y)).a;
    outputStrength += BlurWeights[1].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[1].w, In.TexCoord.y)).a;
    outputStrength += BlurWeights[2].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x + BlurOffsetsH[2].x, In.TexCoord.y)).a;

    return ShadowColor * outputStrength;
};

float4 SampleShadowVPS( VS_OUTPUT In) : SV_Target
{
    float4 outputColor = float4(0, 0, 0, 0);

    outputColor += BlurWeights[0].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].x));
    outputColor += BlurWeights[0].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].y));
    outputColor += BlurWeights[0].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].z));
    outputColor += BlurWeights[0].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].w));
    outputColor += BlurWeights[1].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].x));
    outputColor += BlurWeights[1].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].y));
    outputColor += BlurWeights[1].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].z));
    outputColor += BlurWeights[1].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].w));
    outputColor += BlurWeights[2].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[2].x));

    return outputColor;
};

float4 SampleMaskShadowVPS( VS_OUTPUT In) : SV_Target
{
    float4 outputColor = float4(0, 0, 0, 0);

    outputColor += BlurWeights[0].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].x));
    outputColor += BlurWeights[0].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].y));
    outputColor += BlurWeights[0].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].z));
    outputColor += BlurWeights[0].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[0].w));
    outputColor += BlurWeights[1].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].x));
    outputColor += BlurWeights[1].y * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].y));
    outputColor += BlurWeights[1].z * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].z));
    outputColor += BlurWeights[1].w * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[1].w));
    outputColor += BlurWeights[2].x * tex.Sample(sShadowSampler, float2(In.TexCoord.x, In.TexCoord.y + BlurOffsetsV[2].x));

    return outputColor * mask.Sample(sMaskSampler, In.MaskTexCoord).a;
};

PS_TEXT_OUTPUT SampleTextTexturePS( VS_OUTPUT In) : SV_Target
{
    PS_TEXT_OUTPUT output;
    output.color = float4(TextColor.r, TextColor.g, TextColor.b, 1.0);
    output.alpha.rgba = tex.Sample(sSampler, In.TexCoord).bgrg * TextColor.a;
    return output;
};

PS_TEXT_OUTPUT SampleTextTexturePSMasked( VS_OUTPUT In) : SV_Target
{
    PS_TEXT_OUTPUT output;
    
    float maskValue = mask.Sample(sMaskSampler, In.MaskTexCoord).a;

    output.color = float4(TextColor.r, TextColor.g, TextColor.b, 1.0);
    output.alpha.rgba = tex.Sample(sSampler, In.TexCoord).bgrg * TextColor.a * maskValue;
    
    return output;
};

technique10 SampleTexture
{
    pass P0
    {
        SetRasterizerState(TextureRast);
        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleTexturePS()));
    }
}

technique10 SampleRadialGradient
{
    pass APos
    {
        SetRasterizerState(TextureRast);
        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientPS( sSampler )));
    }
    pass A0
    {
        SetRasterizerState(TextureRast);
        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientA0PS( sSampler )));
    }
    pass APosWrap
    {
        SetRasterizerState(TextureRast);
        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientPS( sWrapSampler )));
    }
    pass A0Wrap
    {
        SetRasterizerState(TextureRast);
        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientA0PS( sWrapSampler )));
    }
    pass APosMirror
    {
        SetRasterizerState(TextureRast);
        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientPS( sMirrorSampler )));
    }
    pass A0Mirror
    {
        SetRasterizerState(TextureRast);
        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleRadialVS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleRadialGradientA0PS( sMirrorSampler )));
    }
}

technique10 SampleMaskedTexture
{
    pass P0
    {
        SetRasterizerState(TextureRast);
        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleMaskTexturePS()));
    }
}

technique10 SampleTextureWithShadow
{
    // Horizontal pass
    pass P0
    {
        SetRasterizerState(TextureRast);
        SetBlendState(ShadowBlendH, float4(1.0f, 1.0f, 1.0f, 1.0f), 0xffffffff);
        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleShadowHPS()));
    }
    // Vertical pass
    pass P1
    {
        SetRasterizerState(TextureRast);
        SetBlendState(ShadowBlendV, float4(1.0f, 1.0f, 1.0f, 1.0f), 0xffffffff);
        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleShadowVPS()));
    }
    // Vertical pass - used when using a mask
    pass P2
    {
        SetRasterizerState(TextureRast);
        SetBlendState(ShadowBlendV, float4(1.0f, 1.0f, 1.0f, 1.0f), 0xffffffff);
        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleMaskShadowVPS()));
    }
}

technique10 SampleTextTexture
{
    pass Unmasked
    {
        SetRasterizerState(TextureRast);
        SetBlendState(bTextBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleTextTexturePS()));
    }
    pass Masked
    {
        SetRasterizerState(TextureRast);
        SetBlendState(bTextBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
        SetGeometryShader(NULL);
        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleTextTexturePSMasked()));
    }
}

back to top