2014-10-30 25 views
5

Sto lavorando a un'applicazione che utilizza SharpDX e SharpDX Toolkit per disegnare semplici forme 3D e l'esempio di Geometrics.Desktop è stato molto utile per iniziare. Ora sto cercando di rendere alcune forme trasparenti, e per mantenere le cose semplici sto solo cercando di far apparire trasparente il modello di teiera in quel campione (forse traslucido sarebbe più preciso).Come posso disegnare un oggetto 3D trasparente con SharpDX Toolkit?

Per chi non ha familiarità con l'esempio Geometrics.Desktop, disegna alcune semplici forme geometriche primitive in 3D. Essendo un'app di esempio, è piuttosto semplice, quindi è uno scratchpad piuttosto buono per sperimentare le funzionalità 3D della libreria "Toolkit" di SharpDX.

ho aggiunto questo al metodo LoadContent (che viene eseguita una volta al tempo di avvio), in uno sforzo per preparare Direct3D fare miscelazione:

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

mi hanno istituito lo stencil di profondità come segue:

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

E nel metodo Draw (che gira alla frequenza di fotogrammi e scorre attraverso una piccola serie di modelli 3D, disegnandoli ciascuno), ho aggiunto il codice qui sotto. Sposta la teiera al centro del viewport e la rende abbastanza grande da occludere alcuni degli altri oggetti. La teiera è disegnato scorso, quindi gli altri modelli sono già stati resi, così mi è stato davvero sperando questo richiama una teiera traslucida su di essi:

// 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); 

(Il commento e la chiamata finale disegnare facevano parte di il codice di esempio originale)

Ma, ahimè, il risultato è un grande opaca teiera tra gli altri oggetti:.

enter image description here

che cosa devo fare per fare che te l'apot trasparente?

Mi manca qualcosa o ho configurato erroneamente lo stato di fusione?

E solo per completezza, ho anche provato a strutturare i miei oggetti con immagini che hanno il canale alfa al 50%, ma che comunque risulta in oggetti opachi.

Grazie in anticipo per qualsiasi assistenza!

+0

Stai utilizzando direct3d11? Perché non esiste * primitivo * solo * contesto *. –

+0

Sì, sto usando D3D11, tuttavia stavo usando la parola "primitivo" nel senso geometrico: cubo, sfera, cilindro e così via. Il toolkit SharpDX offre classi che facilitano il disegno di tali forme e sono facili da utilizzare. Soprattutto. È stato molto difficile renderli trasparenti. – NSFW

risposta

2

Ho SourceAlphaBlend e DestinationAlphaBlend impostato su Zero e funziona come dovrebbe. A parte quelli, la descrizione dello stato mi sembra corretta. Inoltre, assicurati che AlphaToCoverage sia disabilitato nel blendstate altrimenti avrai altre cose strane.

Assicurarsi inoltre di impostare BlendState prima di disegnare ciascun fotogramma.

+0

Sei sicuro che quelle sono le uniche modifiche che hai apportato? Ho appena apportato queste modifiche alla mia app di test e la teiera è ancora opaca. Che tu abbia un alfa che lavora mi dà comunque una grande speranza! – NSFW

+1

Stai usando Visual Studio?In tal caso, utilizzare lo strumento "Debug-> Graphics-> Start Diagnostrics" per eseguire il debug del dispositivo D3D11 e gli stati in fase di esecuzione. Forse uno stato non viene vincolato correttamente. –

+0

Ho una teiera trasparente! Il blendstate che è apparso nello strumento diagnostico non è uguale a quello che ho configurato nel codice. L'ho spostato nel ciclo di rendering e ora la trasparenza funziona. Mi piacerebbe spostarlo dal ciclo di rendering, ovviamente, ma esaminerò quello successivo. – NSFW