gpt4 book ai didi

opengl - 如何在 PBR 中实现金属工作流程?

转载 作者:行者123 更新时间:2023-12-03 15:00:10 24 4
gpt4 key购买 nike

Cook-Torrance BRDF 和 Lambert BRDF 上有很多 Material 。 Real Shading in Unreal Engine 4Moving Frostbite to BPR深入解释如何实现它们以进行实时渲染。

他们省略的是两个 BRDF 的组合来创建完整的着色模型。如果我理解正确,我们至少可以使用两个基本原则来做到这一点:镜面反射和金属度工作流程。 Here是他们的比较。

我决定实现金属度工作流程。所以我有以下参数作为计算的基础:

  • 反照率 (RGB)
  • 粗糙度(浮点)
  • 金属性( float )

  • 对于镜面反射部分,我需要确定我的镜面反射颜色。

    Mamoset指出

    When using a metalness map, insulative surfaces - pixels set to 0.0 (black) in the metalness map – are assigned a fixed reflectance value (linear: 0.04 sRGB: 0.22) and use the albedo map for the diffuse value. For metallic surfaces – pixels set to 1.0 (white) in the metalness map – the specular color and intensity is taken from the albedo map, and the diffuse value is set to 0 (black) in the shader.



    因此,应通过以下方式计算镜面反射颜色:
    vec3 specularColor = mix(vec3(0.04), material.albedo, material.metalness);

    随后,这可用于计算反射辐射。为了限制我的问题的延伸,我将引用 Brian Karis的实现在这里,这是以下内容:
    vec3 L_specular = specularIBL(specularColor, material.roughness, normal, view);

    对于漫反射部分,我需要确定反照率。

    它的工作原理在上面的同一引文中有所描述:
    vec3 albedo = mix(material.albedo, vec3(0), material.metalness);

    现在,Lambert BRDF 可用于计算来自某些入射辐照度 E 的漫射照明:
    vec3 L_diffuse = f_lambert(albedo) * E;

    为了得到最终的辐射,漫反射和镜面反射部分被结合起来:
    vec3 L = kd * L_diffuse + ks * L_specular;

    我的问题是如何计算 kdks ?
  • Codinglabs建议对半球上的菲涅耳函数进行积分以计算 ks .
  • kd之后计算如下:
    vec3 kd = (1 - ks) * (1 - material.metalness);

    例如,将非金属与虚幻引擎进行比较时,我得到的结果并不是我所期望的。法向入射时的反射比预期的要低得多,这应该是由于在非金属情况下设置的 F0 低。但我检查了进一步的来源,0.04 似乎是常用的值。

    有人可以确认 Codinglabs 的建议计算吗? ?或者甚至提供 Epic 使用的代码?

    最佳答案

    正如您已经确定的那样,反照率对应于 Material 的漫反射颜色。
    当谈到镜面反射时,它有两种方式:电介质或导体(通常是金属的)。
    对于电介质,这很简单,镜面反射颜色始终为纯白色(无着色),并由菲涅耳和基础反射率(也称为 F0 )定义:此标量仅表示光的百分比直视表面时会反射。
    ' 0.04 ' 值对应于 4% 基础反射率,您可以通过代入 的 IOR 计算出1.5 对于菲涅耳反射率公式中的 n1 和空气的 IOR(近似于 1.0 )对于 n2 (taken off Wikipedia) :
    enter image description here
    给定 Material 的 IOR 在互联网上很容易找到,大多数介电常数位于 左右。 1.5 反正。

    在导体的情况下,公式并不那么简单,因此您会发现实现的通常方法(由 Codinglabs、UE4 和其他引擎)是明确指定金属色的色调/反射/镜面颜色,因为它更具艺术性-友好的。例如,纯红色意味着 100% 的红光被反射,而 100% 的蓝光和绿光被吸收。
    金属度项只是一个粗略的近似值,用于在明确的艺术家指定的反射颜色和正确/计算出的 之间进行插值。 F0 这适用于电介质。

    我不相信你发布的链接上的公式是完全正确的。能量守恒定律意味着漫反射能量和镜面反射能量之和为 1.0 .因此, kd 应该是:

    kd = (1 - ks)
    可以这样想:任何未被 Material 吸收的光都应该被反射。
    此外, (1 - material.metalness) 在计算镜面反射颜色时已经考虑了:
    vec3 specularColor = mix(vec3(0.04), material.albedo, material.metalness);
    对于漫反射颜色也:
    vec3 albedo = mix(material.albedo, vec3(0), material.metalness);
    纯导体基本上只有镜面反射,没有扩散。

    关于opengl - 如何在 PBR 中实现金属工作流程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36401272/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com