рисование линии с использованием вершинного шейдера и фрагментного шейдера в spritkit в swift - PullRequest
0 голосов
/ 21 ноября 2018

Мне нужно нарисовать линию между двумя спринтодами, когда рука указывает от одного узла к другому с помощью рендеринга или анимации.Рисование линий работает для меня, так как я перехожу по этой ссылке, ответ Бобджта Animate Path Drawing in SpriteKit .Здесь я использовал концепцию фрагментного шейдера и вершинного шейдера ..

Я добавил файл animatestroke.fsh и применил следующий код. Но анимация в ручном режиме и скорость рисования линий иногда не совпадают.рендеринг моей линии, я дал приращение на

strokeLengthFloat +=   0.01

А продолжительность хэндплеера составляет 1,5:

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

Вот мой код реализации:

объявление переменной

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
    }
}

Способ загрузки

   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
        }
  }

Как я могу это исправить?Или, если у кого-то есть другая идея для реализации этого сценария, поделитесь своей идеей.

...