• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Makers_F

Set some specific vertex position, interpolating it for the others

0 posts in this topic

I have a mesh composed by numerous vertices (600 ± 300 ).

The vertices are simply disposed on 2 parallel line, so that every vertices on a line have the y component equal to the other(they practically are along the sides of a rectangle orthogonal to the screen).
I'm working in a 2D world.

I'm trying to position some vertices in specific points i pass to the shader, and make the other vertices interpolate their position from them.
I generate in my code this matrix

[CODE]
u_specialCoordinatesLocation = {
x1, x2, x3, x4,
y1, y2, y3, y4,
x5, x6, x7, x8,
y5, y6, y7, y8 };
[/CODE]

and pass it to the shader as an uniform (transposing it).

This is the code of the shader. Below i explain it.

[CODE]
/* upperVertexShader*/
/* externally defined:
* QUALITY_CODE
* SCREEN_WIDTH
* SCREEN_HEIGHT
*/

uniform mat4 u_modelViewProjectionMatrix;
uniform vec2 u_playerPosition;
uniform float u_elapsedSeconds;
/*
* mat4 = {
* {x1, x2, x3, x4},
* {y1, y2, y3, y4},
* {x5, ...},
* {}}
*/

uniform mat4 u_specialCoordinatesPosition;

attribute vec4 a_position;
attribute vec2 a_textureCoordinates;

varying vec2 v_textureCoordinates;
varying vec2 v_playerPosition;
varying vec2 v_pointPosition;

const float ERROR_LIMIT = 0.01;
const float MIN_VALUE = -2e6;
const float MAX_VALUE = 2e6;

float linearInterp(float n0, float n1, float a) {
return ((1.0 - a) * n0) + (a * n1);
}

float scurve5(float a) {
float a3 = a*a*a;
float a4 = a3 * a;
float a5 = a4 * a;
return (6.0 * a5) - (15.0 * a4) + (10.0 * a3);
}

float min4fv(vec4 vector) {
return min(min(vector.x, vector.y),min(vector.z, vector.w));
}

float max4fv(vec4 vector) {
return max(max(vector.x, vector.y),max(vector.z, vector.w));
}

/* only return the correct value to offset the vertex if the vertex is one of the ones in the uniform, 0.f otherwise*/
float offsetValue(float Xposition) {
float offSet = 0.0;
vec4 tmp_vector4;
vec4 positionX = vec4(Xposition);

// first row
// 1.0 if positionX is almost equal to the one specified in the uniform
tmp_vector4 = 1.0 - step(ERROR_LIMIT, abs(u_specialCoordinatesPosition[0] - positionX));
tmp_vector4 = tmp_vector4 * u_specialCoordinatesPosition[1];
offSet += tmp_vector4.x + tmp_vector4.y + tmp_vector4.z + tmp_vector4.w;

// second row
tmp_vector4 = 1.0 - step(ERROR_LIMIT, abs(u_specialCoordinatesPosition[2] - positionX));
tmp_vector4 = tmp_vector4 * u_specialCoordinatesPosition[3];
offSet += tmp_vector4.x + tmp_vector4.y + tmp_vector4.z + tmp_vector4.w;

return offSet;
}

vec2 interpolationVertices(float vertexX) {
/* .x = left distance
* .y = right distance
*/
vec2 distances;

/* 0 if at the left of the vertex, else 1*/
vec4 left_filter;
/* 1 if at the left of the vertex, else 0*/
vec4 right_filter;

vec4 positionX = vec4(vertexX);
/* First row*/
left_filter = step(positionX + ERROR_LIMIT, u_specialCoordinatesPosition[0]);
// grants that the vertices at the right of the point will not count, by adding only to them a very negative number
distances.x = max4fv(u_specialCoordinatesPosition[0] - positionX + left_filter * MIN_VALUE);

right_filter = 1.0 - step(positionX - ERROR_LIMIT, u_specialCoordinatesPosition[0]);
// grants that the vertices at the left of the point will not count, by adding only to them a very positive number
distances.y = min4fv(u_specialCoordinatesPosition[0] - positionX + left_filter * MAX_VALUE);

/* Second row*/
left_filter = step(positionX + ERROR_LIMIT, u_specialCoordinatesPosition[2]);
// grants that the vertices at the right of the point will not count, by adding only to them a very negative number
distances.x = max(distances.x, max4fv(u_specialCoordinatesPosition[2] - positionX + left_filter * MIN_VALUE));

right_filter = 1.0 - step(positionX - ERROR_LIMIT, u_specialCoordinatesPosition[2]);
// grants that the vertices at the left of the point will not count, by adding only to them a very positive number
distances.y = min(distances.y , min4fv(u_specialCoordinatesPosition[2] - positionX + left_filter * MAX_VALUE));

return distances;
}

