void shader( GLWindow& window, GLRenderer& renderer ) {

 auto camera = PerspectiveCamera::create(
    60, ( float )renderer.width() / renderer.height(), 1, 10000
  );
  camera->position().z = 300;

  auto scene = Scene::create();
  auto texture = ImageUtils::loadTexture( threeDataPath( "textures/sprites/spark1.png" ) );

  Uniforms uniforms;
  uniforms[ "color" ]      = Uniform( THREE::c, Color( 0xffffff ) );
  uniforms[ "texture" ]    = Uniform( THREE::t, texture.get() );

  Attributes attributes;
  attributes[ "size" ]        = Attribute( THREE::f );
  attributes[ "customColor" ] = Attribute( THREE::c );

  auto shaderMaterial = ShaderMaterial::create(
    vertexShader,
    fragmentShader,
    uniforms,
    attributes,
    Material::Parameters().add( "blending", THREE::AdditiveBlending )
                          .add( "depthTest", false )
                          .add( "transparent", true )
  );

  // Geometries
  const auto radius = 200.f;
  const auto pointCount = 100000;

  auto geometry = Geometry::create();

  auto& vertices = geometry->vertices;
  vertices.reserve( pointCount );

  std::generate_n(
    std::back_inserter(vertices),
    pointCount,
    [=]() -> Vector3 {
      return Vector3( Math::random(-1.f, 1.f),
                      Math::random(-1.f, 1.f),
                      Math::random(-1.f, 1.f) ).multiplyScalar( radius );
    }
  );

  auto sphere = ParticleSystem::create( geometry, shaderMaterial );
  sphere->geometry->dynamic = true;
  sphere->sortParticles = false;

  std::vector<float> values_size( pointCount );
  std::vector<Color> values_color( pointCount );

  for ( int v = 0; v < pointCount; v++ ) {

    values_size[ v ] = 10;
    values_color[ v ].set( 0xffaa00 );

    if ( vertices[ v ].x < 0 )
      values_color[ v ].setHSL( 0.5f + 0.1f * ( (float)v / pointCount ), 0.7f, 0.5f );
    else
      values_color[ v ].setHSL( 0.0f + 0.1f * ( (float)v / pointCount), 0.9f, 0.5f );

  }

  auto& size  = shaderMaterial->attributes[ "size" ];
  auto& color = shaderMaterial->attributes[ "customColor" ];

  size.value  = values_size;
  color.value = values_color;

  scene->add( sphere );

  /////////////////////////////////////////////////////////////////////////

  window.addEventListener( SDL_WINDOWEVENT, [&]( const SDL_Event& event ) {
    if (event.window.event != SDL_WINDOWEVENT_RESIZED) return;
    camera->aspect = ( float )event.window.data1 / event.window.data2;
    camera->updateProjectionMatrix();
    renderer.setSize( event.window.data1, event.window.data2 );
  } );

  /////////////////////////////////////////////////////////////////////////

  auto time = 0.f;

  window.animate( [&]( float dt ) -> bool {

    time += dt;
    sphere->rotation().z = time * 0.03f;

    auto& sizes = size.value.cast<std::vector<float>>();
    for( size_t i = 0; i < sizes.size(); i++ ) {
      sizes[ i ] = 10.f + 9.f * Math::sin( 0.1f * i + time * 3.f );
    }
    size.needsUpdate = true;

    renderer.render( *scene, *camera );

    return true;

  } );

}
Exemple #2
0
void geometries( GLWindow& window, GLRenderer& renderer ) {

    auto camera = PerspectiveCamera::create(
                      45, ( float )renderer.width() / renderer.height(), 10, 20000
                  );
    camera->position().y = 700;

    auto scene = Scene::create();

    scene->add( AmbientLight::create( 0x404040 ) );

    auto light = DirectionalLight::create( 0xffffff );
    light->position().set( 0, 1, 0 );
    scene->add( light );

    auto map = ImageUtils::loadTexture( threeDataPath( "textures/UV_Grid_Sm.jpg" ) );
    map->wrapS = map->wrapT = THREE::RepeatWrapping;
    map->anisotropy = 16;

    auto material = MeshLambertMaterial::create(
                        Material::Parameters()
                        .add( "ambient", Color( 0xbbbbbb ) )
                        .add( "map", map )
                        .add( "side", THREE::DoubleSide )
                    );

    //

    auto sphere = Mesh::create( SphereGeometry::create( 75, 20, 10 ), material );
    sphere->position().set( -400, 0, 200 );
    scene->add( sphere );

    auto ico = Mesh::create( IcosahedronGeometry::create( 75, 1 ), material );
    ico->position().set( -200, 0, 200 );
    scene->add( ico );

    auto octa = Mesh::create( OctahedronGeometry::create( 75, 2 ), material );
    octa->position().set( 0, 0, 200 );
    scene->add( octa );

    auto tetra = Mesh::create( TetrahedronGeometry::create( 75, 0 ), material );
    tetra->position().set( 200, 0, 200 );
    scene->add( tetra );

    //

    auto plane = Mesh::create( PlaneGeometry::create( 100, 100, 4, 4 ), material );
    plane->position().set( -400, 0, 0 );
    scene->add( plane );

    auto cube = Mesh::create( BoxGeometry::create( 100, 100, 100, 4, 4, 4 ), material );
    cube->position().set( -200, 0, 0 );
    scene->add( cube );

    auto circle = Mesh::create( CircleGeometry::create( 50, 20, 0, Math::PI() * 2 ), material );
    circle->position().set( 0, 0, 0 );
    scene->add( circle );

    auto ring = Mesh::create( RingGeometry::create( 10, 50, 20, 5, 0, Math::PI() * 2 ), material );
    ring->position().set( 200, 0, 0 );
    scene->add( ring );

    auto cylinder = Mesh::create( CylinderGeometry::create( 25, 75, 100, 40, 5 ), material );
    cylinder->position().set( 400, 0, 0 );
    scene->add( cylinder );

    //

    std::vector<Vector3> points;
    for ( auto i = 0; i < 50; i ++ ) {

        points.push_back( Vector3( Math::sin( (float)i * 0.2 ) * Math::sin( (float)i * 0.1 ) * 15 + 50, 0, ( (float)i - 5 ) * 2 ) );

    }

    auto lathe = Mesh::create( LatheGeometry::create( points, 20 ), material );
    lathe->position().set( -400, 0, -200 );
    scene->add( lathe );

    auto torus = Mesh::create( TorusGeometry::create( 50, 20, 20, 20 ), material );
    torus->position().set( -200, 0, -200 );
    scene->add( torus );

    auto torusKnot = Mesh::create( TorusKnotGeometry::create( 50, 10, 50, 20 ), material );
    torusKnot->position().set( 0, 0, -200 );
    scene->add( torusKnot );

    auto axis = AxisHelper::create( 50 );
    axis->position().set( 200, 0, -200 );
    scene->add( axis );

    auto arrow = ArrowHelper::create( Vector3( 0, 1, 0 ), Vector3( 0, 0, 0 ) );
    arrow->setLength(50);
    arrow->position().set( 400, 0, -200 );
    scene->add( arrow );

    /////////////////////////////////////////////////////////////////////////

    window.addEventListener( SDL_WINDOWEVENT, [&]( const SDL_Event& event ) {
        if (event.window.event != SDL_WINDOWEVENT_RESIZED) return;
        camera->aspect = ( float )event.window.data1 / event.window.data2;
        camera->updateProjectionMatrix();
        renderer.setSize( event.window.data1, event.window.data2 );
    } );

    /////////////////////////////////////////////////////////////////////////

    auto time = 0.f;
    int benchmarkFrames = 100000;

    window.animate( [&]( float dt ) -> bool {

        time += dt;

        camera->position().x = Math::cos( time * 0.2 ) * 800;
        camera->position().z = Math::sin( time * 0.2 ) * 800;
        camera->lookAt( scene->position() );

        for ( size_t i = 0; i < scene->children.size(); i ++ ) {

            auto& object = scene->children[ i ];

            object->rotation().x = time * 1;
            object->rotation().y = time * 0.25;

        }

        renderer.render( *scene, *camera );

        return --benchmarkFrames > 0;

    } );

}
Exemple #3
0
void particles_billboards( GLWindow& window, GLRenderer& renderer ) {

  auto camera = PerspectiveCamera::create(
    55, ( float )renderer.width() / renderer.height(), 2.f, 2000
  );
  camera->position().z = 1000;

  auto scene = Scene::create();
  scene->fog = FogExp2::create( 0x000000, .001f );

  auto geometry = Geometry::create();

  const auto particleCount = 10000;
  geometry->vertices.reserve( particleCount );

  std::generate_n( std::back_inserter( geometry->vertices ),
                   particleCount,
                   [] { return Vector3( Math::random(-1000.f, 1000.f),
                                        Math::random(-1000.f, 1000.f),
                                        Math::random(-1000.f, 1000.f) ); } );

  auto sprite = ImageUtils::loadTexture(
    threeDataPath("textures/sprites/disc.png")
  );

  auto material = ParticleSystemMaterial::create(
    Material::Parameters().add( "size", 35.f )
                          .add( "map", sprite )
                          .add( "sizeAttenuation", false )
                          .add( "transparent", true)
  );
  material->color.setHSL( 1.f, 0.3f, 0.7f );

  auto particles = ParticleSystem::create( geometry, material );
  particles->sortParticles = true;
  scene->add( particles );

  /////////////////////////////////////////////////////////////////////////

  auto mouseX = 0.f, mouseY = 0.f;
  window.addEventListener( SDL_MOUSEMOTION, [&]( const SDL_Event& event ) {
    mouseX = 2.f * ( ( float )event.motion.x / renderer.width()  - 0.5f );
    mouseY = 2.f * ( ( float )event.motion.y / renderer.height() - 0.5f );
  } );

  window.addEventListener( SDL_WINDOWEVENT, [&]( const SDL_Event& event ) {
    if (event.window.event != SDL_WINDOWEVENT_RESIZED) return;
    camera->aspect = ( float )event.window.data1 / event.window.data2;
    camera->updateProjectionMatrix();
    renderer.setSize( event.window.data1, event.window.data2 );
  } );

  /////////////////////////////////////////////////////////////////////////

  auto time = 0.f;

  window.animate( [&]( float dt ) -> bool {

    time += dt * .05f;

    camera->position().x += ( -1000.f * mouseX - camera->position().x ) * 3 * dt;
    camera->position().y += (  1000.f * mouseY - camera->position().y ) * 3 * dt;
    camera->lookAt( scene->position() );

    const auto h = Math::fmod( 360.f * ( 1.f + time ), 360.f ) / 360.f;
    material->color.setHSL( h, 0.5f, 0.5f );

    renderer.render( *scene, *camera );

    return true;

  } );

}
Exemple #4
0
void particles_sprites( GLWindow& window, GLRenderer& renderer ) {

  auto camera = PerspectiveCamera::create(
    75, ( float )renderer.width() / renderer.height(), 1.f, 2000
  );
  camera->position().z = 1000;

  auto scene = Scene::create();
  scene->fog = FogExp2::create( 0x000000, .0008f );

  auto geometry = Geometry::create();

  auto sprite1 = ImageUtils::loadTexture( threeDataPath("textures/sprites/snowflake1.png") );
  auto sprite2 = ImageUtils::loadTexture( threeDataPath("textures/sprites/snowflake2.png") );
  auto sprite3 = ImageUtils::loadTexture( threeDataPath("textures/sprites/snowflake3.png") );
  auto sprite4 = ImageUtils::loadTexture( threeDataPath("textures/sprites/snowflake4.png") );
  auto sprite5 = ImageUtils::loadTexture( threeDataPath("textures/sprites/snowflake5.png") );

  const auto particleCount = 10000;
  geometry->vertices.reserve( particleCount );

  std::generate_n( std::back_inserter( geometry->vertices ),
                   particleCount,
                   [] { return Vector3( Math::random(-1000.f, 1000.f),
                                        Math::random(-1000.f, 1000.f),
                                        Math::random(-1000.f, 1000.f) ); } );

  std::vector<Material::Ptr> materials;
  auto addParticleSystem = [&]( const Vector3& color, const Texture::Ptr& sprite, float size ) {

    auto material = ParticleSystemMaterial::create(
      Material::Parameters().add( "size", size )
                            .add( "map", sprite )
                            .add( "blending", THREE::AdditiveBlending )
                            .add( "depthTest", false )
                            .add( "transparent", true )
    );

    materials.push_back( material );
    material->color.setHSL( color[0], color[1], color[2] );

    auto particles = ParticleSystem::create( geometry, material );

    particles->rotation() = Euler( Math::random() * 6,
                                   Math::random() * 6,
                                   Math::random() * 6 );

    scene->add( particles );
  };

  typedef std::tuple<Vector3, Texture::Ptr, float> ColorSpriteSize;
  std::array<ColorSpriteSize, 5> params = {
    ColorSpriteSize( Vector3(  1.f, 0.2f,  0.5f), sprite2, 20.f ),
    ColorSpriteSize( Vector3(0.95f, 0.1f,  0.5f), sprite3, 13.f ),
    ColorSpriteSize( Vector3(0.90f, 0.05f, 0.5f), sprite1, 10.f ),
    ColorSpriteSize( Vector3(0.85f, 0.f,   0.5f), sprite5, 8.f ),
    ColorSpriteSize( Vector3(0.80f, 0.f,   0.5f), sprite4, 5.f )
  };
  for ( const auto& param : params ) {
    addParticleSystem( std::get<0>(param), std::get<1>(param), std::get<2>(param) );
  }

  /////////////////////////////////////////////////////////////////////////

  auto mouseX = 0.f, mouseY = 0.f;
  window.addEventListener( SDL_MOUSEMOTION, [&]( const SDL_Event& event ) {
    mouseX = 2.f * ( ( float )event.motion.x / renderer.width()  - 0.5f );
    mouseY = 2.f * ( ( float )event.motion.y / renderer.height() - 0.5f );
  } );

  window.addEventListener( SDL_WINDOWEVENT, [&]( const SDL_Event& event ) {
    if (event.window.event != SDL_WINDOWEVENT_RESIZED) return;
    camera->aspect = ( float )event.window.data1 / event.window.data2;
    camera->updateProjectionMatrix();
    renderer.setSize( event.window.data1, event.window.data2 );
  } );

  /////////////////////////////////////////////////////////////////////////

  auto time = 0.f;

  window.animate( [&]( float dt ) -> bool {

    time += dt * .05f;

    camera->position().x += ( -1000.f * mouseX - camera->position().x ) * 3 * dt;
    camera->position().y += (  1000.f * mouseY - camera->position().y ) * 3 * dt;
    camera->lookAt( scene->position() );

    for ( size_t i = 0; i < scene->children.size(); ++i ) {
      auto& object = *scene->children[ i ];
      if ( object.type() == THREE::ParticleSystem ) {
        object.rotation().y = time * ( i < 4 ? i + 1 : - ( (int)i + 1 ) );
      }
    }

    for ( size_t i = 0; i < materials.size(); ++i ) {
      auto& color = std::get<0>(params[ i ]);
      const auto h = Math::fmod( 360.f * ( color[0] + time ), 360.f ) / 360.f;
      materials[ i ]->color.setHSL( h, color[ 1 ], color[ 2 ] );
    }

    renderer.render( *scene, *camera );

    return true;

  } );

}