Author Topic: Creation of Predeformed Textures For Sega Saturn Display For Non Rectangle Faces  (Read 3169 times)


  • Newbie
  • *
  • Posts: 3
  • Karma: +4/-0
    • View Profile

This is my first post on JoEngine forums, so apologies if there is any misformating or missing screenshots. As English is not my first
language, grammar and spelling of this post are far from perfect, so if this post will be judged useful by JoEngine community, it will
have to be rewritten in better form and by someone with better command of English, with more testing involved.
Last but not least, some may find length of this post and detail provided excessive, but because I personally was quite often stuck for
hours, days or weeks, sometimes more because instructions provided were ambiguous, it is my personal rule to be as explicit as possible,
as it is better to have too much information than not enough.



28.09.18 - Edited points 01 and 03 instructing to disable "Interpolation" in "Image Sampling" section of "Texture" tab.


Creation of Predeformed Textures For Sega Saturn Display For Non Rectangle Faces

Note: Testing done using Yabause Sega Saturn emulator. 3D model creation, texturing and export/import done using Blender 2.79a.
         Methods presented below were not extensively tested and may not cover all use cases. Information presented below
         may contain errors, so please let me know if you spot any.

As you probably know Sega Saturn does not use UV mapping, and as result if you use model with textured faces that are not
rectangle/square (rectangle being defined as four-sided flat shape where every angle is a right angle (90°) and opposite sides
are parallel and of equal length) and create *.h file using "JoMapEditor.exe", texture of your model will apear distorted compared to
texture displayed by Blender.

Please take a look at following comparison:

Non Rectangular textured polygon displayed in Blender with square shaped UV map:

Trapezoid 001 - Non Deformed Tex.png

The same polygon displayed in Yabause emulator after being exported into *.obj file and converted using "JoMapEditor.exe"
into *.h file, where list of vertices in "static POLYGON" structure is fixed so that texture is displayed in proper orientation
(details further down in document):

Trapezoid 004 - Sega Saturn Emu - Non Deformed Tex Display.png

As you can see there is significant difference, because Blender uses UV mapped polygons, and Sega Saturn Distorted Sprites.

Difference between display of UV mapped polygon used for example by Playstation,
resulting deformation of texture when polygon’s shape is changed, and display of Sega Saturn's sprite and resulting
deformation of texture when polygon’s shape is changed can be seen in following video:

As you can see in presented approximation while UV mapped polygon "deforms" texture when polygon's shape is changed,
in case of Sega Saturn as shown in tessellated example in video above the textured polygon/sprite will be smoothly scaled.

Advantage of using triangles that can be UV mapped can be seen in non box/cube shapes, such as human faces (where distortion of textures
is not acceptable), where in case of Sega Saturn you are forced to use faces that are as close to rectangle/square as possible to avoid
deformation of texture, limitation which can force you to use significantly more geometry compared to model made from UV mapped triangles.

Solution to this problem is quite simple - crate your 3D model, unwrap it making sure that every face in UV editor is perfect
square, texture it using whatever method you prefer, duplicate your model, give it new image texture, give it dense geometry
using simple subdivision modifier, "Subdivide UVs" checked (simple subdivision modifier does not "smooth" model, it will simply
cut every face into multiple smaller faces without modifing shape of the model) and bake your texture onto new model. More details below.

Following procedure is not meant to be Blender 3D tutorial but will go into more details for sake of clarity:

00. Open Blender, hit Ctrl+Alt+U to bring up "Blender User Preferences", select "System" and uncheck "Mipmaps". Doing so deactivates
      filtering that makes textures to appear "smooth", higher resolution than they actually are, and displays only raw texture, exactly
      like it will be displayed by Sega Saturn without any color operations.
      Next, go to and download "" file. Go to "Add-ons" in "Blender User Preferences"
      and install add-on file you downloaded. Save user settings.

