How to project on object


I’ve trying to realize how to project & draw only inside of PlaneBufferGeometry but not the whole canvas dimension.
Here is the example:

		Width = 0.8;
		Height = 0.8;
		geometry = new THREE.PlaneBufferGeometry(Width, Height, 1, 1);
		material = new THREE.RawShaderMaterial({
			uniforms: {
				time: { value: 1.0 },
				resolution: { value: new THREE.Vector2(Width,Height) }
			vertexShader: `
		      attribute vec4 position;
		      uniform mat4 projectionMatrix;
		      uniform mat4 modelViewMatrix;
		      uniform vec2 resolution;
		      void main() {
		      	gl_Position = projectionMatrix * modelViewMatrix * position;
			fragmentShader: `
		      precision highp float;
		      uniform vec2 resolution;
		      void main() {
		        vec2 st = gl_FragCoord.xy/resolution.xy;		        
		        vec3 color = vec3(st.x,st.y,0.);
		        gl_FragColor = vec4(color,1.0);

When resolution consists of Width & Height, I’ve got the yellow box (r&g always 1) instead of various colors. When resolution consists of window.innerWidth & window.innerHeight, I’ve got various colors (but only part of it) and my PlaneBufferGeometry looks like mask for background canvas…

The point is how to make position projection in shader to draw only inside of PlaneBufferGeometry like on canvas to avoid “mask effect” and also tranform result of shader while transforming an object (i.e. if object is rotated the result of shader also rotated same way).

99% I don’t understand what you mean (a screen / picture / sample could be useful) - but what you’re looking for isn’t just a dynamic texture (since it, indeed, inherits transform from the object it is applied on) ?

here is the example. I need draw a circle using shader inside of PlaneBufferGeometry space and I need it to transform with respect of mesh transformation without using texture. In the example you can see that circle like background of canvas but not mesh (mesh looks like a mask for canvas)… if mesh moves/rotates circle will be at center of canvas always not modified. Is there a way using shader without texture to achieve same effect as texture using?



This is what the example looks to me, no circles there:

Yes, treat the shader output as a texture sample - just multiply it by same matrices you’d multiply a usual texture material (in vertex shader.)

To avoid using textures (loading etc) for simple tasks such as circle as texture (just draw it in shader)

So, It needs to be stored in some internal buffer first (i.e. rendered to some WebGLRenderTarget) and then it can be used as texture? But is it possible to do it on the fly (pass matricies to shader etc) without storing the result?

Here is what I see in the jsfiddle:

If all you need to draw is a very simple circle, you don’t really need to store anything - just calculate the distance from the centre of the geometry (or simply a UV position) - if the distance vectors length is greater than the circle radius, white pixel, smaller or equal the circle radius, black pixel.

Have a look at this topic: Petals 2020 (for NY contest)
There are two point coulds for petals and for blossoms on the tree. “Textures” for both of them are made with shaders on-the-fly.

Yes, but I can’t achieve the result… circle always in the center of canvas and not transformed/translated as mesh transformed/translated

Thanks for example, but it hard to understand how to achieve my goal but I will try ;).

Finally, I’ve got what I want -> jsfiddle example
All I need was to pass not modified position from vertex shader to fragment shader and there st = vpos.xy/box.xy; // where box is width/height of my PlaneBufferGeometry mesh.

Now as you can see it is modified as needed (mesh is translated and rotated at picture):

UPD This solution is with restriction - geometry position/rotation in default state (otherwise some matricies should be applied, I’ve tryied realize which one but without luck)… Only mesh rotation,translation works correct with this solution.

1 Like