[Direct3D/C#] Gamedesign problemen

Pagina: 1 2 3 Laatste
Acties:
  • 9.046 views sinds 30-01-2008
  • Reageer

Acties:
  • 0 Henk 'm!

  • Mischa_NL
  • Registratie: Mei 2004
  • Laatst online: 01-02-2023
Na het bouwen van globale planetaire ringen ga ik nu beginnen aan het maken van de ringen als je jezelf erin bevind. Dit alles alá Infinity: The Quest for Earth. Ik heb al het een en ander doorgedacht maar een aantal dingen kom ik niet aan uit:

De ringen hangen om een planeet in en bestaan uit een 2d disc-vormige mesh. De mesh heeft een start punt vanaf het centrum van de planeet en daarnaast een diameter van de ring. totale diameter van de ene naar de andere kant van de mesh is dus: (start + diameter) * 2.
Nu wil ik als LOD systeem gebruik maken van een octree, omdat het een 3d veld betreft. De 2d mesh van de ring is goed genoeg omdat die dikte slechts een paar kilometer is. Kom je dichterbij dan geven de daadwerkelijke asteroiden-meshes het volume.
Het octree-centre komt dus op de plek van het centrum van de planeet, en heeft het de hele ring erin zitten. Ik subdivide de tree op basis van afstand tot een octree node, en deze tree heeft een fixed aantal levels (bv: max 10). Hoe dieper je komt hoe kleiner de extra gespawnde asteroiden worden: dieperin de ring -> meer detail!
De octree zorgt op deze manier dus voor LOD, omdat de 100.000en asteroiden nooit allemaal tegelijk te renderen zijn.

Het spawnen van de asteroiden is echter het probleem. Ik wil graag dat de asteroiden daadwerkelijk aan de hand van tijd op een bepaalde plek te vinden zijn. Een 'random' seed gaat dus niet werken. Als ik 1 asteroide rood maak dan wil ik kunnen uitrekenen waar deze zich op een gesteld tijdstip bevind! Het probleem is: hoe weet ik zonder dat ik de snelheid etc van de asteroid heb, in welk deel van de octree deze zich bevind!?

* Eerst had ik het idee om de gehele octree een draaiing mee te geven. Probleem hierbij is dat dan elke asteroide met dezelfde snelheid beweegt. Dit is iets wat ik zeker niet wil, omdat het geen realistisch beeld gaat geven.

En dit is waar ik vast zit:

* De planetaire ring heeft geen fixed aantal asteroiden, waarschijnlijk is de enige oplossing om een ´max´ aantal stenen per compleet octree level te geven en te zorgen dat dit altijd dezelfde asteroiden worden, adhv een pseudo/random nummer.
* probleem hierbij is: hoe kan ik weten dat als ik aan de hand van een pseudo-random nummer een asteroide genereer, dat deze zich daadwerkelijk binnen de bound van de octree bevind?
* Updaten: hoe update ik deze tree? Voor elke steen iedere frame/paar frames kijken of ze zich nog in de bounds bevinden: if not->kill asteroid.

Ik zal vast veel te moeilijk denken bij dit probleem...

Acties:
  • 0 Henk 'm!

  • Mischa_NL
  • Registratie: Mei 2004
  • Laatst online: 01-02-2023
Toch weer maar een keer een update, met wat vragen erbij...

Zo ongeveer een complete rewrite verder is er wel het een en ander veranderd. Normal mapping heeft een hogere resolutie dan de geometry.
Verder maak ik niet langer gebruik van instancing ivm precisie op de gpu.
Daarnaast zijn normal maps nu (toch!) in tangent space.

Alle maps worden op de gpu gegenereerd. Dat wil zeggen per patch: geometry map, normal map en diffuse map. normals en diffuse op 8X resolutie in low orbit en 32(!) in high orbit.

Afbeeldingslocatie: http://j.imagehost.org/t/0695/planeetwolken.jpg
Afbeeldingslocatie: http://j.imagehost.org/t/0564/globalview.jpg

Verder heb ik nog steeds problemen met precisie op de gpu. Patches liggen tussen -1 en 1, en op die manier haal ik dus maximale precisie uit mijn floats. Toch heb ik helaas niet genoeg. bij diepere levels (+18) is het duidelijk dat de precisie in de noise functie op de gpu op is... Ik vraag me nog steeds af hoe ik dit ooit kan gaan fixxen...
Is het mogelijk om 2d perlin noise te 'tilen'? ik kan hier eigenlijk niet echt duidelijk een antwoord op vinden.
Zo ja kan ik de kleine details dmv een tileable map opleuken, en nog dieper dmv een normal map die correspondeert met de detail texture.

Nog enkele pictures in low orbit / ground level:
Afbeeldingslocatie: http://j.imagehost.org/t/0448/bergen.jpg
Afbeeldingslocatie: http://j.imagehost.org/t/0866/sunset.jpg
Afbeeldingslocatie: http://j.imagehost.org/t/0656/planeet_met_gras.jpg

Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
Mischa_NL schreef op maandag 03 mei 2010 @ 23:44:

Is het mogelijk om 2d perlin noise te 'tilen'? ik kan hier eigenlijk niet echt duidelijk een antwoord op vinden.
Zo ja kan ik de kleine details dmv een tileable map opleuken, en nog dieper dmv een normal map die correspondeert met de detail texture.
Gegeven een noise-functie (of in mijn geval een noise-texture) werkte deze functie bij mij prima on de noise te tilen. Als je de noise op de GPU genereert kun je de tex2D aanroepen gewoon vervangen voor de noise-functie met de bijbehorende xy/uv coordinaten.

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
float tiledNoise(sampler2D noise, float2 uv, float2 scale){
    float w = scale.x;
    float h = scale.y;
    
    uv = fmod(uv, scale);
    
    float t = (
        tex2D(noise, uv)                         * (w - uv.x) * (h - uv.y) +
        tex2D(noise, float2(uv.x - w, uv.y))     * uv.x       * (h - uv.y) +
        tex2D(noise, float2(uv.x - w, uv.y - h)) * uv.x       * uv.y +
        tex2D(noise, float2(uv.x, uv.y - h))     * (w - uv.x) * uv.y
    ) / (w*h);
    
    return t;
}

[ Voor 6% gewijzigd door PrisonerOfPain op 04-05-2010 01:45 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Wat natuurlijk gewoon een bilinear filter is :). Overigens wil je nog steeds zorgen dat je uv coordinaten rond de 0/1 liggen.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Mischa_NL
  • Registratie: Mei 2004
  • Laatst online: 01-02-2023
.oisyn schreef op dinsdag 04 mei 2010 @ 11:42:
Wat natuurlijk gewoon een bilinear filter is :). Overigens wil je nog steeds zorgen dat je uv coordinaten rond de 0/1 liggen.
Ik ben aan het proberen geweest om na een bepaalde diepte in de tree niks nieuws meer te genereren maar heightmaps van parents te samplen en deze linear te filteren. Klopt echter niet aan de randen. point filter werkt perfect. Dit is zeker omdat linear filteren aan de rand niet correct gebeurd? moet ik een extra pixel toevoegen?

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Je hoeft geen extra pixel toe te voegen, maar je moet wel samplen tot aan de buitenste pixelcentra van de texture en niet verder. Ik weet even alleen niet uit m'n hoofd op het centrum van 1 texel nou op (0, 0) of op (0.5, 0.5) ligt. Wel dat DirectX voor framebuffers (schrijven) het ene gebruikt en voor textures (lezen) het andere 8)7.

