jak-project/docs/scratch/sprite_distort_vu1.txt
Ethan Lafrenais 8ba010ca97
Sprite Distort (#1626)
* [WIP] initial sprite distort implementation

* Clean up

* More clean up + document sprite distort VU program

* Format code

* Address CI issues

* Adjust hacks in distort fragment shader

* oops

* Optimize sprite distort rendering down to one draw call

~2x speed up

* Format file

* Clean up distort rendering and add separate profile scopes

* Fix glVertexAttribPointer

* Fix sprite distort getting messed up when the viewable area doesn't fit the window perfectly

* Add debug option to disable sprite distort

* One evil space to fail CI...

* oops

* Increase sprite-aux-list size when PC_BIG_MEMORY is true

* Address lints
2022-07-08 21:56:38 -04:00

95 lines
5.7 KiB
Plaintext

;; VU memory:
;; 0: GS vertex data (buffer 1)
;; 176: GS vertex data (buffer 2)
;; 352: sinetables.entry[128]
;; 480: sinetables.ientry[9]
;; 489: sinetables.giftag
;; 490: sinetables.color
;; 511: num sprites
;; 512: sprite data
;; Init
lq.xyzw vf01, 489(vi00) | nop ;; Load giftag
lq.xyzw vf05, 490(vi00) | nop ;; Load color
ilw.x vi01, 511(vi00) | nop ;; Load number of sprites
iaddiu vi04, vi00, 0x200 | nop ;; Address of sprite data (512)
iaddi vi02, vi00, 0x0 | nop
;; Loop for each sprite
L1:
ilw.w vi07, 1(vi04) | nop ;; Get sprite.flag
;; The flag represents the 'resolution' of the sprite,
;; which is a circle. The vertices are constructed below
;; by creating "pie-slices" of a circle where the number
;; of slices is the value of flag. In practice, flag
;; can range from 3-11.
ior vi05, vi02, vi00 | nop
ilw.x vi06, 477(vi07) | nop ;; Get ptr to sinetables.entry
;; addr = sinetables.ientry[flag - 3]
;; The smallest value of flag is 3 and 3 + 477 = 480,
;; which is sinetables.ientry.
;; The values in ientry are an index of entry + 352,
;; which gives the address of an entry element.
sqi.xyzw vf01, vi05 | nop ;; Write giftag to GS data
iaddiu vi08, vi07, 0x4000 | nop
iaddiu vi08, vi08, 0x4000 | nop
isw.x vi08, -1(vi05) | nop ;; Set giftag.nloop to flag (number of slices)
lqi.xyzw vf02, vi04 | nop ;; Get sprite.xyz
lqi.xyzw vf03, vi04 | nop ;; Get sprite.st
lqi.xyzw vf04, vi04 | nop ;; Get sprite.rgba
nop | ftoi4.xyzw vf14, vf02
;; Loop the number of times denoted by sprite.flag
;; Here, we build the GS data for a single distort sprite
L2:
lqi.xyzw vf06, vi06 | nop ;; Load 4 sine table vectors
lqi.xyzw vf07, vi06 | nop
lq.xyzw vf08, 0(vi06) | nop
lq.xyzw vf09, 1(vi06) | nop
iaddi vi07, vi07, -0x1 | muly.xyzw vf10, vf06, vf04 ;; Decrement loop count
nop | mulz.xyzw vf11, vf07, vf04 ;; Calculate vertex positions, texture coords, and color
nop | muly.xyzw vf12, vf08, vf04
nop | mulz.xyzw vf13, vf09, vf04
nop | mulx.xyzw vf06, vf06, vf04
nop | mulx.xyzw vf07, vf07, vf04
nop | mulx.xyzw vf08, vf08, vf04
nop | mulx.xyzw vf09, vf09, vf04
nop | add.xyzw vf10, vf10, vf02
nop | add.xyzw vf11, vf11, vf03
nop | add.xyzw vf12, vf12, vf02
nop | add.xyzw vf13, vf13, vf03
nop | add.xyzw vf06, vf06, vf02
nop | add.xyzw vf07, vf07, vf03
nop | add.xyzw vf08, vf08, vf02
nop | add.xyzw vf09, vf09, vf03
nop | ftoi4.xyzw vf10, vf10
nop | ftoi4.xyzw vf12, vf12
nop | ftoi4.xyzw vf06, vf06
nop | ftoi4.xyzw vf08, vf08
sqi.xyzw vf07, vi05 | nop ;; Write the 5 vertexes for this "pie-slice" to GS data
sqi.xyzw vf05, vi05 | nop
sqi.xyzw vf06, vi05 | nop
sqi.xyzw vf09, vi05 | nop
sqi.xyzw vf05, vi05 | nop
sqi.xyzw vf08, vi05 | nop
sqi.xyzw vf11, vi05 | nop
sqi.xyzw vf05, vi05 | nop
sqi.xyzw vf10, vi05 | nop
sqi.xyzw vf13, vi05 | nop
sqi.xyzw vf05, vi05 | nop
sqi.xyzw vf12, vi05 | nop
sqi.xyzw vf03, vi05 | nop
sqi.xyzw vf05, vi05 | nop
ibne vi00, vi07, L2 | nop ;; Repeat for remaining slices
sqi.xyzw vf14, vi05 | nop
;; Finally, tell the GS to draw the current sprite and switch
;; to the other buffer for the next sprite
xgkick vi02 | nop ;; Draw sprite
iaddi vi01, vi01, -0x1 | nop
iaddiu vi03, vi00, 0xb0 | nop ;; Switch buffer
ibne vi00, vi01, L1 | nop ;; Loop for remaining sprites
isub vi02, vi03, vi02 | nop
nop | nop :e
nop | nop