Jump to content
  • Advertisement

Unity Weekly Updates #34 - Levels of details



Why hello there! Welcome to this new installment of your favourite blog!

To be honest with you, this one isn't supposed to be noticeable (at least for the first part). To put it simply, this week was really a modelling one. Most of the time I worked on different LOD models of most of my meshes. 

Secondly, I've also implemented some fancy affine mapping for my textured meshes, mimicking PlayStation's own texturing method, with all those juicy deformations and all.

So let's get right to it then!


For those who didn't know, rendering a mesh takes resources. The number of resources used depends on the complexity of a mesh. Generally speaking, the more vertices the more resource intensive the rendering is. 

However, sometimes the rendering process is simply too complex for the number of pixels the mesh actually has. This makes the game run generally slower.

The solution? LOD grouping.

Overlays displaying the active LOD levels

Basically, we can create different meshes with different levels of details (i.e. different mesh complexity). We can then tell the game which meshes to use based on how much space the model takes on screen.

This means that objects that are generally far away can use a simpler geometry altogether. if they're far enough they might even get culled altogether.

With all that, it can ease the rendering process just a bit. I still need to add some type of dynamic occlusion system to get really noticable performance boosts, but using LODs generally helps.

Affine Mapping

Next, I want to talk about affine mapping.

Vaporwave, in general, is supposed to invoke feelings of nostalgia in general. In videogames, there are a lot of ways to create that, but most of the time we need to invoke the 5th console generation (N64 and PlayStation generally speaking).

While the N64 can have nice graphics the PlayStation is by far the most interesting of them. 


Basically, the PlayStation uses a mapping technique called affine mapping. This technique was usually one of the fastest of them all (at least at the time). But this came with a cost...


Using this mapping algorithm induce noticable distortion on any primitives that have weird viewing angle (such as looking at it almost perpendicular or really close to it)


It was a nice trade-off. This meant that 3D rendering was fast enough for the PlayStation's hardware while still being somehow fully 3D.

Today we've mostly moved on. There are far better mapping techniques that don't induce distortions.

But for this game, I'm trying to get them back.

PSX Shaders

One of the things to understand is that affine mapping wasn't a shader: it was an algorithm. This means that in our age of DirectX and OpenGL we need to make a shader that adds those distortions back in.

Thankfully there's already some PSX emulation shader available for Unity.


It's just a matter of integrating the specific feature of those shaders into mine, which isn't too complex at all...

So here's what I've got:

