diff options
author | pryazha <pryadeiniv@mail.ru> | 2025-07-23 20:55:29 +0500 |
---|---|---|
committer | pryazha <pryadeiniv@mail.ru> | 2025-07-23 20:55:29 +0500 |
commit | 33d5f67044d104d69cb2d11e78e6a79bc20d4c4e (patch) | |
tree | 61a61becc4a2ccf2638403ecd85518d26bbf1a23 /pbr/2.1.1.ibl_irradiance_conversion/pbr.frag | |
parent | 76df5cc4186ca3449e9b957e7de753cb6df4047b (diff) |
some prb examples
Diffstat (limited to 'pbr/2.1.1.ibl_irradiance_conversion/pbr.frag')
-rw-r--r-- | pbr/2.1.1.ibl_irradiance_conversion/pbr.frag | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/pbr/2.1.1.ibl_irradiance_conversion/pbr.frag b/pbr/2.1.1.ibl_irradiance_conversion/pbr.frag new file mode 100644 index 0000000..db9edea --- /dev/null +++ b/pbr/2.1.1.ibl_irradiance_conversion/pbr.frag @@ -0,0 +1,105 @@ +#version 330 core + +in vert_t { + vec3 position; + vec3 normal; +} vert; + +out vec4 frag_color; + +uniform vec3 camera; + +uniform vec3 color; +uniform float metallic; +uniform float roughness; +uniform float ao; + +struct light_t { + vec3 position; + vec3 color; +}; + +const int light_count = 4; +uniform light_t lights[light_count]; + +const float PI = 3.14159265358; + +vec3 fresnel_shlick(float costheta, vec3 f0) +{ + return f0 + (1.0 - f0) * pow(1.0 - costheta, 5.0); +} + +float distribution_ggx(vec3 n, vec3 h, float roughness) +{ + float a = roughness * roughness; + float a2 = a * a; + float ndoth = max(dot(n, h), 0.0); + float ndoth2 = ndoth * ndoth; + + float num = a2; + float denom = (ndoth2 * (a2 - 1.0) + 1.0); + denom = PI * denom * denom; + + return num / denom; +} + +float geometry_shlick_ggx(float ndotv, float roughness) +{ + float r = roughness + 1.0; + float k = r * r / 8.0; + + float num = ndotv; + float denom = ndotv * (1.0 - k) + k; + + return num / denom; +} + +float geometry_smith(vec3 n, vec3 v, vec3 l, float roughness) +{ + float ndotv = max(dot(n, v), 0.0); + float ndotl = max(dot(n, l), 0.0); + float ggx2 = geometry_shlick_ggx(ndotv, roughness); + float ggx1 = geometry_shlick_ggx(ndotl, roughness); + + return ggx1 * ggx2; +} + +void main(void) +{ + vec3 n = vert.normal; + vec3 v = normalize(camera - vert.position); + + vec3 lo = vec3(0.0); + for (int i = 0; i < light_count; i++) { + vec3 l = normalize(lights[i].position - vert.position); + vec3 h = normalize(v + l); + float ndotv = max(dot(n, v), 0.0); + float ndotl = max(dot(n, l), 0.0); + + float distance = length(lights[i].position - vert.position); + float attenuation = 1.0 / (distance * distance); + + vec3 radiance = lights[i].color * attenuation; + + vec3 f0 = vec3(0.04); + f0 = mix(f0, color, metallic); + vec3 f = fresnel_shlick(max(dot(h, v), 0.0), f0); + + float ndf = distribution_ggx(n, h, roughness); + float g = geometry_smith(n, v, l, roughness); + + vec3 numerator = ndf * g * f; + float denominator = 4.0 * ndotv * ndotl; + vec3 specular = numerator / max(denominator, 0.001); + + vec3 ks = f; + vec3 kd = vec3(1.0) - ks; + + kd *= 1.0 - metallic; + + lo += (kd * color / PI + specular) * radiance * ndotl; + } + + vec3 ambient = vec3(0.03) * color * ao; + frag_color = vec4(ambient + lo, 1.0); +} |