Skip to content

Commit

Permalink
Add experimental shaders for simulating minetest on a
Browse files Browse the repository at this point in the history
planet-like sphere, enable them in minetest.conf with
minetest_planet = true
and set the planet radius with
planet_radius = 20
with 20 here being the planet's radius in map blocks (16 nodes)
  • Loading branch information
Jeija committed May 17, 2016
1 parent 1434014 commit 50f8a37
Show file tree
Hide file tree
Showing 7 changed files with 319 additions and 17 deletions.
76 changes: 75 additions & 1 deletion client/shaders/default_shader/opengl_vertex.glsl
Original file line number Diff line number Diff line change
@@ -1,9 +1,83 @@
uniform mat4 mWorldViewProj;

const float BS = 10.0;

/*
* inverse(mat4 m) function:
* This GLSL version doesn't have inverse builtin, using version from https://github.com/stackgl/glsl-inverse
* (c) 2014 Mikola Lysenko. MIT License
*/
mat4 inverse(mat4 m) {
float
a00 = m[0][0], a01 = m[0][1], a02 = m[0][2], a03 = m[0][3],
a10 = m[1][0], a11 = m[1][1], a12 = m[1][2], a13 = m[1][3],
a20 = m[2][0], a21 = m[2][1], a22 = m[2][2], a23 = m[2][3],
a30 = m[3][0], a31 = m[3][1], a32 = m[3][2], a33 = m[3][3],

b00 = a00 * a11 - a01 * a10,
b01 = a00 * a12 - a02 * a10,
b02 = a00 * a13 - a03 * a10,
b03 = a01 * a12 - a02 * a11,
b04 = a01 * a13 - a03 * a11,
b05 = a02 * a13 - a03 * a12,
b06 = a20 * a31 - a21 * a30,
b07 = a20 * a32 - a22 * a30,
b08 = a20 * a33 - a23 * a30,
b09 = a21 * a32 - a22 * a31,
b10 = a21 * a33 - a23 * a31,
b11 = a22 * a33 - a23 * a32,

det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;

return mat4(
a11 * b11 - a12 * b10 + a13 * b09,
a02 * b10 - a01 * b11 - a03 * b09,
a31 * b05 - a32 * b04 + a33 * b03,
a22 * b04 - a21 * b05 - a23 * b03,
a12 * b08 - a10 * b11 - a13 * b07,
a00 * b11 - a02 * b08 + a03 * b07,
a32 * b02 - a30 * b05 - a33 * b01,
a20 * b05 - a22 * b02 + a23 * b01,
a10 * b10 - a11 * b08 + a13 * b06,
a01 * b08 - a00 * b10 - a03 * b06,
a30 * b04 - a31 * b02 + a33 * b00,
a21 * b02 - a20 * b04 - a23 * b00,
a11 * b07 - a10 * b09 - a12 * b06,
a00 * b09 - a01 * b07 + a02 * b06,
a31 * b01 - a30 * b03 - a32 * b00,
a20 * b03 - a21 * b01 + a22 * b00) / det;
}

void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = mWorldViewProj * gl_Vertex;

vec4 pos = gl_Vertex;

#ifdef ENABLE_PLANET
mat4 viewModel = inverse(gl_ModelViewMatrix);
vec3 camPos = viewModel[3].xyz;

// Step 1: Transform normal coordinates into coordinates as if they were on a sphere
float radius = PLANET_RADIUS * BS * 16 + pos.y;
float xangle = (pos.x - camPos.x) / (PLANET_RADIUS * BS * 16);
float zangle = (pos.z - camPos.z) / (PLANET_RADIUS * BS * 16);
float distangle = pow(xangle * xangle + zangle * zangle, 0.5);

// Step 2: Transform back from spherical coordinates to cartesian system with
// the center of the planet in the origin of the coordinate system.
float planet_x = sin(xangle) * radius;
float planet_z = sin(zangle) * radius;
float planet_y = cos(distangle) * radius;

// Step 3: Translate coordinates so that they are relative to the camera, not the planet center
// The planet center is *always* position PLANET_RADIUS underneath the player
pos.y = planet_y - (PLANET_RADIUS * BS * 16);
pos.x = camPos.x + planet_x;
pos.z = camPos.z + planet_z;
#endif

gl_Position = mWorldViewProj * pos;

gl_FrontColor = gl_BackColor = gl_Color;
}
78 changes: 70 additions & 8 deletions client/shaders/nodes_shader/opengl_vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,51 @@ float smoothTriangleWave(float x)
return smoothCurve(triangleWave(x)) * 2.0 - 1.0;
}

