【发布时间】:2019-06-30 21:47:41
【问题描述】:
【问题讨论】:
标签: ios swift shader scenekit metal
【问题讨论】:
标签: ios swift shader scenekit metal
您可以使用片段着色器修改器获得非常接近预期效果。基本做法如下:
这是执行此操作的着色器修改器代码:
#pragma arguments
float revealage;
texture2d<float, access::sample> noiseTexture;
#pragma transparent
#pragma body
const float edgeWidth = 0.02;
const float edgeBrightness = 2;
const float3 innerColor = float3(0.4, 0.8, 1);
const float3 outerColor = float3(0, 0.5, 1);
const float noiseScale = 3;
constexpr sampler noiseSampler(filter::linear, address::repeat);
float2 noiseCoords = noiseScale * _surface.ambientTexcoord;
float noiseValue = noiseTexture.sample(noiseSampler, noiseCoords).r;
if (noiseValue > revealage) {
discard_fragment();
}
float edgeDist = revealage - noiseValue;
if (edgeDist < edgeWidth) {
float t = edgeDist / edgeWidth;
float3 edgeColor = edgeBrightness * mix(outerColor, innerColor, t);
_output.color.rgb = edgeColor;
}
请注意,revealage 参数作为材质参数公开,因为您可能希望对其进行动画处理。还有其他内部常数,例如边缘宽度和噪声比例,可以微调以获得所需的内容效果。
不同的噪波纹理会产生不同的溶解效果,因此您也可以尝试一下。我刚刚使用了这个多倍频程值噪声图像:
将图像加载为UIImage 或NSImage,并将其设置为暴露为noiseTexture 的材质属性:
material.setValue(SCNMaterialProperty(contents: noiseImage), forKey: "noiseTexture")
您需要添加光晕作为后期处理,以获得发光的电子线效果。在 SceneKit 中,这就像启用 HDR 管道并设置一些参数一样简单:
let camera = SCNCamera()
camera.wantsHDR = true
camera.bloomThreshold = 0.8
camera.bloomIntensity = 2
camera.bloomBlurRadius = 16.0
camera.wantsExposureAdaptation = false
所有数字参数都可能需要根据您的内容进行调整。
为了保持整洁,我更喜欢将着色器修改器保存在它们自己的文本文件中(我将我的命名为“dissolve.fragment.txt”)。以下是如何加载一些修改器代码并将其附加到材质上。
let modifierURL = Bundle.main.url(forResource: "dissolve.fragment", withExtension: "txt")!
let modifierString = try! String(contentsOf: modifierURL)
material.shaderModifiers = [
SCNShaderModifierEntryPoint.fragment : modifierString
]
最后,为了动画效果,您可以使用 CABasicAnimation 包裹 SCNAnimation:
let revealAnimation = CABasicAnimation(keyPath: "revealage")
revealAnimation.timingFunction = CAMediaTimingFunction(name: .linear)
revealAnimation.duration = 2.5
revealAnimation.fromValue = 0.0
revealAnimation.toValue = 1.0
let scnRevealAnimation = SCNAnimation(caAnimation: revealAnimation)
material.addAnimation(scnRevealAnimation, forKey: "Reveal")
【讨论】: