standard pbr(二)

博客主要围绕像素着色器代码展开,展示了相关代码片段,提及去掉分支但clip无需去掉,走进UNITY_SETUP_BRDF_INPUT,默认是SpecularSetup,实际因定义为MetallicSetup,还添加了自发光和边缘光,最后剩下BRDF和BRDF_GI。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下一步看像素着色器代码

 half4 fragBase (VertexOutputForwardBase i) : SV_Target { return fragForwardBaseInternal(i); }

half4 fragForwardBaseInternal (VertexOutputForwardBase i)
{
    FRAGMENT_SETUP(s)
#if UNITY_OPTIMIZE_TEXCUBELOD
    s.reflUVW       = i.reflUVW;
#endif

    UnityLight mainLight = MainLight ();
    half atten = SHADOW_ATTENUATION(i);


    half occlusion = Occlusion(i.tex.xy);
    UnityGI gi = FragmentGI (s, occlusion, i.ambientOrLightmapUV, atten, mainLight);

    half4 c = UNITY_BRDF_PBS (s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, -s.eyeVec, gi.light, gi.indirect);
    c.rgb += UNITY_BRDF_GI (s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, -s.eyeVec, occlusion, gi);
    c.rgb += Emission(i.tex.xy);

    UNITY_APPLY_FOG(i.fogCoord, c.rgb);
    return OutputForward (c, s.alpha);
}
FRAGMENT_SETUP(s)等价于

FragmentCommonData s= FragmentSetup(i.tex, i.eyeVec, IN_VIEWDIR4PARALLAX(i), i.tangentToWorldAndParallax, IN_WORLDPOS(i));

struct FragmentCommonData
{
    half3 diffColor, specColor;
    // Note: smoothness & oneMinusReflectivity for optimization purposes, mostly for DX9 SM2.0 level.
    // Most of the math is being done on these (1-x) values, and that saves a few precious ALU slots.
    half oneMinusReflectivity, smoothness;
    half3 normalWorld, eyeVec, posWorld;
    half alpha;

#if UNITY_OPTIMIZE_TEXCUBELOD || UNITY_STANDARD_SIMPLE
    half3 reflUVW;
#endif

#if UNITY_STANDARD_SIMPLE
    half3 tangentSpaceNormal;
#endif
};
 

去掉分支

struct FragmentCommonData
{
    half3 diffColor, specColor;
    // Note: smoothness & oneMinusReflectivity for optimization purposes, mostly for DX9 SM2.0 level.
    // Most of the math is being done on these (1-x) values, and that saves a few precious ALU slots.
    half oneMinusReflectivity, smoothness;
    half3 normalWorld, eyeVec, posWorld;
    half alpha;
    half3 reflUVW;
};
oneMinusReflectivity 看单词意思反射率,不知道干嘛的,存疑
看函数FragmentSetup
inline FragmentCommonData FragmentSetup (float4 i_tex, half3 i_eyeVec, half3 i_viewDirForParallax, half4 tangentToWorld[3], half3 i_posWorld)
{
    i_tex = Parallax(i_tex, i_viewDirForParallax);

    half alpha = Alpha(i_tex.xy);
    #if defined(_ALPHATEST_ON)
        clip (alpha - _Cutoff);
    #endif

    FragmentCommonData o = UNITY_SETUP_BRDF_INPUT (i_tex);
    o.normalWorld = PerPixelWorldNormal(i_tex, tangentToWorld);
    o.eyeVec = NormalizePerPixelNormal(i_eyeVec);
    o.posWorld = i_posWorld;

    // NOTE: shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha)
    o.diffColor = PreMultiplyAlpha (o.diffColor, alpha, o.oneMinusReflectivity, /*out*/ o.alpha);
    return o;
}
i_tex = Parallax(i_tex, i_viewDirForParallax);忽略,没用视差贴图,这句等于没用
half alpha = Alpha(i_tex.xy);
    #if defined(_ALPHATEST_ON)
        clip (alpha - _Cutoff);
    #endif

 clip不需要去掉

