OleM80 Skrevet 5. oktober 2009 Del Skrevet 5. oktober 2009 (endret) Jeg har problemer med transparent triangler i DirectX Jeg har en vertextliste slik triangleList = new CustomVertex.PositionColored[200]; ut fra denne bygger jeg en Mesh meshTerrain.SetVertexBufferData(triangleList, LockFlags.None); meshTerrain.SetIndexBufferData(indices, LockFlags.None); int[] adjac = new int[meshTerrain.NumberFaces * 3]; meshTerrain.GenerateAdjacency(0.5f, adjac); meshTerrain.OptimizeInPlace(MeshFlags.OptimizeVertexCache, adjac); Dette fungerer fint. Problemet er bare at triangler som skulle vært usynlig ses fra alle kameraposisjoner fordi trianglene er transparent. Hva gjør jeg med dette. Verticenes farger hentes fra dette arrayet ut fra høydene deres. Color[] colorArray = new Color[] { Color.Blue, Color.LightBlue, Color.Yellow, Color.YellowGreen, Color.LightGreen, Color.Green, Color.DarkOrange, Color.Orange, Color.OrangeRed, Color.Red }; Endret 5. oktober 2009 av OleM80 Lenke til kommentar
GeirGrusom Skrevet 5. oktober 2009 Del Skrevet 5. oktober 2009 (endret) Nei, problemet er nok at depth-test ikke er skrudd på. Nå er det en stund siden jeg drev med Managed Direct3D, men jeg mener dette ligger i GraphicsDevice.DeviceState. Sett DepthTest, ZTest eller hva det enn heter til true. edit: i XNA heter det RenderState.DepthBufferEnable edit2: Det er dessverre ingen enkel løsning på problemet med transparente polygoner, den enkleste er å sortere etter avstand. Det finnes noen løsninger som bruker shaders og slikt, men disse bruker som regel veldig mye ressurser. Endret 5. oktober 2009 av GeirGrusom Lenke til kommentar
OleM80 Skrevet 5. oktober 2009 Forfatter Del Skrevet 5. oktober 2009 Nei, problemet er nok at depth-test ikke er skrudd på. Nå er det en stund siden jeg drev med Managed Direct3D, men jeg mener dette ligger i GraphicsDevice.DeviceState. Sett DepthTest, ZTest eller hva det enn heter til true. edit: i XNA heter det RenderState.DepthBufferEnable edit2: Det er dessverre ingen enkel løsning på problemet med transparente polygoner, den enkleste er å sortere etter avstand. Det finnes noen løsninger som bruker shaders og slikt, men disse bruker som regel veldig mye ressurser. Ok men hvordan blir dette løst i f.eks. spill da? Hvis du har 3 persons view. Så vil du jo ikke se terrenget bak spillfiguren. Er det teksturer som løser dette? Lenke til kommentar
GeirGrusom Skrevet 5. oktober 2009 Del Skrevet 5. oktober 2009 Nei, terreng er ikke gjennomsiktig og har heller ikke dette problemet. Det du derimot kanskje har sett i noen spill innimellom, er at dersom du for eksempel ser inn igjennom et vindu på et basseng med vann, så kan vannet forsvinne, bli tegnet foran vinduet eller lignende. Det er ingen alpha+depth test i skjermkort av en eller annen grunn, selv om dette hadde vært temmelig simpelt å løse (hvis noe er bak en gjennomsiktig pixel i Z-bufferet, må alpha-testen snus) men det er ikke blitt prioritert. Inntill videre må du bare sortere objekter eller polygoner etter rekkefølgen i Z-bufferet. Dette gjøres ved å multiplisere objektets posisjon med model, view og projection matrisene, og sortere etter Z verdien du får tilbake. Men igjen; dette er kun et problem med gjennomsiktige ting. Lenke til kommentar
OleM80 Skrevet 5. oktober 2009 Forfatter Del Skrevet 5. oktober 2009 Nei, terreng er ikke gjennomsiktig og har heller ikke dette problemet. Det du derimot kanskje har sett i noen spill innimellom, er at dersom du for eksempel ser inn igjennom et vindu på et basseng med vann, så kan vannet forsvinne, bli tegnet foran vinduet eller lignende. Det er ingen alpha+depth test i skjermkort av en eller annen grunn, selv om dette hadde vært temmelig simpelt å løse (hvis noe er bak en gjennomsiktig pixel i Z-bufferet, må alpha-testen snus) men det er ikke blitt prioritert. Inntill videre må du bare sortere objekter eller polygoner etter rekkefølgen i Z-bufferet. Dette gjøres ved å multiplisere objektets posisjon med model, view og projection matrisene, og sortere etter Z verdien du får tilbake. Men igjen; dette er kun et problem med gjennomsiktige ting. Ok skjønner. Problemstillingen min er at jeg har en stor terrengmodell med f.eks. 30000 triangler. Dette tegnes ut som en Mesh. I tillegg tegnes det ut en grabb/skuff. Dersom denne kommer under terrenget skal den delen av skuffen som er under terrenget bli usynlig. Noen forslag på hvordan dette kan løses? Må jeg gjøre det så komplisert som å hente ut de delene av Mesh Nr2 som ligger over terrengmodellen? Trodde slik funksjonalitet var innebygget i DirectX. Om du har noen ide hvordan jeg kan løse dette hadde det vært til STOR hjelp. Lenke til kommentar
GeirGrusom Skrevet 5. oktober 2009 Del Skrevet 5. oktober 2009 Det er jo enkelt nok så lenge terrenget ikke er gjennomsiktig. Direct3D bruker som sagt Z-buffering for å fikse dybdeproblemer. Som sagt så ligger problemet i at Direct3D ikke lagrer noen alphainformasjon i rendertargeten, noe som gjør at det er umulig å teste per pixel på alpha, så derfor blir kun Z-bufferet brukt istedet, noe som gjør at dersom du tegner noe etter du har tegner noe gjennomsiktig (for eksempel terrenget blir tegnet etter et glassvindu) så vil terrenget ikke være synlig bak glasset. Derfor, tegn terrenget først, og alt gjennomsiktig sist, så unngår du problemet mer eller mindre fullstendig. Z-bufferet vil bli brukt, dog det er ingen tradisjonell clipping (som var vanlig i software renderer) men snarere lagrer den et Z-buffer som inneholder avstanden på hver pixel, slik at pixler som blir tegnet langt unna ikke skal overskrive pixler som er nærme. Derimot blir ikke alpha-verdien tatt med i beregningen. Men stort sett skal det fungere fint, det er bare unntaksvis at du vil få slike problemer. Lenke til kommentar
OleM80 Skrevet 5. oktober 2009 Forfatter Del Skrevet 5. oktober 2009 Det er jo enkelt nok så lenge terrenget ikke er gjennomsiktig. Direct3D bruker som sagt Z-buffering for å fikse dybdeproblemer. Som sagt så ligger problemet i at Direct3D ikke lagrer noen alphainformasjon i rendertargeten, noe som gjør at det er umulig å teste per pixel på alpha, så derfor blir kun Z-bufferet brukt istedet, noe som gjør at dersom du tegner noe etter du har tegner noe gjennomsiktig (for eksempel terrenget blir tegnet etter et glassvindu) så vil terrenget ikke være synlig bak glasset. Derfor, tegn terrenget først, og alt gjennomsiktig sist, så unngår du problemet mer eller mindre fullstendig. Z-bufferet vil bli brukt, dog det er ingen tradisjonell clipping (som var vanlig i software renderer) men snarere lagrer den et Z-buffer som inneholder avstanden på hver pixel, slik at pixler som blir tegnet langt unna ikke skal overskrive pixler som er nærme. Derimot blir ikke alpha-verdien tatt med i beregningen. Men stort sett skal det fungere fint, det er bare unntaksvis at du vil få slike problemer. Får det fremdeles ikke helt til å fungere. Legger ved en enkel eksempelApp for å demonstrere using System; using System.Drawing; using System.Windows.Forms; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; namespace ZBufferTest { public class DX3D_Form : Form { private readonly Device device; private readonly CustomVertex.PositionColored[] triangle1; private readonly CustomVertex.PositionColored[] triangle2; public DX3D_Form() { InitializeComponent(); this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true); PresentParameters presentParams = new PresentParameters {Windowed = true, SwapEffect = SwapEffect.Discard}; device = new Device(0, DeviceType.Hardware, this,CreateFlags.SoftwareVertexProcessing | CreateFlags.FpuPreserve, presentParams); triangle1 = CreateTriangle(5, Color.Red); triangle2 = CreateTriangle(6, Color.Blue); } private void InitializeComponent() { this.SuspendLayout(); this.ClientSize = new Size(707, 493); this.Name = "RenderForm"; this.ResumeLayout(false); } private static CustomVertex.PositionColored[] CreateTriangle(float distanceFromCam, Color color) { CustomVertex.PositionColored[] triangle = new CustomVertex.PositionColored[3]; triangle[0].Position = new Vector3(distanceFromCam,0f, 1f); triangle[0].Color = color.ToArgb(); triangle[1].Position = new Vector3(distanceFromCam, 2f, 1f); triangle[1].Color = color.ToArgb(); triangle[2].Position = new Vector3(distanceFromCam, 1f, 3f); triangle[2].Color = color.ToArgb(); return triangle; } protected override void OnPaint(PaintEventArgs e) { device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0); device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, (float)Width / Height, 1f, 3000f); device.Transform.View = Matrix.LookAtLH(new Vector3(1, 1, 1), new Vector3(5, 1, 1), new Vector3(0, 0, 1)); device.RenderState.CullMode = Cull.None; device.RenderState.Lighting = false; device.RenderState.ZBufferEnable = true; device.VertexFormat = CustomVertex.PositionColored.Format; device.BeginScene(); device.RenderState.FillMode = FillMode.Solid; device.DrawUserPrimitives(PrimitiveType.TriangleStrip, 1, triangle1); device.DrawUserPrimitives(PrimitiveType.TriangleStrip, 1, triangle2); device.EndScene(); device.Present(); Invalidate(); } static void Main() { Application.Run(new DX3D_Form()); } } } Tegner ut 2 triangler med samme størrelse med en gitt avstand fra kamera. triangel 2 er lengst fra kamera og i dette eksempelet så burde vel z bufferet slik du forklarte det fjernet alle verticer på dette triangelet. Slik fungerer det ikke. Med mindre det blir tegnet først. Hvis triangle1 hadde vært terrenget ville triangle2 bli synlig bak terrenget. Dette ønskes selvfølgelig ikke. Ofte er også tilfellet slik at et triangel eller en mesh bare er delvis synlig slik jeg postet tidligere. Greier du å se noen åpenbare feil jeg gjør her? Lenke til kommentar
OleM80 Skrevet 5. oktober 2009 Forfatter Del Skrevet 5. oktober 2009 Fant løsning! Når jeg opprettet PresentParameters måtte jeg sette EnableAutoDepthStencil = true, AutoDepthStencilFormat = DepthFormat.D16 I tillegg til device.RenderState.ZBufferEnable = true; og tømming av Z buffer slik device.Clear(ClearFlags.Target|ClearFlags.ZBuffer, Color.Black, 1.0f, 0); Etter dette var det gjort. Så kom meg videre siden du snakket om det her med depth etc. Men tok litt tid før jeg fant de to øverste parametrene her. Uansett! Takk for hjelpa for du satte meg bra på sporet i forhold til en løsning Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå