Warsztat » Forum

[DirectX] Problem z oświetleniem terenu

20 wypowiedzi na 2 stronach: 1 2 Dec 29, 2008
kulesz
Dec 29, 2008

Problem z oświetleniem terenu

Witam,

Jako, że jest to mój pierwszy post, mówię grzecznie "Dzień dobry" :-)
Korzystając z chwili czasu i strony http://www.chadvernon.com/blog/ postanowiłem sobie odświeżyć wiadomości o Direct3D. Z tutorialami szło mi całkiem nieźle, ale obecnie pracuję nad oświetleniem terenu i troszkę mi nie wychodzi. Jeśli teren pokrywam jedną teksturą i używam standardowego oświetlenia (np. punktowego), wszystko działa OK. Kod renderujący:

Kod: 

pDevice->SetTexture( 0, m_pTextureBase );
m_vb.Render( pDevice, m_numIndices - 2, D3DPT_TRIANGLESTRIP );


Wierzchołki generowane z opcjami: D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1, oczywiście wszystkie dane prawidłowe i - jak widać na screenie - działa przyzwoicie (bez oświetlenia ambient):

0

Gdy chcę dodać drugą teksturkę (dokładniejszą), kod wygląda tak:
Kod: 

pDevice->SetTexture( 0, m_pTextureBase );

    if ( m_pTextureDetail )
    {
        pDevice->SetTexture( 1, m_pTextureDetail );
        pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
        pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
        pDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_CURRENT );
        pDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_TEXTURE );
        pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_ADDSIGNED );
    }
    m_vb.Render( pDevice, m_numIndices - 2, D3DPT_TRIANGLESTRIP );


Tekstura jest nałożona poprawnie, teren wygląda lepiej, ale oświetlenie nie działa:
http://images43.fotosik.pl/238/934edb5c5960c9b2.jpg

Wierzchołki z tworzone z opcjami: D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX2, wszystkie poprawne.

Czy w przypadku multiteksturingu coś powienenem zmieniać ze światłem?
Jeśli opis problemu jest mało szczegółowy, to przepraszam, ale dopiero wracam do formy :-)
Pozdrawiam i dziękuję z góry za odpowiedzi...



Xion
Dec 30, 2008

Odp: Problem z oświetleniem terenu

Na początek ustaw sobie jakieś filtrowanie tekstur - ze screenów które podałeś, po oczach bije pikseloza.

Co do problemu, to ciężko jest coś powiedzieć bez kodu odpowiedzialnego za ustawianie świateł. Skoro masz problem z oświetleniem, to powinieneś go pokazać :)
kulesz
Dec 30, 2008

Odp: Problem z oświetleniem terenu

Jeśli chodzi o światła, to tak (akurat kierunkowe, ale nie działa z każdym rodzajem):

Kod: 

ZeroMemory(&m_light,sizeof(m_light));
m_light.Type = D3DLIGHT_DIRECTIONAL;
m_light.Diffuse.r = 1.0f;
m_light.Diffuse.g = 0.0f;
m_light.Diffuse.b = 1.0f;
m_light.Direction.x = 0.8f;
m_light.Direction.y = -1.0f;
m_light.Direction.z = 1.0f;
m_light.Range = 1000.0f;


i potem:

Kod: 

pDevice->SetRenderState( D3DRS_FILLMODE, m_pFramework->GetFillMode() );     
pDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD ); 
pDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
pDevice->SetRenderState( D3DRS_ZENABLE,D3DZB_TRUE);
pDevice->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_XRGB( 50, 50, 50 ) );

pDevice->SetLight( 0, &m_light );
pDevice->LightEnable( 0, TRUE );
Krzysiek K.
Dec 28, 2008

Odp: Problem z oświetleniem terenu

Cytat:
Co do problemu, to ciężko jest coś powiedzieć bez kodu odpowiedzialnego za ustawianie świateł.

Gdzie tam ciężko - błąd jest jasno widoczny już w kodzie z pierwszego posta.

Kod:         pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
        pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
        pDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_CURRENT );
        pDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_TEXTURE );
        pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_ADDSIGNED );

Skoro mieszanie tekstur jest tak ustawione, że nie uwzględnia oświetlenia (color = T0 + T1 - 0.5), to nie dziwne, że oświetlenia nie ma. :)
Xion
Dec 29, 2008

Odp: Problem z oświetleniem terenu

No tak - nie sądziłem że ktoś może tak ustawić mieszanie tekstur a potem się zastanawiać, gdzie światło wcięło ;)
Krzysiek K.
Dec 29, 2008

Odp: Problem z oświetleniem terenu

Inna kwestia, że bez shaderów, to się tego oświetlenia w tej sytuacji poprawnie zrobić nie da. :)
Xion
Dec 30, 2008

Odp: Problem z oświetleniem terenu

Cytat:

