发布于 2017-03-09 08:52:37
我在我的一个应用程序中使用了类似的效果(见下文),并使用了SceneKit着色器修饰符。

下面是一些可能有帮助的示例代码。
let boxNode = SCNNode(geometry: SCNBox(width: 1.0, height: 1.0, length: 1.0, chamferRadius: 0))
boxNode.geometry?.firstMaterial?.diffuse.contents = UIColor.red
scene.rootNode.addChildNode(boxNode)
let pulseSize:CGFloat = 5.0
let pulsePlane = SCNPlane(width: pulseSize, height: pulseSize)
pulsePlane.firstMaterial?.isDoubleSided = true
pulsePlane.firstMaterial?.diffuse.contents = UIColor.blue
let pulseNode = SCNNode(geometry: pulsePlane)
let pulseShaderModifier =
"#pragma transparent; \n" +
"vec4 originalColour = _surface.diffuse; \n" +
"vec4 transformed_position = u_inverseModelTransform * u_inverseViewTransform * vec4(_surface.position, 1.0); \n" +
"vec2 xy = vec2(transformed_position.x, transformed_position.y); \n" +
"float xyLength = length(xy); \n" +
"float xyLengthNormalised = xyLength/" + String(describing: pulseSize / 2) + "; \n" +
"float speedFactor = 1.5; \n" +
"float maxDist = fmod(u_time, speedFactor) / speedFactor; \n" +
"float distbasedalpha = step(maxDist, xyLengthNormalised); \n" +
"distbasedalpha = max(distbasedalpha, maxDist); \n" +
"_surface.diffuse = mix(originalColour, vec4(0.0), distbasedalpha);"
pulsePlane.firstMaterial?.shaderModifiers = [SCNShaderModifierEntryPoint.surface:pulseShaderModifier]
boxNode.addChildNode(pulseNode)红色框(boxNode)仅用于上下文。
脉冲节点由一个SCNPlane组成,该片段着色器通过SceneKit的表面着色修饰符对其进行修改。如果您注释掉设置着色器修饰符的代码,您将看到一个平淡的蓝色方块。
为着色器修饰符的表面入口点指定的代码被注入到SceneKit使用的片段着色器中。这意味着您在屏幕空间中使用像素。着色器修饰符的前几行使用逆模型和视图转换将屏幕空间坐标转换回模型空间坐标。
每个呈现的像素距平面中心的距离(在模型空间中)被计算为xyLength。然后对“脉冲平面”xyLengthNormalised的总尺寸进行规范化处理。使用模块化的时间操作来获得脉冲效果;您可以将其切换到sin函数,以获得输入然后输出类型的脉冲。我们使用mod操作的结果来确定哪些像素应该透明。
飞机旋转着红色的盒子,因为它是盒子的一个子节点。您可以通过添加约束来覆盖此行为,如下所示。我使用了约束,因为我个人在SCNBillboardConstraint上从来没有取得过很大的成功。
let pulseNodeConstraint = SCNLookAtConstraint(target: cameraNode)
pulseNode.constraints = [pulseNodeConstraint]最终结果

对那些喜欢目标C的人来说.
SCNNode *boxNode = [SCNNode nodeWithGeometry:[SCNBox boxWithWidth:1.0 height:1.0 length:1.0 chamferRadius:0.0]];
boxNode.geometry.firstMaterial.diffuse.contents = [UIColor redColor];
[scene.rootNode addChildNode:boxNode];
CGFloat pulseSize = 5.0;
SCNPlane *pulsePlane = [SCNPlane planeWithWidth:pulseSize height:pulseSize];
[pulsePlane.firstMaterial setDoubleSided:true];
pulsePlane.firstMaterial.diffuse.contents = [UIColor blueColor];
SCNNode *pulseNode = [SCNNode nodeWithGeometry:pulsePlane];
NSString *pulseShaderModifier = [NSString stringWithFormat:
@"#pragma transparent; \n"
"vec4 originalColour = _surface.diffuse; \n"
"vec4 transformed_position = u_inverseModelTransform * u_inverseViewTransform * vec4(_surface.position, 1.0); \n"
"vec2 xy = vec2(transformed_position.x, transformed_position.y); \n"
"float xyLength = length(xy); \n"
"float xyLengthNormalised = xyLength/%f; \n"
"float speedFactor = 1.5; \n"
"float maxDist = fmod(u_time, speedFactor) / speedFactor; \n"
"float distbasedalpha = step(maxDist, xyLengthNormalised); \n"
"distbasedalpha = max(distbasedalpha, maxDist); \n"
"_surface.diffuse = mix(originalColour, vec4(0.0), distbasedalpha);", pulseSize/2.0];
NSDictionary *smdict = [NSDictionary dictionaryWithObject:pulseShaderModifier forKey:SCNShaderModifierEntryPointSurface];
[pulsePlane.firstMaterial setShaderModifiers:smdict];
[boxNode addChildNode:pulseNode];
SCNLookAtConstraint *pulseNodeConstraint = [SCNLookAtConstraint lookAtConstraintWithTarget:cameraNode];
NSArray *constraints = [NSArray arrayWithObject:pulseNodeConstraint];
[pulseNode setConstraints:constraints];发布于 2017-03-08 07:08:34
您可以使用https://github.com/shu223/Pulsator的pod
配置
let pulsator = Pulsator()
view.layer.addSublayer(pulsator)
pulsator.start()脉冲数
pulsator.numPulse = 3半径
pulsator.radius = 240.0彩色
pulsator.backgroundColor = UIColor(red: 1, green: 1, blue: 0, alpha: 1).CGColor动画持续时间
使用下列属性
animationDuration : duration for each pulse
pulseInterval : interval between pulses宽松
可以设置timingFunction属性。
重复
使用repeatCount属性。
只是正确地配置了它。祝好运。
https://stackoverflow.com/questions/42664563
复制相似问题