/*
* inverse(mat4 m) function:
* This GLSL version doesn't have inverse builtin, using version from https://github.com/stackgl/glsl-inverse
* (c) 2014 Mikola Lysenko. MIT License
*/
mat4 inverse(mat4 m) {
float
a00 = m[0][0], a01 = m[0][1], a02 = m[0][2], a03 = m[0][3],
a10 = m[1][0], a11 = m[1][1], a12 = m[1][2], a13 = m[1][3],
a20 = m[2][0], a21 = m[2][1], a22 = m[2][2], a23 = m[2][3],
a30 = m[3][0], a31 = m[3][1], a32 = m[3][2], a33 = m[3][3],

b00 = a00 * a11 - a01 * a10,
b01 = a00 * a12 - a02 * a10,
b02 = a00 * a13 - a03 * a10,
b03 = a01 * a12 - a02 * a11,
b04 = a01 * a13 - a03 * a11,
b05 = a02 * a13 - a03 * a12,
b06 = a20 * a31 - a21 * a30,
b07 = a20 * a32 - a22 * a30,
b08 = a20 * a33 - a23 * a30,
b09 = a21 * a32 - a22 * a31,
b10 = a21 * a33 - a23 * a31,
b11 = a22 * a33 - a23 * a32,

det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;

return mat4(
a11 * b11 - a12 * b10 + a13 * b09,
a02 * b10 - a01 * b11 - a03 * b09,
a31 * b05 - a32 * b04 + a33 * b03,
a22 * b04 - a21 * b05 - a23 * b03,
a12 * b08 - a10 * b11 - a13 * b07,
a00 * b11 - a02 * b08 + a03 * b07,
a32 * b02 - a30 * b05 - a33 * b01,
a20 * b05 - a22 * b02 + a23 * b01,
a10 * b10 - a11 * b08 + a13 * b06,
a01 * b08 - a00 * b10 - a03 * b06,
a30 * b04 - a31 * b02 + a33 * b00,
a21 * b02 - a20 * b04 - a23 * b00,
a11 * b07 - a10 * b09 - a12 * b06,
a00 * b09 - a01 * b07 + a02 * b06,
a31 * b01 - a30 * b03 - a32 * b00,
a20 * b03 - a21 * b01 + a22 * b00) / det;
}

void main(void)
{
Expand Down Expand Up @@ -66,29 +111,46 @@ float disp_z;
smoothTriangleWave(animationTimer * 13.0 + tOffset)) * 0.5;
#endif

vec4 pos = gl_Vertex;

#ifdef ENABLE_PLANET
mat4 viewModel = inverse(gl_ModelViewMatrix);
vec3 camPos = viewModel[3].xyz;

// Step 1: Transform normal coordinates into coordinates as if they were on a sphere
float radius = PLANET_RADIUS * BS * 16 + pos.y;
float xangle = (pos.x - camPos.x) / (PLANET_RADIUS * BS * 16);
float zangle = (pos.z - camPos.z) / (PLANET_RADIUS * BS * 16);
float distangle = pow(xangle * xangle + zangle * zangle, 0.5);

// Step 2: Transform back from spherical coordinates to cartesian system with
// the center of the planet in the origin of the coordinate system.
float planet_x = sin(xangle) * radius;
float planet_z = sin(zangle) * radius;
float planet_y = cos(distangle) * radius;

// Step 3: Translate coordinates so that they are relative to the camera, not the planet center
// The planet center is *always* position PLANET_RADIUS underneath the player
pos.y = planet_y - (PLANET_RADIUS * BS * 16);
pos.x = camPos.x + planet_x;
pos.z = camPos.z + planet_z;
#endif

#if (MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE) && ENABLE_WAVING_WATER
vec4 pos = gl_Vertex;
pos.y -= 2.0;
float posYbuf = (pos.z / WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH);
pos.y -= sin(posYbuf) * WATER_WAVE_HEIGHT + sin(posYbuf / 7.0) * WATER_WAVE_HEIGHT;
gl_Position = mWorldViewProj * pos;
#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES
vec4 pos = gl_Vertex;
pos.x += disp_x;
pos.y += disp_z * 0.1;
pos.z += disp_z;
gl_Position = mWorldViewProj * pos;
#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS
vec4 pos = gl_Vertex;
if (gl_TexCoord[0].y < 0.05) {
pos.x += disp_x;
pos.z += disp_z;
}
gl_Position = mWorldViewProj * pos;
#else
gl_Position = mWorldViewProj * gl_Vertex;
#endif
gl_Position = mWorldViewProj * pos;


vPosition = gl_Position.xyz;
Expand Down
76 changes: 75 additions & 1 deletion client/shaders/selection_shader/opengl_vertex.glsl
Original file line number Diff line number Diff line change
@@ -1,9 +1,83 @@
uniform mat4 mWorldViewProj;

