Reputation: 3838
In a scenario where vertices are displaced in the vertex shader, how to retrieve their transformed positions in WebGL / Three.js?
Other questions here suggest to write the positions to a texture and then read the pixels, but the resulting value don't seem to be correct.
In the example below the position is passed to the fragment shader without any transformations:
// vertex shader
varying vec4 vOut;
void main() {
gl_Position = vec4(position, 1.0);
vOut = vec4(position, 1.0);
}
// fragment shader
varying vec4 vOut;
void main() {
gl_FragColor = vOut;
}
Then reading the output texture, I would expect pixel[0].r
to be identical to positions[0].x
, but that is not the case.
Here is a jsfiddle showing the problem: https://jsfiddle.net/brunoimbrizi/m0z8v25d/2/
What am I missing?
Upvotes: 1
Views: 1070
Reputation: 5431
You're not writing the vertices out correctly.
https://jsfiddle.net/ogawzpxL/
First off you're clipping the geometry, so your vertices actually end outside the view, and you see the middle of the quad without any vertices.
You can use the uv
attribute to render the entire quad in the view.
gl_Position = vec4( uv * 2. - 1. , 0. ,1.);
Everything in the buffer represents some point on the quad. What seems to be tricky is when you render, the pixel will sample right next to your vertex. In the fiddle i've applied an offset to the world space thing by how much it would be in pixel space, and it didn't really work.
The reason why it seems to work with points is that this is all probably wrong :) If you want to transform only the vertices, then you need to store them properly in the texture. You can use points for this, but ideally they wouldn't be spaced out so much. In your scenario, they would fill the first couple of rows of the texture (since it's much larger than it could be).
You might start running into problems as soon as you try to apply this to something other than PlaneGeometry
. In which case this problem has to be broken down.
Upvotes: 1
Reputation: 3838
Solved. Quite a few things were wrong with the jsfiddle mentioned in the question.
width * height
should be equal to the vertex count. A PlaneBufferGeometry
with 4 by 4 segments results in 25 vertices. 3 by 3 results in 16. Always (w + 1) * (h + 1).1.0 / width
.width
and height
, they can be passed in as uniforms.gl.POINTS
with gl_PointSize = 1.0
.Working jsfiddle: https://jsfiddle.net/brunoimbrizi/m0z8v25d/13/
Upvotes: 1