It is currently Sat Dec 16, 2017 1:47 pm

All times are UTC - 7 hours



Forum rules


Related:



Post new topic Reply to topic  [ 295 posts ]  Go to page 1, 2, 3, 4, 5 ... 20  Next
Author Message
PostPosted: Sun Feb 21, 2016 9:56 am 
Online
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3162
Location: Nacogdoches, Texas
I just thought I'd include that in the title as not to mislead anyone. Anyway, thanks to darryl.revok (me misreading the logo :lol: ) and psychopathicteen (the bullet rendering) for the idea.

Anyway, what the plan is that it'll be top down, and there'll be a layer solely devoted to the ink colors. Whenever there's a change in it, (a splat that appears) the tiles where the change occurred are uploaded to vram, but only if it's onscreen. Whenever the screen scrolls, it'll load extra tiles like any other game. The buffer is to be a lot bigger than the screen, and I'd probably need extra ram on the cartridge if I get that far.

This is really pretty incomplete, (I kind of need to know how to code 8x16 multiplication for multiplying the y position with the buffer width at two parts) but I'm not sure how I should do everything. In the process of writing this, I just realized that my idea of having the code look through the whole splat horizontally won't really work, because in the actual thing, it would need to check collisions... I think I'll recode it to where it draws the thing 8x8 block by block. The splat graphics will just have to have a blank tile at the top and bottom. (I'll be drawing blank areas, but whatever. Probably faster to do that than check every 8x1 pixel sliver.) I'll also reorder where the data for the pixels are in them, but I'll keep how I had the mask and the actual pattern the same, where the bytes for both are intertwined. Actually, additionally, if I'm drawing it by every tile, it should be a lot easier to see what tiles I need to upload if the splat appeared onscreen. (Also, I won't need different code for every width of the splat.) I haven't done anything with checking the edges of the buffer when drawing the graphic, and I really kind of wonder how I'll handle the graphic if it starts off the buffer. (If only parts of the splat are visible from the top and left.)

Anyway, it isn't commented right now because I'm feeling lazy (I have to fix it anyway, so I can do it then.) I find it to be pretty easy to follow, but then again, I wrote it, so... :lol:

