PBR
This commit is contained in:
@ -2,6 +2,7 @@
|
||||
const float EPS = 0.001;
|
||||
const int MAX_ITER = 128;
|
||||
const float INF = 1e10;
|
||||
const float PI = 3.14159;
|
||||
|
||||
uniform vec2 u_resolution;
|
||||
out vec4 fragColor;
|
||||
@ -68,17 +69,76 @@ vec3 nrm(vec3 p) {
|
||||
));
|
||||
}
|
||||
|
||||
float saturate(float x) {
|
||||
return clamp(x, 0.0, 1.0);
|
||||
}
|
||||
|
||||
float ggx_distribution(vec3 n, vec3 h, float roughness) {
|
||||
float alpha = roughness * roughness;
|
||||
float alpha2 = alpha * alpha;
|
||||
float NdotH = saturate(dot(n, h));
|
||||
float denom = NdotH * NdotH * (alpha2 - 1.0) + 1.0;
|
||||
return alpha2 / max(PI * denom * denom, EPS);
|
||||
}
|
||||
|
||||
float geometry_schlick_ggx(float NdotX, float roughness) {
|
||||
float r = roughness + 1.0;
|
||||
float k = r * r / 8.0;
|
||||
return NdotX / max(NdotX * (1.0 - k) + k, EPS);
|
||||
}
|
||||
|
||||
float geometry_smith(vec3 n, vec3 v, vec3 l, float roughness) {
|
||||
float NdotV = saturate(dot(n, v));
|
||||
float NdotL = saturate(dot(n, l));
|
||||
return geometry_schlick_ggx(NdotV, roughness) * geometry_schlick_ggx(NdotL, roughness);
|
||||
}
|
||||
|
||||
vec3 fresnel_schlick(vec3 f0, float cos_theta) {
|
||||
return f0 + (1.0 - f0) * pow(1.0 - saturate(cos_theta), 5.0);
|
||||
}
|
||||
|
||||
vec3 tonemap_aces(vec3 c) {
|
||||
const float a = 2.51;
|
||||
const float b = 0.03;
|
||||
const float c1 = 2.43;
|
||||
const float d = 0.59;
|
||||
const float e = 0.14;
|
||||
return clamp((c * (a * c + b)) / (c * (c1 * c + d) + e), 0.0, 1.0);
|
||||
}
|
||||
|
||||
vec4 materialColor(int obj_id) {
|
||||
<COLOR_BLOCK>
|
||||
return vec4(1.0);
|
||||
}
|
||||
|
||||
vec4 color(vec3 p, int obj_id) {
|
||||
vec3 normal = nrm(p);
|
||||
vec3 light_dir = normalize(vec3(0.5, 0.8, -0.6));
|
||||
float light = 0.2 + 0.8 * max(dot(normal, light_dir), 0.0);
|
||||
vec4 base = materialColor(obj_id);
|
||||
return vec4(base.rgb * light, base.a);
|
||||
vec4 color(vec3 p, vec3 r, int obj_id) {
|
||||
vec3 light_col = vec3(1.0);
|
||||
vec4 albedo = materialColor(obj_id);
|
||||
vec3 N = nrm(p);
|
||||
vec3 V = normalize(-r);
|
||||
vec3 L = normalize(vec3(0.5, 0.8, -0.6));
|
||||
vec3 H = normalize(V + L);
|
||||
float roughness = 0.45;
|
||||
float metallic = 0.02;
|
||||
float NdotL = saturate(dot(N, L));
|
||||
float NdotV = saturate(dot(N, V));
|
||||
float D = ggx_distribution(N, H, roughness);
|
||||
float G = geometry_smith(N, V, L, roughness);
|
||||
vec3 F0 = mix(vec3(0.04), albedo.rgb, metallic);
|
||||
vec3 F = fresnel_schlick(F0, dot(V, H));
|
||||
vec3 kD = (1.0 - F) * (1.0 - metallic);
|
||||
vec3 diffuse = kD * albedo.rgb / PI;
|
||||
vec3 specular = D * G * F / max(4.0 * NdotL * NdotV, EPS);
|
||||
|
||||
float hemi = N.y * 0.5 + 0.5;
|
||||
vec3 sky_ambient = vec3(0.60, 0.72, 0.92);
|
||||
vec3 ground_ambient = vec3(0.18, 0.16, 0.14);
|
||||
vec3 ambient = mix(ground_ambient, sky_ambient, hemi) * (diffuse + 0.25 * F0) * 0.35;
|
||||
|
||||
vec3 col = ambient + (diffuse + specular) * light_col * NdotL;
|
||||
col = tonemap_aces(col);
|
||||
col = pow(col, vec3(1.0 / 2.2));
|
||||
return vec4(col, 1.0);
|
||||
}
|
||||
|
||||
vec4 march(vec3 p, vec3 r) {
|
||||
@ -87,7 +147,7 @@ vec4 march(vec3 p, vec3 r) {
|
||||
for(int i = 0; i < MAX_ITER; ++i) {
|
||||
qry = sd(p);
|
||||
if(qry.value < EPS){
|
||||
col = color(p, qry.obj_id);
|
||||
col = color(p, r, qry.obj_id);
|
||||
break;
|
||||
}
|
||||
p += qry.value * r;
|
||||
|
||||
Reference in New Issue
Block a user