Eevee: Diffuse Lights (1 / 2)

I added srgb tonemapping for previewing purpose. Also since the color buffer is still not HDR, there is ugly artifacts (fixed in part2)
This commit is contained in:
Clément Foucault 2017-03-28 00:09:45 +02:00
parent 4d3d10f625
commit 6d21970aa0
7 changed files with 210 additions and 9 deletions

View File

@ -103,6 +103,8 @@ data_to_c_simple(engines/clay/shaders/ssao_groundtruth.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lit_surface_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lit_surface_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/tonemap_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/bsdf_direct_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/bsdf_common_lib.glsl SRC)
data_to_c_simple(modes/shaders/common_globals_lib.glsl SRC)
data_to_c_simple(modes/shaders/edit_overlay_frag.glsl SRC)

View File

@ -25,6 +25,8 @@
#include "DRW_render.h"
#include "BLI_dynstr.h"
#include "eevee.h"
#include "eevee_private.h"
@ -37,6 +39,8 @@ static struct {
struct GPUShader *tonemap;
} e_data = {NULL}; /* Engine data */
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_bsdf_direct_lib_glsl[];
extern char datatoc_lit_surface_frag_glsl[];
extern char datatoc_lit_surface_vert_glsl[];
extern char datatoc_tonemap_frag_glsl[];
@ -61,7 +65,17 @@ static void EEVEE_engine_init(void *vedata)
}
if (!e_data.default_lit) {
e_data.default_lit = DRW_shader_create(datatoc_lit_surface_vert_glsl, NULL, datatoc_lit_surface_frag_glsl, "#define MAX_LIGHT 128\n");
char *lib_str = NULL;
DynStr *ds_vert = BLI_dynstr_new();
BLI_dynstr_append(ds_vert, datatoc_bsdf_common_lib_glsl);
BLI_dynstr_append(ds_vert, datatoc_bsdf_direct_lib_glsl);
lib_str = BLI_dynstr_get_cstring(ds_vert);
BLI_dynstr_free(ds_vert);
e_data.default_lit = DRW_shader_create_with_lib(datatoc_lit_surface_vert_glsl, NULL, datatoc_lit_surface_frag_glsl, lib_str, "#define MAX_LIGHT 128\n");
MEM_freeN(lib_str);
}
if (!e_data.tonemap) {

View File

@ -30,9 +30,12 @@
#define MAX_LIGHT 210 /* TODO : find size by dividing UBO max size by light data size */
typedef struct EEVEE_Light {
float position[3], pad;
float position[3], dist;
float color[3], spec;
float spot_size, spot_blend, area_x, area_y;
float spotsize, spotblend, radius, shadowid;
float rightvec[3], sizex;
float upvec[3], sizey;
float forwardvec[3], lamptype;
} EEVEE_Light;
@ -88,11 +91,44 @@ void EEVEE_lights_update(EEVEE_StorageList *stl)
EEVEE_Light *evli = stl->lights_data + i;
Object *ob = stl->lights_ref[i];
Lamp *la = (Lamp *)ob->data;
float mat[4][4], scale[3];
/* Position */
copy_v3_v3(evli->position, ob->obmat[3]);
/* Color */
evli->color[0] = la->r * la->energy;
evli->color[1] = la->g * la->energy;
evli->color[2] = la->b * la->energy;
/* Influence Radius */
evli->dist = la->dist;
/* Vectors */
normalize_m4_m4_ex(mat, ob->obmat, scale);
copy_v3_v3(evli->forwardvec, mat[2]);
normalize_v3(evli->forwardvec);
negate_v3(evli->forwardvec);
copy_v3_v3(evli->rightvec, mat[0]);
normalize_v3(evli->rightvec);
copy_v3_v3(evli->upvec, mat[1]);
normalize_v3(evli->upvec);
/* Spot size & blend */
if (la->type == LA_SPOT) {
evli->sizex = scale[0] / scale[2];
evli->sizey = scale[1] / scale[2];
evli->spotsize = cosf(la->spotsize * 0.5f);
evli->spotblend = (1.0f - evli->spotsize) * la->spotblend;
}
// else if (la->type == LA_SPOT) {
// }
/* Lamp Type */
evli->lamptype = (float)la->type;
}
/* Upload buffer to GPU */

View File

@ -0,0 +1,3 @@
#define M_PI 3.14159265358979323846 /* pi */
#define M_1_PI 0.318309886183790671538 /* 1/pi */

View File

@ -0,0 +1,68 @@
/* Bsdf direct light function */
/* in other word, how materials react to scene lamps */
/* Naming convention
* N World Normal (normalized)
* L Outgoing Light Vector (Surface to Light in World Space) (normalized)
* Ldist Distance from surface to the light
* W World Pos
*/
/* ------------ Diffuse ------------- */
float direct_diffuse_point(vec3 N, vec3 L, float Ldist)
{
float bsdf = max(0.0, dot(N, L));
bsdf /= Ldist * Ldist;
bsdf *= M_1_PI; /* Normalize */
return bsdf;
}
#if 0
float direct_diffuse_sphere(vec3 N, vec3 L)
{
}
float direct_diffuse_rectangle(vec3 N, vec3 L)
{
}
#endif
/* infinitly far away point source, no decay */
float direct_diffuse_sun(vec3 N, vec3 L)
{
float bsdf = max(0.0, dot(N, L));
bsdf *= M_1_PI; /* Normalize */
return bsdf;
}
#if 0
float direct_diffuse_unit_disc(vec3 N, vec3 L)
{
}
/* ----------- GGx ------------ */
float direct_ggx_point(vec3 N, vec3 L)
{
float bsdf = max(0.0, dot(N, L));
bsdf *= M_1_PI; /* Normalize */
return bsdf;
}
float direct_ggx_sphere(vec3 N, vec3 L)
{
}
float direct_ggx_rectangle(vec3 N, vec3 L)
{
}
float direct_ggx_disc(vec3 N, vec3 L)
{
}
#endif

View File

@ -2,11 +2,28 @@
uniform int light_count;
struct LightData {
vec4 position;
vec4 colorAndSpec; /* w : Spec Intensity */
vec4 spotAndAreaData;
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];
};
@ -16,14 +33,57 @@ in vec3 worldNormal;
out vec4 fragColor;
/* type */
#define POINT 0.0
#define SUN 1.0
#define SPOT 2.0
#define HEMI 3.0
#define AREA 4.0
vec3 light_diffuse(LightData ld, vec3 N, vec3 W, vec3 color) {
vec3 light, wL, L;
if (ld.lampType == SUN) {
L = -ld.lampForward;
light = color * direct_diffuse_sun(N, L) * ld.lampColor;
}
else {
wL = ld.lampPosition - W;
float dist = length(wL);
light = color * direct_diffuse_point(N, wL / dist, dist) * ld.lampColor;
}
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;
float ellipse = 1.0 / sqrt(1.0 + x * x + y * y);
float spotmask = smoothstep(0.0, 1.0, (ellipse - ld.lampSpotSize) / ld.lampSpotBlend);
light *= spotmask;
}
return light;
}
vec3 light_specular(LightData ld, vec3 V, vec3 N, vec3 T, vec3 B, vec3 spec, float roughness) {
vec3 L = normalize(ld.lampPosition - worldPosition);
vec3 light = L;
return light;
}
void main() {
vec3 n = normalize(worldNormal);
vec3 diffuse = vec3(0.0);
vec3 albedo = vec3(1.0, 1.0, 1.0);
for (int i = 0; i < MAX_LIGHT && i < light_count; ++i) {
LightData ld = lights_data[i];
vec3 l = normalize(ld.position.xyz - worldPosition);
diffuse += max(0.0, dot(l, n)) * ld.colorAndSpec.rgb / 3.14159;
diffuse += light_diffuse(lights_data[i], n, worldPosition, albedo);
}
fragColor = vec4(diffuse,1.0);

View File

@ -5,6 +5,24 @@ in vec4 uvcoordsvar;
out vec4 fragColor;
float linearrgb_to_srgb(float c)
{
if (c < 0.0031308)
return (c < 0.0) ? 0.0 : c * 12.92;
else
return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
}
void linearrgb_to_srgb(vec4 col_from, out vec4 col_to)
{
col_to.r = linearrgb_to_srgb(col_from.r);
col_to.g = linearrgb_to_srgb(col_from.g);
col_to.b = linearrgb_to_srgb(col_from.b);
col_to.a = col_from.a;
}
void main() {
fragColor = texture(hdrColorBuf, uvcoordsvar.st);
linearrgb_to_srgb(fragColor, fragColor);
}