{"action":"created","issue":{"url":"https://api.github.com/repos/melonjs/melonJS/issues/637","labels_url":"https://api.github.com/repos/melonjs/melonJS/issues/637/labels{/name}","comments_url":"https://api.github.com/repos/melonjs/melonJS/issues/637/comments","events_url":"https://api.github.com/repos/melonjs/melonJS/issues/637/events","html_url":"https://github.com/melonjs/melonJS/issues/637","id":54693623,"number":637,"title":"Reconcile the global matrix","user":{"login":"parasyte","id":456942,"avatar_url":"https://avatars.githubusercontent.com/u/456942?v=3","gravatar_id":"","url":"https://api.github.com/users/parasyte","html_url":"https://github.com/parasyte","followers_url":"https://api.github.com/users/parasyte/followers","following_url":"https://api.github.com/users/parasyte/following{/other_user}","gists_url":"https://api.github.com/users/parasyte/gists{/gist_id}","starred_url":"https://api.github.com/users/parasyte/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/parasyte/subscriptions","organizations_url":"https://api.github.com/users/parasyte/orgs","repos_url":"https://api.github.com/users/parasyte/repos","events_url":"https://api.github.com/users/parasyte/events{/privacy}","received_events_url":"https://api.github.com/users/parasyte/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/melonjs/melonJS/labels/Improvement","name":"Improvement","color":"d7e102"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/melonjs/melonJS/milestones/5","html_url":"https://github.com/melonjs/melonJS/milestones/Future","labels_url":"https://api.github.com/repos/melonjs/melonJS/milestones/5/labels","id":173694,"number":5,"title":"Future","description":"A general milestone for tickets \"on the back burner\" -- for future consideration.","creator":{"login":"parasyte","id":456942,"avatar_url":"https://avatars.githubusercontent.com/u/456942?v=3","gravatar_id":"","url":"https://api.github.com/users/parasyte","html_url":"https://github.com/parasyte","followers_url":"https://api.github.com/users/parasyte/followers","following_url":"https://api.github.com/users/parasyte/following{/other_user}","gists_url":"https://api.github.com/users/parasyte/gists{/gist_id}","starred_url":"https://api.github.com/users/parasyte/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/parasyte/subscriptions","organizations_url":"https://api.github.com/users/parasyte/orgs","repos_url":"https://api.github.com/users/parasyte/repos","events_url":"https://api.github.com/users/parasyte/events{/privacy}","received_events_url":"https://api.github.com/users/parasyte/received_events","type":"User","site_admin":false},"open_issues":64,"closed_issues":6,"state":"open","created_at":"2012-09-12T06:48:16Z","updated_at":"2015-09-06T07:26:08Z","due_on":null,"closed_at":null},"comments":1,"created_at":"2015-01-18T11:27:44Z","updated_at":"2015-09-20T06:41:38Z","closed_at":null,"body":"This ticket will pick up where #591 leaves off. The goal here is to remove dependence on the global matrix, as much as possible. It will allow us to put almost every matrix transformation entirely within the GPU, where it can take advantage of highly parallelized vector ALUs that we don't have access to in JavaScript.\r\n\r\nTo start, recall that 3D rendering typically uses three matrices; called \"model matrix\", \"view matrix\", and \"projection matrix\". Working backwards, melonJS needs the projection matrix to transform our pixel coordinates to WebGL cube space coordinates using orthographic projection; and a view matrix is used for nested containers and other object that need relative drawing operations. The model matrix is unnecessary because the majority of entities drawn in melonJS are quads (exactly two triangles). A model matrix is more useful with large meshes, which have a greater number of vertices.\r\n\r\nThe scaling and rotation values can be streamed to the GPU as part of the vertex attribute array. These can be packed into 2 floats (a 3x3 matrix requires 6 floats for full precision) assuming 16 bits for each of the scaling coordinates. Additionally, the rotation angle and texture index can be packed into the same float. The anchor point will also be required, which is a 3rd float. These attributes can be applied within the vertex shader, since the order of operations is static; translation can be added to the destination coordinates before calling `drawImage`.\r\n\r\nEntities that need a model matrix can implement one with a custom compositor and shader. Spine is an example that will benefit from a model matrix.\r\n\r\nTo reconcile the global matrix, we need to remove most of the matrix transformation usage. `me.Sprite` and `me.Particle` make heavy use of the global matrix right now. Here is the last proposal for a replacement: https://github.com/melonjs/melonJS/issues/591#issuecomment-68618550 The important part is that the first argument provides information about things like scaling and rotation for each `drawImage` call. The function signature will have to change to accept a texture region instead of coordinates, as an additional optimization. See: https://github.com/melonjs/melonJS/commit/e785724ac5439f27e43a3a9c42a5eaa082bff1f2#commitcomment-9329151\r\n\r\nWith that part done, each view matrix transformation will be treated as change in WebGL state; it will be sent to the GPU as a uniform variable, so changes to the matrix require flushing the compositor. This will be pretty efficient, assuming view matrix transformations only occur on `me.Container` boundaries.\r\n\r\nAdditional TODO items:\r\n\r\n* [ ] Implement fonts (hard), lines (easy), stroke (hard)\r\n* [ ] Create a packet inspector for debugging\r\n* [ ] Enable mipmapping on power-of-two textures\r\n* [ ] Pack multiple attributes into each float\r\n* [ ] Use a standard sampler2D-uniform on mobile\r\n\r\n**Attribute Packing**: E.g. texture coordinates can be packed into a single float, since each axis will never be bigger than 65,536 pixels (fits into 16-bits). The packing algorithms will provide less than 16-bits of precision, probably 15-bits, which is still plenty for texture coordinates. Another candidate is colors, and much bigger win: pack a `vec4` into a single float with almost no loss in precision!\r\n"},"comment":{"url":"https://api.github.com/repos/melonjs/melonJS/issues/comments/141753053","html_url":"https://github.com/melonjs/melonJS/issues/637#issuecomment-141753053","issue_url":"https://api.github.com/repos/melonjs/melonJS/issues/637","id":141753053,"user":{"login":"parasyte","id":456942,"avatar_url":"https://avatars.githubusercontent.com/u/456942?v=3","gravatar_id":"","url":"https://api.github.com/users/parasyte","html_url":"https://github.com/parasyte","followers_url":"https://api.github.com/users/parasyte/followers","following_url":"https://api.github.com/users/parasyte/following{/other_user}","gists_url":"https://api.github.com/users/parasyte/gists{/gist_id}","starred_url":"https://api.github.com/users/parasyte/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/parasyte/subscriptions","organizations_url":"https://api.github.com/users/parasyte/orgs","repos_url":"https://api.github.com/users/parasyte/repos","events_url":"https://api.github.com/users/parasyte/events{/privacy}","received_events_url":"https://api.github.com/users/parasyte/received_events","type":"User","site_admin":false},"created_at":"2015-09-20T06:41:38Z","updated_at":"2015-09-20T06:41:38Z","body":"I'll just add a note here: mobile platforms *hate* the fragment shader I wrote. The sampler2D array trick causes the GPU to run very poorly. (I've added a TODO item here to get this fixed.)"}}