Eevee: Remove ShadingData struct.
That was a bad idea after all.
This commit is contained in:
@@ -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 --------- */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 ----------------- */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user