Skip to content

Instantly share code, notes, and snippets.

@ryancheu
Created November 18, 2013 16:21
Show Gist options
  • Save ryancheu/7530694 to your computer and use it in GitHub Desktop.
Save ryancheu/7530694 to your computer and use it in GitHub Desktop.
test
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul(_Object2World, v.vertex); //get position in world frame
o.pos -= _playerOffset; //Shift such that we use a coordinate system where the player is at 0,0,0
o.uv1.xy = v.texcoord; //get the UV coordinate for the current vertex, will be passed to fragment shade
float speed = sqrt( pow((_vpc.x),2) + pow((_vpc.y),2) + pow((_vpc.z),2));
//vw + vp/(1+vw*vp/c^2)
float vuDot = (_vpc.x*_viw.x + _vpc.y*_viw.y + _vpc.z*_viw.z); //Get player velocity dotted with velocity of the object.
float4 uparra;
//IF our speed is zero, this parallel velocity component will be NaN, so we have a check here just to be safe
if ( speed != 0 )
{
uparra = (vuDot/(speed*speed)) * _vpc; //Get the parallel component of the object's velocity
}
//If our speed is zero, set parallel velocity to zero
else
{
uparra = 0;
}
//Get the perpendicular component of our velocity, just by subtraction
float4 uperp = _viw - uparra;
//relative velocity calculation
float4 vr =( _vpc - uparra - (sqrt(1-speed*speed))*uperp)/(1+vuDot);
//set our relative velocity
o.vr = vr;
vr *= -1;
//relative speed
float speedr = sqrt( pow((vr.x),2) + pow((vr.y),2) + pow((vr.z),2));
o.svc = sqrt( 1 - speedr * speedr); // To decrease number of operations in fragment shader, we're storing this value
//You need this otherwise the screen flips and weird stuff happens
#ifdef SHADER_API_D3D9
if (_MainTex_TexelSize.y < 0)
o.uv1.y = 1.0- o.uv1.y;
#endif
//riw = location in world, for reference
float4 riw = o.pos; //Position that will be used in the output
if (speedr != 0) // If speed is zero, rotation fails
{
float a; //angle
float ux;
float uy;
float ca; //cosine of a
float sa; /// sine of a
if ( speed != 0 )
{
//we're getting the angle between our z direction of movement and the world's Z axis
a = -acos(-_vpc.z/speed);
if ( _vpc.x != 0 || _vpc.y != 0 )
{
ux = _vpc.y/sqrt(_vpc.x*_vpc.x + _vpc.y*_vpc.y);
uy = -_vpc.x/sqrt(_vpc.x*_vpc.x + _vpc.y*_vpc.y);
}
else
{
ux = 0;
uy = 0;
}
ca = cos(a);
sa = sin(a);
//We're rotating player velocity here, making it seem like the player's movement is all in the Z direction
//This is because all of our equations are based off of movement in one direction.
//And we rotate our point that much to make it as if our magnitude of velocity is in the Z direction
riw.x = o.pos.x * (ca + ux*ux*(1-ca)) + o.pos.y*(ux*uy*(1-ca)) + o.pos.z*(uy*sa);
riw.y = o.pos.x * (uy*ux*(1-ca)) + o.pos.y * ( ca + uy*uy*(1-ca)) - o.pos.z*(ux*sa);
riw.z = o.pos.x * (-uy*sa) + o.pos.y * (ux*sa) + o.pos.z*(ca);
}
//Here begins the original code, made by the guys behind the Relativity game
//Rotate our velocity
float4 rotateViw = float4(0,0,0,0);
if ( speed != 0 )
{
//Here we rotate our object's velocity so that we keep consistent with the rotation of our player's velocity.
rotateViw.x = (_viw.x * (ca + ux*ux*(1-ca)) + _viw.y*(ux*uy*(1-ca)) + _viw.z*(uy*sa))*_spdOfLight;
rotateViw.y = (_viw.x * (uy*ux*(1-ca)) + _viw.y * ( ca + uy*uy*(1-ca)) - _viw.z*(ux*sa))*_spdOfLight;
rotateViw.z = (_viw.x * (-uy*sa) + _viw.y * (ux*sa) + _viw.z*(ca))*_spdOfLight;
}
else
{
rotateViw.x = (_viw.x) * _spdOfLight;
rotateViw.z = (_viw.z) * _spdOfLight;
rotateViw.y = (_viw.y) * _spdOfLight;
}
float c = -(riw.x*riw.x + riw.y*riw.y + riw.z*riw.z); //first get position squared (position doted with position)
float b = -(2 * ( riw.x*rotateViw.x + riw.y*rotateViw.y + riw.z*rotateViw.z)); //next get position doted with velocity, should be only in the Z direction
float d = (_spdOfLight*_spdOfLight) - (rotateViw.x*rotateViw.x + rotateViw.y*rotateViw.y + rotateViw.z*rotateViw.z);
float tisw = (float)(((-b - (sqrt((b * b) - ((float)float(4)) * d * c))) / (((float)float(2)) * d)));
//Check to make sure that objects that have velocity do not appear before they were created (Moving Person objects behind Sender objects)
if (_wrldTime + tisw > _strtTime || _strtTime==0)
{
o.draw = 1;
}
else
{
o.draw = 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment