gpt4 book ai didi

ios - 如何在 SCNSphere 对象上应用脉冲效果?

转载 作者:可可西里 更新时间:2023-11-01 00:21:15 27 4
gpt4 key购买 nike

我想在 SCNSphere 对象上应用脉冲效果,任何人都可以帮助我吗。

Pulse effect

enter image description here

提前致谢。

最佳答案

我在我的一个应用程序中追求类似的效果(见下文)并使用了 SceneKit 着色器修改器。

Pulse effect in 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 的表面着色器修改器进行修改。如果您注释掉设置着色器修改器的代码,您将看到预期的扁平蓝色方 block 。

为着色器修改器的表面入口点指定的代码被注入(inject)到 SceneKit 使用的片段着色器中。这意味着您正在使用像素在屏幕空间中工作。着色器修改器的前几行使用反向模型和 View 变换将屏幕空间坐标转换回模型空间坐标。

计算每个渲染像素到平面中心(在模型空间中)的距离 xyLength。然后针对“脉冲平面”xyLengthNormalised 的总大小对其进行归一化。使用对时间的模运算来获得脉冲效果;您可以将其切换为 sin 函数以获得先入后出类型的脉冲。我们使用模运算的结果来确定哪些像素应该透明。

飞机随着红色框旋转,因为它是框的子节点。您可以通过添加约束来覆盖此行为,如下所示。我使用了约束条件,因为我个人从未在 SCNBillboardConstraint 方面取得太大成功。

let pulseNodeConstraint = SCNLookAtConstraint(target: cameraNode)
pulseNode.constraints = [pulseNodeConstraint]

最终结果

Pulse effect in SceneKit with constraint

对于那些喜欢 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];

关于ios - 如何在 SCNSphere 对象上应用脉冲效果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42664563/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com