Autor Wątek: [Direct3D 11] Texture3D jako RenderTarget(View)  (Przeczytany 945 razy)

Offline komorra

  • Użytkownik
    • Blog naszego teamu (o grze Voxelfield)

# Luty 08, 2013, 07:54:22
Witam. Wczoraj zainteresował mnie temat tekstur wolumetrycznych i mam podstawowy problem: Nie potrafię napełnić tekstury 3D pikselami poprzez shader (DX11, SM 4.0). Debugując aplikację zauważyłem że jak rysuję quada to napełnia mi się kolorem czerwonym (bo pixel shader ma tylko return float4(1,0,0,1)) jedynie pierwszy slajs mojej tekstury 3D (40x40x40, debuguje zapisując kolejne slajsy jako obrazki 40x40).

Zauważyłem też, że przesuwanie Z quada nie powoduje rysowania na kolejnych slajsach.

Efekt jaki chciałbym uzyskać to wypełnienie tekstury 3D jakimś gradientem wolumetrycznym, np. żebym miał w rogach różne kolorki a piksele w środki się zinterpolują między nimi.

W shaderze przekazuje jedynie POSITION. Fantazja mi podpowiada że powinna być metoda w DX11 która powoduje narysowanie sześcianu wolumetrycznego, tak aby w float4 Position : POSITION dostać "przejście" po wszystkich pikselach tekstury 3D.

Czy w ogóle rendering do rendertargetu 3D (bo sobie taki utworzyłem) jest możliwy? (napewno da się zbindować do urządzenia).

Dzięki z góry za pomoc.

Offline Mr. Spam

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

Offline Hans

  • Użytkownik

# Luty 08, 2013, 11:40:35
Wprawdzie tego osobiście nie testowałem, ale można podpiąć geometry shader, który będzie zapodawał trójkąty do różnych slice'ów z tekstury 3d (patrz: SV_RenderTargetArrayIndex)

Alternatywnie można bindować i renderować każdą warstwę osobno.

Offline Krzysiek K.

  • Moderator
    • DevKK.net

# Luty 08, 2013, 12:07:10

Offline komorra

  • Użytkownik
    • Blog naszego teamu (o grze Voxelfield)

# Luty 08, 2013, 14:11:39
Ło... dzięki Wam wielkie :D o to chyba chodziło sprawdzę w domu jak śmiga :)

Offline komorra

  • Użytkownik
    • Blog naszego teamu (o grze Voxelfield)

# Luty 08, 2013, 18:05:07
No i niedziała... chyba mam zły shader... Teraz wszystkie slajsy mam czarne zamiast czerwonego wybranego
uint g_layer = 0;

struct VSInput
{
float4 Position : POSITION;
};

struct PSInput
{
float4 Position : POSITION;
};

struct GS_OUT_LAYER
{
float4 posH    : SV_POSITION;
uint   layer : SV_RenderTargetArrayIndex;
};

[maxvertexcount(3)]
void GS_SetLayer(triangle PSInput input[3],
inout TriangleStream<GS_OUT_LAYER> triOutputStream)
{
GS_OUT_LAYER output;

for(int i=0; i < 3; ++i)
{
output.posH  = input[i].Position;
output.layer = g_layer;

triOutputStream.Append(output);
}
}



PSInput VS(VSInput input)
{
PSInput output = (PSInput)0;
output.Position = input.Position;
return output;
}

float4 PS(GS_OUT_LAYER input) : SV_TARGET
{
return float4(1,0,0,1);
}

technique tech1
{
pass
{
VertexShader = compile vs_4_0 VS();
GeometryShader = compile gs_4_0 GS_SetLayer();
PixelShader = compile ps_4_0 PS();
}
}

Offline komorra

  • Użytkownik
    • Blog naszego teamu (o grze Voxelfield)

# Luty 08, 2013, 20:28:37
OK :) Już działa, zamiast POSITION powinno być wszędzie SV_POSITION