Autor Wątek: Deferred w XNA  (Przeczytany 2017 razy)

Offline piechota

  • Użytkownik

# Marzec 11, 2015, 23:19:14
Mam pewien problem z deferred w XNA - powstają artefakty gdy się bliżej podejdzie do obiektu.
Wygląda to na precyzję depth'a ale zrobiłem teraz przeliczanie z float'a na kolor żeby wykorzystać wszystkie składowe pixela i wciąż jest to samo. Po zmianie SurfaceFormat na Color jest jeszcze gorzej więc zaczynam się zastanawiać czy to nie jest problem z precyzją normalnych.
Nie robiłem nic za bardzo wcześniej w XNA i podejrzewam, że trzeba po prostu jakoś mądrze ustawić parametry dla render target'ów itp jakby ktoś mógł coś podpowiedzieć byłbym wdzięczny :)
Nie zbyt wiem które fragmenty kodu mogą coś rozjaśnić więc wrzucę shader do generowania gbuffer'a i directional light:

GBuffer
float3 floatToColor(float f)
{
float3 color;
f *= 256;
color.x = floor(f);
f = (f - color.x) * 256;
color.y = floor(f);
color.z = f - color.y;
color.xy *= 0.00390625;
return color;
}

PSO PS(VSO input)
{
PSO output;

output.diffuse = tex2D(diffuseSampler, input.uv);

output.normal = tex2D(normalSampler, input.uv);
output.normal = output.normal * 2.0f - 1.0f;
output.normal.xyz = mul(output.normal.xyz, input.TBN);
output.normal.xyz = mul(float4(output.normal.xyz, 0.0f), wvMatrix);
output.normal.xyz = normalize(output.normal.xyz);
output.normal.w = 1.0f;
output.normal = output.normal * 0.5f + 0.5f;

output.depth.rgb = floatToColor(input.depth.x / input.depth.y);
output.depth.w = tex2D(specularSampler, input.uv).r;

return output;
}

Directional
float3 ToViewPosition(float z, float2 uv)
{
float x = uv.x * 2.0f - 1.0f;
float y = (1 - uv.y) * 2.0f - 1.0f;
float4 vProjectionPos = float4(x, y, z, 1.0f);
float4 vPositionVS = mul(vProjectionPos, pMatrixInv);

return vPositionVS.xyz / vPositionVS.w;
}

float colorToFloat(float3 color)
{
const float3 byte_to_float = float3(1.0, 1.0 / 256, 1.0 / (256 * 256));
return dot(color, byte_to_float);
}

float4 PS(VSIO input) : COLOR0
{
float3 N = tex2D(normal, input.uv).rgb;
N = N * 2.0f - 1.0f;

float3 positionView = ToViewPosition(colorToFloat(tex2D(depth, input.uv).rgb), input.uv);

float NdotL = dot(N, -lightDirection);
NdotL = NdotL * 0.5f + 0.5f;
NdotL *= NdotL;
NdotL += 0.05f;

float3 E = eyePosition - positionView;
E = normalize(E);

float3 H = normalize(E - lightDirection);
float NdotH = dot(N, H);
float intensity = pow(saturate(NdotH), 100.0f);
float specular = intensity * tex2D(depth, input.uv).a;

float4 color;
color.rgb = lightColor * NdotL;
color.a = specular;

return color;
}

//EDIT
na tym pierwszym screenie widać o co mi chodzi dopiero jak się otworzy w nowym okienku/karcie :)
« Ostatnia zmiana: Marzec 11, 2015, 23:29:59 wysłana przez piechota »

Offline Mr. Spam

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

Offline koirat

  • Użytkownik

# Marzec 11, 2015, 23:54:17
Wklej vertex shader, pokaż jak tworzysz macierz TBN.

Offline piechota

  • Użytkownik

# Marzec 12, 2015, 00:40:03
VSO VS(VSI input)
{
VSO output;

output.position = mul(input.position, wvpMatrix);
output.uv = input.uv;
output.depth.xy = output.position.zw;
output.TBN[0] = input.tangent;
output.TBN[1] = input.bitangent;
output.TBN[2] = input.normal;

return output;
}

Magii nie ma. FBX + load'er XNA podają tangnet, bitangent i normalną dla modelu (no chyba, że nie ale wtedy całe oświetlenie było by złe raczej)