Unity 常用Light API 使用简介

1.UnityObjectToWorldNormal

用于将object space下的normal向量转换到world space下。

// Transforms normal from object to world space
inline float3 UnityObjectToWorldNormal( in float3 norm )
{
#ifdef UNITY_ASSUME_UNIFORM_SCALING
    return UnityObjectToWorldDir(norm);
#else
    // mul(IT_M, norm) => mul(norm, I_M) => {dot(norm, I_M.col0), dot(norm, I_M.col1), dot(norm, I_M.col2)}
    return normalize(mul(norm, (float3x3)unity_WorldToObject));
#endif
}

其中,UNITY_ASSUME_UNIFORM_SCALING宏显然是优化用的,即如果是统一scale变换的情况下,直接用object to world space的矩阵就可以了,不用再去特意计算normal变换的矩阵;否则,根据Unity提供的注释,计算出变换后的normal:
( n ′ ) T = ( M − 1 ) T ⋅ n T = ( n ⋅ M − 1 ) T (n')^T = (M^{-1})^T \cdot n^T = (n \cdot M^{-1})^T (n)T=(M1)TnT=(nM1)T

2.DotClamped

用于将两个向量的点积进行clamp,使其值位于0~1之间。

inline half DotClamped (half3 a, half3 b)
{
    #if (SHADER_TARGET < 30)
        return saturate(dot(a, b));
    #else
        return max(0.0h, dot(a, b));
    #endif
}

3.EnergyConservationBetweenDiffuseAndSpecular

用来计算一个object的diffuse color的能量保存程度,保存程度越大,那么反射出来的diffuse color越弱,通常用来解决一个object的diffuse color + spec color过亮的问题(例如亮度超过入射光的强度)。

// Helper functions, maybe move into UnityCG.cginc

half SpecularStrength(half3 specular)
{
    #if (SHADER_TARGET < 30)
        // SM2.0: instruction count limitation
        // SM2.0: simplified SpecularStrength
        return specular.r; // Red channel - because most metals are either monocrhome or with redish/yellowish tint
    #else
        return max (max (specular.r, specular.g), specular.b);
    #endif
}

// Diffuse/Spec Energy conservation
inline half3 EnergyConservationBetweenDiffuseAndSpecular (half3 albedo, half3 specColor, out half oneMinusReflectivity)
{
    oneMinusReflectivity = 1 - SpecularStrength(specColor);
    #if !UNITY_CONSERVE_ENERGY
        return albedo;
    #elif UNITY_CONSERVE_ENERGY_MONOCHROME
        return albedo * oneMinusReflectivity;
    #else
        return albedo * (half3(1,1,1) - specColor);
    #endif
}

我们可以这样使用:

float oneMinusReflectivity;
albedo = EnergyConservationBetweenDiffuseAndSpecular(albedo, specColor, oneMinusReflectivity);
float3 diffuse = albedo * lightColor * DotClamped(lightDir, i.normal);
float3 specular = specColor * lightColor * pow(DotClamped(halfVector, i.normal), _Smoothness);
return float4(diffuse + specular, 1);

4.DiffuseAndSpecularFromMetallic

用于根据一个object的金属化程度,计算出它的diffuse和spec分量。金属化程度越高,spec分量越大,diffuse分量越小。

inline half OneMinusReflectivityFromMetallic(half metallic)
{
    // We'll need oneMinusReflectivity, so
    //   1-reflectivity = 1-lerp(dielectricSpec, 1, metallic) = lerp(1-dielectricSpec, 0, metallic)
    // store (1-dielectricSpec) in unity_ColorSpaceDielectricSpec.a, then
    //   1-reflectivity = lerp(alpha, 0, metallic) = alpha + metallic*(0 - alpha) =
    //                  = alpha - metallic * alpha
    half oneMinusDielectricSpec = unity_ColorSpaceDielectricSpec.a;
    return oneMinusDielectricSpec - metallic * oneMinusDielectricSpec;
}

inline half3 DiffuseAndSpecularFromMetallic (half3 albedo, half metallic, out half3 specColor, out half oneMinusReflectivity)
{
    specColor = lerp (unity_ColorSpaceDielectricSpec.rgb, albedo, metallic);
    oneMinusReflectivity = OneMinusReflectivityFromMetallic(metallic);
    return albedo * oneMinusReflectivity;
}

值得注意的是,这里的specColor是API返回的,而并非是我们事先设置的。我们可以这样使用:

float oneMinusReflectivity;
albedo = DiffuseAndSpecularFromMetallic(albedo, metallic, specColor, oneMinusReflectivity);
float3 diffuse = albedo * lightColor * DotClamped(lightDir, i.normal);
float3 specular = specColor * lightColor * pow(DotClamped(halfVector, i.normal), _Smoothness);
return float4(diffuse + specular, 1);

如果你觉得我的文章有帮助,欢迎关注我的微信公众号(大龄社畜的游戏开发之路-

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s8mj38GX-1614615331819)(F:\Learning\blogs\qrcode_for_gh_16d0016744ab_258.jpg)]

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity3D中常用API包括Component、Transform、GameObjectObject和Time等。\[1\]这些API可以用于处理游戏对象的组件、变换、实例化和销毁等操作。例如,可以使用Component来获取和管理游戏对象的组件,使用Transform来控制游戏对象的位置、旋转和缩放,使用GameObject来创建、查找和销毁游戏对象,使用Object来处理资源的加载和释放,使用Time来获取游戏的时间信息。此外,还有一些常见的API函数,如Instantiate函数用于实例化预制件,Start函数和Update函数用于处理游戏对象的初始化和更新等。\[2\]\[3\]这些API和函数是Unity开发中经常使用的工具,可以帮助开发者实现各种功能和效果。 #### 引用[.reference_title] - *1* [Unity3D数字孪生笔记——Unity常用API篇](https://blog.csdn.net/Lcl_huolitianji/article/details/120875486)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Unity3D常用API](https://blog.csdn.net/u011360242/article/details/77046732)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [【Unity 3D】常见API的讲解以及在C#脚本中的执行(附源码)](https://blog.csdn.net/jiebaoshayebuhui/article/details/128510864)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值