Inna kwestia, że bez shaderów, to się tego oświetlenia w tej sytuacji poprawnie zrobić nie da. :)

Dlaczego nie? Jak dla mnie oświetlenie per vertex na fixed pipeline jest tak samo poprawne jak pikselowe liczone w shaderze. Że mniej dokładne i brzydsze, to inna sprawa :)
Krzysiek K.
Dec 30, 2008

Odp: Problem z oświetleniem terenu

Cytat:
Dlaczego nie? Jak dla mnie oświetlenie per vertex na fixed pipeline jest tak samo poprawne jak pikselowe liczone w shaderze. Że mniej dokładne i brzydsze, to inna sprawa :)

W takim razie spróbuj rozpisać wzór "color = (T0 + T1 - 0.5)*Diffuse" na dwa* texture stage. ;)


*) Trzema to wiem, że się da, ale jedynymi kartami, które wspierają ponad dwa texture stage, a nie mają jeszcze shaderów, są intele z serii 8xx. :)
kulesz
Jan 1, 2009

Odp: Problem z oświetleniem terenu

Cytat:

Inna kwestia, że bez shaderów, to się tego oświetlenia w tej sytuacji poprawnie zrobić nie da. :)


Czyli, jak rozumiem, nie tędy droga i tym sposobem dwóch tekstur razem nie oświetlę? :-)
Krzysiek K.
Jan 1, 2009

Odp: Problem z oświetleniem terenu

Cytat:
Czyli, jak rozumiem, nie tędy droga i tym sposobem dwóch tekstur razem nie oświetlę? :-)

Oświetlisz. Musisz tylko poprzestawiać odpowiednio stany przez SetTextureStageState (doczytaj o tym, co one robią i jak się je programuje).
kulesz
Jan 1, 2009

Odp: Problem z oświetleniem terenu

Dziękuję, udało mi się uzyskać w miarę zadowalający efekt przy:

Kod: 

pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
pDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
pDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_ADDSIGNED );
pDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_CURRENT );
pDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_TEXTURE );


Chyba tak powinno wyglądać, prawda?
Krzysiek K.
Jan 2, 2009

Odp: Problem z oświetleniem terenu

Cytat:
Chyba tak powinno wyglądać, prawda?

No tak nie do końca. Mnożenie przez kolor światła powinno być na samym końcu. :)
kulesz
Jan 2, 2009

Odp: Problem z oświetleniem terenu

A teraz to się trochę zbiłem z tropu... :-) Jak to zrobić tylko w 2 przejściach?
Xion
Jan 2, 2009

Odp: Problem z oświetleniem terenu

Cytat:

Cytat:
Chyba tak powinno wyglądać, prawda?

No tak nie do końca. Mnożenie przez kolor światła powinno być na samym końcu. :)

To zależy, czy woli cieniowanie D*(T0 + T1 - 0.5) od T0*D + T1 - 0.5, które ma teraz. Może przy jakichś szczególnych teksturach to aktualne wygląda lepiej? ;)
Nie da się aczkolwiek ukryć, że w pixel shaderze wyglądałoby to jakieś dwadzieścia trzy razy przejrzyściej.
kulesz
Jan 2, 2009

Odp: Problem z oświetleniem terenu

Sprawdziłbym jeszcze te D*(T0 + T1 - 0.5) [wydaje się nauralniejsze], ale właśnie nie mogę zaskoczyć, jak to zapisać (ciężki dzień) :-) A co pixel shaderów, to nie mam jeszcze żadnego doświadczenia i będę dopiero z tym startował :-)
Xion
Dec 30, 2008

Odp: Problem z oświetleniem terenu

Cytat:

Sprawdziłbym jeszcze te D*(T0 + T1 - 0.5) [wydaje się nauralniejsze], ale właśnie nie mogę zaskoczyć, jak to zapisać (ciężki dzień) :-) A co pixel shaderów, to nie mam jeszcze żadnego doświadczenia i będę dopiero z tym startował :-)

D*(T0 + T1 - 0.5) nie da się zrobić na dwóch stage'ach w jednym przebiegu renderowania. Musisz albo użyć 3 stage'ów, albo 2 passów z odpowiednio ustawionym blendingiem.

Rozwiązanie dla 3 stage'ów to coś w tym stylu:

Stage0 = { Arg1 = TEXTURE, Arg2 = cokolwiek, Op = SELECTARG1 }
Stage1 = { Arg1 = CURRENT, Arg2 = TEXTURE, Op = ADDSIGNED }
Stage2 = { Arg1 = CURRENT, Arg2 = DIFFUSE, Op = MODULATE }

Nie da się tego zrobić na dwa, bo w jednym stage'u możesz odczytać tylko jedną teksturę.

Aby odpowiedzieć w temacie "[DirectX] Problem z oświetleniem terenu" musisz się najpierw zalogować/zarejestrować

Strony: 1 2