[TD + GLScene] Używanie TGLTexCombineShader |
![]() ![]() |
[TD + GLScene] Używanie TGLTexCombineShader |
sob, 06 mar 2010 - 23:21
Post
#1
|
|
|
Archon Grupa: Moderatorzy Postów: 1,868 Dołączył: pią, 28 paź 05 Skąd: Wieża Archona Nr użytkownika: 10 Gadu-Gadu: posiadam |
Czy bawił się ktoś może klasą TGLTexCombineShader ? No i pytanie właściwe, w sumie to rzuciłem okiem na demo, i pogrzebałem w googlu ale jakoś nie znalazłem ani manuala ani tutka jak tego używać. Niby mam kod shadera w stylu:
Delphi fGLTexShader.Combiners.Add('Tex0:=Tex0'); fGLTexShader.Combiners.Add('Tex1:=Tex1*Tex0'); fGLTexShader.Combiners.Add('Tex1:=Tex1*Tex0'); fGLTexShader.Combiners.Add('Tex2:=Tex1*Tex2'); ale szczerze mówiąc niewiele mi on mówi, może ktoś rzucić trochę światła na zagadnienie ? np. Jak mam 3 textury gdzie textura nr 1, 2 to diffuse map, a 3 to textura o wartościach 0-255 które oznaczałyby przenikanie textur 1/2 to jak takowy kod powinien wyglądać ? -------------------- |
|
|
|
nie, 07 mar 2010 - 01:32
Post
#2
|
|
|
Pomocna dłoń Grupa: Super użytkownicy Postów: 289 Dołączył: nie, 30 paź 05 Skąd: Mogilno Nr użytkownika: 25 Gadu-Gadu: 8249331 |
Witam,
Hmm dziwna konstrukcja albo rybki alb akwarium nie ma takiego czegoś jak shader i combnery na raz, ale domyślam się że to błąd nazewnictwa panów od glscene x) Niestety nie wiem jak to jest rozwiązane w silniku chciałem ogarnąć ale gdzieś mi kody zaginęły, może to co napiszę ułatwi poszukiwania. Są dwie opcje: 1. Shader Równanie interpolacji liniowej powinno być takie: wynik = T0 + (T1 - T0) * T2 gdzie T0, T1 to właśnie diffuse, a T2 to przenikanie Samplujemy 3 tekstury przepisujemy to co wyżej po czym powinno bez problemów działać Ale to tylko w shaderze tak więc trzeba się liczyć że karta musi obsługiwać (stare czasy teraz już nie ma takiego problemu). 1. Texture Combiners http://www.opengl.org/wiki/Texture_Combiners Ogólnie koncepcja jest taka że do tego typu zadania trzeba użyć combinerów dla interpolacji. Problem jest taki że wewnątrz combinera masz dostęp tylko do dwóch tekstur: - tekstura z poprzedniego wyniku combinera - tekstura aktualnie łączona Czyli ciężko będzie to policzyć w jednym przebiegu. Zazwyczaj ten problem rozwiązuje się używając koloru alpha (dla wierzchołka) jako zanik i wystarcza. W innym przypadku myślę że trzeba będzie rozbić równanie na dwie części no tak: wynik = T0 * (1 -T2) + T1*T2 Pierwszy przebieg: wynik = T0 * (1 - T2) // jesteśmy w stanie wykonać operacje 1-T2 przy pobieraniu koloru Blending addytywny Drugi przebieg wynik = T1*T2 Trochę niewygodnie i mało optymalnie ale niestety tak to wygląda. Z tego co wiem jeśli pisze się bezpośrednio pod kartę graficzną wybranego producenta można to dużo ładniej rozwiązać. Możliwe też glScene sobie jakoś z tym radzi nie jestem w stanie wiele powiedzieć na ten temat niestety. Powiedz co próbujesz zrobić może jest lepsze rozwiązanie Pozdrawiam, Spider -------------------- www.spider.dathox.com :)
|
|
|
|
nie, 07 mar 2010 - 11:00
Post
#3
|
|
|
Archon Grupa: Moderatorzy Postów: 1,868 Dołączył: pią, 28 paź 05 Skąd: Wieża Archona Nr użytkownika: 10 Gadu-Gadu: posiadam |
Po dluzszej pogawedce z Forcem doszlismy do wniosku ze lepiej bedzie uzyc cgShadera normalnego, wlasnie staram sie to wbic sobie do glowy ale manual 356 skutecznie obniza moja motywacje. Obecnie eksperymentuje z programem do shaderow ktory nic nie zrobi z widokiem, i jakos mi nie idzie. mam takie cos pod glScene:
Delphi procedure TForm2.InitGLScene; begin fGlScene := TGLScene.Create(self); fGlViewer := TGLSceneViewer.Create(self); fGLCamera := TGLCamera(fGlScene.Cameras.AddNewChild(TGLCamera)); with fGlViewer do begin Left := 0; Top := 0; Width := 603; Height := 405; Camera := fGLCamera; Buffer.BackgroundColor := clGray; Buffer.Lighting := False; Align := alClient; ParentWindow := self.Handle; end; fTerrainHDS := TGLBitmapHDS.Create(nil); fTerrainHDS.MaxPoolSize:=8*1024*1024; fTerrainHDS.Picture.LoadFromFile('data\terrain.bmp'); fTerrainHDS.InfiniteWrap := false; fGLMaterialLib := TGLMaterialLibrary.Create(self); fGLMaterialLib.AddTextureMaterial('ground', 'data\trawka.jpg', true); fGLMaterialLib.AddTextureMaterial('Detail2', 'data\trawka2.jpg', true); fTerrain := TGLTerrainRenderer(fGlScene.Objects.AddNewChild(TGLTerrainRenderer)); with fTerrain do begin TileSize := 32; TilesPerTexture := 1; QualityDistance := 150; fTerrain.HeightDataSource := fTerrainHDS; Material.MaterialLibrary := fGLMaterialLib; Material.LibMaterialName := 'ground'; end; with fGLCamera do begin DepthOfView := 1650; Position.y := 100; Position.x := 100; Position.z := 0; targetObject := fDummy; PitchAngle := 90; end; fGLTexShader := TCgShader.Create(self); fGLTexShader.OnApplyVP := CgShader1ApplyVP; fGLTexShader.OnApplyFP := CgShader1ApplyFP; fGLTexShader.OnUnApplyFP := CgShader1UnApplyFP; fGLTexShader.OnInitialize := CgShader1Initialize; fGLTexShader.VertexProgram.LoadFromFile('data\vProg.cg'); fGLTexShader.FragmentProgram.LoadFromFile('data\fProg.cg'); fGLTexShader.VertexProgram.Enabled:=true; fGLTexShader.FragmentProgram.Enabled:=true; fGLTexShader.Enabled := true; fGLMaterialLib.Materials[0].Shader := fGLTexShader; end; procedure TForm2.CgShader1Initialize(CgShader: TCustomCgShader); begin with CgShader.FragmentProgram, fGLMaterialLib do begin ParamByName('Map0').SetToTextureOf(Materials[0]); ParamByName('Map1').SetToTextureOf(Materials[1]); end; end; procedure TForm2.CgShader1ApplyFP(CgProgram: TCgProgram; Sender: TObject); begin with CgProgram do begin ParamByName('Map0').EnableTexture; ParamByName('Map1').EnableTexture; end; end; procedure TForm2.CgShader1UnApplyFP(CgProgram: TCgProgram); begin with CgProgram do begin ParamByName('Map0').DisableTexture; ParamByName('Map1').DisableTexture; end; end; procedure TForm2.CgShader1ApplyVP(CgProgram: TCgProgram; Sender: TObject); begin with CgProgram.ParamByName('modelViewProj') do SetAsStateMatrix( CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY); end; i mam taki program dla vShadera: C++ struct appin { float4 Pos : POSITION; float4 Tex : TEXCOORD0; }; struct vertout { float4 HPosition : POSITION; float4 Tex0 : TEXCOORD0; float4 Tex1 : TEXCOORD1; }; vertout main( appin IN, uniform float4x4 modelViewProj ) { vertout OUT; OUT.HPosition = mul(modelViewProj, IN.Pos); OUT.Tex0.x = IN.Tex.x;; OUT.Tex0.y = IN.Tex.y; OUT.Tex0.z = IN.Tex.z; OUT.Tex1.x = IN.Tex.x; OUT.Tex1.y = IN.Tex.y; OUT.Tex1.z = IN.Tex.z; return OUT; } i widze sieke na ekranie -------------------- |
|
|
|
![]() ![]() |
|
Wersja Lo-Fi | Aktualny czas: środa, 08 wrzesień 2010 - 13:51 |