forked from LeenkxTeam/LNXSDK
		
	Update leenkx/Shaders/sss_pass/sss_pass.frag.glsl
This commit is contained in:
		| @ -1,6 +1,7 @@ | ||||
| // | ||||
| // Copyright (C) 2012 Jorge Jimenez (jorge@iryoku.com) | ||||
| // Copyright (C) 2012 Diego Gutierrez (diegog@unizar.es) | ||||
| // Copyright (C) 2025 Onek8 (info@leenkx.com) | ||||
| // All rights reserved. | ||||
| // | ||||
| // Redistribution and use in source and binary forms, with or without | ||||
| @ -33,6 +34,14 @@ | ||||
| // policies, either expressed or implied, of the copyright holders. | ||||
| // | ||||
|  | ||||
| // TODO: | ||||
| // Add real sss radius | ||||
| // Add real sss scale | ||||
| // Move temp hash, reorganize shader utility functions | ||||
| // Add compiler flag for quality presets or with samples parameter | ||||
| // Clean up + Document comment | ||||
|  | ||||
|  | ||||
| #version 450 | ||||
|  | ||||
| #include "compiled.inc" | ||||
| @ -49,67 +58,93 @@ out vec4 fragColor; | ||||
|  | ||||
| const float SSSS_FOVY = 108.0; | ||||
|  | ||||
| // Separable SSS Reflectance | ||||
| // const float sssWidth = 0.005; | ||||
| // Temp hash func -  | ||||
| float hash13(vec3 p3) { | ||||
| 	p3 = fract(p3 * vec3(0.1031, 0.1030, 0.0973)); | ||||
| 	p3 += dot(p3, p3.yzx + 33.33); | ||||
| 	return fract((p3.x + p3.y) * p3.z); | ||||
| } | ||||
|  | ||||
| vec4 SSSSBlur() { | ||||
| 	// Quality = 0 | ||||
| 	const int SSSS_N_SAMPLES  = 11; | ||||
| 	vec4 kernel[SSSS_N_SAMPLES];		 | ||||
| 	kernel[0] = vec4(0.560479, 0.669086, 0.784728, 0); | ||||
| 	kernel[1] = vec4(0.00471691, 0.000184771, 5.07566e-005, -2); | ||||
| 	kernel[2] = vec4(0.0192831, 0.00282018, 0.00084214, -1.28); | ||||
| 	kernel[3] = vec4(0.03639, 0.0130999, 0.00643685, -0.72); | ||||
| 	kernel[4] = vec4(0.0821904, 0.0358608, 0.0209261, -0.32); | ||||
| 	kernel[5] = vec4(0.0771802, 0.113491, 0.0793803, -0.08); | ||||
| 	kernel[6] = vec4(0.0771802, 0.113491, 0.0793803, 0.08); | ||||
| 	kernel[7] = vec4(0.0821904, 0.0358608, 0.0209261, 0.32); | ||||
| 	kernel[8] = vec4(0.03639, 0.0130999, 0.00643685, 0.72); | ||||
| 	kernel[9] = vec4(0.0192831, 0.00282018, 0.00084214, 1.28); | ||||
| 	kernel[10] = vec4(0.00471691, 0.000184771, 5.07565e-005, 2); | ||||
| 	const int SSSS_N_SAMPLES = 15; | ||||
| 	vec4 kernel[SSSS_N_SAMPLES]; | ||||
| 	 | ||||
| 	// color neutral kernel weights to prevent color shifting | ||||
| 	kernel[0] = vec4(0.2, 0.2, 0.2, 0.0); | ||||
| 	kernel[1] = vec4(0.12, 0.12, 0.12, 0.2); | ||||
| 	kernel[2] = vec4(0.09, 0.09, 0.09, 0.4); | ||||
| 	kernel[3] = vec4(0.06, 0.06, 0.06, 0.8); | ||||
| 	kernel[4] = vec4(0.04, 0.04, 0.04, 1.2); | ||||
| 	kernel[5] = vec4(0.025, 0.025, 0.025, 1.6); | ||||
| 	kernel[6] = vec4(0.015, 0.015, 0.015, 2.0); | ||||
| 	kernel[7] = vec4(0.005, 0.005, 0.005, 2.5); | ||||
| 	kernel[8] = vec4(0.12, 0.12, 0.12, -0.2); | ||||
| 	kernel[9] = vec4(0.09, 0.09, 0.09, -0.4); | ||||
| 	kernel[10] = vec4(0.06, 0.06, 0.06, -0.8); | ||||
| 	kernel[11] = vec4(0.04, 0.04, 0.04, -1.2); | ||||
| 	kernel[12] = vec4(0.025, 0.025, 0.025, -1.6); | ||||
| 	kernel[13] = vec4(0.015, 0.015, 0.015, -2.0); | ||||
| 	kernel[14] = vec4(0.005, 0.005, 0.005, -2.5); | ||||
| 	 | ||||
| 	vec4 colorM = textureLod(tex, texCoord, 0.0); | ||||
|  | ||||
| 	// Fetch linear depth of current pixel | ||||
| 	float depth = textureLod(gbufferD, texCoord, 0.0).r; | ||||
| 	float depthM = cameraProj.y / (depth - cameraProj.x); | ||||
|  | ||||
| 	// Calculate the sssWidth scale (1.0 for a unit plane sitting on the projection window) | ||||
| 	float distanceToProjectionWindow = 1.0 / tan(0.5 * radians(SSSS_FOVY)); | ||||
| 	float scale = distanceToProjectionWindow / depthM; | ||||
|  | ||||
| 	// Calculate the final step to fetch the surrounding pixels | ||||
| 	vec2 finalStep = sssWidth * scale * dir; | ||||
| 	finalStep *= 1.0;//SSSS_STREGTH_SOURCE; // Modulate it using the alpha channel. | ||||
| 	finalStep *= 1.0 / 3.0; // Divide by 3 as the kernels range from -3 to 3. | ||||
| 	finalStep *= 0.05; // | ||||
| 	 | ||||
|  | ||||
| 	// Accumulate the center sample: | ||||
| 	vec4 colorBlurred = colorM; | ||||
| 	colorBlurred.rgb *= kernel[0].rgb; | ||||
|  | ||||
| 	// Accumulate the other samples | ||||
| 	vec3 jitterSeed = vec3(texCoord.xy * 1000.0, fract(cameraProj.x * 0.0001)); | ||||
| 	float jitterOffset = (hash13(jitterSeed) * 2.0 - 1.0) * 0.15; // 15% jitteR | ||||
| 	 | ||||
| 	finalStep *= (1.0 + jitterOffset); | ||||
| 	finalStep *= 0.05;  | ||||
| 	vec3 colorBlurred = vec3(0.0); | ||||
| 	vec3 weightSum = vec3(0.0); | ||||
| 	colorBlurred += colorM.rgb * kernel[0].rgb; | ||||
| 	weightSum += kernel[0].rgb; | ||||
| 	 | ||||
| 	// Accumulate the other samples with per-pixel jittering to reduce banding | ||||
| 	for (int i = 1; i < SSSS_N_SAMPLES; i++) { | ||||
| 		// Fetch color and depth for current sample | ||||
| 		vec2 offset = texCoord + kernel[i].a * finalStep; | ||||
| 		float sampleJitter = hash13(vec3(texCoord.xy * 720.0, float(i) * 37.45)) * 0.1 - 0.05; | ||||
| 		 | ||||
| 		vec2 offset = texCoord + (kernel[i].a + sampleJitter) * finalStep; | ||||
| 		vec4 color = textureLod(tex, offset, 0.0); | ||||
| 		//#if SSSS_FOLLOW_SURFACE == 1 | ||||
| 		// If the difference in depth is huge, we lerp color back to "colorM": | ||||
| 		//float depth = textureLod(tex, offset, 0.0).r; | ||||
| 		//float s = clamp(300.0f * distanceToProjectionWindow * sssWidth * abs(depthM - depth),0.0,1.0); | ||||
| 		//color.rgb = mix(color.rgb, colorM.rgb, s); | ||||
| 		//#endif | ||||
| 		// Accumulate | ||||
| 		colorBlurred.rgb += kernel[i].rgb * color.rgb; | ||||
| 		 | ||||
| 		// ADJUST FOR SURFACE FOLLOWING | ||||
| 		// 0.0 = disabled (maximum SSS but with bleeding), 1.0 = fully enabled (prevents bleeding but might reduce SSS effect) | ||||
| 		const float SURFACE_FOLLOWING_STRENGTH = 0.15; // Reduced to preserve more SSS effect | ||||
| 		 | ||||
| 		if (SURFACE_FOLLOWING_STRENGTH > 0.0) { | ||||
| 			float sampleDepth = textureLod(gbufferD, offset, 0.0).r; | ||||
| 			float depthScale = 5.0;  | ||||
| 			float depthDiff = abs(depth - sampleDepth) * depthScale; | ||||
| 			if (depthDiff > 0.3) {  | ||||
| 				float blendFactor = clamp(depthDiff - 0.3, 0.0, 1.0) * SURFACE_FOLLOWING_STRENGTH; | ||||
| 				color.rgb = mix(color.rgb, colorM.rgb, blendFactor); | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		colorBlurred += color.rgb * kernel[i].rgb; | ||||
| 		weightSum += kernel[i].rgb; | ||||
| 	} | ||||
|  | ||||
| 	return colorBlurred; | ||||
| 	vec3 normalizedColor = colorBlurred / max(weightSum, vec3(0.00001)); | ||||
| 	float dither = hash13(vec3(texCoord * 1333.0, 0.0)) * 0.003 - 0.0015; | ||||
| 	return vec4(normalizedColor + vec3(dither), colorM.a); | ||||
| } | ||||
|  | ||||
| void main() { | ||||
| 	 | ||||
| 	if (textureLod(gbuffer0, texCoord, 0.0).a == 8192.0) { | ||||
| 		fragColor = clamp(SSSSBlur(), 0.0, 1.0); | ||||
| 	} | ||||
| 	else { | ||||
| 		vec4 originalColor = textureLod(tex, texCoord, 0.0); | ||||
| 		vec4 blurredColor = SSSSBlur(); | ||||
| 		vec4 finalColor = mix(blurredColor, originalColor, 0.15); | ||||
| 		 | ||||
| 		fragColor = clamp(finalColor, 0.0, 1.0); | ||||
| 	} else { | ||||
| 		fragColor = textureLod(tex, texCoord, 0.0); | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user