Как получить координаты комнаты (или экрана) из шейдера Gamemaker Studio 2? - PullRequest
1 голос
/ 06 февраля 2020

Я в основном новичок в написании шейдеров, и, возможно, это не лучшее место для начала, но я пытаюсь сделать шейдер, чтобы объект "сверкал". Я не буду вдаваться в подробности того, как он должен выглядеть, но для его создания мне нужно значение, которое меняется в зависимости от положения объекта в комнате (или на экране, поскольку камера зафиксирована). Я пробовал v_vTexcoord, in_Position, gl_Position и другие без ожидаемого результата. Если бы я использовал их неправильно или что-то пропустил, я бы не удивился, но любой совет полезен.

Не думаю, что они будут полезны, но вот мой вершинный шейдер:

//it's mostly the same as the default
// Simple passthrough vertex shader
//
attribute vec3 in_Position;                  // (x,y,z)
//attribute vec3 in_Normal;                  // (x,y,z)     unused in this shader.
attribute vec4 in_Colour;                    // (r,g,b,a)
attribute vec2 in_TextureCoord;              // (u,v)

varying vec2 v_vTexcoord;
varying vec4 v_vColour;
varying vec3 v_inpos;

void main()
{
    vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0);
    gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos;

    v_vColour = in_Colour;
    v_vTexcoord = in_TextureCoord;
    v_inpos = /*this is the variable that i'd like to set to the x,y*/;
}

и мой фрагментный шейдер:

//
//
//
varying vec2 v_vTexcoord; //x is <1, >.5
varying vec4 v_vColour;
varying vec3 v_inpos;
uniform float pixelH; //unused, but left in for accuracy
uniform float pixelW; //see above

void main() //WHEN AN ERROR HAPPENS, THE SHADER JUST WON'T DO ANYTHING AT ALL.
{
    vec2 offset = vec2 (pixelW, pixelH);
    gl_FragColor = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord );

    /* i am planning on just testing different math until something works, but i can't
    vec3 test = vec3 (v_inpos.x, v_inpos.x, v_inpos.x); //find the values i need to test it
    test.x = mod(test.x,.08);
    test.x = test.x - 4;
    test.x = abs(test.x);


    while (test.x > 1.0){
        test.x = test.x/10;
    }
    test = vec3 (test.x, test.x, test.x);
    gl_FragColor.a = test.x;
    */
    //everything above doesn't cause an error when uncommented, i think

    //if (v_inpos.x == 0.0){gl_FragColor.rgb = vec3 (1,0,0);}
    //if (v_inpos.x > 1)  {gl_FragColor.rgb = vec3 (0,1,0);}
    //if (v_inpos.x < 1)  {gl_FragColor.rgb = vec3 (0,0,1);}
}

, если этот вопрос не имеет смысла, я постараюсь прояснить любые другие вопросы в комментариях.

1 Ответ

2 голосов
/ 06 февраля 2020

Если вы хотите получить позицию в мировом пространстве, то вам нужно преобразовать координату вершины из модельного пространства в мировое пространство.
Это может сделать матрица модели (мира) (gm_Matrices[MATRIX_WORLD]). См. game-maker-studio-2 - Матрицы .

Например:

vec4 object_space_pos = vec4(in_Position.xyz, 1.0);
vec4 world_space_pos  = gm_Matrices[MATRIX_WORLD] * object_space_pos;

Нет, можно получить декартову позицию в мировом пространстве по:
(см. также Swizzling)

vec3 pos = world_space_pos.xyz;
...