float interpolatedValue(float vertexX) {
vec2 interpVertices = interpolationVertices(vertexX);
vec2 interpValue = vec2(offsetValue(vertexX + interpVertices.x), offsetValue(vertexX + interpVertices.y));
float int_value = scurve5(abs((vertexX - interpVertices.x) / (interpVertices.y - interpVertices.x)));
return linearInterp(interpValue.x, interpValue.y, int_value);
}

void main(void)
{
v_textureCoordinates = a_textureCoordinates;
v_playerPosition = u_playerPosition;
v_pointPosition = a_position.xy;
v_pointPosition.y += interpolatedValue(a_position.x) * (a_position.y) / (a_position.y + 0.0001);
vec4 temp_position = u_modelViewProjectionMatrix * vec4(v_pointPosition, a_position.z, a_position.w);
gl_Position = temp_position;
}
[/CODE]

The vertices y position in the VBO have only 2 different values: 0, or another fixed value (SCREEN_HEIGHT/3).
The vertices that have position.y = 0 shouldn't be moved, so
[CODE]
v_pointPosition.y = interpolatedValue(a_position.x) * (a_position.y) / (a_position.y + 0.0001);
[/CODE]

is equal 0 if a_position.y is 0, else is almost equal
[CODE]
v_pointPosition.y = interpolatedValue(a_position.x);
[/CODE]

The function
[CODE]float offsetValue(float Xposition)[/CODE]

should find the value of the Ya in the u_specialCoordinateLocation when passed Xa, 0 otherwise.
The 1.0 - step function is used in order to only account for the correct value each time (since only if the passed vertices distance from the Xa is less than ERROR_LIMIT it will be set to 1.0 and then multiplied by the Ya value)

The function
[CODE]vec2 interpolationVertices(float vertexX)[/CODE]

should find the Xa and Xb value of the 2 vertices inside the u_specialCoordinateLocation matrix that are nearest to the passed x coordinate.
This is achived by calculating the max of the distance from the left (that should be negative) without taking into account the values bigger than 0
In fact
[CODE]
left_filter = step(positionX + ERROR_LIMIT, u_specialCoordinatesPosition[0]);
[/CODE]
will set each component to 0 for each vertex on the left of the passed X position, and to 1.0 otherwise, while
[CODE]
u_specialCoordinatesPosition[0] - positionX + left_filter * MIN_VALUE
[/CODE]
will subtract a big value if the filter component is set to 1, thus making impossible to vertices at the right of the position X to contribute once this value is passed to max4fv()

The same is done for the right distance, and then the 2 X coordinates of the 2 vertices are returned.

Finally
[CODE]
float interpolatedValue(float vertexX)
[/CODE]
find the 2 vertices "bounding" the passed vertex, retrieve their values, interpolate between them, and return the new position.

I think everything should work, but when i test it on my phone the mesh doesn't show up.
What i'm doing wrong?
Is there a better way of doing it, i must admit that my code isn't really stright forward, and i wish there is a more elegant way?
What do you suggest? (rebuilding the VBO on the cpu and streaming is not a viable option since i would need to do it every frame for 2 meshes of this kind)

Thanks for the help and the patience Edited by Makers_F
0

Share this post


Link to post
Share on other sites

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
Sign in to follow this  
Followers 0