diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2020-07-30 14:55:13 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2020-07-30 17:44:58 +0300 |
commit | da741013a1e1b2e7c4f61a9486588253a457afd2 (patch) | |
tree | b491c53eadf1fcc07e2a326d000b1c94fbf07f48 /source/blender/draw/intern | |
parent | 55401fbb3d0daa82c999e388c2b5b87e7113b091 (diff) |
EEVEE: GLSL refactor/cleanup
- add the use of DRWShaderLibrary to EEVEE's glsl codebase to reduce code
complexity and duplication.
- split bsdf_common_lib.glsl into multiple sub library which are now shared
with other engines.
- the surface shader code is now more organised and have its own files.
- change default world to use a material nodetree and make lookdev shader
more clear.
Reviewed By: jbakker
Differential Revision: https://developer.blender.org/D8306
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r-- | source/blender/draw/intern/DRW_render.h | 17 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_shader.c | 12 | ||||
-rw-r--r-- | source/blender/draw/intern/shaders/common_hair_lib.glsl | 22 | ||||
-rw-r--r-- | source/blender/draw/intern/shaders/common_view_lib.glsl | 107 |
4 files changed, 143 insertions, 15 deletions
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 7a889d9399e..3f55cd13a40 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -198,6 +198,17 @@ void DRW_uniformbuffer_free(struct GPUUniformBuffer *ubo); } while (0) /* Shaders */ + +#ifndef __GPU_MATERIAL_H__ +/* FIXME: Meh avoid including all GPUMaterial. */ +typedef void(GPUMaterialEvalCallbackFn)(struct GPUMaterial *mat, + int options, + const char **vert_code, + const char **geom_code, + const char **frag_lib, + const char **defines); +#endif + struct GPUShader *DRW_shader_create(const char *vert, const char *geom, const char *frag, @@ -237,7 +248,8 @@ struct GPUMaterial *DRW_shader_create_from_world(struct Scene *scene, const char *geom, const char *frag_lib, const char *defines, - bool deferred); + bool deferred, + GPUMaterialEvalCallbackFn *callback); struct GPUMaterial *DRW_shader_create_from_material(struct Scene *scene, struct Material *ma, struct bNodeTree *ntree, @@ -248,7 +260,8 @@ struct GPUMaterial *DRW_shader_create_from_material(struct Scene *scene, const char *geom, const char *frag_lib, const char *defines, - bool deferred); + bool deferred, + GPUMaterialEvalCallbackFn *callback); void DRW_shader_free(struct GPUShader *shader); #define DRW_SHADER_FREE_SAFE(shader) \ do { \ diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c index 0bb20631537..bde08b770b3 100644 --- a/source/blender/draw/intern/draw_manager_shader.c +++ b/source/blender/draw/intern/draw_manager_shader.c @@ -430,7 +430,8 @@ GPUMaterial *DRW_shader_create_from_world(struct Scene *scene, const char *geom, const char *frag_lib, const char *defines, - bool deferred) + bool deferred, + GPUMaterialEvalCallbackFn *callback) { GPUMaterial *mat = NULL; if (DRW_state_is_image_render() || !deferred) { @@ -450,7 +451,8 @@ GPUMaterial *DRW_shader_create_from_world(struct Scene *scene, geom, frag_lib, defines, - wo->id.name); + wo->id.name, + callback); } if (GPU_material_status(mat) == GPU_MAT_QUEUED) { @@ -470,7 +472,8 @@ GPUMaterial *DRW_shader_create_from_material(struct Scene *scene, const char *geom, const char *frag_lib, const char *defines, - bool deferred) + bool deferred, + GPUMaterialEvalCallbackFn *callback) { GPUMaterial *mat = NULL; if (DRW_state_is_image_render() || !deferred) { @@ -490,7 +493,8 @@ GPUMaterial *DRW_shader_create_from_material(struct Scene *scene, geom, frag_lib, defines, - ma->id.name); + ma->id.name, + callback); } if (GPU_material_status(mat) == GPU_MAT_QUEUED) { diff --git a/source/blender/draw/intern/shaders/common_hair_lib.glsl b/source/blender/draw/intern/shaders/common_hair_lib.glsl index ffff631e34b..8684d82f228 100644 --- a/source/blender/draw/intern/shaders/common_hair_lib.glsl +++ b/source/blender/draw/intern/shaders/common_hair_lib.glsl @@ -95,7 +95,7 @@ void hair_get_interp_attrs( * For final drawing, the vertex index and the number of vertex per segment */ -#ifndef HAIR_PHASE_SUBDIV +#if !defined(HAIR_PHASE_SUBDIV) && defined(GPU_VERTEX_SHADER) int hair_get_strand_id(void) { return gl_VertexID / (hairStrandsRes * hairThicknessRes); @@ -206,4 +206,24 @@ vec3 hair_get_strand_pos(void) return texelFetch(hairPointBuffer, id).point_position; } +vec2 hair_get_barycentric(void) +{ + /* To match cycles without breaking into individual segment we encode if we need to invert + * the first component into the second component. We invert if the barycentricTexCo.y + * is NOT 0.0 or 1.0. */ + int id = hair_get_base_id(); + return vec2(float((id % 2) == 1), float(((id % 4) % 3) > 0)); +} + #endif + +/* To be fed the result of hair_get_barycentric from vertex shader. */ +vec2 hair_resolve_barycentric(vec2 vert_barycentric) +{ + if (fract(vert_barycentric.y) != 0.0) { + return vec2(vert_barycentric.x, 0.0); + } + else { + return vec2(1.0 - vert_barycentric.x, 0.0); + } +} diff --git a/source/blender/draw/intern/shaders/common_view_lib.glsl b/source/blender/draw/intern/shaders/common_view_lib.glsl index 095bc64a19e..a55d2cd8c1a 100644 --- a/source/blender/draw/intern/shaders/common_view_lib.glsl +++ b/source/blender/draw/intern/shaders/common_view_lib.glsl @@ -22,6 +22,16 @@ layout(std140) uniform viewBlock vec4 CameraTexCoFactors; }; +#define ViewNear (ViewVecs[0].w) +#define ViewFar (ViewVecs[1].w) + +#define cameraForward ViewMatrixInverse[2].xyz +#define cameraPos ViewMatrixInverse[3].xyz +#define cameraVec \ + ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward) +#define viewCameraVec \ + ((ProjectionMatrix[3][3] == 0.0) ? normalize(-viewPosition) : vec3(0.0, 0.0, 1.0)) + #ifdef world_clip_planes_calc_clip_distance # undef world_clip_planes_calc_clip_distance # define world_clip_planes_calc_clip_distance(p) \ @@ -104,10 +114,13 @@ uniform int resourceId; /* Use this to declare and pass the value if * the fragment shader uses the resource_id. */ -# define RESOURCE_ID_VARYING flat out int resourceIDFrag; -# define RESOURCE_ID_VARYING_GEOM flat out int resourceIDGeom; -# define PASS_RESOURCE_ID resourceIDFrag = resource_id; -# define PASS_RESOURCE_ID_GEOM resourceIDGeom = resource_id; +# ifdef USE_GEOMETRY_SHADER +# define RESOURCE_ID_VARYING flat out int resourceIDGeom; +# define PASS_RESOURCE_ID resourceIDGeom = resource_id; +# else +# define RESOURCE_ID_VARYING flat out int resourceIDFrag; +# define PASS_RESOURCE_ID resourceIDFrag = resource_id; +# endif #endif /* If used in a fragment / geometry shader, we pass @@ -118,7 +131,7 @@ uniform int resourceId; flat in int resourceIDGeom[]; # define resource_id resourceIDGeom -# define PASS_RESOURCE_ID(i) resourceIDFrag = resource_id[i]; +# define PASS_RESOURCE_ID resourceIDFrag = resource_id[0]; #endif #ifdef GPU_FRAGMENT_SHADER @@ -171,9 +184,12 @@ uniform mat4 ModelMatrixInverse; * Note: This is only valid because we are only using the mat3 of the ViewMatrixInverse. * ViewMatrix * transpose(ModelMatrixInverse) **/ -#define normal_object_to_view(n) (mat3(ViewMatrix) * (transpose(mat3(ModelMatrixInverse)) * n)) -#define normal_object_to_world(n) (transpose(mat3(ModelMatrixInverse)) * n) -#define normal_world_to_object(n) (transpose(mat3(ModelMatrix)) * n) +#define NormalMatrix transpose(mat3(ModelMatrixInverse)) +#define NormalMatrixInverse transpose(mat3(ModelMatrix)) + +#define normal_object_to_view(n) (mat3(ViewMatrix) * (NormalMatrix * n)) +#define normal_object_to_world(n) (NormalMatrix * n) +#define normal_world_to_object(n) (NormalMatrixInverse * n) #define normal_world_to_view(n) (mat3(ViewMatrix) * n) #define normal_view_to_world(n) (mat3(ViewMatrixInverse) * n) @@ -199,3 +215,78 @@ uniform mat4 ModelMatrixInverse; #define DRW_BASE_FROM_DUPLI (1 << 2) #define DRW_BASE_FROM_SET (1 << 3) #define DRW_BASE_ACTIVE (1 << 4) + +/* ---- Opengl Depth conversion ---- */ + +float linear_depth(bool is_persp, float z, float zf, float zn) +{ + if (is_persp) { + return (zn * zf) / (z * (zn - zf) + zf); + } + else { + return (z * 2.0 - 1.0) * zf; + } +} + +float buffer_depth(bool is_persp, float z, float zf, float zn) +{ + if (is_persp) { + return (zf * (zn - z)) / (z * (zn - zf)); + } + else { + return (z / (zf * 2.0)) + 0.5; + } +} + +float get_view_z_from_depth(float depth) +{ + if (ProjectionMatrix[3][3] == 0.0) { + float d = 2.0 * depth - 1.0; + return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]); + } + else { + return ViewVecs[0].z + depth * ViewVecs[1].z; + } +} + +float get_depth_from_view_z(float z) +{ + if (ProjectionMatrix[3][3] == 0.0) { + float d = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2]; + return d * 0.5 + 0.5; + } + else { + return (z - ViewVecs[0].z) / ViewVecs[1].z; + } +} + +vec2 get_uvs_from_view(vec3 view) +{ + vec4 ndc = ProjectionMatrix * vec4(view, 1.0); + return (ndc.xy / ndc.w) * 0.5 + 0.5; +} + +vec3 get_view_space_from_depth(vec2 uvcoords, float depth) +{ + if (ProjectionMatrix[3][3] == 0.0) { + return vec3(ViewVecs[0].xy + uvcoords * ViewVecs[1].xy, 1.0) * get_view_z_from_depth(depth); + } + else { + return ViewVecs[0].xyz + vec3(uvcoords, depth) * ViewVecs[1].xyz; + } +} + +vec3 get_world_space_from_depth(vec2 uvcoords, float depth) +{ + return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz; +} + +vec3 get_view_vector_from_screen_uv(vec2 uv) +{ + if (ProjectionMatrix[3][3] == 0.0) { + return normalize(vec3(ViewVecs[0].xy + uv * ViewVecs[1].xy, 1.0)); + } + else { + return vec3(0.0, 0.0, 1.0); + } +} |