01. Create your 3D model, in edit mode hit "A" to select all your vertices/faces hit "U" key and from "UV Mapping" popup select "Lightmap Pack",
      which will result in every face being unwrapped into square shape, which is important to obtain desired results.
      Remember, all faces have to be unwrapped into perfect square (rectangle will probably work as well - not tested).
      Create separate UV editor window next to your 3D view, and if you need you can create some distance between unwrapped faces to avoid situation
      where when painting on one face, pixels on the edge will paint into pixels of neighbouring face by going to UV editor, hitting "Ctrl+Tab" and
      from "UV Select Mode" selecting "Face", selecting one face, hitting "S" key an typing something like .9, followed by hitting "Enter", or other
      value as needed. This will scale selected face by whatever value was typed. Do it for each face as necessary. Create new image in UV editor,
      and give it distinct name, for example "UV_Tex_Standard", use PNG format (PNG supports lossless data compression). Save your image texture file.

      Go to "Properties" view, "Texture" tab, "Image Sampling" section and disable/uncheck "Interpolation". Doing so helps to avoid blurring or other
      changes to baked texture when process of texture baking takes place(some sources advise setting "Filter:" to "Box", if you do it you may also try
      to set "Filter Size:" to 0.00 - "Box" setting was not used during testing of this process, only interpolation was disabled leaving filter on default).
      Note: 128 x 128 PNG image with RGB 8bit color was used for all textures in this test.

      Here you can see unwrapped and textured face in Blender and resulting texture in UV window
      (Texture created using "Texture Paint" mode in 3D view):
      Trapezoid 001 - Non Deformed Tex.png


      If you try to export it into *.obj immediately, and then convert it to JoEngine *.h file using "JoMapEditor.exe" it will look like this
      (vertex order sorted in *.h file to display texture in proper orientation - more details below):

      Trapezoid 004 - Sega Saturn Emu - Non Deformed Tex Display.png


02. Duplicate your model(in "Object Mode") by selecting it, hitting "Shift+D", and hitting "Enter". When duplicating model do not touch the mouse, your duplicated model
      should have exactly the same position as original. Make sure that your duplicated model is selected, hit "M" and then hit "2" to move your duplicated
      model to second layer (for simplicity original model should be on layer "1").

03. Create new image in UV Editor, name it something like "SS_Tex_Predistorted", PNG format. Make sure that your duplicated model does not share any
      materials or textures by using "make single-user copy" button in properties window, "Material" tab, and in "Texture" window select and assign
      newly created "SS_Tex_Predistorted" image. The purpose of this step is to avoid overwriting or modification of original texture.

      Go to "Properties" view, "Texture" tab, "Image Sampling" section and disable/uncheck "Interpolation". Doing so helps to avoid blurring or other
      changes to baked texture when process of texture baking takes place(some sources advise setting "Filter:" to "Box", if you do it you may also try
      to set "Filter Size:" to 0.00 - "Box" setting was not used during testing of this process, only interpolation was disabled leaving filter on default).

04. With your duplicated model selected, go to "Modifiers" tab, and assign two or more subdivision modifiers set to "Simple" Subdivisions > View > 6.
      "Subdivide UVs" should be active/checked. "Simple" setting is used because we need model with dense geometry, preferably more dense than density
      of pixels in used texture to eliminate UV distortion.               
05. Go to first layer by hitting "1", and select your original model. Make sure nothing else is selected. Go to second layer by hitting "2",
      hold "Shift" and select your duplicated model.

06. Go to "Render" tab, "Bake" section, set "Bake Mode:" to "Textures", make sure that "Selected to Active" is activated/checked, and click "Bake" button.

07. Save newly baked image texture of your duplicated model. Duplicated model with baked texture and subdivision modifiers still enabled should
      look like this:

      Trapezoid 002 - Predeformed Tex - Subdiv Modifier.png


      And with subdivision modifiers disabled like this:

      Trapezoid 003 - Predeformed Tex - No Subdiv Modifier.png


      As you can see there is difference between Standard UV mapped texture and texture mapped on subdivided/tessellated object.

08. Disable subdivision modifiers on your duplicated model, save your blend file, make sure that your image textures are saved as well,
      make sure that duplicated object is the only one selected, Click File > Export > Wavefront(.obj). In "Export OBJ" panel uncheck
      "Apply Modifiers" and check following: "Selection Only", "Include Edges", "Write Normals", "Include UVs", "Write Materials",
      "Objects as OBJ Objects" and "Keep Vertex Order". While some of those settings may not be necessary, those settings were used during
      testing. Leave "Scale" at 1.00, and set "Path Mode" to "Relative". When giving name to your exported file, avoid names like "File001",
      because when similar file names were used during testing, output *.h file provided by "JoMapEditor.exe" created material names which included
      number from file name, one example being "SpriteDataMaterial.0020[] " where dot in material name caused compilation issues.
      Save your *.obj file.

09. Run "JoMapEditor.exe", cilck 3D > Wavefront(.obj) to Jo Engine source file. Select your exported *.obj and convert it using "Import textures..."
      and "Polygon must be visible on both sides" options.

10. In Blender go to 3D View, hit "N" to open the properties shelf. Select your duplicated object and go to edit mode, and select all vertices.
     Doing that displays "Mesh Display" section in properties shelf. At the bottom of this section look for "Visualize indices", select "Vertices", and click
     "Visualize indices". This Index Visualiser is enabled from add-on described in point 00 of this instruction list. Take a look at screenshot below:

     Trapezoid 006 - Blender Vertex Index.png


     As you can see Blender displays vertex indices, starting from upper left and going clockwise in following order: 2, 3, 1, 0.

11. Open your Jo Engine source file (*.h) in your preferred editor(Notepad++ suggested). Find "static POLYGON" usually called "PolygonUnnamed1".
      Please take a look at screenshot below.
      Trapezoid 007 - Model H File Mod - Line 18 & 19.png


      Line 18 is commented out. This is original line. Line 19 is the copy of line 18, but series of numbers {0, 1, 3, 2} was changed to {2, 3, 1, 0}.
      Take a look again at screenshot in point 10, and clockwise vertex order(2, 3, 1, 0). If line was left unchanged, texture would be displayed
      differently than expected, for example inverted. If texture in your game is displayed in wrong orientation on given face, use "Visualize indices"
      add-on, and modify this list of vertices as needed in your *.h file. Save *.h file if modified.

12. Include your model *.h file in your main.c, position, scale and orient it for display. Following screenshot shows polygon displaying predeformed texture
     created using procedure listed above. As you can see texture is being displayed properly, without any distortions:

     Trapezoid 005 - Sega Saturn Emu - Predformed Tex Display.png



This procedure also works with "Four vertex triangles". Sega Saturn does not display actual triangles, so if you want to create something that looks exactly
like triangle, you take four vertex polygon and position one of the vertices in exactly the same position as other selected vertex. Example below.

"Four vertex triangle" with standard UV mapping (Texture created using "Texture Paint" mode in 3D view):

Four Vertex Triangle 001 - Non Deformed Tex.png

"Four vertex triangle" subdivided duplicate with baked texture (resulting in predeformed texture):

Four Vertex Triangle 002 - Predeformed Tex - Subdiv Modifier.png

"Four vertex triangle" duplicate with predeformed texture and subdivision disabled:

Four Vertex Triangle 003 - Predeformed Tex - No Subdiv Modifier.png

"Four vertex triangle" in Blender vertex indices visualization:

Four Vertex Triangle 005 - Blender Vertex Index.png

"Four vertex triangle" JoEngine source *.h file polygon vertex list order modification:

Four Vertex Triangle 006 - Model H File Mod - Line 18 & 19.png

"Four vertex triangle" exported *.h file included in main.c with predeformed texture and displayed in Yabause:

Four Vertex Triangle 004 - Sega Saturn Emu - Predeformed Tex Display


Note: Not tested.

With strong enough computer you could probably skip baking, as you could create your model, unwrap it and tessellate using simple subdivision,
and paint texture directly on tessellated model, but required amount of geometry will probably cause significant performance issues.



« Last Edit: September 28, 2018, 04:49:09 am by L_Level »


  • Full Member
  • ***
  • Posts: 220
  • Karma: +22/-1
    • View Profile
Great post


Sitemap 1 2 3 4 5 6 7 8 9 10