ios – Swift SceneKit照明和影响发射纹理

ios – Swift SceneKit照明和影响发射纹理,第1张

概述我正在开发一个关于太阳系的应用程序. 我试图关闭发射纹理,光线照射到行星表面.但问题是,默认情况下,发射纹理总是显示发射点,无论光线是否存在. 我的要求简而言之:(我想隐藏发光点,在光线照射表面的地方) override func viewDidLoad() { super.viewDidLoad() let scene = SCNScene() let earth = 我正在开发一个关于太阳系的应用程序.
我试图关闭发射纹理,光线照射到行星表面.但问题是,默认情况下,发射纹理总是显示发射点,无论光线是否存在.

我的要求简而言之:(我想隐藏发光点,在光线照射表面的地方)

overrIDe func vIEwDIDLoad() {    super.vIEwDIDLoad()    let scene = SCNScene()    let earth = SCNSphere(radius: 1)    let earthNode = SCNNode()    let earthMaterial = SCNMaterial()    earthMaterial.diffuse.contents = UIImage(named: "earth.jpg")    earthMaterial.emission.contents = UIImage(named: "earthEmission.jpg")    earth.materials = [earthMaterial]    earthNode.geometry = earth    scene.rootNode.addChildNode(earthNode)    let lightNode = SCNNode()    lightNode.light = SCNlight()    lightNode.light?.type = .omni    lightNode.position = SCNVector3(x: 0,y: 10,z: 5)    scene.rootNode.addChildNode(lightNode)    sceneVIEw.scene = scene}
解决方法@H_502_20@ SceneKit的 shader modifiers非常适合这种任务.

您可以看到最终结果here的镜头.

片段着色器修改器

我们可以使用_lightingContribution.diffuse(表示应用于漫反射的光的RGB(vec3)颜色)来确定被照亮的对象(在本例中为地球)的区域,然后使用它来掩盖fragment shader modifier中的发射纹理.

你使用它的方式取决于你.这是我提出的最简单的解决方案(使用GLSL语法,但如果你使用它将在运行时自动转换为Metal)

uniform sampler2D emissionTexture;vec3 light = _lightingContribution.diffuse;float lum = max(0.0,1 - (0.2126*light.r + 0.7152*light.g + 0.0722*light.b)); // 1vec4 emission = texture2D(emissionTexture,_surface.diffuseTexcoord) * lum; // 2,3_output.color += emission; // 4

>计算_lightingContribution.diffuse颜色的亮度(使用公式from here)(如果灯光不是纯白色)
>从一个中减去它以获得“黑暗面”的亮度
>使用漫反射UV坐标从自定义纹理获取发射(授予发射和漫反射纹理具有相同的纹理)并通过乘法将亮度应用于它
>将其添加到最终输出颜色(与应用常规发射的方式相同)

这就是着色器部分,现在让我们通过Swift方面的东西.

Swift设置

首先,我们不会使用材质的emission.contents属性,而是需要创建自定义SCNMaterialProperty

let emissionTexture = UIImage(named: "earthEmission.jpg")!let emission = SCNMaterialProperty(contents: emissionTexture)

并使用setValue(_:forKey :)将其设置为材质

earthMaterial.setValue(emission,forKey: "emissionTexture")

密切关注键 – 它应该与着色器修改器中的制服相同.此外,您不需要自己保留材质属性,setValue会创建一个强引用.

剩下要做的就是将片段着色器修改器设置为材质:

let shaderModifIEr ="""uniform sampler2D emissionTexture;vec3 light = _lightingContribution.diffuse;float lum = max(0.0,1 - (0.2126*light.r + 0.7152*light.g + 0.0722*light.b));vec4 emission = texture2D(emissionTexture,_surface.diffuseTexcoord) * lum;_output.color += emission;"""earthMaterial.shaderModifIErs = [.fragment: shaderModifIEr]

这是运动中着色器修改器的footage.

请注意,光源必须非常明亮,否则会在“地球”周围看到昏暗的灯光.我必须在你的设置中将lightNode.light?.intensity设置为至少2000才能按预期工作.您可能希望尝试计算发光度并应用于发射以获得更好结果的方式.

如果您可能需要它,_lightingContribution是片段着色器修饰符中可用的结构,它还具有环境和镜面成员(下面是Metal语法):

struct SCNShaderlightingContribution {    float3 ambIEnt;    float3 diffuse;    float3 specular;} _lightingContribution;
总结

以上是内存溢出为你收集整理的ios – Swift SceneKit照明和影响发射纹理全部内容,希望文章能够帮你解决ios – Swift SceneKit照明和影响发射纹理所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1060108.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存