I Need Help with Interpolation

Everything is a mess…

RedShift Pre-prototype Demo

I’m working on a mobile game that is taking advantage of a phenomenon known as chromostereopsis. Basically certain combinations of colors will make some parts of an image appear closer to the user than others. You can visit the Wikipedia page to learn more about the illusion or search Google or Bing for examples, but basically, I’m trying to make a game look three-dimensional like 3DS games, but by using just colors instead of 3D graphics or fancy hardware.

The graphics as-is is very rudimentary, so the effect currently isn’t very intense. This will be fixed in the future, but that’s not the issue at hand.

As you can see in the video above, I’m allowing the player to transition between the various planes with a fake zoom effect. This is meant to enrich the 3D illusion as well as provide more gameplay depth.

The problem is that if all the colors appear at the same alpha, the interface just looks busy and complicated rather than adding to the effect. Therefore, I’m interpolating between alpha values so that the planes that the player is not in will appear less opaque than the one that they’re in. In general, the further away the plane is from the plane the user is in, the less opaque the plane and all the objects in that plane will appear. Complicating the matter is that when the player is on the top plane (red), the bottom plane (blue) should not be as transparent as the top plane (red) looks when the player is on the bottom plane(blue).

I’m also adjusting the scale of the sprites so that sprites that are supposed to be further away appear smaller than the same sprite that’s closer to the top plane.

The reason for interpolating between the values is that as the player transitions from one plane to another, the plane they’re traveling to will gradually look like it’s moving closer. That’s the intent, at least. This effect should also happen when an NPC is moving from one plane to another; they should look like they’re moving closer or further away.

Currently, I’m using a linear interpolation to get an gradual transition between one alpha value and another, but this will only seem to work when either the player is transitioning between planes or when an NPC is floating or falling between planes and not both. Moreover, I’m hardcoding one of the values in each case as you can see.

const obj_z_0_usr_z_0 = Vector2(0,1.0)
const obj_z_0_usr_z_100 = Vector2(100,0.5)

const obj_z_50_usr_z_0 = Vector2(0,0.5)
const obj_z_50_usr_z_50 = Vector2(50,1.0)
const obj_z_50_usr_z_100 = Vector2(100,0.5)

const obj_z_100_usr_z_0 = Vector2(0,0.25)
const obj_z_100_usr_z_100 = Vector2(100,1.0)

func calculateOpacityPlayerPlaneChange(object_z,debug=false):
	var opacity = 1.0
	match object_z:
		0: 
			return obj_z_0_usr_z_0.linear_interpolate(obj_z_0_usr_z_100,user_z_index/100).y
		50: 
			var q0 = obj_z_50_usr_z_0.linear_interpolate(obj_z_50_usr_z_50,user_z_index/100)
			if debug: print("q0: " + String(q0))
			var q1 = obj_z_50_usr_z_50.linear_interpolate(obj_z_50_usr_z_100,user_z_index/100)
			if debug: print("q1: " + String(q1))
			var q = q0.linear_interpolate(q1,user_z_index/100)
			if debug: print("q: " + String(q))
			return q.y
		100:
			return obj_z_100_usr_z_0.linear_interpolate(obj_z_100_usr_z_100,user_z_index/100).y
	return opacity
func calculateOpacityFloatFall(object_z,debug=false):
	var opacity = 1.0
	match user_z_index:
		0:
			return obj_z_0_usr_z_0.linear_interpolate(obj_z_0_usr_z_100,object_z/100).y
		50:
			var q0 = obj_z_50_usr_z_0.linear_interpolate(obj_z_50_usr_z_50,object_z/100)
			if debug: print("q0: " + String(q0))
			var q1 = obj_z_50_usr_z_50.linear_interpolate(obj_z_50_usr_z_100,object_z/100)
			if debug: print("q1: " + String(q1))
			var q = q0.linear_interpolate(q1,object_z/100)
			if debug: print("q: " + String(q))
			return q.y
		100:
			return obj_z_100_usr_z_0.linear_interpolate(obj_z_100_usr_z_100,object_z/100).y

It’s all a big mess right now and I wish it weren’t.

Also, my attempt at a quadratic bezier interpolation failed miserably and it’s always returning 0.5 even when the z_index is 50.

Ideally, there would be a single function that would be called that takes in both the player’s z_index and the object’s z_index (I’m using values between 0 and 100) and interpolate based on a predefined set of values. Both the color (ranging from red to purple to blue and all values in between) and the opacity (ranging from 0.0 to 1.0) would be returned as a single modulate based on something like this:

object_z: 0object_z: 50object_z: 100
player_z: 01.00.50.25
player_z: 500.51.00.5
player_z: 1000.80.9100
Opacity
object_z: 0object_z: 50object_z: 100
RGB(0.0,0.0,1.0)RGB(0.8,0.0,1.0)RGB(1.0,0.0,0.0)
Color
object_z: 0object_z: 50object_z: 100
player_z: 0scale*1.0scale*1.1scale*1.5
player_z: 50scale*0.9scale*1.0scale*1.25
player_z: 100scale*0.8scale*0.9scale*1.0
Scale

The color and scale are very separate from the transparency, so I’m fine with having separate functions for those, however, the transparency is something I’m really struggling with implementing.

Comment below or email me if you have some tips. Thanks.

Leave a comment

Design a site like this with WordPress.com
Get started