Skocz do zawartości

[TD + GLScene] Używanie TGLTexCombineShader


Toster

Polecane posty

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:

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ć ?

Always Dark<br />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

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 :)

Link do komentarza
Udostępnij na innych stronach

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;

[/cpp]

i widze sieke na ekranie

Always Dark<br />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

×
×
  • Utwórz nowe...