Code moet efficiënter draaien. Dat altijd. En in het maken van dat soort efficiënte code is een compiler in de meeste gevallen rdelijk goed (herleiden doet 'ie best wel erg goed zelfs).
Maar er zijn ook gevalletjes waarvan je denkt: waarom dit nou weer? Daar hoort deze bij:
Ik heb maal alvast de comments erbijgezet, maar wat ik dus doe is diepte (in A) en de genormaliseerde normaal (in RGB) van de pixel opslaan in een speciale Deferred Renderer-achtige buffer voor SSAO.
Dit is een nogal veelvoorkomende actie, dus wilde ik de assembly wel eens zien of er wat te verbeteren viel. Allemaal best helder, behalve regel 10 (regel 10 t/m 12 zijn de uitwerking van normalize() in HLSL).
Maar wat is daar ooit het nut van die dp3? Dat dotproduct levert toch altijd 1 (cos-1(1) = 0 graden verschil) op. Waarom kan die niet gewoon 1 laden in c0.y ofzo?
Laten we toch even aannemen dat r0.x netjes 1 wordt. Dan zal die door rsq veranderen in (wonderbaarlijk) 1: 1/wrtl(1) is natuurlijk ook gewoon 1. Dan de normaal zelf met 1 vermenigvuldigen heeft geen comments nodig.
Dit gaat gewoon nergens over, maar toch krijgt de DX9-compiler het voor mekaar om deze (lijkt me) shite in code te proppen.
Helaas zijn er bar weinig boekjes of tutorials die over assembly van HLSL gaan, wat best wel jammer is.
Maar goed, weet iemand waar dit door komt?
Maar er zijn ook gevalletjes waarvan je denkt: waarom dit nou weer? Daar hoort deze bij:
GAS:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| ps_3_0 // compileprofiel def c0, -0.5, 0, 0, 0 // de te gebruiken constantes dcl_texcoord v0.xyz // normal in view space (TEXCOORD0) dcl_texcoord1 v1.xy // diepte in screen space, zw (TEXCOORD1) dcl_texcoord2 v2.xy // texturecoordinaat (TEXCOORD2) dcl_2d s0 // diffusetex sampler texld r0, v2, s0 // sample de texture gebonden aan s0 op coordinaat v2, sla kleur op in r0 add r0, r0.w, c0.x // aangezien we alleen r0.w nodig hebben, tel bij r0.w -0.5 op en sla weer op in r0 texkill r0 // en skip de texture als dus de alpha minder dan 0.5 is. dp3 r0.x, v0, v0 // doe een dot product tussen normal en normal? wut? dit levert toch altijd 1 op... rsq r0.x, r0.x // neem de inverse wortel, dit levert de lengte van de vector op. En omdat we willen vermenigvuldigen tot [0,1] , nemen we inverse mul oC0.xyz, r0.x, v0 // en vermenigvuldig met 1/lengte zodat vector -> [0,1]. zet neer in RT0.xyz rcp r0.x, v1.y // neem de omgekeerde diepte.w mul oC0.w, r0.x, v1.x // en vermenigvulding diepte.z daarmee (zoals hoort bij Projectie), zet neer in RT0.w |
Ik heb maal alvast de comments erbijgezet, maar wat ik dus doe is diepte (in A) en de genormaliseerde normaal (in RGB) van de pixel opslaan in een speciale Deferred Renderer-achtige buffer voor SSAO.
Dit is een nogal veelvoorkomende actie, dus wilde ik de assembly wel eens zien of er wat te verbeteren viel. Allemaal best helder, behalve regel 10 (regel 10 t/m 12 zijn de uitwerking van normalize() in HLSL).
Maar wat is daar ooit het nut van die dp3? Dat dotproduct levert toch altijd 1 (cos-1(1) = 0 graden verschil) op. Waarom kan die niet gewoon 1 laden in c0.y ofzo?
Laten we toch even aannemen dat r0.x netjes 1 wordt. Dan zal die door rsq veranderen in (wonderbaarlijk) 1: 1/wrtl(1) is natuurlijk ook gewoon 1. Dan de normaal zelf met 1 vermenigvuldigen heeft geen comments nodig.
Dit gaat gewoon nergens over, maar toch krijgt de DX9-compiler het voor mekaar om deze (lijkt me) shite in code te proppen.
Helaas zijn er bar weinig boekjes of tutorials die over assembly van HLSL gaan, wat best wel jammer is.
Maar goed, weet iemand waar dit door komt?