如何在 SCNSphere 对象上应用脉冲效果?
How to apply pulse effect on SCNSphere object?
我想在 SCNSphere 对象上应用脉冲效果,谁能帮我实现这个。
提前致谢。
您可以使用来自 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
属性.
刚刚配置正确。祝你好运。
我在我的一个应用程序中使用了类似的效果(见下文)并使用了 SceneKit 着色器 modifier。
下面是一些可能有帮助的示例代码。
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 的表面着色器 mod 进行了 mod 化。如果您注释掉设置着色器 modifier 的代码,您将按预期看到一个平坦的蓝色方块。
为着色器的表面入口点指定的代码 modifier 被注入到 SceneKit 使用的片段着色器中。这意味着您正在使用像素在屏幕 space 中工作。着色器 modifier 的前几行使用反向 model 和视图变换将屏幕 space 坐标转换回 model space 坐标。
计算每个渲染像素到平面中心的距离(在 model space 中)xyLength
。然后将其归一化为 'pulse plane' xyLengthNormalised
的总大小。使用modulo on time 操作来获得脉冲效果;您可以将其切换为 sin
函数以获得先入后出类型的脉冲。我们使用 mod 操作的结果来确定哪些像素应该透明。
飞机随着红色框旋转,因为它是框的子节点。您可以通过添加约束来覆盖此行为,如下所示。我已经使用了约束条件,因为我个人从未在 SCNBillboardConstraint
.
方面取得过太大的成功
let pulseNodeConstraint = SCNLookAtConstraint(target: cameraNode)
pulseNode.constraints = [pulseNodeConstraint]
最终结果
对于那些喜欢 Objective-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];
我想在 SCNSphere 对象上应用脉冲效果,谁能帮我实现这个。
提前致谢。
您可以使用来自 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
属性.
刚刚配置正确。祝你好运。
我在我的一个应用程序中使用了类似的效果(见下文)并使用了 SceneKit 着色器 modifier。
下面是一些可能有帮助的示例代码。
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 的表面着色器 mod 进行了 mod 化。如果您注释掉设置着色器 modifier 的代码,您将按预期看到一个平坦的蓝色方块。
为着色器的表面入口点指定的代码 modifier 被注入到 SceneKit 使用的片段着色器中。这意味着您正在使用像素在屏幕 space 中工作。着色器 modifier 的前几行使用反向 model 和视图变换将屏幕 space 坐标转换回 model space 坐标。
计算每个渲染像素到平面中心的距离(在 model space 中)xyLength
。然后将其归一化为 'pulse plane' xyLengthNormalised
的总大小。使用modulo on time 操作来获得脉冲效果;您可以将其切换为 sin
函数以获得先入后出类型的脉冲。我们使用 mod 操作的结果来确定哪些像素应该透明。
飞机随着红色框旋转,因为它是框的子节点。您可以通过添加约束来覆盖此行为,如下所示。我已经使用了约束条件,因为我个人从未在 SCNBillboardConstraint
.
let pulseNodeConstraint = SCNLookAtConstraint(target: cameraNode)
pulseNode.constraints = [pulseNodeConstraint]
最终结果
对于那些喜欢 Objective-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];