1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
// Copyright (C) 2014 NVIDIA Corporation.
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef PHYS_GLOSSY_BSDF_GLSLLIB
#define PHYS_GLOSSY_BSDF_GLSLLIB 1
float qt_sqr(float v)
{
return v*v;
}
float qt_Gterm(float cosTheta, float roughness)
{
float k = roughness * 0.31830988618; // roughness / pi
return clamp((cosTheta / (cosTheta*(1.0-k) + k) + (1.0 - k*k)) * 0.5, 0.0, 1.0);
}
float qt_SmithGGXMasking(in float NdotL, in float NdotV, in float a2)
{
float ia2 = 1.0 - a2;
float A = NdotV * sqrt(a2 + ia2 * NdotL * NdotL);
float B = NdotL * sqrt(a2 + ia2 * NdotV * NdotV);
return 2.0 * NdotL * NdotV / (A + B);
}
// Isotropic GGX + smith
vec4 qt_kggxGlossyBSDFMtl(in vec3 N, in vec3 L, in vec3 V, in vec3 lightSpecular, in float roughness)
{
vec4 rgba = vec4(0.0, 0.0, 0.0, 1.0);
float NdotL = dot(N, L);
if (NdotL > 0.0) {
float NdotV = dot(N, V);
vec3 H = normalize(L + V);
float NdotH = dot(N, H);
float a2 = roughness * roughness;
float G2 = qt_SmithGGXMasking(NdotL, NdotV, a2);
float D = a2 / (3.1415926535 * qt_sqr(qt_sqr(NdotH) * (a2 - 1.0) + 1.0));
rgba.rgb = lightSpecular * G2 * D / (4.0 * NdotV * NdotH);
}
return rgba;
}
vec4 qt_kggxGlossyDefaultMtl(in vec3 normal, in vec3 tangent, in vec3 L, in vec3 V,
in vec3 lightSpecular, in vec3 materialSpecular, in float roughness)
{
return vec4(materialSpecular, 1.0) * qt_kggxGlossyBSDFMtl(normal, L, V, lightSpecular, roughness);
}
#endif
|