.edit: volgens mij liggen texel centra gewoon in het midden. Als je map 32 pixels groot is, dan wil je dus ook maar samplen tussen 0.5/32 en 31.5/32 ipv tussen 0 en 1.

[ Voor 20% gewijzigd door .oisyn op 05-05-2010 02:10 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Mischa_NL
  • Registratie: Mei 2004
  • Laatst online: 01-02-2023
.oisyn schreef op woensdag 05 mei 2010 @ 02:05:
Je hoeft geen extra pixel toe te voegen, maar je moet wel samplen tot aan de buitenste pixelcentra van de texture en niet verder. Ik weet even alleen niet uit m'n hoofd op het centrum van 1 texel nou op (0, 0) of op (0.5, 0.5) ligt. Wel dat DirectX voor framebuffers (schrijven) het ene gebruikt en voor textures (lezen) het andere 8)7.

.edit: volgens mij liggen texel centra gewoon in het midden. Als je map 32 pixels groot is, dan wil je dus ook maar samplen tussen 0.5/32 en 31.5/32 ipv tussen 0 en 1.
Geprobeerd inderdaad. in de VS map ik de position als volgt:
code:
1
2
3
4
5
6
7
8
9
10
11
    // Half pixel offset for correct texel centering.
    In.position.xy -= 0.5;
    
    // Viewport adjustment.
    In.position.xy /= ViewportSize;
            
    In.position.xy *= float2(2, -2);
    In.position.xy -= float2(1, -1);
    
    Out.position = float4(In.position.xy,1,1);
    Out.TexCoord = In.Tex;


position word dan: [-1, 1] + halfpixel.
texcoords zijn [0-1].

Het leek me dat dit dan correct moet zijn, maar om de een of andere reden is het dat niet...

Moet ik wellicht de position [-1,1] houden en texcoords [0+halfpixel, 1 - halfpixel maken] ?

Ik zal eens gaan proberen!

Acties:
  • 0 Henk 'm!

  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
Ja je moet de texcoords aanpassen en niet de posities

ex-FE Programmer: CMR:DiRT2,DiRT 3, DiRT Showdown, GRID 2, Mad Max


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Feitelijk maakt dat niet zoveel uit. Wat je uiteindelijk wilt bewerkstelligen is dat de samplepunten waarop voor de pixels in de framebuffer de pixelshaders worden uitgevoerd uitgelijnd zijn met de samplepunten van je texture fetches. Dus ofwel je schuift je fetches op, ofwel je positie met tegengestelde richting.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Mischa_NL
  • Registratie: Mei 2004
  • Laatst online: 01-02-2023
.oisyn schreef op woensdag 05 mei 2010 @ 17:17:
Feitelijk maakt dat niet zoveel uit. Wat je uiteindelijk wilt bewerkstelligen is dat de samplepunten waarop voor de pixels in de framebuffer de pixelshaders worden uitgevoerd uitgelijnd zijn met de samplepunten van je texture fetches. Dus ofwel je schuift je fetches op, ofwel je positie met tegengestelde richting.
Dat vermoedde ik al inderdaad... Toch doet linear filtering om de een of andere reden niet wat ik wil. Wellicht een bug ergens anders in mijn code. ik ga op zoek!

Acties:
  • 0 Henk 'm!

  • Mischa_NL
  • Registratie: Mei 2004
  • Laatst online: 01-02-2023
Toch heb ik nog een vraag mbt pixel texel mapping!

Wat ik ervan begrijp is dat als je rendered in screenspace (dus RTT, dmv een quad) dat je dan de texture coordinaten moet aanpassen OF de positie coordinaten.

Dat wordt dan:
code:
1
2
3
4
5
//pos
new Vector2(-1 - half, 1 + half), new Vector2(1 - half, -1 + half),

//of voor tex
new Vector2(-1 + half, 1 - half), new Vector2(1 + half, -1 - half),


Nou denk ik dat ik het begrijp: als ik deze offset pak en bv een texture lookup doe, dan kloppen nu de coordinaten met de pixels.

Echter wat nou als ik de tCoords niet gebruik voor een TexLookup maar als input voor een noise functie?!
Dan klopt ineens die positie niet meer omdat tcoord = 0 niet geld voor pixel = 0, maar voor pixel = -0.5...

Verander ik dit vervolgens dan klopt het NOG niet... Ik snap er werkelijk niets meer van en google helpt me ook al niet!

Effectief de vraag:

Wanneer moet ik die halve pixel shiften? Moet dat ALTIJD als ik in screen space render? Of moet dit alleen als ik in deze rendering een texture lookup doe uit een andere texture?

Ik krijg de coordinaten op geen enkele manier perfect gematched 8)7

topic titel zou wel gewijzigd mogen worden opzich. Of nieuw topic aanmaken?

[ Voor 3% gewijzigd door Mischa_NL op 20-05-2010 21:54 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Waar het om gaat is wanneer je pixelshader wordt uitgevoerd. Laten we voor het gemak even denken in hele coordinaten (dus een 16 texels brede texture loopt van 0 tot 16, en eveneens zo voor de framebuffer). Als jij een quad tekent van (0, 0) tot (16, 16) dan runt je pixelshader voor elk hele coordinaat in DX9. Dus x=0, x=1, x=2, etc., t/m x=15. Gebruik je ook bijbehorende texturecoordinaten van (0, 0) tot (16, 16), dan worden die ook gewoon geinterpoleerd van 0 tot 16, wat betekent dat je bij x=0 ook u=0 hebt, en bij x=1 ook u=1, etc.

Het probleem is echter, als jij precies de texel linksboven in het texture wilt samplen, dan heb je (0.5, 0.5) als coordinaat nodig. Echter, de geinterpoleerde texture-coordinaat is bij de eerste pixel (0, 0). Schuif je je texture coordinaten naar rechtsonder - dus de texturecoordinaten van de quad lopen van (0.5, 0.5) tot (16.5, 16.5). En nu ik dit opschrijf besef ik me ook ineens waar de fout vandaan komt, zie jij 'm ook? Ja, dat was 16.5, en niet 15.5, zoals ik in mijn originele post suggereerde. Natuurlijk, de laatste sample, x=15, zal een u=15.5 hebben. Maar je quad loopt tot 16 (of minder, als het maar meer is dan 15), dus moet je texture ook zo ver doorlopen anders wordt hij gestretcht. Een andere optie is natuurlijk om je quad een halve pixel naar linksboven te bewegen, zoals je eerder al geprobeerd had.

Maar goed, dat geldt dus voor texture sampling. Wat jij voor je noise generator nodig hebt ligt natuurlijk aan je eigen wensen. De vraag die je moet stellen is: waar ligt precies het linkerbovenste noise sample, op (0, 0) of op (0.5, 0.5)?

Zie ook http://msdn.microsoft.com/en-us/library/bb219690(VS.85).aspx.
(Let er trouwens wel op dat dit met D3D10 veranderd is - daar wordt een pixel in de framebuffer wel op (0.5, 0.5) gesampled, zoals in OpenGL)

[ Voor 10% gewijzigd door .oisyn op 21-05-2010 00:39 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1 2 3 Laatste