rj-action-library/Runtime/Reallusion/Shaders/Hair/CCHairBase.gdshaderinc

421 lines
14 KiB
Plaintext

#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Colors.gdshaderinc"
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Textures.gdshaderinc"
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Math.gdshaderinc"
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Cameras.gdshaderinc"
group_uniforms Albedo;
uniform bool enabled = true;
uniform vec4 albedo : source_color;
uniform sampler2D texture_albedo : source_color, filter_linear_mipmap_anisotropic;
uniform vec3 hslOffset = vec3( 0, 0, 0 );
uniform sampler2D texture_blend : source_color,hint_default_white, filter_linear_mipmap_anisotropic;
uniform float blendAmount:hint_range(0, 1) =1;
uniform float naturalColors: hint_range(0, 1) = 0.5;
uniform sampler2D texture_opacity:hint_default_white, filter_linear_mipmap_anisotropic;
uniform float opacity: hint_range(0, 1) = 0.5;
uniform float opacityGamma = 1;
#ifdef USE_SHADOW
uniform float opacityFarScale: hint_range(0, 1) = 0.4;
uniform float opacityBlur : hint_range(0, 10) = 4;
uniform float opacityBlurFarScale : hint_range(0, 10) = 8;
uniform float opacityFarStart = 0.5;
uniform float opacityFarRange = 5;
uniform float opacityFarPower = 0.5;
uniform float extending = 0.001;
#endif
#ifdef USE_ALPHA_SCISSOR
uniform float alphaScissorTreshold:hint_range(0,1) = 0.5;
#endif
#ifdef USE_ALPHA_DISCARD
uniform float alphaDiscardTreshold:hint_range(0,1) = 0.05;
#endif
group_uniforms;
group_uniforms HairMaps;
uniform sampler2D rootMap : filter_linear_mipmap_anisotropic;
uniform sampler2D flowMap : filter_linear_mipmap_anisotropic;
uniform sampler2D idMap : filter_linear_mipmap_anisotropic;
group_uniforms;
group_uniforms MainColors;
uniform float diffuseStrength:hint_range(0.0, 1.0) = 1;
uniform float vertexColorStrength:hint_range(0.0, 1.0) = 1;
uniform vec4 vertexGreyToColor:source_color;
uniform bool activateHairColor = true;
uniform float baseColorMapStrength:hint_range(0.0, 1.0) = 1;
uniform vec4 strandRootColor:source_color;
uniform float strandRootStrength:hint_range(0.0, 1.0) = 1;
uniform vec4 strandEndColor:source_color;
uniform float strandEndStrength:hint_range(0.0, 1.0) = 1;
uniform float strandGamma = 1.0;
group_uniforms;
group_uniforms Highlights;
uniform float maximumHighlightAmount = 0.25;
uniform float highlightFadeOutStart = 0.1;
uniform float highlightFadeOutEnd = 1;
uniform float highlightFadeOutPower = 0.5;
uniform float highlightFadeOutAmount = 0.2;
group_uniforms;
group_uniforms HighlightA;
uniform vec4 highlightAColor:source_color;
uniform float highlightAStrength:hint_range(0.0, 1.0) = 1.0;
uniform vec3 highlightARange = vec3( 0, 0.25, 0.5);
uniform float highlightAOverlapEnd: hint_range(0.0, 1.0) = 1.0;
uniform float highlightAInvert: hint_range(0.0, 1.0) = 0.0;
group_uniforms;
group_uniforms HighlightB;
uniform vec4 highlightBColor:source_color;
uniform float highlightBStrength:hint_range(0.0, 1.0) = 1.0;
uniform vec3 highlightBRange = vec3( 0, 0.25, 0.5);
uniform float highlightBOverlapEnd: hint_range(0.0, 1.0) = 1.0;
uniform float highlightBInvert: hint_range(0.0, 1.0) = 0.0;
group_uniforms;
// group_uniforms Normal;
// uniform sampler2D texture_normal : hint_roughness_normal, filter_linear_mipmap_anisotropic, repeat_enable;
// uniform float normal_scale : hint_range(-16.0, 16.0) = 1.0;
group_uniforms Roughness_Metallness;
uniform float roughness : hint_range(0.0, 1.0) = 1.0;
uniform float roughnessOffset: hint_range(-1.0, 1.0) = -0.1;
uniform sampler2D texture_roughness : hint_roughness_r, filter_linear_mipmap_anisotropic, repeat_enable;
uniform float metallic : hint_range(0.0, 1.0, 0.01) = 1.0;
uniform float metallicOffset: hint_range(-1.0, 1.0) = 0.25;
uniform sampler2D texture_metallic : hint_default_white, filter_linear_mipmap_anisotropic, repeat_enable;
uniform float specular : hint_range(0.0, 1.0, 0.01) = 0.2;
uniform float specularOpacityAmount: hint_range(0.0, 1.0) = 1;
uniform float specularOpacityGamma: hint_range(0.0, 3) = 2;
uniform float anisotropy_ratio: hint_range(0.0, 1.0) = 1;
group_uniforms;
group_uniforms emission;
uniform sampler2D texture_emission : source_color, hint_default_black, filter_linear_mipmap_anisotropic, repeat_enable;
uniform vec4 emission : source_color;
uniform float emission_energy : hint_range(0.0, 100.0, 0.01);
uniform vec4 backlight : source_color;
uniform float albedoToBacklightAmount : hint_range(0.0, 1.0) = 0.25;
uniform sampler2D texture_backlight : hint_default_black, filter_linear_mipmap_anisotropic, repeat_enable;
uniform float subsurface_scattering_strength : hint_range(0.0, 1.0) = 1.0;
group_uniforms;
// uniform float rim : hint_range(0.0, 1.0, 0.01);
// uniform float rim_tint : hint_range(0.0, 1.0, 0.01);
// uniform sampler2D texture_rim : hint_default_white, filter_linear_mipmap_anisotropic, repeat_enable;
// uniform float clearcoat : hint_range(0.0, 1.0, 0.01);
// uniform float clearcoat_roughness : hint_range(0.0, 1.0, 0.01);
// uniform sampler2D texture_clearcoat : hint_default_white, filter_linear_mipmap_anisotropic, repeat_enable;
group_uniforms Occlusion;
uniform sampler2D texture_ambient_occlusion : hint_default_white, filter_linear_mipmap_anisotropic, repeat_enable;
uniform float ao_light_affect : hint_range(0.0, 1.0 ) = 1.0;
uniform float ambientOcclusion:hint_range(0.0, 2.0) = 1.0;
uniform float aoGamma: hint_range(0.1, 10) = 1.0;
uniform float rootOcclusionAmount: hint_range(0.0, 1.0 ) = 0.1;
uniform float rootOcclusionRange: hint_range(0.0, 1.0 ) = 0.3;
uniform float endOcclusionAmount: hint_range(0.0, 1.0 ) = 0.1;
uniform float endOcclusionRange: hint_range(0.0, 1.0 ) = 0.3;
uniform float rootBasedOcclusion:hint_range(0.0, 1.0) = 0.5;
group_uniforms;
// uniform float subsurface_scattering_strength : hint_range(0.0, 1.0, 0.01);
// uniform sampler2D texture_subsurface_scattering : hint_default_white, filter_linear_mipmap_anisotropic, repeat_enable;
// uniform vec4 transmittance_color : source_color;
// uniform float transmittance_depth : hint_range(0.001, 8.0, 0.001);
// uniform sampler2D texture_subsurface_transmittance : hint_default_white, filter_linear_mipmap_anisotropic, repeat_enable;
// uniform float transmittance_boost : hint_range(0.0, 1.0, 0.01);
// uniform sampler2D texture_heightmap : hint_default_black, filter_linear_mipmap_anisotropic, repeat_enable;
// uniform float heightmap_scale : hint_range(-16.0, 16.0, 0.001);
// uniform int heightmap_min_layers : hint_range(1, 64);
// uniform int heightmap_max_layers : hint_range(1, 64);
// uniform vec2 heightmap_flip;
// uniform vec3 uv1_scale;
// uniform vec3 uv1_offset;
// uniform vec3 uv2_scale;
// uniform vec3 uv2_offset;
float computeCameraFadeout( float cameraDistance, float close, float range, float power, float closeValue, float farValue )
{
float far = close + range;
float mapped = mapClamped( cameraDistance, close, far, 0, 1 );
float powered = pow( mapped, power );
return mix( closeValue, farValue, powered );
}
float computeHighlightCameraFadeout( float cameraDistance, float fadeStart, float fadeEnd, float power, float fadeOut )
{
float mapped = mapClamped( cameraDistance, fadeStart, fadeEnd, 0, 1 );
float powered = pow( mapped, power );
return mix( 1, fadeOut, powered );
}
varying float fadeAmount;
#ifdef USE_SHADOW
varying float shadowBlur;
varying float shadowOpacity;
#endif
void vertex()
{
// UV = UV * uv1_scale.xy + uv1_offset.xy;
float cameraDistance = cameraDistanceLocal( VERTEX, CAMERA_POSITION_WORLD, MODEL_MATRIX );
fadeAmount = computeHighlightCameraFadeout(
cameraDistance, highlightFadeOutStart, highlightFadeOutEnd, highlightFadeOutPower, highlightFadeOutAmount
) * maximumHighlightAmount;
#ifdef USE_SHADOW
float farAmount = computeCameraFadeout(
cameraDistance, opacityFarStart, opacityFarRange, opacityFarPower, 0, 1
);
shadowBlur = mix( opacityBlur, opacityBlurFarScale, farAmount );
shadowOpacity = mix( opacity, opacityFarScale, farAmount );
vec2 uv = UV - 0.5;
float angle = atan( uv.y, uv.x );
vec3 viewPosition = normalize( localToView( VERTEX, MODELVIEW_MATRIX ) );
vec2 uvE = vec2( cos( angle ), sin( angle ) );
uvE = viewPosition.xy;
vec3 localX = viewToLocalDirection( vec3( 1, 0, 0 ), INV_VIEW_MATRIX, MODEL_MATRIX );
vec3 localY = viewToLocalDirection( vec3( 0, 1, 0 ), INV_VIEW_MATRIX, MODEL_MATRIX );
VERTEX += extending * NORMAL;
#endif
// fadeAmountA = max( 1, clamp01( fadeAmountA ) );
// fadeAmountB = max( 1, clamp01( fadeAmountB ) );
}
void fragment()
{
if ( ! enabled )
{
discard;
}
// if ( ! FRONT_FACING )
// {
// NORMAL = -NORMAL;
// }
vec2 base_uv = UV;
vec4 albedo_tex = albedo * texture( texture_albedo, base_uv );
albedo_tex.rgb = adjustHSL( albedo_tex.rgb, hslOffset );
albedo_tex.rgb = albedo_tex.rgb * diffuseStrength;
#ifdef USE_SHADOW
albedo_tex.rgb = vec3( 0, 0, 0 );
float sampledAlpha = sampleRedBlurredUnclamped( texture_opacity, base_uv, shadowOpacity, 0, shadowBlur );
ALPHA = clamp01( sampledAlpha );
#else
ALPHA = pow( sampleRed( texture_opacity, base_uv, opacity, 0 ), opacityGamma );
#endif
#ifdef USE_ALPHA_SCISSOR
ALPHA_SCISSOR_THRESHOLD = alphaScissorTreshold;
#endif
#ifdef USE_ALPHA_DISCARD
if ( ALPHA < alphaDiscardTreshold )
{
discard;
}
#endif
float root = clamp01( 1.0 - texture( rootMap, UV ).r );
float id = texture( idMap, UV ).r;
if ( activateHairColor )
{
albedo_tex = mix( vec4( 1, 1, 1, 1 ), albedo_tex, baseColorMapStrength );
albedo_tex.rgb = mix( albedo_tex.rgb, vertexGreyToColor.rgb, ( 1.0 - COLOR.r ) * vertexColorStrength );
float strandAmount = mix( strandEndStrength, strandRootStrength, root );
vec4 strandColor = mix( strandEndColor, strandRootColor, root );
strandColor = gamma( strandColor, strandGamma );
// albedo_tex.rgb = blendMode_colorHSL( albedo_tex, strandColor, strandAmount ).rgb;
// albedo_tex.rgb = mix( albedo_tex.rgb, strandColor.rgb, strandAmount );
albedo_tex.rgb = mix( albedo_tex, strandColor, strandAmount ).rgb;
float highlightABlend = rangeAmount( id, highlightARange ) * highlightAStrength;
float rootBlendAmountA = mix( 1.0, mix( root, 1.0 - root, highlightAInvert ), highlightAOverlapEnd );
vec3 rootBlendedA = mix( albedo_tex.rgb, highlightAColor.rgb, clamp01( rootBlendAmountA ) );
albedo_tex.rgb = mix( albedo_tex.rgb, rootBlendedA, highlightABlend * fadeAmount );
float highlightBBlend = rangeAmount( id, highlightBRange ) * highlightBStrength;
float rootBlendAmountB = mix( 1.0, mix( root, 1.0 - root, highlightBInvert ), highlightBOverlapEnd );
vec3 rootBlendedB = mix( albedo_tex.rgb, highlightBColor.rgb, clamp01( rootBlendAmountB ) );
albedo_tex.rgb = mix( albedo_tex.rgb, rootBlendedB, highlightBBlend * fadeAmount );
}
else
{
albedo_tex.rgb = mix( albedo_tex.rgb, vertexGreyToColor.rgb, ( 1.0 - COLOR.r ) * vertexColorStrength );
}
ALBEDO = albedo_tex.rgb;
if ( naturalColors > 0.0 )
{
// ALBEDO = ALBEDO * 0.95;
vec3 hsl = RGBtoHSL( ALBEDO );
hsl.z = pow( hsl.z, 0.95 ) * 0.95 + hsl.y * 0.05;
hsl.y = pow( hsl.y, 2 );
hsl = clamp( hsl, 0, 1 );
ALBEDO = mix( ALBEDO, HSLtoRGB( hsl ), naturalColors );
}
vec4 blendTexture = texture( texture_blend, UV );
ALBEDO = mix( ALBEDO, ALBEDO * blendTexture.rgb, blendAmount );
// ALBEDO = clamp( COLOR.rgb, 0, 1 );
float metallic_tex = texture(texture_metallic, base_uv).r;
METALLIC = clamp( metallic_tex * metallic + metallicOffset, 0, 1 );
SPECULAR = specular * mix( 1.0, pow( ALPHA, specularOpacityGamma ), specularOpacityAmount );
float roughness_tex =texture(texture_roughness, base_uv).r;
ROUGHNESS = clamp( roughness_tex * roughness + roughnessOffset, 0, 1 );
// // Normal Map: Enabled
// NORMAL_MAP = texture(texture_normal, base_uv).rgb;
// NORMAL_MAP_DEPTH = normal_scale;
// Emission: Enabled
vec3 emission_tex = texture(texture_emission, base_uv).rgb;
// Emission Operator: Add
EMISSION = (emission.rgb + emission_tex) * emission_energy;
// // Rim: Enabled
// vec2 rim_tex = texture(texture_rim, base_uv).xy;
// RIM = rim * rim_tex.x;
// RIM_TINT = rim_tint * rim_tex.y;
// // Clearcoat: Enabled
// vec2 clearcoat_tex = texture(texture_clearcoat, base_uv).xy;
// CLEARCOAT = clearcoat * clearcoat_tex.x;
// CLEARCOAT_ROUGHNESS = clearcoat_roughness * clearcoat_tex.y;
// Ambient Occlusion: Enabled
float sampledAO = texture(texture_ambient_occlusion, base_uv).a;
float rootAO = mapClamped( root, 0.0, rootOcclusionRange, 1.0 - rootOcclusionAmount, 1 );
float endAO = mapClamped( root, 1.0, 1.0 - endOcclusionRange, 1.0 - endOcclusionAmount, 1 );
sampledAO *= mix( 1, ( rootAO * endAO ), rootBasedOcclusion );
AO = mix( 1, pow( sampledAO, aoGamma ), ambientOcclusion );
AO_LIGHT_AFFECT = ao_light_affect;
// // Subsurface Scattering: Enabled
// float sss_tex = texture(texture_subsurface_scattering, base_uv).r;
SSS_STRENGTH = subsurface_scattering_strength * ALPHA;
// // Backlight: Enabled
// vec3 backlight_tex = texture(texture_backlight, base_uv).rgb;
// BACKLIGHT = (backlight.rgb + backlight_tex);
BACKLIGHT = albedo_tex.rgb * albedoToBacklightAmount;
vec3 anisotropy_tex = texture(flowMap, base_uv).rga;
ANISOTROPY = anisotropy_ratio * anisotropy_tex.b;
ANISOTROPY_FLOW = anisotropy_tex.rg * 2.0 - 1.0;
#ifdef USE_SHADOW
ALBEDO = vec3( 0, 0, 0 );
BACKLIGHT = vec3( 0, 0, 0 );
AO_LIGHT_AFFECT = 1.0;
AO = 0.0;
EMISSION = vec3( 0, 0, 0 );
ROUGHNESS = 1.0;
METALLIC = 0.0;
SPECULAR = 0.0;
#endif
}