2017-10-07 6 views
1

Je joue avec webgl copié de this page. Je veux utiliser la souris pour contrôler la position de la lumière.Webgl - position de la souris dynamique

Si je viens d'envoyer la valeur statique js-fragment shader il fonctionnera:

mouseLocation = gl.getUniformLocation(program, "mouse"); 
gl.uniform2f(mouseLocation, 0,0); 

J'ai une fonction de mettre à jour la position de la souris:

function updateMousePosition(e){ 
    console.log(e.pageX); 
    mousex = e.pageX; 
    mousey = e.pageY; 
} 

qui est appelée lorsque déplacement de la souris:

canvas.addEventListener('mousemove', updateMousePosition, false); 

puis envoyer la position de la souris à fragment shader chaque image:

gl.uniform2f(mouseLocation, mousex,mousey); 

Après que je vais obtenir la position de la souris de fragment shader:

uniform vec2 mouse; 

void main(void) { 
    //mp - mouse position 
    vec2 mp = vec2(mouse.x/resolution.x, 1.0 - mouse.y/resolution.y); 

    //lp depend on mp 
    vec3 lp = vec3(mp.x, mp.y, -1.0); 

    //other calculation ... 
} 

il ne fonctionne pas. Mais quand je fait descendre la valeur statique de console.log dans updateMousePosition(e):

gl.uniform2f(mouseLocation, 679, 590);//number taken from console.log 

travail il.

Je ne suis pas sûr de ce qui ne fonctionne pas mais je suspecte est le format ou le type du nombre, js n'est pas strictement le type mais glsl est.

Comment puis-je résoudre ce problème?

+0

Vous devez afficher plus de code. Il n'y a rien de mal avec ce que vous avez montré. – gman

Répondre

0

Finaly a décidé de mettre cette réponse (éditée).

Comme l'a commenté Gman, il n'y a pratiquement rien de mal avec votre code. Techniquement, cela devrait fonctionner. Cependant vous avez souligné un aspect délicat du couple WebGL/Javascript par rapport à OpenGL: Le typage. Et en raison de la façon dont les variables Javascript fonctionnent, vous générez facilement des bogues étranges.

Imaginez cette situation absurde:

var x = 55; 
var y = 128; 

// some code here... 

x = "blah"; // oups ! 

// some code here... 

gl.uniform2f(mouseLocation, x, y); 

Avec C, C++ ou autre langage fort typé, telle absurdité est presque impossible de le faire (ce qui est possible grâce à des pointeurs, mais cela est un autre sujet), parce que le compilateur interdisez-le strictement et jetez une erreur. Mais en javascript, il n'y a pas de problème, et dans ce cas, la variable numérique x devient une variable chaîne, et lorsqu'elle est passée à WebGL, elle devient NaN. Si vous n'avez pas suivi correctement la variable x, vous allez chercher longtemps pourquoi cela ne fonctionne pas.

Toutes les fonctions WebGL n'acceptent que les données saisies dans la dernière étape, car la dernière étape est le GPU et le GPU est de bas niveau. C'est-à-dire, même si vous transmettez une variable Pure Javascript Number à une fonction WebGL, cette variable Javascript sera convertie en données typées auparavant. Mais le fait est que Javascript ne jettera jamais une erreur sur les types de variables incorrectes: Il convertit (cast) en données typées, et même si ce que vous essayez de faire est absurde, il ne vous avertira jamais, il transformera les données non convertibles en 'NaN'.

Heureusement, pour éviter toute ambiguïté, WebGL est livré avec un tas de nouveaux objets Javascript: les tableaux typés: https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/TypedArray

avec les tableaux typés, vous pouvez savoir dans votre code javascript quelles données sont stockées, et ainsi les données sera envoyé au GPU avant de l'envoyer. En d'autres termes, vous pouvez utiliser un tableau typé pour convertir (convertir) des variables Javascript en données typées connues avant de les envoyer au GPU.

var mousePos = new Float32Array(2); 

function updateMousePosition(e){ 
    mousePos[0] = e.pageX; 
    mousePos[1] = e.pageY; 
} 

// do something 

console.log(mousePos); 
gl.uniform2fv(mouseLocation, mousePos); 

Dans l'exemple ci-dessus, les variables e.pageX et e.pageY sont directement converties en données tapées compatible WebGL. De cette façon, si vous imprimez maintenant la variable mousePos en utilisant console.log vous verrez ce qui sera vraiment envoyé, comme ça, à WebGL. Pour le débogage, vous pouvez mettre le console.log juste avant l'appel à gl.uniform2fv pour vous assurer que rien de mal ne s'est produit "hors de vue".

Dans cet exemple, si des données ont été incorrectement converties, vous verrez quelque chose comme NaN, NaN dans votre journal de sortie, vous savez donc que vous devez chercher quelque part une erreur dans votre code.

+0

J'ai en quelque sorte compris ce qui s'est passé mais j'ai oublié de mettre à jour la réponse. Vous avez raison dans votre réponse. Cependant, ma solution est similaire mais plus simple. Je viens de déclarer et d'initialiser la variable comme 'var x = 0.0' alors tout fonctionne comme un charme. Quoi qu'il en soit, j'accepte votre réponse pour l'explication des détails. – sooon