const float BS = 10.0;

/*
* inverse(mat4 m) function:
* This GLSL version doesn't have inverse builtin, using version from https://github.com/stackgl/glsl-inverse
* (c) 2014 Mikola Lysenko. MIT License
*/
mat4 inverse(mat4 m) {
float
a00 = m[0][0], a01 = m[0][1], a02 = m[0][2], a03 = m[0][3],
a10 = m[1][0], a11 = m[1][1], a12 = m[1][2], a13 = m[1][3],
a20 = m[2][0], a21 = m[2][1], a22 = m[2][2], a23 = m[2][3],
a30 = m[3][0], a31 = m[3][1], a32 = m[3][2], a33 = m[3][3],

b00 = a00 * a11 - a01 * a10,
b01 = a00 * a12 - a02 * a10,
b02 = a00 * a13 - a03 * a10,
b03 = a01 * a12 - a02 * a11,
b04 = a01 * a13 - a03 * a11,
b05 = a02 * a13 - a03 * a12,
b06 = a20 * a31 - a21 * a30,
b07 = a20 * a32 - a22 * a30,
b08 = a20 * a33 - a23 * a30,
b09 = a21 * a32 - a22 * a31,
b10 = a21 * a33 - a23 * a31,
b11 = a22 * a33 - a23 * a32,

det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;

return mat4(
a11 * b11 - a12 * b10 + a13 * b09,
a02 * b10 - a01 * b11 - a03 * b09,
a31 * b05 - a32 * b04 + a33 * b03,
a22 * b04 - a21 * b05 - a23 * b03,
a12 * b08 - a10 * b11 - a13 * b07,
a00 * b11 - a02 * b08 + a03 * b07,
a32 * b02 - a30 * b05 - a33 * b01,
a20 * b05 - a22 * b02 + a23 * b01,
a10 * b10 - a11 * b08 + a13 * b06,
a01 * b08 - a00 * b10 - a03 * b06,
a30 * b04 - a31 * b02 + a33 * b00,
a21 * b02 - a20 * b04 - a23 * b00,
a11 * b07 - a10 * b09 - a12 * b06,
a00 * b09 - a01 * b07 + a02 * b06,
a31 * b01 - a30 * b03 - a32 * b00,
a20 * b03 - a21 * b01 + a22 * b00) / det;
}

void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = mWorldViewProj * gl_Vertex;

vec4 pos = gl_Vertex;

#ifdef ENABLE_PLANET
mat4 viewModel = inverse(gl_ModelViewMatrix);
vec3 camPos = viewModel[3].xyz;

// Step 1: Transform normal coordinates into coordinates as if they were on a sphere
float radius = PLANET_RADIUS * BS * 16 + pos.y;
float xangle = (pos.x - camPos.x) / (PLANET_RADIUS * BS * 16);
float zangle = (pos.z - camPos.z) / (PLANET_RADIUS * BS * 16);
float distangle = pow(xangle * xangle + zangle * zangle, 0.5);

// Step 2: Transform back from spherical coordinates to cartesian system with
// the center of the planet in the origin of the coordinate system.
float planet_x = sin(xangle) * radius;
float planet_z = sin(zangle) * radius;
float planet_y = cos(distangle) * radius;

// Step 3: Translate coordinates so that they are relative to the camera, not the planet center
// The planet center is *always* position PLANET_RADIUS underneath the player
pos.y = planet_y - (PLANET_RADIUS * BS * 16);
pos.x = camPos.x + planet_x;
pos.z = camPos.z + planet_z;
#endif

gl_Position = mWorldViewProj * pos;

gl_FrontColor = gl_BackColor = gl_Color;
}
82 changes: 75 additions & 7 deletions client/shaders/water_surface_shader/opengl_vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,90 @@ float smoothTriangleWave(float x)
return smoothCurve(triangleWave( x )) * 2.0 - 1.0;
}

