Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is particle rotation supported in THREE.Particle and THREE.ParticleSystem? #1891

Closed
Hanrui opened this issue May 10, 2012 · 12 comments
Closed
Labels

Comments

@Hanrui
Copy link

Hanrui commented May 10, 2012

Actually two questions here:

Is it still the situation that ParticleSystem is WebGLRenderer-only?

Is it possible to control each particle's velocity, gravity and texture rotation via ParticleSystem? (I know that's feasible via THREE.Sprite in WebGLRenderer. And in CanvasRenderer, texture rotation seems not supported.) -- If all the particles are using the same texture and only different in rotation around Z-axis.

Thank you!

@mrdoob
Copy link
Owner

mrdoob commented May 15, 2012

Is it still the situation that ParticleSystem is WebGLRenderer-only?

Sadly, yes.

Is it possible to control each particle's velocity, gravity and texture rotation via ParticleSystem?

ParticleSystem uses geometry.vertices, so you just need to do the velocity and gravity calculation on your own, then modify the position of the particles and then do geometry.verticesNeedUpdate = true.

@Hanrui
Copy link
Author

Hanrui commented May 16, 2012

Thanks for the reply! For the 2nd question, how about the rotation? I mean if I want the all the particles in the ParticleSystem are sharing the same image but having different rotations (imaging the arrows that may point to up, down, left, right...), is that possible?

Thanks!

@zz85
Copy link
Contributor

zz85 commented May 20, 2012

you could try passing rotation as attributes to the fragment shader where you draw a rotated texture in the shader

@Hanrui
Copy link
Author

Hanrui commented May 21, 2012

Hi @zz85,
Cuz all particles in this ParticleSystem share the same texture, how can I set the different rotations to them?

Thanks!

@zz85
Copy link
Contributor

zz85 commented May 21, 2012

@Hanrui you can pass rotation to them as custom attributes. you can checkout those custom attribute examples. http://mrdoob.github.com/three.js/examples/webgl_custom_attributes_particles2.html

@Hanrui
Copy link
Author

Hanrui commented May 23, 2012

@zz85
I don't need change the color or size of the material, is that possible to use a ParticleBasicMaterial but not ShaderMaterial?
And, how to rotate the texture of each vertex to different directions? I know how to control the particle size and position via custom attributes, but still have no idea on how to rotate its texture picture.

Thanks!

@Hanrui
Copy link
Author

Hanrui commented May 24, 2012

I see there's a demo showing how to rotate the texture with Face4(http://www.html5rocks.com/en/tutorials/webgl/million_letters/), but it's rotating 4 vertex for a face which seems a little heavy for my needs. I just want rotating pictures on each vertex.
Just like the demo you pasted me above: http://mrdoob.github.com/three.js/examples/webgl_custom_attributes_particles2.html, is that possible to make each vertex texture on the sample rotate?

Thanks!

@zz85
Copy link
Contributor

zz85 commented May 24, 2012

THREE.ParticleSystem uses point particles, so I don't think you can really rotate them in the vertex shader. You might probably need to pass rotation from the vertex shader to the fragment shader via varing variables. For that you probably need a ShaderMaterial instead of ParticleBasicMaterial.

Here's some pesudocode I can think of out of my head

--- vertex shader ---
attribute float rotation;
varing float vRotation;

vRotation = rotation;
--- fragment shader ---
varing vRotation;
uniform sampler2D tDiffuse; // your texture

vec2 rotated = vec2(cos(vRotation) * (gl_PointCoord.x - 0.5) + 0.5, sin(vRotation) * (gl_PointCoord.y - 0.5) + 0.5);
vec4 texture = texture2D( tDiffuse,  rotated);
gl_FragColor = vec4(color, 1.0) * texture;

@mrdoob mrdoob closed this as completed May 24, 2012
@Hanrui
Copy link
Author

Hanrui commented May 25, 2012

OK, I finally solved this issue. Thanks @zz85 very much!
Pasting my vertex shader and fragment shader codes here if somebody else meets the same problem later:

  -- vertex shader --
    attribute float size;
    attribute float rotation;
    uniform vec3 ca;

    varying vec3 vColor;
    varying float vRotation;
    varying float vPointSize;

    void main() {
      vColor = ca;
      vRotation = rotation;

      vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
      gl_PointSize = size * ( 300.0 / length( mvPosition.xyz ) );
      gl_Position = projectionMatrix * mvPosition;

      vPointSize = gl_PointSize;
    }

  -- fragment shader --
    uniform vec3 color;
    uniform sampler2D texture;

    varying vec3 vColor;
    varying float vRotation;
    varying float vPointSize;

    void main() {
      float mid = 0.5;
      vec2 rotated = vec2(cos(vRotation) * (gl_PointCoord.x - mid) + sin(vRotation) * (gl_PointCoord.y - mid) + mid,
                          cos(vRotation) * (gl_PointCoord.y - mid) - sin(vRotation) * (gl_PointCoord.x - mid) + mid);
      vec4 rotatedTexture = texture2D( texture,  rotated);
      gl_FragColor = vec4( color * vColor, 1.0 ) * rotatedTexture;
    }

@AmdEagle
Copy link

AmdEagle commented Dec 1, 2015

i have tried this shader for rotating a Point inside my THREE.Points but the output seems to look wierd.
untitled

//=========== My Vertex Shader ===============//

attribute vec3 color;
attribute float size;
attribute float rotation;

varying vec3 vColor;
varying float vRot;
void main()
{
    vColor = color;
    vRot = rotation;
    vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );          
    gl_PointSize = size * ( 300.0 / length( mvPosition.xyz ) );
    gl_Position = projectionMatrix * mvPosition;
}

//===========| my fragment shader |=================//

uniform sampler2D texture;
varying vec3 vColor;
varying float vRot; 
void main()
{
    vec4 outColor   = texture2D( texture, gl_PointCoord );
    if( outColor.a < 0.5  )
    {
        discard;    
    }       
    float mid = 0.5;
    vec2 rotated = vec2(cos(vRot) * (gl_PointCoord.x - mid) + sin(vRot) * (gl_PointCoord.y - mid) + mid,    cos(vRot) * (gl_PointCoord.y - mid) - sin(vRot) * (gl_PointCoord.x - mid) + mid);
        vec4 rotatedTexture = texture2D( texture, rotated );                
    gl_FragColor    = outColor * vec4( 1.0, 0.0, 0.0 , 1.0 ) * rotatedTexture;
}

Please help me i am not sure what i am doing wrong

@WestLangley
Copy link
Collaborator

@balakrishnanv Please use stackoverflow for help.

@neilning-xc
Copy link

@Hanrui Cool! It works perfectly!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants