WebGL- добавить метку и выбрать объект

Я пробовал выбирать, используя технику цветового индекса, но я хочу использовать технику лучевого вещания, а также добавить метку 3d на выбранной точке 3d.

Я новичок в webgl, и я хочу пример кода о том, как сделать выбор объекта в webgl с помощью raycasting.

как сделать проект и unproject в webgl.

Я использую чистый WebGl для этого (не Three.js или другие фреймворки), поэтому помогите мне с примерами кода WebGL.

1 ответ

Если вы заинтересованы в решении на базе процессора, вот как:

Прежде всего, чтобы преобразовать мировое пространство в координаты экранного пространства, все, что вам нужно сделать, - это преобразовать мир pos с помощью матрицы проекции вида. Затем вам нужно сделать перспективное деление, разделив x,y,z на w. Это оно. Эта форма имеет наибольшее значение для меня: (Предполагая, что у вас есть соответствующие матричные функции):

vec3.toScreenSpace = function(out, v3, viewProjectionMatrix, width, height){
    vec3.transformByMat(out, v3, viewProjectionMatrix);
    var m = viewProjectionMatrix;
    var w = m[3] * v3[0] + m[7] * v3[1] + m[11] * v3[2] + m[15]; // required for perspective divide
    if (w !== 0){
        var invW = 1.0/w;
        out[0] = (out[0]*invW+1)/2 * width;
        out[1] = (1-out[1]*invW)/2 * height; // note: Y axis oriented top -> down in screen space
    }
    return out;
};

Преобразование экранного пространства в мировое пространство является в основном обратной операцией с матрицей проекции обратного вида:

vec3.toWorldSpace = function(out, v3, viewProjectionMatrix, width, height){
    // expects v3[2] (z value) to be -1 if want position at zNear and +1 at zFar
    var invViewProj = mat4.inverse(vec3.SHARED_MAT4, viewProjectionMatrix);
    var x = 2*v3[0]/width - 1.0;
    var y = 1.0 - (2*v3[1]/height); // note: Y axis oriented top -> down in screen space
    var z = v3[2];
    out[0] = x;
    out[1] = y;
    out[2] = z;
    var m = invViewProj;
    vec3.transformByMat(out, out, m);
    var w = m[3] * x + m[7] * y + m[11] * z + m[15]; // required for perspective divide
    if (w !== 0){
        var invW = 1.0/w;
        out[0] *= invW;
        out[1] *= invW;
        out[2] *= invW;
    }

    return out;
};

Затем, когда вы выбираете координаты оси и Y на экране, вы можете вычислить луч в мировом пространстве следующим образом:

function screenPickTest(x, y){
    var pos = SHARED_V;
    var posFar = SHARED_V2;
    pos[0] = x;
    pos[1] = y;
    pos[2] = -1;

    posFar[0] = x;
    posFar[1] = y;
    posFar[2] = +1;

    pos = vec3.toWorldSpace(pos, pos, viewProjection, canvas.width, canvas.height);
    posFar = vec3.toWorldSpace(posFar, posFar, viewProjection, canvas.width, canvas.height);

    var dir = vec3.minus(SHARED_V2, posFar, pos);

    return raySweepTestAgainst____(pos, dir, COLLISION_GEOMETRYS);
}

Вы должны реализовать функцию обнаружения столкновений, которая обнаруживает первый объект, куда луч попадает, и возвращает точку столкновения (вместе с другими данными, если требуется).

При этом вы можете создать метку в точке столкновения и т. Д.

Другие вопросы по тегам