zoukankan      html  css  js  c++  java
  • 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 cdot n^T = (n cdot M^{-1})^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);
    

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

  • 相关阅读:
    客户端不能连接MySQL
    Linux 7.x 防火墙&端口
    MYSQL.版本查看-LINUX
    Java之.jdk卸载-Linux
    Redis.之.环境搭建(集群)
    Elasticsearch.安装插件(head)
    Linux安装Nodejs
    Linux.ls 查看常用参数
    Elasticsearch.安装(单节点)
    Andrew NG 机器学习编程作业3 Octave
  • 原文地址:https://www.cnblogs.com/back-to-the-past/p/14466807.html
Copyright © 2011-2022 走看看