0

ぼかし用にこの HLSL シェーダーがあります。

   struct VS_INPUT
   {
      float4 Position  : POSITION0;
      float2 TexCoord  : TEXCOORD0;
      float4 Color     : TEXCOORD1;
   };
   struct VS_OUTPUT
   {
      float4 Position  : POSITION0;
      float4 Color     : COLOR0;
      float2 TexCoord  : TEXCOORD0;
   };

   float4x4 al_projview_matrix;

   VS_OUTPUT vs_main(VS_INPUT Input)
   {
      VS_OUTPUT Output;
      Output.Position = mul(Input.Position, al_projview_matrix);
      Output.Color = Input.Color;
      Output.TexCoord = Input.TexCoord;
      return Output;
   }

フラグ

texture al_tex;
   sampler2D s = sampler_state {
      texture = <al_tex>;
   };

   int tWidth;
   int tHeight;
   float blurSize = 5.0;
   float4 ps_main(VS_OUTPUT Input) : COLOR0
   {
      float2 pxSz = float2(1.0 / tWidth,1.0 / tHeight);
      float4 outC = 0;
      float outA = 0;
      outA += Input.Color.a * tex2D(s, Input.TexCoord.xy + float2(0,-4.0 * pxSz.y * blurSize)).a * 0.05;
      outA += Input.Color.a * tex2D(s, Input.TexCoord.xy + float2(0,-3.0 * pxSz.y * blurSize)).a * 0.09;
      outA += Input.Color.a * tex2D(s, Input.TexCoord.xy + float2(0,-2.0 * pxSz.y * blurSize)).a * 0.12;
      outA += Input.Color.a * tex2D(s, Input.TexCoord.xy + float2(0,-pxSz.y * blurSize)).a * 0.15;
      outA += Input.Color.a * tex2D(s, Input.TexCoord.xy + float2(0,0)).a * 0.16;
      outA += Input.Color.a * tex2D(s, Input.TexCoord.xy + float2(0,pxSz.y * blurSize)).a * 0.15;
      outA += Input.Color.a * tex2D(s, Input.TexCoord.xy + float2(0,2.0 * pxSz.y * blurSize)).a * 0.12;
      outA += Input.Color.a * tex2D(s, Input.TexCoord.xy + float2(0,3.0 * pxSz.y * blurSize)).a * 0.09;
      outA += Input.Color.a * tex2D(s, Input.TexCoord.xy + float2(0,4.0 * pxSz.y * blurSize)).a * 0.05;

     outC.a = outA;
      return outC;
   }

水平用に同様のものがあります...

アイデアは、テクスチャの tWidth、tHeight と高さを提供し、それを使用して、UV 座標に対するピクセルの「サイズ」を取得することです。

次に、これを使用して、隣人の加重平均をとることで通常のぼかしを行います。

これをGLSLに移植しました:

attribute vec4 al_pos;
attribute vec4 al_color;
attribute vec2 al_texcoord;
uniform mat4 al_projview_matrix;
varying vec4 varying_color;
varying vec2 varying_texcoord;
void main()
{
   varying_color = al_color;
   varying_texcoord = al_texcoord;
   gl_Position = al_projview_matrix * al_pos;
}

フラグ

uniform sampler2D al_tex;
varying float blurSize;
varying float tWidth;
varying float tHeight;
varying vec2 varying_texcoord;
varying vec4 varying_color;
void main()
{
    vec4 sum = vec4(0.0);
    vec2 pxSz = vec2(1.0 / tWidth,1.0 / tHeight);
    // blur in x
    // take nine samples, with the distance blurSize between them
    sum += texture2D(al_tex, varying_texcoord.xy + vec2(0,-4.0 * pxSz.y * blurSize))* 0.05;
    sum += texture2D(al_tex, varying_texcoord.xy + vec2(0,-3.0 * pxSz.y * blurSize))* 0.09;
    sum += texture2D(al_tex, varying_texcoord.xy + vec2(0,-2.0 * pxSz.y * blurSize))* 0.12;
    sum += texture2D(al_tex, varying_texcoord.xy + vec2(0,-pxSz.y * blurSize))* 0.15;
    sum += texture2D(al_tex, varying_texcoord.xy + vec2(0,0))* 0.16;
    sum += texture2D(al_tex, varying_texcoord.xy + vec2(0,pxSz.y * blurSize))* 0.15;
    sum += texture2D(al_tex, varying_texcoord.xy + vec2(0,2.0 * pxSz.y * blurSize))* 0.12;
    sum += texture2D(al_tex, varying_texcoord.xy + vec2(0,3.0 * pxSz.y * blurSize))* 0.09;
    sum += texture2D(al_tex, varying_texcoord.xy + vec2(0,4.0 * pxSz.y * blurSize))* 0.05;
    gl_FragColor = varying_color * sum;
}

これは少し異なりますが、同じロジックです。ピクセル座標を UV 座標に変換し、hlsl 係数と同じようにぼかし係数を掛けます。それでも、glsl は、ぼやけていない、元のバージョンよりもわずかに透明なバージョンを提供します。

何が原因でしょうか?

4

1 に答える 1

1

フラグメント シェーダーには、次のものがあります。

varying vec4 varying_color;
[...]
     gl_FragColor = varying_color;

したがって、すべてのテクスチャ フェッチと計算は、最終的なシェーダー出力には影響しません (コンパイラによって完全に削除される可能性があります)。おそらく、それを出力sumしたり、変更したりしたいと思うでしょうgl_FragColor = varying_color * sum;

別のこと: フラグメント シェーダーでは、テクスチャ サイズの変数を定義しますが、頂点シェーダーからそれらを渡しません。それらはユニフォームである必要があります(または、最新のGLSLでは、textureSize()明示的に渡すことなくその値を直接処理できるGLSL関数もあります)。

于 2013-09-01T02:28:53.357 に答える