diff options
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders/surface_lib.glsl')
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/surface_lib.glsl | 166 |
1 files changed, 157 insertions, 9 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl index d7fc5e0b52a..1f2f7cb65cc 100644 --- a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl @@ -1,12 +1,23 @@ /** This describe the entire interface of the shader. */ +#pragma BLENDER_REQUIRE(common_math_lib.glsl) + #define SURFACE_INTERFACE \ vec3 worldPosition; \ vec3 viewPosition; \ vec3 worldNormal; \ vec3 viewNormal; -#if defined(STEP_RESOLVE) || defined(STEP_RAYTRACE) +#ifndef IN_OUT +# if defined(GPU_VERTEX_SHADER) +# define IN_OUT out +# elif defined(GPU_FRAGMENT_SHADER) +# define IN_OUT in +# endif +#endif + +#ifndef EEVEE_GENERATED_INTERFACE +# if defined(STEP_RESOLVE) || defined(STEP_RAYTRACE) /* SSR will set these global variables itself. * Also make false positive compiler warnings disappear by setting values. */ vec3 worldPosition = vec3(0); @@ -14,22 +25,23 @@ vec3 viewPosition = vec3(0); vec3 worldNormal = vec3(0); vec3 viewNormal = vec3(0); -#elif defined(GPU_GEOMETRY_SHADER) +# elif defined(GPU_GEOMETRY_SHADER) in ShaderStageInterface{SURFACE_INTERFACE} dataIn[]; out ShaderStageInterface{SURFACE_INTERFACE} dataOut; -# define PASS_SURFACE_INTERFACE(vert) \ - dataOut.worldPosition = dataIn[vert].worldPosition; \ - dataOut.viewPosition = dataIn[vert].viewPosition; \ - dataOut.worldNormal = dataIn[vert].worldNormal; \ - dataOut.viewNormal = dataIn[vert].viewNormal; +# define PASS_SURFACE_INTERFACE(vert) \ + dataOut.worldPosition = dataIn[vert].worldPosition; \ + dataOut.viewPosition = dataIn[vert].viewPosition; \ + dataOut.worldNormal = dataIn[vert].worldNormal; \ + dataOut.viewNormal = dataIn[vert].viewNormal; -#else /* GPU_VERTEX_SHADER || GPU_FRAGMENT_SHADER*/ +# else /* GPU_VERTEX_SHADER || GPU_FRAGMENT_SHADER*/ IN_OUT ShaderStageInterface{SURFACE_INTERFACE}; -#endif +# endif +#endif /* EEVEE_GENERATED_INTERFACE */ #ifdef HAIR_SHADER IN_OUT ShaderHairInterface @@ -40,6 +52,7 @@ IN_OUT ShaderHairInterface float hairThickness; float hairTime; flat int hairStrandID; + vec2 hairBary; }; #endif @@ -52,3 +65,138 @@ IN_OUT ShaderPointCloudInterface flat int pointID; }; #endif + +#if defined(GPU_FRAGMENT_SHADER) && defined(CODEGEN_LIB) + +# if defined(USE_BARYCENTRICS) && !defined(HAIR_SHADER) +vec3 barycentric_distances_get() +{ + /* NOTE: No need to undo perspective divide since it is not applied yet. */ + vec3 pos0 = (ProjectionMatrixInverse * gpu_position_at_vertex(0)).xyz; + vec3 pos1 = (ProjectionMatrixInverse * gpu_position_at_vertex(1)).xyz; + vec3 pos2 = (ProjectionMatrixInverse * gpu_position_at_vertex(2)).xyz; + vec3 edge21 = pos2 - pos1; + vec3 edge10 = pos1 - pos0; + vec3 edge02 = pos0 - pos2; + vec3 d21 = safe_normalize(edge21); + vec3 d10 = safe_normalize(edge10); + vec3 d02 = safe_normalize(edge02); + vec3 dists; + float d = dot(d21, edge02); + dists.x = sqrt(dot(edge02, edge02) - d * d); + d = dot(d02, edge10); + dists.y = sqrt(dot(edge10, edge10) - d * d); + d = dot(d10, edge21); + dists.z = sqrt(dot(edge21, edge21) - d * d); + return dists.xyz; +} +# endif + +GlobalData init_globals(void) +{ + GlobalData surf; + +# if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE) + surf.P = -cameraVec(worldPosition); + surf.N = surf.Ng = -surf.P; + surf.ray_length = 0.0; +# else + surf.P = worldPosition; + surf.N = safe_normalize(worldNormal); + surf.Ng = safe_normalize(cross(dFdx(surf.P), dFdy(surf.P))); + surf.ray_length = distance(surf.P, cameraPos); +# endif + surf.barycentric_coords = vec2(0.0); + surf.barycentric_dists = vec3(0.0); + if (!FrontFacing) { + surf.N = -surf.N; + } +# ifdef HAIR_SHADER + /* Shade as a cylinder. */ + vec3 B = normalize(cross(worldNormal, hairTangent)); + float cos_theta; + if (hairThicknessRes == 1) { + /* Random cosine normal distribution on the hair surface. */ + cos_theta = texelfetch_noise_tex(gl_FragCoord.xy).x * 2.0 - 1.0; + } + else { + /* Shade as a cylinder. */ + cos_theta = hairThickTime / hairThickness; + } + float sin_theta = sqrt(max(0.0, 1.0 - cos_theta * cos_theta)); + surf.N = safe_normalize(worldNormal * sin_theta + B * cos_theta); + surf.T = hairTangent; + surf.is_strand = true; + surf.hair_time = hairTime; + surf.hair_thickness = hairThickness; + surf.hair_strand_id = hairStrandID; +# ifdef USE_BARYCENTRICS + surf.barycentric_coords = hair_resolve_barycentric(hairBary); +# endif +# else + surf.T = vec3(0.0); + surf.is_strand = false; + surf.hair_time = 0.0; + surf.hair_thickness = 0.0; + surf.hair_strand_id = 0; +# ifdef USE_BARYCENTRICS + surf.barycentric_coords = gpu_BaryCoord.xy; + surf.barycentric_dists = barycentric_distances_get(); +# endif +# endif + surf.ray_type = rayType; + surf.ray_depth = 0.0; + return surf; +} +#endif + +vec3 coordinate_camera(vec3 P) +{ + vec3 vP; +#if defined(PROBE_CAPTURE) + /* Unsupported. It would make the probe camera-dependent. */ + vP = P; +#elif defined(WORLD_BACKGROUND) + vP = transform_direction(ViewMatrix, P); +#else + vP = transform_point(ViewMatrix, P); +#endif + vP.z = -vP.z; + return vP; +} + +vec3 coordinate_screen(vec3 P) +{ + vec3 window = vec3(0.0); +#if defined(PROBE_CAPTURE) + /* Unsupported. It would make the probe camera-dependent. */ + window.xy = vec2(0.5); + +#elif defined(WORLD_BACKGROUND) + window.xy = project_point(ProjectionMatrix, viewPosition).xy * 0.5 + 0.5; + window.xy = window.xy * CameraTexCoFactors.xy + CameraTexCoFactors.zw; + +#else /* MESH */ + window.xy = project_point(ViewProjectionMatrix, P).xy * 0.5 + 0.5; + window.xy = window.xy * CameraTexCoFactors.xy + CameraTexCoFactors.zw; +#endif + return window; +} + +vec3 coordinate_reflect(vec3 P, vec3 N) +{ +#if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE) + return N; +#else + return -reflect(cameraVec(P), N); +#endif +} + +vec3 coordinate_incoming(vec3 P) +{ +#if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE) + return -P; +#else + return cameraVec(P); +#endif +}
\ No newline at end of file |