void vert(inout appdata_full v, out Input o) {

	float4 snapToPixel = UnityObjectToClipPos(v.vertex);
	float4 vertex = snapToPixel;
	vertex.xyz = snapToPixel.xyz / snapToPixel.w;
	vertex.x = floor(160 * vertex.x) / 160;
	vertex.y = floor(120 * vertex.y) / 120;
	vertex.xyz *= snapToPixel.w;

	float distance = length(UnityObjectToViewPos(v.vertex));
	//Affine Texture Mapping
	float4 affinePos = vertex; //vertex;
	o.affineLength = (distance + (vertex.w*(UNITY_LIGHTMODEL_AMBIENT.a * 8)) / distance / 2).r;
	v.texcoord *= distance + (vertex.w*(UNITY_LIGHTMODEL_AMBIENT.a * 8)) / distance / 2;


inline float2 mapping(float2 mainMap, Input IN) {
	return mainMap / IN.affineLength;

void surf (Input IN, inout SurfaceOutputStandard o) {
	o.Albedo = tex2D(_MainTex, mapping(IN.uv_MainTex, IN);

Basically, we're doing a bunch of calculation based on the distance of vertices to the center of the object and changing the texture coordinates accordingly.

Later on, we simply divide again to get the right texture scale and voilà: a nice affine shader.

Here's a nice video of it:

We can also change the amount of distortion by changing the alpha value of the ambient colour.

In my case, it wasn't an issue at all, but I'm pretty sure that we could technically change that and put it as a shader property.

However, there's a catch: on low-poly meshes, the shader applies too much distortion, and even while changing the distortion parameter...

The simplest solution is to simply subdivide the meshes. This way the distortion becomes relatively sane.


Paired with Point filtering and low-res texture this makes for quite the PlayStation experience!


Minor Changes

  • Fixed bugs with the grass colour not matching their wetness levels
  • Continued the Shader .cginc refactors
  • Fixed a bug with the Analog blur creating strange dark artifacts on lighted surfaces
  • Added a bunch of shader optimizations, especially with instancing
  • Added some billboarding balls to bridge poles
  • Refactored the mall floors so that they have simpler geometries that use normal maps rather than actual geometries.
  • Resized textures to make them as much low-res I can get away with
  • Resolve a bug with picked up items not properly making their pick up sounds
  • Added an enemy failsafe so that enemies below the level that somehow survived the chasm will still get killed
  • Change most material property changing scripts to also apply properties changes to their LODs 

Next Week

We're continuing on the refactor train. I'm also not done with LODs in general, so I'm also planning to complete those as well.

Otherwise, I'm also starting to think that I need other types of enemies... Fighting the same enemy can really be repetitive sometimes...

Aside from that, there are our traditional usual suspects (Capacities, equipment, relics, etc.)

But keep in mind that next week could be potentially slow, as it IS spring break after all, and there are a bunch of little ones running around...


Recommended Comments

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
  • Advertisement
  • Blog Entries

  • Similar Content

    • By RoKabium Games
      SAMA Tip #1 Are you missing items you know you dug out? Perhaps you have an unclaimed grave somewhere in the level. Check the mini-map for pulsating pink dots.
    • By ashlelia
      Hi all,
      I did a bit of searching around the forum before posting and I couldn't find anything that quite fit my question. A boyfriend and I are working on creating a word game for mobile that would include a grid of multi-color letters, a goal, and boosters to help you achieve the goal. We plan to build in Unity. He's doing the coding, I'm responsible for pretty much everything else (the concept is mine from the jump so lol) and right now my focus is on level design. I am pretty lost on where I would begin with creating the kind of levels I want; each level should have a goal of something like "create five blue words" or "create five blue words of only three letters." Down the line, some may be timed or have turn limits.
      Would this be something that I would have to manually design, or is there a way to generate the goals more dynamically based on particular constraints
    • By SCP-173
      I'm currently working on a 3D mobile game in Unity, and I've basically designed the whole thing already. Problem is, I do not know where to get started on the music/rhythm integration for the game. I'm relatively new to coding in C#, but am pretty comfortable with the Unity workflow having made some games off tutorials to learn C# and Unity. I was wondering if there is anyone who is experienced in or knows about making rhythm-based games who could help me understand the process? My concept is similar to these to just give you an idea of what I'm going towards: https://www.youtube.com/watch?v=RcHzJ5lAdHQ
      I've also read about this software Koreographer while doing research on how to make a rhythm-based game, but I'm hoping that whoever's willing to help can help me achieve some of the neat effects that Koreographer can do without buying and learning the software.
    • By Alex Gomez Cortes
      Hello everyone,
      About a month ago I finished programming the lighting (or at least it is what I thought), because a few hours ago I realized that when I translate the object, the lighting breaks (not when rotating, because I multiply the normals by the transpose of the inverse of the modelMatrix), only if I move the object from the 0,0,0.
      I only have one light, a directional one. 
      Here the rock is at 0,0,0.
      Here the rock is at -10,0,0.

      I only moved it to the left, and as you can see looks like the normals are wrong, but I do not touch them, except when I multiply them by the transpose of the inverse of the modelMatrix (if I do not multply the normals by that matrix the lighting doesnt break but when the object rotates the light rotates with it). So, is there a way to have the normals well for translating and rotating? 

      Now I can translate the object and the lighting doesnt brake, but if I rotate it the light rotates with it.

      Now I can rotate it but if I move it the lighting breaks.
      Thanks a lot!!
    • By RoKabium Games
      ALPHA TESTERS WANTED! Our PC game "Something Ate My Alien" is starting public testing today! If you would like to test our game, contact us or visit the link below:
      SAMA forums: http://bit.ly/sama-testing

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!