#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 grow:hint_range(-0.01, 0.01, 0.0001) = 00; 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; 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; // VERTEX += NORMAL * grow; #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 }