Sto implementando un esempio di shadow volume, e sto quindi trovalo la
silhouette dell'oggetto interessato.
Per farlo, servono necessariamente le adiacenze dell'oggetto, e passarle al
device come PRIMITIVE TOPOLOGY
Ho letto su internet che le adiacenze si generano in qualche modo e si
inseriscono nello stesso index buffer della mesh interessata.
Sapete come procedere?
Dai un'occhiata a questo demo:
http://http.download.nvidia.com/developer/SDK/Individual_Samples/samples.html#infinite_shadow_volumes
c'è tutto il sorgente e la spiegazione tecnica su come creare
correttamente le ombre con gli Shadow Volumes.
Spero possa esserti utile :)
Davide
Avendo un array di UINT, contententi dei numeri interi, ove ogni 3 numeri
interi formano un triangolo, dovrei elaborare un algoritmo che trovi le
adiacenze del triangolo.
Un triangolo è adiacente ad un altro se hanno almeno un lato in comune.
Ogni triangolo ha massimo 3 adiacenze.
http://tinyurl.com/6yhpwb
Dovrei quini cercare, per ogni tripla di indici, un'altra tripla che
condivide almeno 2 indici.
Le dimensioni del buffer (già si sa), dovranno raddoppiare per conterene i
nuovi dati.
Altra cosa pallosa è il contenere i dati nuovi.
Guardando l'immagine sopra, i dati dovranno essere contenuti in modo che, in
ogni 6 posizioni dell'array, nelle posizioni pari ci siano i vertici
originali del triangolo, nei dispari i 3 vertici delle adiacenze.
Io ci sto proprio perdendo la testa, ho abbozzato una specie di ciclo, ma
non so proprio cosa scrivere dentro....
Avede un'idea anche solo teorica di come risolvere questo problema?
"Mim-R" <roma...@email.it> ha scritto nel messaggio
news:4864b10a$0$18155$4faf...@reader3.news.tin.it...
Si presuppone che tu abbia gia' vertici condivisi. In tal caso, la
soluzione di forza bruta, e' un loop che crea gli spigoli (o edges)
controllando ogni triangolo con ogni altro triangolo per vedere se ci
sono spigoli in comune.
Si ha uno spigolo in comune quando due triangoli condividono due
vertici.
In realta' questa e' solo una ottimizzazione (importante) perche'
altrimenti si potrebbe estrudere il volume di ogni triangolo con la
sorgente di luce ed ottenere comunque il giusto risultato.
Occhio anche alla costruzione del volume di ombra. Non basta avere gli
spigoli ma bisogna usare il giusto orientamento. Quindi per ogni
spigolo bisogna tenere conto del verso che cambia a seconda del
triangolo (uno dei due possibili) in considerazione.
bauuuuu
Davide
void CMesh::G()
{
ID3DX10Mesh *m;
ID3D10Device *device;
D3D10_BUFFER_DESC desc;
ID3DX10MeshBuffer *MeshBuffer;
this->MeshData.ColladaBuffer.IndexBuffer->GetDevice(&device);
this->MeshData.ColladaBuffer.VertexBuffer->GetDesc(&desc);
UINT vertici = desc.ByteWidth / this->MeshData.Stride;
D3D10_INPUT_ELEMENT_DESC el[ =
{
{"POSITION",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,D3D10_APPEND_ALIGNED_ELEMENT,D3D10_INPUT_PER_VERTEX_DATA,0
},
{"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,D3D10_APPEND_ALIGNED_ELEMENT,D3D10_INPUT_PER_VERTEX_DATA,0
},
{"TEXCOORD",0,DXGI_FORMAT_R32G32B32_FLOAT,0,D3D10_APPEND_ALIGNED_ELEMENT,D3D10_INPUT_PER_VERTEX_DATA,0
},
};
D3DX10CreateMesh(device,el,3,"POSITION",vertici,this->MeshData.ColladaBuffer.Indici/3,0,&m); m->SetIndexData(this->MeshData.Indices,this->MeshData.ColladaBuffer.Indici); m->GenerateAdjacencyAndPointReps(0.0001f); m->GenerateGSAdjacency(); m->GetIndexBuffer(&MeshBuffer); unsigned int IBsize = MeshBuffer->GetSize(); void *tmp; UINT *indici = new UINT[IBsize]; MeshBuffer->Map((void**)&tmp,0); memcpy(indici,tmp,IBsize); MeshBuffer->Unmap(); MeshBuffer->Release(); m->GetAdjacencyBuffer(&MeshBuffer); unsigned int ABsize = MeshBuffer->GetSize(); UINT *adj = new UINT[ABsize]; MeshBuffer->Map((void**)&tmp,0); memcpy(adj,tmp,ABsize); MeshBuffer->Unmap(); MeshBuffer->Release(); m->Release();#if 0 char tmp3[10]; FILE *fil3 = fopen("IndexBufferConAdiacenzeDaD3DX.txt","w"); int t = IBsize / sizeof(UINT); for (int i = 0; i < t;i++) { sprintf(tmp3,"%d",indici[i]); fwrite(tmp3,1,strlen(tmp3),fil3); fwrite(" \n",1,strlen(" \n"),fil3); } fclose(fil3); fil3 = fopen("BufferAdiacenzeDaD3DX.txt","w"); t = ABsize / sizeof(UINT); for (int i = 0; i < t;i++) { sprintf(tmp3,"%d",adj[i]); fwrite(tmp3,1,strlen(tmp3),fil3); fwrite(" \n",1,strlen(" \n"),fil3); } fclose(fil3);#endif this->MeshData.ColladaBuffer.IndexBuffer->Release(); desc.BindFlags = D3D10_BIND_INDEX_BUFFER; desc.CPUAccessFlags = 0; desc.Usage = D3D10_USAGE_DEFAULT; desc.MiscFlags = 0; desc.ByteWidth = IBsize; D3D10_SUBRESOURCE_DATA init; init.pSysMem = indici; device->CreateBuffer(&desc,&init,&this->MeshData.ColladaBuffer.IndexBuffer); delete[ indici; delete[ adj;}Viene renderizzato tutto bene, ma quando cerco di trovare la silhouettedella mesh interessata, non esce propio un bel niente."Davide Pasca" <dpa...@gmail.com> ha scritto nel messaggionews:b19debc0-7e96-46ad...@h1g2000prh.googlegroups.com...On Jun 28, 9:31 pm, "Mim-R" <romand...@email.it> wrote:> Riporto comunqnue qualche altra info>> Avendo un array di UINT, contententi dei numeri interi, ove ogni 3 numeri> interi formano un triangolo, dovrei elaborare un algoritmo che trovi le> adiacenze del triangolo.> Un triangolo è adiacente ad un altro se hanno almeno un lato in comune.[...]Si presuppone che tu abbia gia' vertici condivisi. In tal caso, lasoluzione di forza bruta, e' un loop che crea gli spigoli (o edges)controllando ogni triangolo con ogni altro triangolo per vedere se cisono spigoli in comune.Si ha uno spigolo in comune quando due triangoli condividono duevertici.In realta' questa e' solo una ottimizzazione (importante) perche'altrimenti si potrebbe estrudere il volume di ogni triangolo con lasorgente di luce ed ottenere comunque il giusto risultato.Occhio anche alla costruzione del volume di ombra. Non basta avere glispigoli ma bisogna usare il giusto orientamento. Quindi per ognispigolo bisogna tenere conto del verso che cambia a seconda deltriangolo (uno dei due possibili) in considerazione.bauuuuuDavide
http://rafb.net/p/wXobit22.html
"Mim-R" <roma...@email.it> ha scritto nel messaggio
news:4868aecf$0$35961$4faf...@reader2.news.tin.it...
..io parlo di 3D tu parli di arrangiarsi con Direct 3D e proponi il
solito pezzone di codice 8)
Se sei serio con la grafica, butta Direct3DXXX al cesso e fai le cose
a mano, usare D3DX10CreateMesh() e' da femminucce ;)
bauuuuuuuu
Davide
"Davide Pasca" <dpa...@gmail.com> ha scritto nel messaggio
news:c1fa7867-7c40-4120...@z24g2000prf.googlegroups.com...
Congratulazioni 8)
bauuuuuuu
Davide
Sto seguendo questo procedimento
Abilito il DepthBuffer e non lo Stencil
Disegno la geometria originale.
Disabilito il DepthBuffer write (si fa mettendo maschera a 0 vero?), ma non
il DepthTest
Tolgo il blending e disabilito il writing sul frame buffer
Abilito lo stencil, funzione ALWAYS così il pixel passa sempre
Metto CULL MODE = NULL per renderizzare tutto
Se Frontface aumenta lo stencil ref (passato a 0)
se Back face diminuisci lo stencil ref.
Ora viene il turno di fare il quadrato e buttarlo sopra, ma oltre alla
maschera stencil dicono di fare un additive blending.
Ma che cazzo è?
Ad ogni modo rimetto il cull a posto e disabilito il blending, e l'ombra fa
schifo.
Come dovrei fare?
> Ora viene il turno di fare il quadrato e buttarlo sopra, ma oltre alla
> maschera stencil dicono di fare un additive blending.
> Ma che cazzo è?
> Ad ogni modo rimetto il cull a posto e disabilito il blending, e l'ombra fa
> schifo.
> Come dovrei fare?
L'additive blending e' quello che somma i valori rgb che disegni a
quelli gia' esistenti nel frame buffer in corso di rendering... pero'
mi suona strano che si usi quello: non ho mai implementato questo
genere di ombre anche se lo vorrei fare, e da quel che posso
immaginare il blending e' il classico "alpha*src+(1-alpha)*dst".
Cosa vuol dire che l'ombra fa schifo?
________________________
Matteo
http://fuzzware.altervista.org
"A man with a new idea is a crank until the idea succeds" - M. Twain
http://img301.imageshack.us/img301/8916/47063122vw7.jpg
Se faccio ruotare la sorgente della luce arriva ad un punto che l'ombra
scompare proprio.
"Matteo Perenzoni" <teo...@inwind.it> ha scritto nel messaggio
news:4b831077-f603-445d...@w7g2000hsa.googlegroups.com...
On Jul 3, 11:48 pm, "Mim-R" <romand...@email.it> wrote:
> Ora viene il turno di fare il quadrato e buttarlo sopra, ma oltre alla
> maschera stencil dicono di fare un additive blending.
> Ma che cazzo č?
"Mim-R" <roma...@email.it> ha scritto nel messaggio
news:486e27c3$0$40314$4faf...@reader5.news.tin.it...
Guardate poi se faccio ruotare la luce, ad un certo punto
http://img57.imageshack.us/img57/9418/75221236es3.jpg
Il cubo diventa nero improvvisamente e troppo di scatto (come se l'ombra
venisse renerizzata sul cubo stesso, difatti dell'ombra poco rimane).
Sto forse cadendo nel DepthFail di Carmack?
"Matteo Perenzoni" <teo...@inwind.it> ha scritto nel messaggio
news:f2e998ff-9519-4928...@y38g2000hsy.googlegroups.com...
Ciao, ho visto quello che stai facendo, ed anche se ultimamente non mi sto
occupando di queste cose penso di poterti dare qualche dritta che potrebbe
facilitarti il debug. Il consiglio di iniziare analizzando un oggetto più
semplice te lo hanno già dato, però più che il cubo ti consiglio di provare
utilizzando una sfera. In secondo luogo (anche per capire se l'errore è nel
settaggio delle maschere o nell'algoritmo) dovresti visualizzare con una
semplice texture una porzione di piano dove stai effettuando la proiezione
ed il wireframe dei volumi creati in modo da ottenere un'immagine del
genere:
Se ti consiglio di usare una sfera è perchè con questa tecnica dovresti
visualizzare un volume di proiezione perfettamente conico come vedi
nell'immagine di destra.
> Forse l'additive blending serve a renderlo piu'...ombroso?
Non c'entra molto. Il blending di tipo additivo costruisce il colore del
pixel da scrivere nell'immagine di destinazione usando questa formula dst =
dst + src, cioè non fa altro che sommare sorgente e destinazione. La
maschera che utilizzi per le ombre di solito è nera (0.0f) dove non esistono
le ombre ed è totalmente bianca (1.0f) dove esistono, quindi se utilizzassi
il blending di tipo additivo otterresti il colore bianco in presenza delle
ombre e non il nero (o viceversa se hai la maschera a colori invertiti, in
ogni caso avresti il bianco che non è corretto).
Come ti hanno già consigliato potresti risolvere usando un tipo di blending
in cui l'immagine di destinazione è uguale a se stessa moltiplicato
l'immagine che contiene le ombre, che farebbe pensare ad un uso di alpha
blending la cui formula è data da dst = dst * (1-alpha) + src * alpha, però
in questo caso dovresti usare un'immagine di destinazione completamente nera
(perchè le ombre sono nere) ed un'immagine di alpha channel pari alla
maschera delle ombre. E' più dispendioso e te lo consiglio solo nel caso in
cui volessi conferire un colore particolare ad un tipo di ombra.
Per ombre completamente nere puoi usare la seguente formula di blending: dst
= dst * src. Adesso non mi ricordo come funziona per le direct, ma
solitamente dovrebbe esistere uno scale factor per il colore di sorgente ed
un altro per quello di destinazione, quindi devi impostare a zero lo scale
factor del colore di sorgente e fare in modo che il colore di destinazione
abbia uno scale factor pari al colore di sorgente (in modo da effettuare la
moltiplicazione). Bada che adesso la maschera deve avere colori invertiti
rispetto a prima, cioè nero-ombre e bianco-ovunque, oppure setti
diversamente lo scale factor, dipende da te. Qualsiasi cosa tu decida
ricorda che la formula di blending è data da dst = (src * sfactor) + (dst *
dfactor). Se non sbaglio nelle direct si chiama blend factor e lo puoi
settare tramite i render state type di tipo D3DRS_SRCBLEND e
D3DRS_DESTBLEND.
Gianpaolo Ingegneri.
www.texturemind.com
Ho fatto una scena un pò piu' normale (scusate se è penosa, ma non ho ancora
un
framework decente, scrivo in D3D10 "pure")
http://img61.imageshack.us/img61/4351/img3bu3.jpg
Questa è l'ombra completa (che non funziona)
Questa è la cosa che non mi convince
http://img378.imageshack.us/img378/3286/img2vs0.jpg
Questo è il wireframe dello shadow volume (che mi sembra a posto)
http://img378.imageshack.us/img378/2936/imgvx1.jpg
"Gianpaolo Ingegneri" <in...@tmind.com> ha scritto nel messaggio
news:486f242a$0$29976$5fc...@news.tiscali.it...
Dato che le Adiacenze non sapevo generarle, ho fatto un algoritmo che mette
il mio index buffer in una D3DX10Mesh, e chiamo una funzione apposita
chiamata GenerateGSAdjacency.
In seguito ho comunque sviluppato una versione del mio algoritmo, che sembra
però lavorare anche meglio.
Vedete già lo shadow volume è piu' "pulito" rispetto al precedente
http://img364.imageshack.us/img364/2340/imgqq9.jpg
http://img391.imageshack.us/img391/8060/img2uf1.jpg
http://img364.imageshack.us/img364/1051/img3mr5.jpg
"Gianpaolo Ingegneri" <in...@tmind.com> ha scritto nel messaggio
news:486f242a$0$29976$5fc...@news.tiscali.it...
Da quello che vedo mi sembra il risultato negativo sia dovuto alla presenza
di poligoni inutili all'interno dello shadow volume. Ho visto anche il
secondo messaggio ed il buffer č piů pulito come dici tu perchč i poligoni
interni sembrano essere scomparsi. Comunque devi migliorare l'algoritmo per
le adiacenze, č sicuramente lě che si annidano i difetti. Se puň esserti
utile ho trovato il seguente demo:
http://rainwarrior.thenoos.net/dragon/effects.zip
http://rainwarrior.thenoos.net/dragon/effects.html
cliccando V puoi vedere in tempo reale il wireframe di uno shadow volume
praticamente perfetto. Inoltre ti consiglio di fare attenzione a questa
parte dell'articolo:
"The egde between them is the silhouette edge, which must now connect to a
second set of points that is the silhouette edge projected to infinity (in
practice either the near or far clipping plane). Finding this edge can be
computationally expensive, but there is a way to quickly approximate the
shape of a shadow volume using the vertex shader. Simply using the normal at
any particular vertex we can determine if that vertex faces the light, and
if it does not, project it onto the near or far clipping plane."
sembra che tu debba usare una ben precisa tecnica per poter implementare gli
shader ed ottenere il risultato migliore (che non significa ancorarsi alle
direct: puoi implementare quel modello e specializzarlo eventualmente per
gli shader, se č tuo interesse).
Gianpaolo Ingegneri
www.texturemind.com
mi sembra di essere arrivato ad un vicolo cieco :(
"Gianpaolo Ingegneri" <in...@tmind.com> ha scritto nel messaggio
news:486f61dc$0$17943$5fc...@news.tiscali.it...
"Gianpaolo Ingegneri" <in...@tmind.com> ha scritto nel messaggio
news:486f61dc$0$17943$5fc...@news.tiscali.it...