走进UNITY_SETUP_BRDF_INPUT ,默认是SpecularSetup

inline FragmentCommonData SpecularSetup (float4 i_tex)
{
    half4 specGloss = SpecularGloss(i_tex.xy);
    half3 specColor = specGloss.rgb;
    half smoothness = specGloss.a;

    half oneMinusReflectivity;
    half3 diffColor = EnergyConservationBetweenDiffuseAndSpecular (Albedo(i_tex), specColor, /*out*/ oneMinusReflectivity);

    FragmentCommonData o = (FragmentCommonData)0;
    o.diffColor = diffColor;
    o.specColor = specColor;
    o.oneMinusReflectivity = oneMinusReflectivity;
    o.smoothness = smoothness;
    return o;
}

但是在standard.shader里有#define UNITY_SETUP_BRDF_INPUT MetallicSetup,所以其实是

inline FragmentCommonData MetallicSetup (float4 i_tex)
{
    half2 metallicGloss = MetallicGloss(i_tex.xy);
    half metallic = metallicGloss.x;
    half smoothness = metallicGloss.y; // this is 1 minus the square root of real roughness m.

    half oneMinusReflectivity;
    half3 specColor;
    half3 diffColor = DiffuseAndSpecularFromMetallic (Albedo(i_tex), metallic, /*out*/ specColor, /*out*/ oneMinusReflectivity);

    FragmentCommonData o = (FragmentCommonData)0;
    o.diffColor = diffColor;
    o.specColor = specColor;
    o.oneMinusReflectivity = oneMinusReflectivity;
    o.smoothness = smoothness;
    return o;
}

  把

FragmentSetup 和
FragmentGI 合并到一块
fixed4 frag(v2f i) : SV_Target
            {
            
                UnityLight mainLight = MainLight ();
                half atten = SHADOW_ATTENUATION(i);
                
                UnityGIInput d;
                d.light = mainLight;
                d.worldPos = i.posWorld;
                half3 worldViewDir  = -normalize(i.eyeVec);
                d.worldViewDir = worldViewDir
                d.atten = atten;
                d.ambient = i_ambientOrLightmapUV.rgb;
                d.lightmapUV = 0;
                d.probeHDR[0] = unity_SpecCube0_HDR;
                d.probeHDR[1] = unity_SpecCube1_HDR;
                fixed metallic = _MetallicMin + channel.g * ( _Metallic - _MetallicMin );
                half oneMinusReflectivity;
                half3 specColor;
                half3 diffColor = DiffuseAndSpecularFromMetallic (mainTex.rgb, metallic, /*out*/ specColor, /*out*/ oneMinusReflectivity);
                fixed smoothness = ( _GlossinessMin + channel.r * (_Glossiness-_GlossinessMin)  )* 0.99h;
                half3 normalWorld = PerPixelWorldNormal(i.tex, i.tangentToWorldAndParallax )
                Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(smoothness, worldViewDir, s.normalWorld, specColor);
                // Replace the reflUVW if it has been compute in Vertex shader. Note: the compiler will optimize the calcul in UnityGlossyEnvironmentSetup itself
                g.reflUVW = i.reflUVW;
                UnityGI gi = UnityGlobalIllumination (d, 1, normalWorld, g);                
                 half4 c = BRDF(diffColor, specColor, oneMinusReflectivity, smoothness, normalWorld, worldViewDir, gi.light, gi.indirect);
                c.rgb += BRDF_GI (diffColor, specColor, oneMinusReflectivity, smoothness, normalWorld, worldViewDir, 1, gi);
                fixed emimask = tex2D(_EmissiveMap, i.uv).r;
                fixed3 Emissive = emimask * _EmissiveColor.rgb * _EmissiveIntensity;
                float3 _Rim = pow(1.0 - max(0, dot(normalWorld, worldViewDir)), _RimArea)*_RimColor.rgb*_RimPower;
                c.rgb += Emissive + _Rim;
                UNITY_APPLY_FOG(i.fogCoord, c.rgb);
                return OutputForward (c, 1);
            }

