drawing line using vertex shader & fragment shader in spritkit in swift












1














I need to draw a line between two spritnodes while hand is pointing from one node to another with rendering or animation.
The line drawing is working for me as I follow this link Bobjt's answer, Animate Path Drawing in SpriteKit . I have used concept of fragment shader and vertex shader here..



I have added animatestroke.fsh file and apply the following code .. But the handplayer animation and line drawing speed is mismatching some times.
my line rendering i have given increment by




strokeLengthFloat += 0.01




And handplayer duration is 1.5:




let moveTosecondObject = SKAction.move(to: handmovepoint, duration: 1.5 )




Here is my implementation code:



variable declaration



var handplayer = SKSpriteNode()
var firstObject = SKSpriteNode()
var secondObject = SKSpriteNode()
var startTrigger: Bool = false

let strokeSizeFactor = CGFloat( 2.0 )
var strokeShader: SKShader!
var strokeLengthUniform: SKUniform!
var _strokeLengthFloat: Float = 0.0
var strokeLengthKey: String!
var strokeLengthFloat: Float {
get {
return _strokeLengthFloat
}
set( newStrokeLengthFloat ) {
_strokeLengthFloat = newStrokeLengthFloat
strokeLengthUniform.floatValue = newStrokeLengthFloat
}
}


Loading method



   override func didMove(to view: SKView) {
handplayer = SKSpriteNode(imageNamed: "HandImage.png")
handplayer.size.width = handplayer.size.width * 0.5
handplayer.size.height = handplayer.size.height * 0.5
handplayer.position.x = firstObject.position
self.addChild(handplayer)
UpdatePosition()
}

func UpdatePosition(){


//Line drawing part
strokeLengthKey = "u_current_percentage"
strokeLengthUniform = SKUniform( name: strokeLengthKey, float: 0.0 )
let uniforms: [SKUniform] = [strokeLengthUniform]
strokeShader = shaderWithFilename( "animateStroke", fileExtension: "fsh", uniforms: uniforms )
strokeLengthFloat = 0.0

let cameraNode = SKCameraNode()
self.camera = cameraNode

let lineStartPosition = CGPoint(x:firstObject.frame.origin.x+firstObject.size.width/2,y:firstObject.frame.origin.y-firstObject.size.height*0.2)

let lineEndPosition = CGPoint(x:secondObject.frame.origin.x+secondObject.size.width/2,y:secondObject.frame.origin.y+secondObject.size.height*1.2)

let path = CGMutablePath()
path.move(to: CGPoint(x: lineStartPosition.x, y: lineStartPosition.y))
path.addLine(to: CGPoint(x: : lineEndPosition.x, y: lineEndPosition.y), transform: CGAffineTransform.identity)

let strokeWidth = 1.0 * strokeSizeFactor
let shapeNode = SKShapeNode( path: path )
shapeNode.lineWidth = strokeWidth
shapeNode.lineCap = .square
shapeNode.addChild( cameraNode )
shapeNode.strokeShader = strokeShader
shapeNode.calculateAccumulatedFrame()
self.addChild( shapeNode )


}

// center the camera
cameraNode.position = CGPoint( x: self.frame.size.width/2.0, y: self.frame.size.height/2.0 )


**Handplayer Rendering part**
let handmovepoint = CGPoint(x: secondObject.position.x , y: secondObject.position.y + handplayer.size.height*0.1 )

let moveTosecondObject = SKAction.move(to: handmovepoint, duration: 1.5 )
let delay = SKAction.wait(forDuration: 1)
handplayer.run(SKAction.sequence([ delay ]), completion: {() -> Void in
self.startTrigger = true

self.handplayer.run(SKAction.sequence([ moveTosecondObject ]), completion: {() -> Void in
//self.handplayer.alpha = 0.0


})

}
//line rendering part
override func update(_ currentTime: TimeInterval) {

if(startTrigger){

strokeLengthFloat += 0.01

}

if startTrigger == true{

if strokeLengthFloat > 1.0 {
//once line drawing completed
self.startTrigger = false

print("Line drawing ended")
self.handplayer.alpha = 0.0
self.handplayer.removeFromParent()


}

}
}


animatestroke.fsh class



        void main()
{
if ( u_path_length == 0.0 ) {
gl_FragColor = vec4( 0.0, 0.0, 1.0, 1.0 ); // draw blue // this is an error
} else if ( v_path_distance / u_path_length <= u_current_percentage ) {
gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 ); // draw red
} else {
gl_FragColor = vec4( 0.0, 0.0, 0.0, 0.0 ); // draw nothing
}
}


