2014-10-30 14 views
5

Pracuję nad aplikacją, która używa SharpDX i SharpDX Toolkit do rysowania prostych kształtów 3D, a próbka Geometrics.Desktop była bardzo pomocna przy rozpoczynaniu pracy. Teraz staram się, aby niektóre kształty były przezroczyste, a żeby wszystko było proste, po prostu próbuję sprawić, by model czajnika w tym sample był przezroczysty (być może półprzezroczysty byłby dokładniejszy).Jak mogę narysować przezroczysty obiekt 3D za pomocą SharpDX Toolkit?

Dla osób nieobeznanych z próbką Geometrics.Desktop rysuje kilka prostych, pierwotnych kształtów geometrycznych w 3D. Ponieważ jest to przykładowa aplikacja, jest dość prosta, więc stanowi całkiem niezłą próbkę do eksperymentowania z funkcjami 3D biblioteki SharpDX "Toolkit".

Dodałem to metody LoadContent (czyli raz w momencie startu), w celu przygotowania Direct3D zrobić mieszania:

 var blendStateDescription = new BlendStateDescription(); 

     blendStateDescription.AlphaToCoverageEnable = false; 

     blendStateDescription.RenderTarget[0].IsBlendEnabled = true; 
     blendStateDescription.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha; 
     blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha; 
     blendStateDescription.RenderTarget[0].BlendOperation = BlendOperation.Add; 
     blendStateDescription.RenderTarget[0].SourceAlphaBlend = BlendOption.Zero; 
     blendStateDescription.RenderTarget[0].DestinationAlphaBlend = BlendOption.Zero; 
     blendStateDescription.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add; 
     blendStateDescription.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All; 

     var blendState = SharpDX.Toolkit.Graphics.BlendState.New(this.GraphicsDevice, blendStateDescription); 
     this.GraphicsDevice.SetBlendState(blendState); 

mam skonfigurować szablon głębokości następująco:

 var depthDisabledStencilDesc = new DepthStencilStateDescription() 
     { 
      IsDepthEnabled = false, 
      DepthWriteMask = DepthWriteMask.All, 
      DepthComparison = Comparison.Less, 
      IsStencilEnabled = true, 
      StencilReadMask = 0xFF, 
      StencilWriteMask = 0xFF, 
      // Stencil operation if pixel front-facing. 
      FrontFace = new DepthStencilOperationDescription() 
      { 
       FailOperation = StencilOperation.Keep, 
       DepthFailOperation = StencilOperation.Increment, 
       PassOperation = StencilOperation.Keep, 
       Comparison = Comparison.Always 
      }, 
      // Stencil operation if pixel is back-facing. 
      BackFace = new DepthStencilOperationDescription() 
      { 
       FailOperation = StencilOperation.Keep, 
       DepthFailOperation = StencilOperation.Decrement, 
       PassOperation = StencilOperation.Keep, 
       Comparison = Comparison.Always 
      } 
     }; 

     // Create the depth stencil state. 
     var depthDisabledStencilState = SharpDX.Toolkit.Graphics.DepthStencilState.New(this.GraphicsDevice, depthDisabledStencilDesc); 
     //turn z-buffer off 
     this.GraphicsDevice.SetDepthStencilState(depthDisabledStencilState, 1); 

W metodzie Draw (która działa z szybkością klatek i iteruje przez małą tablicę modeli 3D, rysując każdy z nich), dodałem poniższy kod. Przesuwa czajniczek do środka rzutni i powoduje, że jest wystarczająco duży, aby zamknąć niektóre inne obiekty. Czajniczek uwagę ostatni, więc pozostałe modele zostały już oddane, więc ja naprawdę nadzieję, że to będzie wyciągnąć półprzezroczystą czajniczek na nich:

// Draw the primitive using BasicEffect 
if (i == 6) 
{ 
    basicEffect.Alpha = 0.5f; 
    basicEffect.World *= Matrix.Translation(-x, -y, 0); 
    basicEffect.World *= Matrix.Scaling(3); 
} 
else 
{ 
    basicEffect.Alpha = 1; 
} 

primitive.Draw(basicEffect); 

(komentarz i ostatecznego wezwania do rysowania były częścią oryginalny kod przykładowy)

Ale niestety, wynik jest wielkim nieprzezroczysty czajniczek wśród innych obiektów.

enter image description here

Co muszę zrobić, aby tego typu bu apot przezroczysty?

Czy czegoś brakuje, czy też źle skonfigurowałem stan mieszania?

Próbowałem również teksturować moje obiekty za pomocą obrazów, które mają kanał alfa o 50%, ale to nadal powoduje, że obiekty nieprzezroczyste.

Z góry dziękujemy za wszelką pomoc!

+0

Czy używasz direct3d11? Ponieważ nie ma * pierwotnego * sprawiedliwego * kontekstu *. –

+0

Tak, używam D3D11, jednak użyłem słowa "prymityw" w sensie geometrycznym - kostka, kula, cylinder i tak dalej. Zestaw narzędzi SharpDX ma klasy, które ułatwiają rysowanie takich kształtów i są łatwe w obsłudze. Przeważnie. Bardzo trudno było uczynić je przejrzystymi. – NSFW

Odpowiedz

2

Mam SourceAlphaBlend i DestinationAlphaBlend ustawione na zero i działa tak, jak powinno. Inne niż ten opis stanu wygląda mi na prawidłowy. Upewnij się również, że AlphaToCoverage jest wyłączone w blendstate, bo inaczej będziesz zachowywał się dziwnie.

Upewnij się także, że ustawisz BlendState przed rysowaniem każdej klatki.

+0

Czy na pewno są to jedyne wprowadzone zmiany? Właśnie wprowadziłem te zmiany do mojej aplikacji testowej, a imbryczka wciąż jest nieprzejrzysta. To, że masz alfa działa, daje mi wielką nadzieję! – NSFW

+1

Czy używasz programu Visual Studio?Jeśli tak, użyj narzędzia "Debugowanie-> Grafika-> Uruchom diagnostykę", aby debugować urządzenie D3D11 i stwierdza w czasie wykonywania. Być może stan nie jest poprawnie związany. –

+0

Mam przezroczysty czajniczek! Blendstate, który pojawił się w narzędziu diagnostycznym, nie jest tym samym, który skonfigurowałem w kodzie. Przeniosłem to do pętli renderowania i przezroczystość działa teraz. Oczywiście chciałbym go usunąć z pętli renderowania, ale przyjrzę się temu dalej. – NSFW

Powiązane problemy