diff options
Diffstat (limited to 'intermediate/surface.glsl')
-rw-r--r-- | intermediate/surface.glsl | 182 |
1 files changed, 156 insertions, 26 deletions
diff --git a/intermediate/surface.glsl b/intermediate/surface.glsl index 82bf2f6..cc287e4 100644 --- a/intermediate/surface.glsl +++ b/intermediate/surface.glsl @@ -9,6 +9,22 @@ fragment: main #ifdef DESC +[option] +name: albedomap +stage: fragment +[option] +name: aomap +stage: fragment +[option] +name: metalmap +stage: fragment +[option] +name: roughmap +stage: fragment +[option] +name: normalmap +stage: fragment + [binding] name: mesh rate: vertex @@ -29,9 +45,6 @@ type: vec2 name: uv type: vec2 [interpolator] -name: screen -type: vec4 -[interpolator] name: position type: vec4 [interpolator] @@ -117,7 +130,7 @@ dimension: cube [texture] name: shadowmaps stage: fragment -dimension: array +dimension: shadowArray [target] name: colour @@ -136,9 +149,7 @@ void main() { interpolator.uv = uv; interpolator.position = pos; interpolator.tbn = mat3(t, b, n); - pos = c_vp.view_projection * pos; - interpolator.screen = pos; - gl_Position = pos; + gl_Position = c_vp.view_projection * pos; } #endif @@ -147,8 +158,8 @@ void main() { #define pi 3.14159265358979323846 -vec3 diffuse_brdf(vec2 uv) { - vec3 a = material.albedo * texture(albedo, uv).rgb; +vec3 diffuse_brdf(vec2 uv, vec3 base) { + vec3 a = base; return a / pi; } @@ -162,7 +173,11 @@ float specular_G1(float a, vec3 v, vec3 n) { float specular_brdf(vec2 uv, vec3 ref, vec3 l, vec3 v, vec3 n) { float ndl = max(dot(n, l), 0.0); float ndv = max(dot(n, v), 0.0); +#if OPT_roughmap float a = texture(rough, uv).r * material.roughness; +#else + float a = material.roughness; +#endif float a2 = a * a; float ndr = max(dot(n, ref), 0.0); float b = ((ndr * ndr) * (a2 - 1) + 1); @@ -175,45 +190,160 @@ float specular_brdf(vec2 uv, vec3 ref, vec3 l, vec3 v, vec3 n) { return (D * F * G) / (4.0 * ndl * ndv + 0.001); } -void main() { +vec2 poissonDisk[16] = vec2[]( + vec2(-0.94201624, -0.39906216), + vec2(0.94558609, -0.76890725), + vec2(-0.094184101, -0.92938870), + vec2(0.34495938, 0.29387760), + vec2(-0.91588581, 0.45771432), + vec2(-0.81544232, -0.87912464), + vec2(-0.38277543, 0.27676845), + vec2(0.97484398, 0.75648379), + vec2(0.44323325, -0.97511554), + vec2(0.53742981, -0.47373420), + vec2(-0.26496911, -0.41893023), + vec2(0.79197514, 0.19090188), + vec2(-0.24188840, 0.99706507), + vec2(-0.81409955, 0.91437590), + vec2(0.19984126, 0.78641367), + vec2(0.14383161, -0.14100790) +); + +float random(vec3 seed, int i){ + vec4 seed4 = vec4(seed,i); + float dot_product = dot(seed4, vec4(12.9898,78.233,45.164,94.673)); + return fract(sin(dot_product) * 43758.5453); +} + +float get_shadow(Light l, vec3 wpos) { + const int taps = 4; + const float w = 1.0 / float(taps); + const float m = 1.0 / 1000.0; int i; + float d = 0.0f; + Caster caster = casters[l.caster_id]; + vec4 surf = caster.projection * vec4(wpos, 1.0); + surf /= surf.w; + surf.xy = surf.xy * 0.5 + 0.5; + surf.z -= 0.005; + for (i = 0; i < taps; i++) { + int index = int(16.0 * random(floor(wpos.xyz * 1000.0), i)) % 16; + vec2 coord = surf.xy + poissonDisk[index] * m; + vec4 vec = vec4(coord, float(l.caster_id), surf.z); + d += texture(shadowmaps, vec).r * w; + } + return d; +} + +vec3 apply_light( + Light l, + vec3 p, + vec2 uv, + vec3 base_diffuse, + vec3 spec_col, + vec3 ref, + vec3 light_dir, + vec3 view_dir, + vec3 nrm, + float cos_theta_i, + float atten +) { + vec3 diffuse = base_diffuse * cos_theta_i; + vec3 spec = + spec_col * + specular_brdf(uv, ref, light_dir, view_dir, nrm) * + cos_theta_i; + float shadow = 1.0f; + if (l.caster_id >= 0) + shadow = get_shadow(l, p); + return (diffuse + spec) * atten * l.brightness * l.colour * shadow; +} + +void main() { + int i, e; vec2 uv = interpolator.uv; - vec2 suv = (interpolator.screen.xy / interpolator.screen.w) * 0.5 + 0.5; vec3 p = interpolator.position.xyz; +#if OPT_normalmap vec3 nrmsample = texture(normal, uv).rgb; vec2 nrmxy = nrmsample.xy * 2.0 - 1.0; vec3 nrm = normalize(vec3(nrmxy, 1.0)); - if (nrmsample.b == 1.0) /* default texture */ - nrm = normalize(interpolator.tbn[2]); - else - nrm = normalize(interpolator.tbn * nrm); + nrm = normalize(interpolator.tbn * nrm); +#else + vec3 nrm = normalize(interpolator.tbn[2]); +#endif +#if OPT_albedomap vec3 col = texture(albedo, uv).rgb * material.albedo; - vec3 view_dir = normalize(globals.camera_pos - p); +#else + vec3 col = material.albedo; +#endif + +#if OPT_metalmap float met = texture(metal, uv).r * material.metalness; +#else + float met = material.metalness; +#endif + + vec3 view_dir = normalize(globals.camera_pos - p); vec3 ref = reflect(-view_dir, nrm); vec3 ref_col = texture(env_cube, ref, material.roughness * 8.0).rgb; vec3 spec_col = mix(ref_col, ref_col * col, met); vec3 amb_col = min(textureLod(env_cube, nrm, 8.0).rgb, 0.05); +#if OPT_aomap vec3 ambient = amb_col * texture(ao, uv).r * material.ao; +#else + vec3 ambient = amb_col * material.ao; +#endif - vec3 base_diffuse = diffuse_brdf(uv) * (1.0 - met); + vec3 base_diffuse = diffuse_brdf(uv, col) * (1.0 - met); vec3 light = 0.0.xxx; - for (i = 0; i < globals.light_count; i++) { + e = globals.sun_irange.y; + for (i = globals.sun_irange.x; i < e; i++) { Light l = lights[i]; - vec3 light_dir = l.dir; + vec3 light_dir = l.pos; float cos_theta_i = max(dot(nrm, light_dir), 0.0); - vec3 diffuse = base_diffuse * cos_theta_i; - vec3 spec = - spec_col * - specular_brdf(uv, ref, light_dir, view_dir, nrm) * - cos_theta_i; - float shadow = texture(shadowmaps, vec3(suv, float(l.caster_id))).r; - light += (diffuse + spec) * l.brightness * l.colour * shadow; + float atten = 1.0; + light += apply_light( + l, + p, + uv, + base_diffuse, + spec_col, + ref, + light_dir, + view_dir, + nrm, + cos_theta_i, + atten + ); + } + e = globals.point_irange.y; + for (i = globals.point_irange.x; i < e; i++) { + Light l = lights[i]; + float cos_theta_i; + vec3 light_dir = l.pos - p; + float d = length(light_dir); + float atten = max(d, 0.01); + atten = 1.0 / (atten * atten); + light_dir /= d; + cos_theta_i = max(dot(nrm, light_dir), 0.0); + light += apply_light( + l, + p, + uv, + base_diffuse, + spec_col, + ref, + light_dir, + view_dir, + nrm, + cos_theta_i, + atten + ); } colour = vec4(ambient + light, 1.0); |