How could i fix this: Or If Anyone have other idea for implementhing this scenario share your Idea.. Any help will be appreciated..










share|improve this question





























    1














    I need to draw a line between two spritnodes while hand is pointing from one node to another with rendering or animation.
    The line drawing is working for me as I follow this link Bobjt's answer, Animate Path Drawing in SpriteKit . I have used concept of fragment shader and vertex shader here..



    I have added animatestroke.fsh file and apply the following code .. But the handplayer animation and line drawing speed is mismatching some times.
    my line rendering i have given increment by




    strokeLengthFloat += 0.01




    And handplayer duration is 1.5:




    let moveTosecondObject = SKAction.move(to: handmovepoint, duration: 1.5 )




    Here is my implementation code:



    variable declaration



    var handplayer = SKSpriteNode()
    var firstObject = SKSpriteNode()
    var secondObject = SKSpriteNode()
    var startTrigger: Bool = false

    let strokeSizeFactor = CGFloat( 2.0 )
    var strokeShader: SKShader!
    var strokeLengthUniform: SKUniform!
    var _strokeLengthFloat: Float = 0.0
    var strokeLengthKey: String!
    var strokeLengthFloat: Float {
    get {
    return _strokeLengthFloat
    }
    set( newStrokeLengthFloat ) {
    _strokeLengthFloat = newStrokeLengthFloat
    strokeLengthUniform.floatValue = newStrokeLengthFloat
    }
    }


    Loading method



       override func didMove(to view: SKView) {
    handplayer = SKSpriteNode(imageNamed: "HandImage.png")
    handplayer.size.width = handplayer.size.width * 0.5
    handplayer.size.height = handplayer.size.height * 0.5
    handplayer.position.x = firstObject.position
    self.addChild(handplayer)
    UpdatePosition()
    }

    func UpdatePosition(){


    //Line drawing part
    strokeLengthKey = "u_current_percentage"
    strokeLengthUniform = SKUniform( name: strokeLengthKey, float: 0.0 )
    let uniforms: [SKUniform] = [strokeLengthUniform]
    strokeShader = shaderWithFilename( "animateStroke", fileExtension: "fsh", uniforms: uniforms )
    strokeLengthFloat = 0.0

    let cameraNode = SKCameraNode()
    self.camera = cameraNode

    let lineStartPosition = CGPoint(x:firstObject.frame.origin.x+firstObject.size.width/2,y:firstObject.frame.origin.y-firstObject.size.height*0.2)

    let lineEndPosition = CGPoint(x:secondObject.frame.origin.x+secondObject.size.width/2,y:secondObject.frame.origin.y+secondObject.size.height*1.2)

    let path = CGMutablePath()
    path.move(to: CGPoint(x: lineStartPosition.x, y: lineStartPosition.y))
    path.addLine(to: CGPoint(x: : lineEndPosition.x, y: lineEndPosition.y), transform: CGAffineTransform.identity)

    let strokeWidth = 1.0 * strokeSizeFactor
    let shapeNode = SKShapeNode( path: path )
    shapeNode.lineWidth = strokeWidth
    shapeNode.lineCap = .square
    shapeNode.addChild( cameraNode )
    shapeNode.strokeShader = strokeShader
    shapeNode.calculateAccumulatedFrame()
    self.addChild( shapeNode )


    }

    // center the camera
    cameraNode.position = CGPoint( x: self.frame.size.width/2.0, y: self.frame.size.height/2.0 )


    **Handplayer Rendering part**
    let handmovepoint = CGPoint(x: secondObject.position.x , y: secondObject.position.y + handplayer.size.height*0.1 )

    let moveTosecondObject = SKAction.move(to: handmovepoint, duration: 1.5 )
    let delay = SKAction.wait(forDuration: 1)
    handplayer.run(SKAction.sequence([ delay ]), completion: {() -> Void in
    self.startTrigger = true

    self.handplayer.run(SKAction.sequence([ moveTosecondObject ]), completion: {() -> Void in
    //self.handplayer.alpha = 0.0


    })

    }
    //line rendering part
    override func update(_ currentTime: TimeInterval) {

    if(startTrigger){

    strokeLengthFloat += 0.01

    }

    if startTrigger == true{

    if strokeLengthFloat > 1.0 {
    //once line drawing completed
    self.startTrigger = false

    print("Line drawing ended")
    self.handplayer.alpha = 0.0
    self.handplayer.removeFromParent()


    }

    }
    }


    animatestroke.fsh class



            void main()
    {
    if ( u_path_length == 0.0 ) {
    gl_FragColor = vec4( 0.0, 0.0, 1.0, 1.0 ); // draw blue // this is an error
    } else if ( v_path_distance / u_path_length <= u_current_percentage ) {
    gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 ); // draw red
    } else {
    gl_FragColor = vec4( 0.0, 0.0, 0.0, 0.0 ); // draw nothing
    }
    }


    How could i fix this: Or If Anyone have other idea for implementhing this scenario share your Idea.. Any help will be appreciated..










    share|improve this question



























      1












      1








      1


      1





      I need to draw a line between two spritnodes while hand is pointing from one node to another with rendering or animation.
      The line drawing is working for me as I follow this link Bobjt's answer, Animate Path Drawing in SpriteKit . I have used concept of fragment shader and vertex shader here..



      I have added animatestroke.fsh file and apply the following code .. But the handplayer animation and line drawing speed is mismatching some times.
      my line rendering i have given increment by




      strokeLengthFloat += 0.01




      And handplayer duration is 1.5:




      let moveTosecondObject = SKAction.move(to: handmovepoint, duration: 1.5 )




      Here is my implementation code:



      variable declaration



      var handplayer = SKSpriteNode()
      var firstObject = SKSpriteNode()
      var secondObject = SKSpriteNode()
      var startTrigger: Bool = false

      let strokeSizeFactor = CGFloat( 2.0 )
      var strokeShader: SKShader!
      var strokeLengthUniform: SKUniform!
      var _strokeLengthFloat: Float = 0.0
      var strokeLengthKey: String!
      var strokeLengthFloat: Float {
      get {
      return _strokeLengthFloat
      }
      set( newStrokeLengthFloat ) {
      _strokeLengthFloat = newStrokeLengthFloat
      strokeLengthUniform.floatValue = newStrokeLengthFloat
      }
      }


      Loading method



         override func didMove(to view: SKView) {
      handplayer = SKSpriteNode(imageNamed: "HandImage.png")
      handplayer.size.width = handplayer.size.width * 0.5
      handplayer.size.height = handplayer.size.height * 0.5
      handplayer.position.x = firstObject.position
      self.addChild(handplayer)
      UpdatePosition()
      }

      func UpdatePosition(){


      //Line drawing part
      strokeLengthKey = "u_current_percentage"
      strokeLengthUniform = SKUniform( name: strokeLengthKey, float: 0.0 )
      let uniforms: [SKUniform] = [strokeLengthUniform]
      strokeShader = shaderWithFilename( "animateStroke", fileExtension: "fsh", uniforms: uniforms )
      strokeLengthFloat = 0.0

      let cameraNode = SKCameraNode()
      self.camera = cameraNode

      let lineStartPosition = CGPoint(x:firstObject.frame.origin.x+firstObject.size.width/2,y:firstObject.frame.origin.y-firstObject.size.height*0.2)

      let lineEndPosition = CGPoint(x:secondObject.frame.origin.x+secondObject.size.width/2,y:secondObject.frame.origin.y+secondObject.size.height*1.2)

      let path = CGMutablePath()
      path.move(to: CGPoint(x: lineStartPosition.x, y: lineStartPosition.y))
      path.addLine(to: CGPoint(x: : lineEndPosition.x, y: lineEndPosition.y), transform: CGAffineTransform.identity)

      let strokeWidth = 1.0 * strokeSizeFactor
      let shapeNode = SKShapeNode( path: path )
      shapeNode.lineWidth = strokeWidth
      shapeNode.lineCap = .square
      shapeNode.addChild( cameraNode )
      shapeNode.strokeShader = strokeShader
      shapeNode.calculateAccumulatedFrame()
      self.addChild( shapeNode )


      }

      // center the camera
      cameraNode.position = CGPoint( x: self.frame.size.width/2.0, y: self.frame.size.height/2.0 )


      **Handplayer Rendering part**
      let handmovepoint = CGPoint(x: secondObject.position.x , y: secondObject.position.y + handplayer.size.height*0.1 )

      let moveTosecondObject = SKAction.move(to: handmovepoint, duration: 1.5 )
      let delay = SKAction.wait(forDuration: 1)
      handplayer.run(SKAction.sequence([ delay ]), completion: {() -> Void in
      self.startTrigger = true

      self.handplayer.run(SKAction.sequence([ moveTosecondObject ]), completion: {() -> Void in
      //self.handplayer.alpha = 0.0


      })

      }
      //line rendering part
      override func update(_ currentTime: TimeInterval) {

      if(startTrigger){

      strokeLengthFloat += 0.01

      }

      if startTrigger == true{

      if strokeLengthFloat > 1.0 {
      //once line drawing completed
      self.startTrigger = false

      print("Line drawing ended")
      self.handplayer.alpha = 0.0
      self.handplayer.removeFromParent()


      }

      }
      }


      animatestroke.fsh class



              void main()
      {
      if ( u_path_length == 0.0 ) {
      gl_FragColor = vec4( 0.0, 0.0, 1.0, 1.0 ); // draw blue // this is an error
      } else if ( v_path_distance / u_path_length <= u_current_percentage ) {
      gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 ); // draw red
      } else {
      gl_FragColor = vec4( 0.0, 0.0, 0.0, 0.0 ); // draw nothing
      }
      }


      How could i fix this: Or If Anyone have other idea for implementhing this scenario share your Idea.. Any help will be appreciated..










      share|improve this question















      I need to draw a line between two spritnodes while hand is pointing from one node to another with rendering or animation.
      The line drawing is working for me as I follow this link Bobjt's answer, Animate Path Drawing in SpriteKit . I have used concept of fragment shader and vertex shader here..



      I have added animatestroke.fsh file and apply the following code .. But the handplayer animation and line drawing speed is mismatching some times.
      my line rendering i have given increment by




      strokeLengthFloat += 0.01




      And handplayer duration is 1.5:




      let moveTosecondObject = SKAction.move(to: handmovepoint, duration: 1.5 )




      Here is my implementation code:



      variable declaration



      var handplayer = SKSpriteNode()
      var firstObject = SKSpriteNode()
      var secondObject = SKSpriteNode()
      var startTrigger: Bool = false

      let strokeSizeFactor = CGFloat( 2.0 )
      var strokeShader: SKShader!
      var strokeLengthUniform: SKUniform!
      var _strokeLengthFloat: Float = 0.0
      var strokeLengthKey: String!
      var strokeLengthFloat: Float {
      get {
      return _strokeLengthFloat
      }
      set( newStrokeLengthFloat ) {
      _strokeLengthFloat = newStrokeLengthFloat
      strokeLengthUniform.floatValue = newStrokeLengthFloat
      }
      }


      Loading method



         override func didMove(to view: SKView) {
      handplayer = SKSpriteNode(imageNamed: "HandImage.png")
      handplayer.size.width = handplayer.size.width * 0.5
      handplayer.size.height = handplayer.size.height * 0.5
      handplayer.position.x = firstObject.position
      self.addChild(handplayer)
      UpdatePosition()
      }

      func UpdatePosition(){


      //Line drawing part
      strokeLengthKey = "u_current_percentage"
      strokeLengthUniform = SKUniform( name: strokeLengthKey, float: 0.0 )
      let uniforms: [SKUniform] = [strokeLengthUniform]
      strokeShader = shaderWithFilename( "animateStroke", fileExtension: "fsh", uniforms: uniforms )
      strokeLengthFloat = 0.0

      let cameraNode = SKCameraNode()
      self.camera = cameraNode

      let lineStartPosition = CGPoint(x:firstObject.frame.origin.x+firstObject.size.width/2,y:firstObject.frame.origin.y-firstObject.size.height*0.2)

      let lineEndPosition = CGPoint(x:secondObject.frame.origin.x+secondObject.size.width/2,y:secondObject.frame.origin.y+secondObject.size.height*1.2)

      let path = CGMutablePath()
      path.move(to: CGPoint(x: lineStartPosition.x, y: lineStartPosition.y))
      path.addLine(to: CGPoint(x: : lineEndPosition.x, y: lineEndPosition.y), transform: CGAffineTransform.identity)

      let strokeWidth = 1.0 * strokeSizeFactor
      let shapeNode = SKShapeNode( path: path )
      shapeNode.lineWidth = strokeWidth
      shapeNode.lineCap = .square
      shapeNode.addChild( cameraNode )
      shapeNode.strokeShader = strokeShader
      shapeNode.calculateAccumulatedFrame()
      self.addChild( shapeNode )


      }

      // center the camera
      cameraNode.position = CGPoint( x: self.frame.size.width/2.0, y: self.frame.size.height/2.0 )


      **Handplayer Rendering part**
      let handmovepoint = CGPoint(x: secondObject.position.x , y: secondObject.position.y + handplayer.size.height*0.1 )

      let moveTosecondObject = SKAction.move(to: handmovepoint, duration: 1.5 )
      let delay = SKAction.wait(forDuration: 1)
      handplayer.run(SKAction.sequence([ delay ]), completion: {() -> Void in
      self.startTrigger = true

      self.handplayer.run(SKAction.sequence([ moveTosecondObject ]), completion: {() -> Void in
      //self.handplayer.alpha = 0.0


      })

      }
      //line rendering part
      override func update(_ currentTime: TimeInterval) {

      if(startTrigger){

      strokeLengthFloat += 0.01

      }

      if startTrigger == true{

      if strokeLengthFloat > 1.0 {
      //once line drawing completed
      self.startTrigger = false

      print("Line drawing ended")
      self.handplayer.alpha = 0.0
      self.handplayer.removeFromParent()


      }

      }
      }


      animatestroke.fsh class



              void main()
      {
      if ( u_path_length == 0.0 ) {
      gl_FragColor = vec4( 0.0, 0.0, 1.0, 1.0 ); // draw blue // this is an error
      } else if ( v_path_distance / u_path_length <= u_current_percentage ) {
      gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 ); // draw red
      } else {
      gl_FragColor = vec4( 0.0, 0.0, 0.0, 0.0 ); // draw nothing
      }
      }


      How could i fix this: Or If Anyone have other idea for implementhing this scenario share your Idea.. Any help will be appreciated..







      ios swift skspritenode fragment-shader vertex-shader






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 22 at 4:37

























      asked Nov 21 at 5:06









      PRADIP KUMAR

      2271424




      2271424





























          active

          oldest

          votes











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53405562%2fdrawing-line-using-vertex-shader-fragment-shader-in-spritkit-in-swift%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown






























          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53405562%2fdrawing-line-using-vertex-shader-fragment-shader-in-spritkit-in-swift%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          404 Error Contact Form 7 ajax form submitting

          How to know if a Active Directory user can login interactively

          TypeError: fit_transform() missing 1 required positional argument: 'X'