/*
* inverse(mat4 m) function:
* This GLSL version doesn't have inverse builtin, using version from https://github.com/stackgl/glsl-inverse
* (c) 2014 Mikola Lysenko. MIT License
*/
mat4 inverse(mat4 m) {
float
a00 = m[0][0], a01 = m[0][1], a02 = m[0][2], a03 = m[0][3],
a10 = m[1][0], a11 = m[1][1], a12 = m[1][2], a13 = m[1][3],
a20 = m[2][0], a21 = m[2][1], a22 = m[2][2], a23 = m[2][3],
a30 = m[3][0], a31 = m[3][1], a32 = m[3][2], a33 = m[3][3],

b00 = a00 * a11 - a01 * a10,
b01 = a00 * a12 - a02 * a10,
b02 = a00 * a13 - a03 * a10,
b03 = a01 * a12 - a02 * a11,
b04 = a01 * a13 - a03 * a11,
b05 = a02 * a13 - a03 * a12,
b06 = a20 * a31 - a21 * a30,
b07 = a20 * a32 - a22 * a30,
b08 = a20 * a33 - a23 * a30,
b09 = a21 * a32 - a22 * a31,
b10 = a21 * a33 - a23 * a31,
b11 = a22 * a33 - a23 * a32,

det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;

return mat4(
a11 * b11 - a12 * b10 + a13 * b09,
a02 * b10 - a01 * b11 - a03 * b09,
a31 * b05 - a32 * b04 + a33 * b03,
a22 * b04 - a21 * b05 - a23 * b03,
a12 * b08 - a10 * b11 - a13 * b07,
a00 * b11 - a02 * b08 + a03 * b07,
a32 * b02 - a30 * b05 - a33 * b01,
a20 * b05 - a22 * b02 + a23 * b01,
a10 * b10 - a11 * b08 + a13 * b06,
a01 * b08 - a00 * b10 - a03 * b06,
a30 * b04 - a31 * b02 + a33 * b00,
a21 * b02 - a20 * b04 - a23 * b00,
a11 * b07 - a10 * b09 - a12 * b06,
a00 * b09 - a01 * b07 + a02 * b06,
a31 * b01 - a30 * b03 - a32 * b00,
a20 * b03 - a21 * b01 + a22 * b00) / det;
}

void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;

#if (MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE) && ENABLE_WAVING_WATER
vec4 pos = gl_Vertex;

#ifdef ENABLE_PLANET
mat4 viewModel = inverse(gl_ModelViewMatrix);
vec3 camPos = viewModel[3].xyz;

// Step 1: Transform normal coordinates into coordinates as if they were on a sphere
float radius = PLANET_RADIUS * BS * 16 + pos.y;
float xangle = (pos.x - camPos.x) / (PLANET_RADIUS * BS * 16);
float zangle = (pos.z - camPos.z) / (PLANET_RADIUS * BS * 16);
float distangle = pow(xangle * xangle + zangle * zangle, 0.5);

// Step 2: Transform back from spherical coordinates to cartesian system with
// the center of the planet in the origin of the coordinate system.
float planet_x = sin(xangle) * radius;
float planet_z = sin(zangle) * radius;
float planet_y = cos(distangle) * radius;

// Step 3: Translate coordinates so that they are relative to the camera, not the planet center
// The planet center is *always* position PLANET_RADIUS underneath the player
pos.y = planet_y - (PLANET_RADIUS * BS * 16);
pos.x = camPos.x + planet_x;
pos.z = camPos.z + planet_z;
#endif

#if (MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE) && ENABLE_WAVING_WATER
pos.y -= 2.0;

float posYbuf = (pos.z / WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH);

pos.y -= sin(posYbuf) * WATER_WAVE_HEIGHT + sin(posYbuf / 7.0) * WATER_WAVE_HEIGHT;
gl_Position = mWorldViewProj * pos;
#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES
vec4 pos = gl_Vertex;
vec4 pos2 = mWorld * gl_Vertex;
vec4 pos2 = mWorld * pos;
/*
* Mathematic optimization: pos2.x * A + pos2.z * A (2 multiplications + 1 addition)
* replaced with: (pos2.x + pos2.z) * A (1 addition + 1 multiplication)
Expand All @@ -57,8 +126,7 @@ void main(void)
pos.z += (smoothTriangleWave(animationTimer*10.0 + pos2XpZ * -0.01) * 2.0 - 1.0) * 0.4;
gl_Position = mWorldViewProj * pos;
#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS
vec4 pos = gl_Vertex;
vec4 pos2 = mWorld * gl_Vertex;
vec4 pos2 = mWorld * pos;
if (gl_TexCoord[0].y < 0.05) {
/*
* Mathematic optimization: pos2.x * A + pos2.z * A (2 multiplications + 1 addition)
Expand All @@ -71,11 +139,11 @@ void main(void)
}
gl_Position = mWorldViewProj * pos;
#else
gl_Position = mWorldViewProj * gl_Vertex;
gl_Position = mWorldViewProj * pos;
#endif

vPosition = gl_Position.xyz;
worldPosition = (mWorld * gl_Vertex).xyz;
worldPosition = (mWorld * pos).xyz;
vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);

vec3 normal, tangent, binormal;
Expand Down
Loading

0 comments on commit 50f8a37

Please sign in to comment.