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:
parent
4d3d10f625
commit
6d21970aa0
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
#define M_PI 3.14159265358979323846 /* pi */
|
||||
#define M_1_PI 0.318309886183790671538 /* 1/pi */
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue