diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-03-31 02:07:30 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-03-31 02:07:51 +0300 |
commit | e254aa896552fa2d06ab406235ace6bdeaf5905c (patch) | |
tree | fac652df1272f4953c2b77c2919c202469a1641e /source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl | |
parent | 3fdbd78a6b5f271a8022f01ddca649ef16cf5516 (diff) |
Eevee: Codestyle, optimisation and a few fixes
Something is very wrong with the energy factor. For now I tweaked them by hand to fit cycles.
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl')
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl | 142 |
1 files changed, 66 insertions, 76 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl index f2c7b9579dd..84b1b1d599e 100644 --- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl @@ -4,28 +4,6 @@ uniform vec3 cameraPos; uniform vec3 eye; uniform mat4 ProjectionMatrix; -struct LightData { - vec4 positionAndInfluence; /* w : InfluenceRadius */ - vec4 colorAndSpec; /* w : Spec Intensity */ - vec4 spotDataRadiusShadow; /* x : spot size, y : spot blend */ - vec4 rightVecAndSizex; /* xyz: Normalized up vector, w: Lamp Type */ - vec4 upVecAndSizey; /* xyz: Normalized right vector, w: Lamp Type */ - vec4 forwardVecAndType; /* xyz: Normalized forward vector, w: Lamp Type */ -}; - -/* convenience aliases */ -#define lampColor colorAndSpec.rgb -#define lampSpec colorAndSpec.a -#define lampPosition positionAndInfluence.xyz -#define lampInfluence positionAndInfluence.w -#define lampSizeX rightVecAndSizex.w -#define lampSizeY upVecAndSizey.w -#define lampRight rightVecAndSizex.xyz -#define lampUp upVecAndSizey.xyz -#define lampForward forwardVecAndType.xyz -#define lampType forwardVecAndType.w -#define lampSpotSize spotDataRadiusShadow.x -#define lampSpotBlend spotDataRadiusShadow.y layout(std140) uniform light_block { LightData lights_data[MAX_LIGHT]; @@ -43,98 +21,110 @@ out vec4 fragColor; #define HEMI 3.0 #define AREA 4.0 -vec3 light_diffuse(LightData ld, vec3 N, vec3 W, vec3 wL, vec3 L, float Ldist, vec3 color) +float light_diffuse(LightData ld, ShadingData sd) { - vec3 light; - - if (ld.lampType == SUN) { - L = -ld.lampForward; - light = color * direct_diffuse_sun(N, L) * ld.lampColor; + if (ld.l_type == SUN) { + return direct_diffuse_sun(ld, sd); } - else if (ld.lampType == AREA) { - light = color * direct_diffuse_rectangle(W, N, L, Ldist, - ld.lampRight, ld.lampUp, ld.lampForward, - ld.lampSizeX, ld.lampSizeY) * ld.lampColor; + else if (ld.l_type == AREA) { + return direct_diffuse_rectangle(ld, sd); } else { - // light = color * direct_diffuse_point(N, L, Ldist) * ld.lampColor; - light = color * direct_diffuse_sphere(N, L, Ldist, ld.lampSizeX) * ld.lampColor; + return direct_diffuse_sphere(ld, sd); } - - return light; } -vec3 light_specular( - LightData ld, vec3 V, vec3 N, vec3 W, vec3 wL, - vec3 L, float Ldist, vec3 spec, float roughness) +float light_specular(LightData ld, ShadingData sd, float roughness) { - vec3 light; - - if (ld.lampType == SUN) { - L = -ld.lampForward; - light = spec * direct_ggx_point(N, L, V, roughness) * ld.lampColor; + if (ld.l_type == SUN) { + return direct_ggx_point(sd, roughness); } - else if (ld.lampType == AREA) { - light = spec * direct_ggx_rectangle(W, N, L, V, Ldist, ld.lampRight, ld.lampUp, ld.lampForward, - ld.lampSizeX, ld.lampSizeY, roughness) * ld.lampColor; + else if (ld.l_type == AREA) { + return direct_ggx_rectangle(ld, sd, roughness); } else { - light = spec * direct_ggx_sphere(N, L, V, Ldist, ld.lampSizeX, roughness) * ld.lampColor; + // return direct_ggx_point(sd, roughness); + return direct_ggx_sphere(ld, sd, roughness); } - - return light; } -float light_visibility( - LightData ld, vec3 V, vec3 N, vec3 W, vec3 wL, vec3 L, float Ldist) +float light_visibility(LightData ld, ShadingData sd) { float vis = 1.0; - if (ld.lampType == SPOT) { - float z = dot(ld.lampForward, wL); - vec3 lL = wL / z; - float x = dot(ld.lampRight, lL) / ld.lampSizeX; - float y = dot(ld.lampUp, lL) / ld.lampSizeY; + if (ld.l_type == SPOT) { + float z = dot(ld.l_forward, sd.l_vector); + vec3 lL = sd.l_vector / z; + float x = dot(ld.l_right, lL) / ld.l_sizex; + float y = dot(ld.l_up, lL) / ld.l_sizey; float ellipse = 1.0 / sqrt(1.0 + x * x + y * y); - float spotmask = smoothstep(0.0, 1.0, (ellipse - ld.lampSpotSize) / ld.lampSpotBlend); + float spotmask = smoothstep(0.0, 1.0, (ellipse - ld.l_spot_size) / ld.l_spot_blend); vis *= spotmask; } - else if (ld.lampType == AREA) { - vis *= step(0.0, -dot(L, ld.lampForward)); + else if (ld.l_type == AREA) { + vis *= step(0.0, -dot(sd.L, ld.l_forward)); } return vis; } -void main() +/* Calculation common to all bsdfs */ +float light_common(inout LightData ld, inout ShadingData sd) { - vec3 N = normalize(worldNormal); + float vis = 1.0; - vec3 V; - if (ProjectionMatrix[3][3] == 0.0) { - V = normalize(cameraPos - worldPosition); + if (ld.l_type == SUN) { + sd.L = -ld.l_forward; } else { - V = normalize(eye); + sd.L = sd.l_vector / sd.l_distance; } - vec3 radiance = vec3(0.0); - vec3 albedo = vec3(1.0, 1.0, 1.0); - vec3 specular = mix(vec3(0.03), vec3(1.0), pow(max(0.0, 1.0 - dot(N,V)), 5.0)); + if (ld.l_type == AREA) { + sd.area_data.corner[0] = sd.l_vector + ld.l_right * -ld.l_sizex + ld.l_up * ld.l_sizey; + sd.area_data.corner[1] = sd.l_vector + ld.l_right * -ld.l_sizex + ld.l_up * -ld.l_sizey; + sd.area_data.corner[2] = sd.l_vector + ld.l_right * ld.l_sizex + ld.l_up * -ld.l_sizey; + sd.area_data.corner[3] = sd.l_vector + ld.l_right * ld.l_sizex + ld.l_up * ld.l_sizey; + sd.area_data.solid_angle = rectangle_solid_angle(sd.area_data); + } + return vis; +} + +void main() +{ + ShadingData sd; + sd.N = normalize(worldNormal); + sd.V = (ProjectionMatrix[3][3] == 0.0) /* if perspective */ + ? normalize(cameraPos - worldPosition) + : normalize(eye); + sd.W = worldPosition; + sd.R = reflect(-sd.V, sd.N); + + /* hardcoded test vars */ + vec3 albedo = vec3(0.0); + vec3 specular = mix(vec3(1.0), vec3(1.0), pow(max(0.0, 1.0 - dot(sd.N, sd.V)), 5.0)); + float roughness = 0.5; + + sd.spec_dominant_dir = get_specular_dominant_dir(sd.N, sd.R, roughness); + + vec3 radiance = vec3(0.0); for (int i = 0; i < MAX_LIGHT && i < light_count; ++i) { - vec3 wL = lights_data[i].lampPosition - worldPosition; - float dist = length(wL); - vec3 L = wL / dist; + LightData ld = lights_data[i]; + + sd.l_vector = ld.l_position - worldPosition; + sd.l_distance = length(sd.l_vector); + + light_common(ld, sd); - float vis = light_visibility(lights_data[i], V, N, worldPosition, wL, L, dist); - vec3 spec = light_specular(lights_data[i], V, N, worldPosition, wL, L, dist, vec3(1.0), .2); - vec3 diff = light_diffuse(lights_data[i], N, worldPosition, wL, L, dist, albedo); + float vis = light_visibility(ld, sd); + float spec = light_specular(ld, sd, roughness); + float diff = light_diffuse(ld, sd); - radiance += vis * (diff + spec); + radiance += vis * (albedo * diff + specular * spec) * ld.l_color; } fragColor = vec4(radiance, 1.0); |