首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在SceneKit中只对球体的一部分应用菲涅耳效果?

如何在SceneKit中只对球体的一部分应用菲涅耳效果?
EN

Stack Overflow用户
提问于 2019-04-15 00:13:45
回答 2查看 322关注 0票数 1

我正在将菲涅耳效果应用于SCNSphere,以获得美丽的地球光芒

然而,由于我正在制作地球模型,我希望球体的照明部分具有菲涅耳效应,而暗面则没有。

如果球体的暗面是透明的,也许可以达到这个效果?或者我可以只使用Scenekit _surface.fresnel的着色器修改器属性?

EN

回答 2

Stack Overflow用户

发布于 2019-04-28 16:47:45

为此,您需要使用定义曲面上每个点发射的颜色的emission实例属性。

可以使用emissive map texture模拟使用自己的灯光发光的曲面部分。SceneKit不会将材质视为光源,而是由发射特性独立于照明来确定材质的颜色。(若要创建显示为发光的对象,您可能希望将几何体与发射贴图和添加到场景中的其他SCNLight对象组合在一起。)

代码语言:javascript
复制
var emission: SCNMaterialProperty { get }

您可以在任何可用的场景工具包的着色器ConstantLambertBlinnPhongPhysically Based中找到emission属性。

代码语言:javascript
复制
let earth = SCNNode(geometry: SCNSphere(radius: 5))
earth.geometry?.firstMaterial?.emission.contents = UIImage(named: "emissionMap.png")

当然,如果您需要创建正方形emissionMap.png纹理(也称为UV贴图)您应该在Autodesk Maya或Autodesk 3dsMax或Maxon Cinema4D等中创建它。此类贴图可以是512x512、1024x1024、2048x2048等。

票数 0
EN

Stack Overflow用户

发布于 2021-11-22 22:49:07

我不是Scenekit和着色器的专家,也许这个解决方案并不是最优的,但有一种方法就是使用着色器修改器:

  1. 首先,我在Scenekit中使用漫反射(=direct,在Scenekit中)照明球体,并将红色、绿色和蓝色的值转换为亮度。源代码可以在here上找到。

vec3 lum = _lightingContribution.diffuse;vec3 lum= 0.2126*light.r + 0.7152*light.g + 0.0722*light.b;

  1. I根据曲面与相机pov的角度计算一个数字。surface entry point

float factorOpacity =( _surface.normal.x * _surface.normal.x + _surface.normal.y * _surface.normal.y );

  1. I设置一个菲涅耳指数来控制边缘光晕的厚度。较低的值意味着菲涅尔效果在中心周围更明显,而较高的值意味着菲涅尔效果更多地出现在边缘周围。

float fresnelExponent = 1.0;

  1. 我为我的大气颜色设置了红色,绿色和蓝色的值(0.0-1.0)。

浮点红= 0.1;浮点绿= 0.2;浮点蓝= 0.4;

  1. 我设置了我想要的垂直向下的透明度。0.0表示完全透明,1.0表示完全不透明。

float nadirTransparency = 0.2;

  1. 我设置了边缘透明度。

float edgeTransparency = 1.0;

我计算了最终的菲涅耳因子,并考虑了菲涅耳指数。,,

  1. ,I,the,the,
  2. ,the。,考虑菲涅耳指数。

功率= factorOpacity (factorOpacity,fresnelExponent);

  1. 最后,我计算几何图形的最终颜色,并根据输入参数和菲涅耳因子乘以所需的透明度。

_output.color =vec4(红、绿、蓝,1.0)* factorOpacity); (lum,1.0)* (nadirTransparency + (edgeTransparency - nadirTransparency) *min

Swift实现如下所示:

代码语言:javascript
复制
    let sphere = SCNSphere(radius: radiusValue)

    self.geometry = sphere        
    
    let ShaderModifier =

    """
    #pragma transparent

    vec3 light = _lightingContribution.diffuse;

    float lum = 0.2126*light.r + 0.7152*light.g + 0.0722*light.b;
    
    float factorOpacity = ( _surface.normal.x * _surface.normal.x + _surface.normal.y * _surface.normal.y );

    float fresnelExponent = 1.0;

    float red = 0.1;
    float green = 0.2;
    float blue = 0.4;

    float nadirTransparency = 0.2;
    float edgeTransparency = 1.0;

    factorOpacity = pow(factorOpacity,fresnelExponent);

    _output.color = vec4(red,green,blue,1.0) * min(lum,1.0) * (nadirTransparency + (edgeTransparency - nadirTransparency) * factorOpacity);

    """

    self.geometry?.firstMaterial?.shaderModifiers = [.fragment: ShaderModifier]

这是它的外观(云的颜色来自另一个着色器)

atmosphere shader scenekit

下面是当设置nadir透明度为0,边缘透明度为1,亮蓝色和高菲涅耳指数时的效果

amplified fresnel effect

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55677388

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档