Eevee: Remove ShadingData struct.

That was a bad idea after all.
This commit is contained in:
Clément Foucault
2017-06-29 01:20:35 +02:00
parent 2117334737
commit 8d57f4e3c6
4 changed files with 58 additions and 65 deletions

View File

@@ -76,11 +76,6 @@ struct ShadowCascadeData {
vec4 bias;
};
struct ShadingData {
vec3 V; /* View vector */
vec3 N; /* World Normal of the fragment */
};
#define cameraVec ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward)
/* ------- Convenience functions --------- */

View File

@@ -11,19 +11,19 @@
/* ------------ Diffuse ------------- */
float direct_diffuse_point(ShadingData sd, vec4 l_vector)
float direct_diffuse_point(vec3 N, vec4 l_vector)
{
float dist = l_vector.w;
vec3 L = l_vector.xyz / dist;
float bsdf = max(0.0, dot(sd.N, L));
float bsdf = max(0.0, dot(N, L));
bsdf /= dist * dist;
return bsdf;
}
/* infinitly far away point source, no decay */
float direct_diffuse_sun(LightData ld, ShadingData sd)
float direct_diffuse_sun(LightData ld, vec3 N)
{
float bsdf = max(0.0, dot(sd.N, -ld.l_forward));
float bsdf = max(0.0, dot(N, -ld.l_forward));
bsdf *= M_1_PI; /* Normalize */
return bsdf;
}
@@ -31,12 +31,12 @@ float direct_diffuse_sun(LightData ld, ShadingData sd)
/* From Frostbite PBR Course
* Analytical irradiance from a sphere with correct horizon handling
* http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf */
float direct_diffuse_sphere(LightData ld, ShadingData sd, vec4 l_vector)
float direct_diffuse_sphere(LightData ld, vec3 N, vec4 l_vector)
{
float dist = l_vector.w;
vec3 L = l_vector.xyz / dist;
float radius = max(ld.l_sizex, 0.0001);
float costheta = clamp(dot(sd.N, L), -0.999, 0.999);
float costheta = clamp(dot(N, L), -0.999, 0.999);
float h = min(ld.l_radius / dist , 0.9999);
float h2 = h*h;
float costheta2 = costheta * costheta;
@@ -61,7 +61,7 @@ float direct_diffuse_sphere(LightData ld, ShadingData sd, vec4 l_vector)
/* From Frostbite PBR Course
* http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf */
float direct_diffuse_rectangle(LightData ld, ShadingData sd, vec4 l_vector)
float direct_diffuse_rectangle(LightData ld, vec3 N, vec3 V, vec4 l_vector)
{
vec3 corners[4];
corners[0] = l_vector.xyz + ld.l_right * -ld.l_sizex + ld.l_up * ld.l_sizey;
@@ -69,7 +69,7 @@ float direct_diffuse_rectangle(LightData ld, ShadingData sd, vec4 l_vector)
corners[2] = l_vector.xyz + ld.l_right * ld.l_sizex + ld.l_up * -ld.l_sizey;
corners[3] = l_vector.xyz + ld.l_right * ld.l_sizex + ld.l_up * ld.l_sizey;
float bsdf = ltc_evaluate(sd.N, sd.V, mat3(1.0), corners);
float bsdf = ltc_evaluate(N, V, mat3(1.0), corners);
bsdf *= M_1_2PI;
return bsdf;
}
@@ -83,35 +83,35 @@ float direct_diffuse_unit_disc(vec3 N, vec3 L)
#endif
/* ----------- GGx ------------ */
vec3 direct_ggx_point(ShadingData sd, vec4 l_vector, float roughness, vec3 f0)
vec3 direct_ggx_point(vec3 N, vec3 V, vec4 l_vector, float roughness, vec3 f0)
{
float dist = l_vector.w;
vec3 L = l_vector.xyz / dist;
float bsdf = bsdf_ggx(sd.N, L, sd.V, roughness);
float bsdf = bsdf_ggx(N, L, V, roughness);
bsdf /= dist * dist;
/* Fresnel */
float VH = max(dot(sd.V, normalize(sd.V + L)), 0.0);
float VH = max(dot(V, normalize(V + L)), 0.0);
return F_schlick(f0, VH) * bsdf;
}
vec3 direct_ggx_sun(LightData ld, ShadingData sd, float roughness, vec3 f0)
vec3 direct_ggx_sun(LightData ld, vec3 N, vec3 V, float roughness, vec3 f0)
{
float bsdf = bsdf_ggx(sd.N, -ld.l_forward, sd.V, roughness);
float VH = max(dot(sd.V, normalize(sd.V - ld.l_forward)), 0.0);
float bsdf = bsdf_ggx(N, -ld.l_forward, V, roughness);
float VH = max(dot(V, normalize(V - ld.l_forward)), 0.0);
return F_schlick(f0, VH) * bsdf;
}
vec3 direct_ggx_sphere(LightData ld, ShadingData sd, vec4 l_vector, float roughness, vec3 f0)
vec3 direct_ggx_sphere(LightData ld, vec3 N, vec3 V, vec4 l_vector, float roughness, vec3 f0)
{
vec3 L = l_vector.xyz / l_vector.w;
vec3 spec_dir = get_specular_dominant_dir(sd.N, sd.V, roughness);
vec3 spec_dir = get_specular_dominant_dir(N, V, roughness);
vec3 P = line_aligned_plane_intersect(vec3(0.0), spec_dir, l_vector.xyz);
vec3 Px = normalize(P - l_vector.xyz) * ld.l_radius;
vec3 Py = cross(Px, L);
vec2 uv = lut_coords(dot(sd.N, sd.V), sqrt(roughness));
vec2 uv = lut_coords(dot(N, V), sqrt(roughness));
vec3 brdf_lut = texture(utilTex, vec3(uv, 1.0)).rgb;
vec4 ltc_lut = texture(utilTex, vec3(uv, 0.0)).rgba;
mat3 ltc_mat = ltc_matrix(ltc_lut);
@@ -131,14 +131,14 @@ vec3 direct_ggx_sphere(LightData ld, ShadingData sd, vec4 l_vector, float roughn
points[5] = l_vector.xyz + Pxy2;
points[6] = l_vector.xyz + Py;
points[7] = l_vector.xyz + Pxy1;
float bsdf = ltc_evaluate_circle(sd.N, sd.V, ltc_mat, points);
float bsdf = ltc_evaluate_circle(N, V, ltc_mat, points);
#else
vec3 points[4];
points[0] = l_vector.xyz + Px;
points[1] = l_vector.xyz - Py;
points[2] = l_vector.xyz - Px;
points[3] = l_vector.xyz + Py;
float bsdf = ltc_evaluate(sd.N, sd.V, ltc_mat, points);
float bsdf = ltc_evaluate(N, V, ltc_mat, points);
/* sqrt(pi/2) difference between square and disk area */
bsdf *= 1.25331413731;
#endif
@@ -151,7 +151,7 @@ vec3 direct_ggx_sphere(LightData ld, ShadingData sd, vec4 l_vector, float roughn
return spec;
}
vec3 direct_ggx_rectangle(LightData ld, ShadingData sd, vec4 l_vector, float roughness, vec3 f0)
vec3 direct_ggx_rectangle(LightData ld, vec3 N, vec3 V, vec4 l_vector, float roughness, vec3 f0)
{
vec3 corners[4];
corners[0] = l_vector.xyz + ld.l_right * -ld.l_sizex + ld.l_up * ld.l_sizey;
@@ -159,11 +159,11 @@ vec3 direct_ggx_rectangle(LightData ld, ShadingData sd, vec4 l_vector, float rou
corners[2] = l_vector.xyz + ld.l_right * ld.l_sizex + ld.l_up * -ld.l_sizey;
corners[3] = l_vector.xyz + ld.l_right * ld.l_sizex + ld.l_up * ld.l_sizey;
vec2 uv = lut_coords(dot(sd.N, sd.V), sqrt(roughness));
vec2 uv = lut_coords(dot(N, V), sqrt(roughness));
vec3 brdf_lut = texture(utilTex, vec3(uv, 1.0)).rgb;
vec4 ltc_lut = texture(utilTex, vec3(uv, 0.0)).rgba;
mat3 ltc_mat = ltc_matrix(ltc_lut);
float bsdf = ltc_evaluate(sd.N, sd.V, ltc_mat, corners);
float bsdf = ltc_evaluate(N, V, ltc_mat, corners);
bsdf *= brdf_lut.b; /* Bsdf intensity */
bsdf *= M_1_2PI;

View File

@@ -118,55 +118,55 @@ float light_visibility(LightData ld, vec3 W, vec4 l_vector)
return vis;
}
float light_diffuse(LightData ld, ShadingData sd, vec4 l_vector)
float light_diffuse(LightData ld, vec3 N, vec3 V, vec4 l_vector)
{
#ifdef USE_LTC
if (ld.l_type == SUN) {
/* TODO disk area light */
return direct_diffuse_sun(ld, sd);
return direct_diffuse_sun(ld, N);
}
else if (ld.l_type == AREA) {
return direct_diffuse_rectangle(ld, sd, l_vector);
return direct_diffuse_rectangle(ld, N, V, l_vector);
}
else {
return direct_diffuse_sphere(ld, sd, l_vector);
return direct_diffuse_sphere(ld, N, l_vector);
}
#else
if (ld.l_type == SUN) {
return direct_diffuse_sun(ld, sd);
return direct_diffuse_sun(ld, N, V);
}
else {
return direct_diffuse_point(sd, l_vector);
return direct_diffuse_point(N, l_vector);
}
#endif
}
vec3 light_specular(LightData ld, ShadingData sd, vec4 l_vector, float roughness, vec3 f0)
vec3 light_specular(LightData ld, vec3 N, vec3 V, vec4 l_vector, float roughness, vec3 f0)
{
#ifdef USE_LTC
if (ld.l_type == SUN) {
/* TODO disk area light */
return direct_ggx_sun(ld, sd, roughness, f0);
return direct_ggx_sun(ld, N, V, roughness, f0);
}
else if (ld.l_type == AREA) {
return direct_ggx_rectangle(ld, sd, l_vector, roughness, f0);
return direct_ggx_rectangle(ld, N, V, l_vector, roughness, f0);
}
else {
return direct_ggx_sphere(ld, sd, l_vector, roughness, f0);
return direct_ggx_sphere(ld, N, V, l_vector, roughness, f0);
}
#else
if (ld.l_type == SUN) {
return direct_ggx_sun(ld, sd, roughness, f0);
return direct_ggx_sun(ld, N, V, roughness, f0);
}
else {
return direct_ggx_point(sd, l_vector, roughness, f0);
return direct_ggx_point(N, V, l_vector, roughness, f0);
}
#endif
}
#ifdef HAIR_SHADER
void light_hair_common(
LightData ld, ShadingData sd, vec4 l_vector, vec3 norm_view,
LightData ld, vec3 N, vec3 V, vec4 l_vector, vec3 norm_view,
out float occlu_trans, out float occlu,
out vec3 norm_lamp, out vec3 view_vec)
{
@@ -181,11 +181,11 @@ void light_hair_common(
lamp_vec = -l_vector.xyz;
}
norm_lamp = cross(lamp_vec, sd.N);
norm_lamp = normalize(cross(sd.N, norm_lamp)); /* Normal facing lamp */
norm_lamp = cross(lamp_vec, N);
norm_lamp = normalize(cross(N, norm_lamp)); /* Normal facing lamp */
/* Rotate view vector onto the cross(tangent, light) plane */
view_vec = normalize(norm_lamp * dot(norm_view, sd.V) + sd.N * dot(sd.N, sd.V));
view_vec = normalize(norm_lamp * dot(norm_view, V) + N * dot(N, V));
float occlusion = (dot(norm_view, norm_lamp) * 0.5 + 0.5);
float occltrans = transmission + (occlusion * (1.0 - transmission)); /* Includes transmission component */

View File

@@ -22,21 +22,23 @@ in vec3 worldNormal;
in vec3 viewNormal;
#endif
/* ----------- default ----------- */
vec3 eevee_surface_lit(vec3 world_normal, vec3 albedo, vec3 f0, float roughness, float ao)
vec3 eevee_surface_lit(vec3 N, vec3 albedo, vec3 f0, float roughness, float ao)
{
roughness = clamp(roughness, 1e-8, 0.9999);
float roughnessSquared = roughness * roughness;
ShadingData sd = ShadingData(cameraVec, normalize(world_normal));
vec3 V = cameraVec;
N = normalize(N);
vec4 rand = texture(utilTex, vec3(gl_FragCoord.xy / LUT_SIZE, 2.0));
/* ---------------- SCENE LAMPS LIGHTING ----------------- */
#ifdef HAIR_SHADER
vec3 norm_view = cross(sd.V, sd.N);
norm_view = normalize(cross(norm_view, sd.N)); /* Normal facing view */
vec3 norm_view = cross(V, N);
norm_view = normalize(cross(norm_view, N)); /* Normal facing view */
#endif
vec3 diff = vec3(0.0);
@@ -53,16 +55,13 @@ vec3 eevee_surface_lit(vec3 world_normal, vec3 albedo, vec3 f0, float roughness,
#ifdef HAIR_SHADER
vec3 norm_lamp, view_vec;
float occlu_trans, occlu;
light_hair_common(ld, sd, l_vector, norm_view, occlu_trans, occlu, norm_lamp, view_vec);
light_hair_common(ld, N, V, l_vector, norm_view, occlu_trans, occlu, norm_lamp, view_vec);
ShadingData hsd = sd;
hsd.N = -norm_lamp;
diff += l_color_vis * light_diffuse(ld, hsd, l_vector) * occlu_trans;
hsd.V = view_vec;
spec += l_color_vis * light_specular(ld, hsd, l_vector, roughnessSquared, f0) * occlu;
diff += l_color_vis * light_diffuse(ld, -norm_lamp, V, l_vector) * occlu_trans;
spec += l_color_vis * light_specular(ld, N, view_vec, l_vector, roughnessSquared, f0) * occlu;
#else
diff += l_color_vis * light_diffuse(ld, sd, l_vector);
spec += l_color_vis * light_specular(ld, sd, l_vector, roughnessSquared, f0);
diff += l_color_vis * light_diffuse(ld, N, V, l_vector);
spec += l_color_vis * light_specular(ld, N, V, l_vector, roughnessSquared, f0);
#endif
}
@@ -70,14 +69,11 @@ vec3 eevee_surface_lit(vec3 world_normal, vec3 albedo, vec3 f0, float roughness,
vec3 out_light = diff * albedo + spec * float(specToggle);
#ifdef HAIR_SHADER
sd.N = -norm_view;
N = -norm_view;
#endif
/* ---------------- SPECULAR ENVIRONMENT LIGHTING ----------------- */
/* Envmaps */
vec3 spec_dir = get_specular_dominant_dir(sd.N, sd.V, roughnessSquared);
/* Accumulate light from all sources until accumulator is full. Then apply Occlusion and BRDF. */
vec4 spec_accum = vec4(0.0);
@@ -85,15 +81,17 @@ vec3 eevee_surface_lit(vec3 world_normal, vec3 albedo, vec3 f0, float roughness,
for (int i = 0; i < MAX_PLANAR && i < planar_count && spec_accum.a < 0.999; ++i) {
PlanarData pd = planars_data[i];
float fade = probe_attenuation_planar(pd, worldPosition, sd.N);
float fade = probe_attenuation_planar(pd, worldPosition, N);
if (fade > 0.0) {
vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, sd.N, sd.V, rand.a, cameraPos, roughness, fade);
vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, rand.a, cameraPos, roughness, fade);
accumulate_light(spec, fade, spec_accum);
}
}
/* Specular probes */
vec3 spec_dir = get_specular_dominant_dir(N, V, roughnessSquared);
/* Starts at 1 because 0 is world probe */
for (int i = 1; i < MAX_PROBE && i < probe_count && spec_accum.a < 0.999; ++i) {
CubeData cd = probes_data[i];
@@ -107,20 +105,20 @@ vec3 eevee_surface_lit(vec3 world_normal, vec3 albedo, vec3 f0, float roughness,
}
/* World Specular */
if (spec_accum.a < 1.0) {
if (spec_accum.a < 0.999) {
vec3 spec = probe_evaluate_world_spec(spec_dir, roughness);
accumulate_light(spec, 1.0, spec_accum);
}
/* Ambient Occlusion */
vec3 bent_normal;
float final_ao = occlusion_compute(sd.N, viewPosition, ao, rand.rg, bent_normal);
float final_ao = occlusion_compute(N, viewPosition, ao, rand.rg, bent_normal);
/* Get Brdf intensity */
vec2 uv = lut_coords(dot(sd.N, sd.V), roughness);
vec2 uv = lut_coords(dot(N, V), roughness);
vec2 brdf_lut = texture(utilTex, vec3(uv, 1.0)).rg;
out_light += spec_accum.rgb * F_ibl(f0, brdf_lut) * specular_occlusion(dot(sd.N, sd.V), final_ao, roughness) * float(specToggle);
out_light += spec_accum.rgb * F_ibl(f0, brdf_lut) * specular_occlusion(dot(N, V), final_ao, roughness) * float(specToggle);
/* ---------------- DIFFUSE ENVIRONMENT LIGHTING ----------------- */