Autor Wątek: Problem z shaderem w xna  (Przeczytany 1612 razy)

Offline muchomorek90

  • Użytkownik

# Grudzień 06, 2010, 23:32:10
Witam.
Otóż zacząłem sobie kodzić prostą gierkę i okazało się, że wyjątkowo potrzebny mi jest efekt blura. Poszedłem na łatwiznę i ściągnąłem exampla z internetu, poczytałem trochę o HLSL i przystosowałem go do XNA, jednak coś jest nie ok, mianowicie nie ma efektu (jednak wywoływany jest ok). Zlituje się ktoś mądrzejszy?
uniform extern texture ScreenTexture;

sampler inputTexture = sampler_state
{
Texture = <ScreenTexture>;
};
   
float PI = 3.14159265358979323846;
float EPSILON = 0.0001;

float ComputeGaussian(float n)
{
  float theta = 2.0f + EPSILON; //float.Epsilon;

 return theta = (float)((1.0 / sqrt(2 * PI * theta)) *
     exp(-(n * n) / (2 * theta * theta)));
}


float4 PixelShader (float2 texCoord: TEXCOORD0) : COLOR
{
   
float SampleWeights[15];
       
SampleWeights[0] = ComputeGaussian(0);
     
float totalWeights = SampleWeights[0];

         
for (int i = 0; i < 15 / 2; i++)
{
               
   float weight = ComputeGaussian(i + 1);

   SampleWeights[i * 2 + 1] = weight;
   SampleWeights[i * 2 + 2] = weight;

   totalWeights += weight * 2;
}

         
for (int j = 0; j < 15; j++)
{
     SampleWeights[j] /= totalWeights;
}

float4 color = 0.0f;
   
for(int k = 0; k < 15; k++ )
{
  color += tex2D(inputTexture,
                      texCoord ) * SampleWeights[k];
}
   return color;
}

technique
{
pass P0
{
PixelShader = compile ps_2_0 PixelShader();
}
}

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline PsichiX (ΨΧΞ)

  • Użytkownik
    • PsichiX Website

# Grudzień 07, 2010, 08:11:57
nie znam sie az tak na shaderach HLSL ale czy nie powinny miec one w technice takze vertex shader?

Offline muchomorek90

  • Użytkownik

# Grudzień 07, 2010, 10:58:55
To jest do gry 2d, więc vertexa w ogóle nie używam.

Offline PsichiX (ΨΧΞ)

  • Użytkownik
    • PsichiX Website

# Grudzień 07, 2010, 11:03:16
ale co z tego? shadery wymagają by podać im vertex shader (tak przynajmniej jest w glsl), gdzieś przecież musi być liczony vertex z którego dopiero fragment przechodzi obróbkę w fragment shaderze. W ogóle linkuje się bez vertex shadera? jak tak to dziwny ten hlsl

Offline muchomorek90

  • Użytkownik

# Grudzień 07, 2010, 12:54:34
Podczas kompilacji nie rzuca żadnych błędów. Prosty shader napisany wg. tego samego schematu przeze mnie (np. mnożenie koloru przez 3) działa ok.

Offline Will

  • Użytkownik

# Grudzień 07, 2010, 13:28:54
for(int k = 0; k < 15; k++ )
{
  color += tex2D(inputTexture,
                      texCoord ) * SampleWeights[k];
}

Po co samplujesz 15 razy to samo? ^.- blur.. na tym nie polega.





Offline muchomorek90

  • Użytkownik

# Grudzień 07, 2010, 16:37:20
Tzn? Nie bardzo rozumiem, średnio ogarniam te shadery.

Offline PsichiX (ΨΧΞ)

  • Użytkownik
    • PsichiX Website

# Grudzień 07, 2010, 16:49:56
chodzi o to ze koordynatow tesktury do samplowania (pobierania koloru z tekstury) nie zmieniasz.

for(int k = -7; k <= 7; k++ )
{
  color += tex2D(inputTexture,
                      texCoord + k * onepersize) * SampleWeights[k];
}

gdzie onepersize to: 1 / rozmiar_tekstury

Offline muchomorek90

  • Użytkownik

# Grudzień 07, 2010, 17:44:50
Wygryzłem coś takiego:

float2 TextureSize = 0.0f;
TextureSize.x = 1/TextureSizeX;
TextureSize.y = 1/TextureSizeY;

for(int k = -7; k < 7; k++ )
{
  color += tex2D(inputTexture,
                      texCoord + k * TextureSize) * SampleWeights[k+7];
}

Nie bardzo rozumiem to 1/RozmiarTekstury. To ma być wektor, czy skalar? W każdym razie wygląda na to, że jest ok. Wielkie dzięki za pomoc.

Btw. jak można zwiększyć "rozmycie"? Zwiększając liczbę passes?
« Ostatnia zmiana: Grudzień 07, 2010, 18:23:04 wysłana przez muchomorek90 »

Offline PsichiX (ΨΧΞ)

  • Użytkownik
    • PsichiX Website

# Grudzień 07, 2010, 20:06:17
raczej zwiekszyc w petli np. tak:
for(int k = -4; k < 14; k++ )
lub skale koordynatu ale jakosc ucierpi:
texCoord + ( k * TextureSize * skala )

Offline Charibo

  • Redaktor

# Grudzień 07, 2010, 20:57:55
Btw. jak można zwiększyć "rozmycie"? Zwiększając liczbę passes?
Najprościej zmniejszyć rozdzielczość rendertargetu parę razy, zblurować, a potem powiększyć spowrotem. Sprzętowe filtrowanie rozmywa "samo" aż miło. :)