GPUMaterial : Add sss_data to Closure struct.
This commit is contained in:
@@ -580,6 +580,9 @@ Closure closure_add(Closure cl1, Closure cl2)
|
||||
struct Closure {
|
||||
vec3 radiance;
|
||||
float opacity;
|
||||
#ifdef USE_SSS
|
||||
vec4 sss_data;
|
||||
#endif
|
||||
vec4 ssr_data;
|
||||
vec2 ssr_normal;
|
||||
int ssr_id;
|
||||
@@ -589,19 +592,29 @@ struct Closure {
|
||||
#define TRANSPARENT_CLOSURE_FLAG -2
|
||||
#define REFRACT_CLOSURE_FLAG -3
|
||||
|
||||
#ifdef USE_SSS
|
||||
#define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec4(0.0), vec2(0.0), -1)
|
||||
#else
|
||||
#define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec2(0.0), -1)
|
||||
#endif
|
||||
|
||||
uniform int outputSsrId;
|
||||
|
||||
Closure closure_mix(Closure cl1, Closure cl2, float fac)
|
||||
{
|
||||
Closure cl;
|
||||
|
||||
#ifdef USE_SSS
|
||||
cl.sss_data = mix(cl1.sss_data, cl2.sss_data, fac);
|
||||
#endif
|
||||
|
||||
if (cl1.ssr_id == outputSsrId) {
|
||||
cl.ssr_data = mix(cl1.ssr_data.xyzw, vec4(vec3(0.0), cl1.ssr_data.w), fac); /* do not blend roughness */
|
||||
cl.ssr_normal = cl1.ssr_normal;
|
||||
cl.ssr_id = cl1.ssr_id;
|
||||
}
|
||||
else {
|
||||
cl.ssr_data = mix(vec4(vec3(0.0), cl2.ssr_data.w), cl2.ssr_data.xyzw, fac); /* do not blend roughness */
|
||||
cl.ssr_data = mix(vec4(vec3(0.0), cl2.ssr_data.w), cl2.ssr_data.xyzw, fac); /* do not blend roughness */
|
||||
cl.ssr_normal = cl2.ssr_normal;
|
||||
cl.ssr_id = cl2.ssr_id;
|
||||
|
||||
@@ -2672,7 +2672,11 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result)
|
||||
#ifdef EEVEE_ENGINE
|
||||
vec3 L = eevee_surface_diffuse_lit(N, vec3(1.0), 1.0);
|
||||
vec3 vN = normalize(mat3(ViewMatrix) * N);
|
||||
result = Closure(L * color.rgb, 1.0, vec4(0.0), normal_encode(vN, viewCameraVec), -1);
|
||||
result.radiance = L * color.rgb;
|
||||
result.opacity = 1.0;
|
||||
result.ssr_data = vec4(0.0);
|
||||
result.ssr_normal = normal_encode(vN, viewCameraVec);
|
||||
result.ssr_id = -1;
|
||||
#else
|
||||
/* ambient light */
|
||||
vec3 L = vec3(0.2);
|
||||
@@ -2697,7 +2701,11 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Clo
|
||||
roughness = sqrt(roughness);
|
||||
vec3 L = eevee_surface_glossy_lit(N, vec3(1.0), roughness, 1.0, int(ssr_id), ssr_spec);
|
||||
vec3 vN = normalize(mat3(ViewMatrix) * N);
|
||||
result = Closure(L * color.rgb, 1.0, vec4(ssr_spec * color.rgb, roughness), normal_encode(vN, viewCameraVec), int(ssr_id));
|
||||
result.radiance = L * color.rgb;
|
||||
result.opacity = 1.0;
|
||||
result.ssr_data = vec4(ssr_spec * color.rgb, roughness);
|
||||
result.ssr_normal = normal_encode(vN, viewCameraVec);
|
||||
result.ssr_id = int(ssr_id);
|
||||
#else
|
||||
/* ambient light */
|
||||
vec3 L = vec3(0.2);
|
||||
@@ -2735,7 +2743,11 @@ void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, float ssr_i
|
||||
roughness = sqrt(roughness);
|
||||
vec3 L = eevee_surface_glass(N, (refractionDepth > 0.0) ? color.rgb : vec3(1.0), roughness, ior, int(ssr_id), ssr_spec);
|
||||
vec3 vN = normalize(mat3(ViewMatrix) * N);
|
||||
result = Closure(L * color.rgb, 1.0, vec4(ssr_spec * color.rgb, roughness), normal_encode(vN, viewCameraVec), int(ssr_id));
|
||||
result.radiance = L * color.rgb;
|
||||
result.opacity = 1.0;
|
||||
result.ssr_data = vec4(ssr_spec * color.rgb, roughness);
|
||||
result.ssr_normal = normal_encode(vN, viewCameraVec);
|
||||
result.ssr_id = int(ssr_id);
|
||||
#else
|
||||
node_bsdf_diffuse(color, 0.0, N, result);
|
||||
#endif
|
||||
@@ -2856,7 +2868,11 @@ void node_bsdf_principled_simple(vec4 base_color, float subsurface, vec3 subsurf
|
||||
|
||||
vec3 L = eevee_surface_lit(N, diffuse, f0, roughness, 1.0, int(ssr_id), ssr_spec);
|
||||
vec3 vN = normalize(mat3(ViewMatrix) * N);
|
||||
result = Closure(L, 1.0, vec4(ssr_spec, roughness), normal_encode(vN, viewCameraVec), int(ssr_id));
|
||||
result.radiance = L;
|
||||
result.opacity = 1.0;
|
||||
result.ssr_data = vec4(ssr_spec, roughness);
|
||||
result.ssr_normal = normal_encode(vN, viewCameraVec);
|
||||
result.ssr_id = int(ssr_id);
|
||||
#else
|
||||
node_bsdf_principled(base_color, subsurface, subsurface_radius, subsurface_color, metallic, specular,
|
||||
specular_tint, roughness, anisotropic, anisotropic_rotation, sheen, sheen_tint, clearcoat,
|
||||
@@ -2909,7 +2925,11 @@ void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subs
|
||||
vec3 L = eevee_surface_clearcoat_lit(N, diffuse, f0, roughness, CN, clearcoat, clearcoat_roughness, 1.0, int(ssr_id), ssr_spec);
|
||||
L = mix(L, L_trans, transmission);
|
||||
vec3 vN = normalize(mat3(ViewMatrix) * N);
|
||||
result = Closure(L, 1.0, vec4(ssr_spec, roughness), normal_encode(vN, viewCameraVec), int(ssr_id));
|
||||
result.radiance = L;
|
||||
result.opacity = 1.0;
|
||||
result.ssr_data = vec4(ssr_spec, roughness);
|
||||
result.ssr_normal = normal_encode(vN, viewCameraVec);
|
||||
result.ssr_id = int(ssr_id);
|
||||
#endif
|
||||
|
||||
#else
|
||||
@@ -2940,10 +2960,21 @@ void node_bsdf_velvet(vec4 color, float sigma, vec3 N, out Closure result)
|
||||
}
|
||||
|
||||
void node_subsurface_scattering(
|
||||
vec4 color, float scale, vec3 radius, float sharpen, float texture_blur, vec3 N,
|
||||
vec4 color, float scale, vec3 radius, float sharpen, float texture_blur, vec3 N, float sss_id,
|
||||
out Closure result)
|
||||
{
|
||||
#if defined(EEVEE_ENGINE) && defined(USE_SSS)
|
||||
vec3 vN = normalize(mat3(ViewMatrix) * N);
|
||||
result.radiance = vec3(0.0);
|
||||
result.opacity = 1.0;
|
||||
result.ssr_data = vec4(0.0);
|
||||
result.ssr_normal = normal_encode(vN, viewCameraVec);
|
||||
result.ssr_id = -1;
|
||||
result.sss_data.rgb = eevee_surface_diffuse_lit(N, vec3(1.0), 1.0) * color.rgb;
|
||||
result.sss_data.a = scale;
|
||||
#else
|
||||
node_bsdf_diffuse(color, 0.0, N, result);
|
||||
#endif
|
||||
}
|
||||
|
||||
void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Closure result)
|
||||
@@ -2952,7 +2983,9 @@ void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Cl
|
||||
color.rgb *= (refractionDepth > 0.0) ? color.rgb : vec3(1.0); /* Simulate 2 absorption event. */
|
||||
roughness = sqrt(roughness);
|
||||
vec3 L = eevee_surface_refraction(N, vec3(1.0), roughness, ior);
|
||||
result = Closure(L * color.rgb, 1.0, vec4(0.0), vec2(0.0), REFRACT_CLOSURE_FLAG);
|
||||
result.radiance = L * color.rgb;
|
||||
result.opacity = 1.0;
|
||||
result.ssr_id = REFRACT_CLOSURE_FLAG;
|
||||
#else
|
||||
node_bsdf_diffuse(color, 0.0, N, result);
|
||||
#endif /* EEVEE_ENGINE */
|
||||
@@ -2980,7 +3013,11 @@ void node_emission(vec4 color, float strength, vec3 N, out Closure result)
|
||||
#ifndef VOLUMETRICS
|
||||
color *= strength;
|
||||
#ifdef EEVEE_ENGINE
|
||||
result = Closure(color.rgb, color.a, vec4(0.0), normal_encode(N, viewCameraVec), -1);
|
||||
result.radiance = color.rgb;
|
||||
result.opacity = color.a;
|
||||
result.ssr_data = vec4(0.0);
|
||||
result.ssr_normal = normal_encode(N, viewCameraVec);
|
||||
result.ssr_id = -1;
|
||||
#else
|
||||
result = Closure(color.rgb, color.a);
|
||||
#endif
|
||||
@@ -3009,7 +3046,8 @@ void node_background(vec4 color, float strength, out Closure result)
|
||||
#ifndef VOLUMETRICS
|
||||
color *= strength;
|
||||
#ifdef EEVEE_ENGINE
|
||||
result = Closure(color.rgb, color.a, vec4(0.0), vec2(0.0), -1);
|
||||
result.radiance = color.rgb;
|
||||
result.opacity = color.a;
|
||||
#else
|
||||
result = Closure(color.rgb, color.a);
|
||||
#endif
|
||||
@@ -4115,7 +4153,8 @@ void node_output_world(Closure surface, Closure volume, out Closure result)
|
||||
{
|
||||
#ifndef VOLUMETRICS
|
||||
#ifdef EEVEE_ENGINE
|
||||
result = Closure(surface.radiance, backgroundAlpha, vec4(0.0), vec2(0.0), -1);
|
||||
result.radiance = surface.radiance;
|
||||
result.opacity = backgroundAlpha;
|
||||
#else
|
||||
result = Closure(surface.radiance, backgroundAlpha);
|
||||
#endif
|
||||
@@ -4142,7 +4181,11 @@ void node_eevee_specular(
|
||||
|
||||
vec3 L = eevee_surface_lit(normal, diffuse.rgb, specular.rgb, roughness, occlusion, int(ssr_id), ssr_spec);
|
||||
vec3 vN = normalize(mat3(ViewMatrix) * normal);
|
||||
result = Closure(L + emissive.rgb, 1.0 - transp, vec4(ssr_spec, roughness), normal_encode(vN, viewCameraVec), int(ssr_id));
|
||||
result.radiance = L + emissive.rgb;
|
||||
result.opacity = 1.0 - transp;
|
||||
result.ssr_data = vec4(ssr_spec, roughness);
|
||||
result.ssr_normal = normal_encode(vN, viewCameraVec);
|
||||
result.ssr_id = int(ssr_id);
|
||||
}
|
||||
|
||||
#endif /* EEVEE_ENGINE */
|
||||
|
||||
@@ -225,7 +225,7 @@ typedef struct bNode {
|
||||
struct uiBlock *block; /* runtime during drawing */
|
||||
|
||||
float ssr_id; /* XXX: eevee only, id of screen space reflection layer, needs to be a float to feed GPU_uniform. */
|
||||
float pad3;
|
||||
float sss_id; /* XXX: eevee only, id of screen subsurface scatter layer, needs to be a float to feed GPU_uniform. */
|
||||
} bNode;
|
||||
|
||||
/* node->flag */
|
||||
|
||||
@@ -527,6 +527,41 @@ static void ntree_shader_tag_ssr_node(bNodeTree *ntree, short compatibility)
|
||||
nodeChainIter(ntree, output_node, ntree_tag_ssr_bsdf_cb, &lobe_count, true);
|
||||
}
|
||||
|
||||
static bool ntree_tag_sss_bsdf_cb(bNode *fromnode, bNode *UNUSED(tonode), void *userdata, const bool UNUSED(reversed))
|
||||
{
|
||||
switch (fromnode->type) {
|
||||
case SH_NODE_BSDF_PRINCIPLED:
|
||||
case SH_NODE_SUBSURFACE_SCATTERING:
|
||||
fromnode->sss_id = (*(float *)userdata);
|
||||
(*(float *)userdata) += 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* EEVEE: Scan the ntree to set the Subsurface Scattering id of every SSS node.
|
||||
*/
|
||||
static void ntree_shader_tag_sss_node(bNodeTree *ntree, short compatibility)
|
||||
{
|
||||
if (compatibility & NODE_NEWER_SHADING) {
|
||||
/* We can only deal with new shading system here. */
|
||||
return;
|
||||
}
|
||||
|
||||
bNode *output_node = ntree_shader_output_node(ntree);
|
||||
if (output_node == NULL) {
|
||||
return;
|
||||
}
|
||||
/* Make sure sockets links pointers are correct. */
|
||||
ntreeUpdateTree(G.main, ntree);
|
||||
|
||||
int sss_count = 0;
|
||||
nodeChainIter(ntree, output_node, ntree_tag_sss_bsdf_cb, &sss_count, true);
|
||||
}
|
||||
|
||||
/* EEVEE: Find which material domain are used (volume, surface ...).
|
||||
*/
|
||||
void ntreeGPUMaterialDomain(bNodeTree *ntree, bool *has_surface_output, bool *has_volume_output)
|
||||
@@ -568,6 +603,7 @@ void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat, short compatibili
|
||||
ntree_shader_relink_displacement(localtree, compatibility);
|
||||
|
||||
ntree_shader_tag_ssr_node(localtree, compatibility);
|
||||
ntree_shader_tag_sss_node(localtree, compatibility);
|
||||
|
||||
exec = ntreeShaderBeginExecTree(localtree);
|
||||
ntreeExecGPUNodes(exec, mat, 1, compatibility);
|
||||
|
||||
@@ -54,7 +54,7 @@ static int node_shader_gpu_subsurface_scattering(GPUMaterial *mat, bNode *node,
|
||||
if (!in[5].link)
|
||||
GPU_link(mat, "world_normals_get", &in[5].link);
|
||||
|
||||
return GPU_stack_link(mat, node, "node_subsurface_scattering", in, out);
|
||||
return GPU_stack_link(mat, node, "node_subsurface_scattering", in, out, GPU_uniform(&node->sss_id));
|
||||
}
|
||||
|
||||
static void node_shader_update_subsurface_scattering(bNodeTree *UNUSED(ntree), bNode *node)
|
||||
|
||||
Reference in New Issue
Block a user