2013-09-01 29 views
0

我对这个模糊的Shader HLSL:GLSL着色器阀块从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; 
    } 

有一个类似的水平...

的想法是,我为纹理提供了宽度,高度和高度,并使用它来获取像素相对于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给了我一个原始的,没有瑕疵的,稍微透明的版本。

这是什么原因造成的?

回答

1

在你的片段着色器,你必须:

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

因此所有的纹理拾取和计算你没有最终着色器输出(任何影响,并有可能被编译器完全去除)。您可能要输出sum或对其进行修改,例如与gl_FragColor = varying_color * sum;或任何你想达到的效果。

另一件事:在碎片着色器中,您定义了纹理大小的变化,但是您不会从顶点着色器中传递它们。那些应该是制服(或者,在现代GLSL中,也有GLSL功能,它允许你直接处理这些值而不明确地传递它们)。

+0

对不起,我已经像你说过的那样,我不小心张贴了一个测试用例。但是,它仍然是这样。 – jmasterx

+0

vary_color是纯rgba白色的顶点颜色。 – jmasterx

+0

@Milo:anothier的东西:在碎片着色器中,你定义了纹理大小的变化,但是你不会从顶点着色器中传递它们。这应该是制服(或者,在现代GLSL中,也有textureSize()GLSL函数,它允许你直接处理这些值而不会明确地传递它们) – derhass