Code:
  lda SplatRequestTable+YPosition,x
  (Multiply by data per line in buffer. I don't know how.)
  sta SplatPosition

  lda SplatRequestTable+XPosition,x
  ror
  ror
  and #%0011111111111111
  clc
  adc SplatPosition
  sta SplatPosition
  lda SplatRequestTable+XPosition,x
  and #%0000000000000111
  bne continue_calculating_offset
  lda #$0001
  sta SplatBetweenTilesWidth
continue_calculating_offset:
  tay
  lda SplatGraphicOffsetPositionTable,y
  clc SplatRequestTable+GraphicOffset,x
  sta SplatGraphicOffset

  lda SplatRequestTable+Height,x
  (Multiply by data per line in buffer. I don't know how.)
  clc
  adc SplatPosition
  sta EndOfSplat

  lda SplatRequestTable+Width,x
  ror
  ror
  and #%0011111111111111
  sta SplatDataWidth
  lda SplatRequestTable+Width,x
  clc
  adc SplatBetweenTilesWidth
  tay
  jsr (VaryingWidthCodeAddressTable,y)

;======================================================================
start_draw_splat_8_tile:
  ldx SplatPosition
  ldy SplatGraphicOffset

draw_splat_8_tile_loop:
  lda Buffer,x
  and #$0000,y
  ora #$0002,y
  sta Buffer,x

  lda Buffer+16,x
  and #$0004,y
  ora #$0006,y
  sta Buffer+16,x

  lda Buffer+32,x
  and #$0008,y
  ora #$000A,y
  sta Buffer+32,x

  lda Buffer+48,x
  and #$000C,y
  ora #$000E,y
  sta Buffer+48,x

  lda Buffer+64,x
  and #$0010,y
  ora #$0012,y
  sta Buffer+64,x

  lda Buffer+80,x
  and #$0014,y
  ora #$0016,y
  sta Buffer+80,x

  lda Buffer+96,x
  and #$0018,y
  ora #$001A,y
  sta Buffer+96,x

  lda Buffer+112,x
  and #$001C,y
  ora #$001E,y
  sta Buffer+112,x

  cpy EndOfSplat
  bcs continue_draw_splat_8_tile_loop
  (Whatever to get ready for looking at the next splat)

continue_draw_splat_8_tile_loop:
  inx
  inx
  tya
  clc
  adc SplatDataWidth
  tay

  bra draw_splat_8_tile_loop


Top
 Profile  
 
PostPosted: Sun Feb 21, 2016 10:17 am 
Online

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19352
Location: NE Indiana, USA (NTSC)
Espozo wrote:
The buffer is to be a lot bigger than the screen

How large do you expect it to be? And at pixel resolution, or would something coarser do?


Top
 Profile  
 
PostPosted: Sun Feb 21, 2016 11:00 am 
Online
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3162
Location: Nacogdoches, Texas
It's to be screen resolution. I looked at 2x2, but it looks like crap, and trying to use some sort of algorithm to smoothen the edges takes too much CPU time.


Top
 Profile  
 
PostPosted: Sun Feb 21, 2016 11:13 am 
Online

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19352
Location: NE Indiana, USA (NTSC)
How large do you expect the buffer at screen resolution to be?


Top
 Profile  
 
PostPosted: Sun Feb 21, 2016 11:34 am 
Online
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3162
Location: Nacogdoches, Texas
Well, the characters are probably going to be about 32x32, and the maps would probably be about the size of the ones in the actual game (If they aren't to be straight up copies, but you'd have to deal with depth then)

Image

and on this same map, you're this size:

Image

So pretty big.


Top
 Profile  
 
PostPosted: Sun Feb 21, 2016 2:30 pm 
Offline
User avatar

Joined: Sun Dec 13, 2009 11:37 am
Posts: 209
Location: Wisconsin
if your characters are going to be that large, why not use 8x8 predefined tiles for the ink splatter? (no ink, team A ink, team B ink).

Use solid ink on the inside of the spray shape and draw rounded corner edge pieces depending on its neighboring tile values.

Code:
........
...CC...
..CSSC..
..SSSS..
..CSSC..


S = known solid ink tiles, C = check when drawing, as in look it its neighbors to determine the tile number for an appropriate rounded edge. When drawing, optimize to avoid redundant checking of neighboring cells multiple times.

end result:
Code:
........
...__...
../OO\..
..OOOO..
..\OO/..



For example, look at an overhead map view in a traditional JRPG, and notice how the water coastline and land transition has rounded, stylized tiles. Or how forest tiles have rounded edges at the transition to grass tiles so as to make more of a blob of forest instead of strictly square edges.

i have a feeling splatoon itself is using a floor grid and is marking each cell either ink color (or none) and picking a texture based on neighbors and its own saturation value. For "immersion" sake, it draws the walls in finer grained per-pixel splatter textures. But walls don't count toward the end score.


Top
 Profile  
 
PostPosted: Sun Feb 21, 2016 3:02 pm 
Online

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19352
Location: NE Indiana, USA (NTSC)
whicker wrote:
i have a feeling splatoon itself is using a floor grid and is marking each cell either ink color (or none) and picking a texture based on neighbors and its own saturation value. For "immersion" sake, it draws the walls in finer grained per-pixel splatter textures. But walls don't count toward the end score.

Grass wear in Animal Crossing: City Folk operates similarly.


Top
 Profile  
 
PostPosted: Sun Feb 21, 2016 3:15 pm 
Online
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3162
Location: Nacogdoches, Texas
whicker wrote:
if your characters are going to be that large, why not use 8x8 predefined tiles for the ink splatter? (no ink, team A ink, team B ink).Use solid ink on the inside of the spray shape and draw rounded corner edge pieces depending on its neighboring tile values.

I understand the concept, but I don't think it possible for you to have a pattern this random looking that way:

Image

I don't have a clue how they have enough memory though to cover every surface if it were the way I described though

I could always join a Splatoon fansite or something and ask if anyone knows how it's rendered if it's that big of a deal.

I'm trying to fix my code, but it's melting my brain... :lol:


Top
 Profile  
 
PostPosted: Sun Feb 21, 2016 3:19 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5899
Location: Canada
The actual resolution of the "blue or orange" texture map is a lot lower than the visual rendering of it.

It takes a sample from the low resolution map, adds some spatially-stable noise to it (i.e. always the same noise in the same world coordinates), and then takes a threshold to decide whether to render that pixel blue or orange.


Top
 Profile  
 
PostPosted: Sun Feb 21, 2016 3:34 pm 
Online
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3162
Location: Nacogdoches, Texas
rainwarrior wrote:
It takes a sample from the low resolution map, adds some spatially-stable noise to it (i.e. always the same noise in the same world coordinates), and then takes a threshold to decide whether to render that pixel blue or orange.

You're saying it gets a low map, blows it up (by like a bilinear filtering sort of deal) and then it does what? This seems like it's more for taking less memory than for speed (which I guess partially explains why the game is only 720p and no anti-aliasing when the geometry is so simple) but I'd rather this run fast and have extra memory, even if it is "cheating".

Wait, how did you even know that?


Top
 Profile  
 
PostPosted: Sun Feb 21, 2016 3:41 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5899
Location: Canada
Yes, bilinear filtering on the low res texture. Then, to add fake visual detail, you layer noise on top of it. Finally, to create sharp edges you apply a threshold.

This process should not be particularly expensive for a pixel shader to do. I don't think it's a tradeoff for rendering speed at all. The gameplay map is low res to conserve memory, and most importantly to conserve network bandwidth, not rendering time.

low res map = less data to send over the network = more responsive netplay

Espozo wrote:
Wait, how did you even know that?

It's an educated guess. I did 3D graphics programming for a living before I quit to work on my NES game.


Top
 Profile  
 
PostPosted: Sun Feb 21, 2016 4:00 pm 
Online
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3162
Location: Nacogdoches, Texas
rainwarrior wrote:
Then, to add fake visual detail, you layer noise on top of it.

You mean like gray if the two colors were to be white and black?

rainwarrior wrote:
Finally, to create sharp edges you apply a threshold.

What does that mean?

rainwarrior wrote:
This process should not be particularly expensive for a pixel shader to do.

It would be for s console without one, which is the deal...

rainwarrior wrote:
more responsive netplay

A second less responsible, and it would be unplayable. The lag is already the worst part the game. You'd have thought they'd base the gameplay a little more around the fact that there's a good amount of lag anytime by giving you more health or something so you don't just magically explode after just meeting someone.


Top
 Profile  
 
PostPosted: Sun Feb 21, 2016 4:33 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5899
Location: Canada
I'll just try to explain visually:

Attachment:
ink_demo.png
ink_demo.png [ 70.62 KiB | Viewed 2873 times ]


1. Low res ink map.
2. Bilinear filtering.
3. Threshold of 2: this makes a nicer edge but the low resolution underlying is too apparent.

4. Noise map.
5. Noise map + bilinear filtered low res ink map.
6. Threshold of 5: creates extra details hiding the low resolution but maintaining its basic shape.

espozo wrote:
rainwarrior wrote:
This process should not be particularly expensive for a pixel shader to do.

It would be for s console without one, which is the deal...

I'm not offering a SNES solution. I'm merely offering an explanation as to how Splatoon might be rendered.


Top
 Profile  
 
PostPosted: Sun Feb 21, 2016 4:35 pm 
Online
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 3162
Location: Nacogdoches, Texas
Okay, here's the revised code: (but still far from complete)

Code:
  lda SplatRequestTable+YPosition,x
  ror
  ror
  ror
  cmp #$0010000000000000
  bcc continue_calculating_vertical_offset
  inc EndOfSplat

continue_calculating_vertical_offset:
  and #%0001111111111111
  (Multiply by data per line in buffer. I don't know how.)
  sta SplatPosition

  lda SplatRequestTable+YPosition,x
  and #$0000000000000111
  asl
  sta SplatGraphicOffset

  lda SplatRequestTable+GraphicOffset,x
  sec
  sbc SplatGraphicOffset
  sta SplatGraphicOffset



  lda SplatRequestTable+XPosition,x
  ror
  ror
  and #%0011111111111111
  clc
  adc SplatPosition
  sta SplatPosition

  lda SplatRequestTable+XPosition,x
  and #%0000000000000111
  bne continue_calculating_x_offset
  inc SplatWidth

continue_calculating_x_offset:
  lda SplatRequestTable+XPosition,x
  and #%0000000000000111
  (Multiply by data per variation of splat graphic. All sizes should be the same.)
  clc
  adc SplatGraphicOffset
  sta SplatGraphicOffset



  lda SplatRequestTable+Height,x
  clc
  adc SplatHeight
  (Multiply by data per line in buffer. I don't know how.)
  clc
  adc SplatPosition
  sta SplatEndOfSplat

  lda SplatRequestTable+Width,x
  ror
  ror
  and #%0011111111111111
  sta SplatDataIncrement

  lda SplatRequestTable+Width,x
  clc
  adc SplatWidth
  sta SplatWidth

;======================================================================

start_draw_splat_loop:
  ldx SplatPosition
  ldy SplatGraphicOffset

draw_splat_loop:
  lda Buffer,x
  and #$0000,y
  ora #$0002,y
  sta Buffer,x

  lda Buffer+2,x
  and #$0004,y
  ora #$0006,y
  sta Buffer+2,x

  lda Buffer+4,x
  and #$0008,y
  ora #$000A,y
  sta Buffer+4,x

  lda Buffer+6,x
  and #$000C,y
  ora #$000E,y
  sta Buffer+6,x

  lda Buffer+8,x
  and #$0010,y
  ora #$0012,y
  sta Buffer+8,x

  lda Buffer+10,x
  and #$0014,y
  ora #$0016,y
  sta Buffer+10,x

  lda Buffer+12,x
  and #$0018,y
  ora #$001A,y
  sta Buffer+12,x

  lda Buffer+14,x
  and #$001C,y
  ora #$001E,y
  sta Buffer+14,x

  cpy EndOfSplat
  beq done
  inc TilesDrawnHorizontally
  cmp SplatWidth
  beq next_row

  txa
  clc
  adc #$0010
  tax
  tya
  clc
  adc SplatDataIncrement
  tay
  bra draw_splat_loop

next_row:
  stz TilesDrawnHorizontally
  txa
  clc
  adc BufferDataPerRow
  tax
  tya
  clc
  adc SplatDataIncrement
  tay
  bra draw_splat_loop

I actually just now realized that "Multiply by data per line in buffer" doesn't exactly work here because of how the tiles are set up in the buffer, but my brain hurts now so It'll have to wait. :lol:

rainwarrior wrote:
I'll just try to explain visually:

That's definitely clever... (Not necessarily for Nintendo, but for whoever came up with the idea.)


Top
 Profile  
 
PostPosted: Sun Feb 21, 2016 4:51 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5899
Location: Canada
Espozo wrote:
That's definitely clever... (Not necessarily for Nintendo, but for whoever came up with the idea.)

Using noise to create extra visual detail in computer graphics is probably at least 40 years old, but if you want someone to thank I think Ken Perlin did the most notable work to popularize the idea in the early 80s.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 295 posts ]  Go to page 1, 2, 3, 4, 5 ... 20  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: Google Adsense [Bot], Majestic-12 [Bot], tepples and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group