2013-09-01 2 views
0

У меня есть этот HLSL Shader для размытия:GLSL Shader адаптированного От 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; 
    } 

Frag

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 для текстуры и высоты и использую это, чтобы получить «размер» пикселя относительно УФ-коордов.

Затем я использую это для нормального размытия, взяв средневзвешенное значение соседей.

я портировал это 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; 
} 

Frag

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; 
} 

Это немного отличается, но это та же самая логика. Я конвертирую пиксельные координаты в УФ-координаты и умножаю их на коэффициент размытия, такой же, как и коэффициент hlsl. Тем не менее, glsl дает мне неровную, чуть более прозрачную версию оригинала.

Что может быть причиной этого?

ответ

1

В вашем пиксельном шейдере, у вас есть:

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

поэтому все текстурные выборки и расчеты вы не оказывает никакого влияния на конечном выходе шейдеров (и, вероятно, будет полностью удалено компилятором). Вы, вероятно, хотите вывести sum или изменить его, например. с gl_FragColor = varying_color * sum; или любым другим эффектом, который вы хотите достичь.

Другое дело: в фракер-шейдере вы определяете изменения размера текстуры, но вы не передаете их из вершинного шейдера. Они должны быть униформами (или, в современном GLSL, есть также функция textureSize() GLSL, которая позволяет вам напрямую обрабатывать эти значения, не передавая их явно).

+0

Извините, у меня уже есть это, как вы сказали, я случайно отправил тестовый пример. Но он все еще действует таким образом. – jmasterx

+0

differenting_color - это цвет вершины, который является чистым rgba white. – jmasterx

+0

@Milo: anothier вещь: в фракер-шейдере вы определяете изменения размера текстуры, но вы не передаете их из вершинного шейдера. Это должна быть униформа (или, в современной GLSL, есть также функция textureSize() GLSL, которая позволяет напрямую обрабатывать эти значения, не передавая их явно) – derhass