后面部分加了自发光和边缘光

现在只剩下BRDF和BRDF_GI 了

转载于:https://www.cnblogs.com/marcher/p/9535049.html

<think>好的,用户想了解数通中的PBR(策略路由)技术实现与应用。首先,我需要回忆PBR的基本概念和它在网络中的作用。PBR允许根据策略而不是传统的路由表来转发数据包,这样可以实现更灵活的流量管理。 接下来,要确认PBR的实现方式。通常涉及路由映射(Route-map)、ACL、IP前缀列表等工具。需要结合这些组件如何协同工作,比如使用ACL匹配流量,再通过Route-map设置下一跳或出接口。 然后,应用场景是用户关心的部分。PBR常用于负载均衡、流量工程、安全策略等。例如,将特定流量引导到防火墙进行检测,或者根据来源IP选择不同的出口。 还要考虑配置步骤,比如在华为或思科设备上的具体命令。但用户可能不需要详细配置,而是更关注原理和用途。此外,需要区分PBR与普通路由的区别,强调其策略优先于路由表的特性。 用户可能的问题包括PBR的优缺点、如何与现有网络集成、常见配置错误等。需要确保回答覆盖这些潜在问题,并提供实际案例帮助理解。 最后,检查是否有引用相关文献的需求。虽然用户提供的引用主要关于filter-policy和BGP,但可以适当关联,比如比较PBR与filter-policy在流量控制上的不同应用。确保回答结构清晰,分点说明,并生成相关问题供用户进一步探索。</think>### 数通PBR(策略路由)技术实现与应用 #### 1. **PBR基础概念** 策略路由(Policy-Based Routing, PBR)是一种基于用户自定义策略(如源/目的地址、协议类型、端口等)而非传统路由表进行数据包转发的技术。它能够绕过标准路由决策,实现更灵活的流量控制[^1]。 #### 2. **PBR核心组件** - **路由映射(Route-map)**:定义匹配条件和动作(如设置下一跳、出接口)。 - **ACL/IP前缀列表**:用于匹配特定流量(例如:`ip access-list extended PBR_ACL`)。 - **策略应用接口**:将策略绑定到特定接口或全局路由进程。 #### 3. **PBR实现步骤** 1. **定义匹配条件**:通过ACL或IP前缀列表筛选流量。 ```plaintext ip access-list standard PBR_TRAFFIC permit 192.168.1.0 0.0.0.255 ``` 2. **配置路由映射**:指定匹配后的动作(如修改下一跳)。 ```plaintext route-map PBR_MAP permit 10 match ip address PBR_TRAFFIC set ip next-hop 10.1.1.2 ``` 3. **应用策略**:在接口或全局启用PBR。 ```plaintext interface GigabitEthernet0/0 ip policy route-map PBR_MAP ``` #### 4. **典型应用场景** - **流量负载均衡**:根据源IP将流量分配到不同链路。 - **服务质量(QoS)**:优先转发关键业务流量(如VoIP)。 - **安全策略**:强制特定流量经过防火墙或IDS检测[^2]。 - **多出口网络**:根据协议类型选择不同ISP出口(如HTTP走电信、FTP走联通)。 #### 5. **PBR与普通路由的区别** | 特性 | 传统路由 | PBR | |--------------|------------------------|-------------------------| | 决策依据 | 目标地址 | 自定义策略(源IP、端口等) | | 优先级 | 低 | 高 | | 灵活性 | 低 | 高 | | 配置复杂度 | 简单 | 较高 | #### 6. **注意事项** - **性能影响**:复杂策略可能增加设备处理延迟。 - **环路风险**:需确保策略不会导致路由环路(例如:下一跳不可达时需配置默认动作)。 - **兼容性**:不同厂商实现细节可能不同(如华为`traffic-policy`与思科`route-map`)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值