// Do not edit. import { ShaderStore } from "../Engines/shaderStore.js"; import "./ShadersInclude/fibonacci.js"; import "./ShadersInclude/helperFunctions.js"; import "./ShadersInclude/subSurfaceScatteringFunctions.js"; import "./ShadersInclude/diffusionProfile.js"; const name = "subSurfaceScatteringPixelShader"; const shader = `#include #include #include #include varying vec2 vUV;uniform vec2 texelSize;uniform sampler2D textureSampler;uniform sampler2D irradianceSampler;uniform sampler2D depthSampler;uniform sampler2D albedoSampler;uniform vec2 viewportSize;uniform float metersPerUnit;const float LOG2_E=1.4426950408889634;const float SSS_PIXELS_PER_SAMPLE=4.;const int _SssSampleBudget=40; #define rcp(x) 1./x #define Sq(x) x*x #define SSS_BILATERAL_FILTER true vec3 EvalBurleyDiffusionProfile(float r,vec3 S) {vec3 exp_13=exp2(((LOG2_E*(-1.0/3.0))*r)*S); vec3 expSum=exp_13*(1.+exp_13*exp_13); return (S*rcp(8.*PI))*expSum; } vec2 SampleBurleyDiffusionProfile(float u,float rcpS) {u=1.-u; float g=1.+(4.*u)*(2.*u+sqrt(1.+(4.*u)*u));float n=exp2(log2(g)*(-1.0/3.0)); float p=(g*n)*n; float c=1.+p+n; float d=(3./LOG2_E*2.)+(3./LOG2_E)*log2(u); float x=(3./LOG2_E)*log2(c)-d; float rcpExp=((c*c)*c)*rcp((4.*u)*((c*c)+(4.*u)*(4.*u)));float r=x*rcpS;float rcpPdf=(8.*PI*rcpS)*rcpExp; return vec2(r,rcpPdf);} vec3 ComputeBilateralWeight(float xy2,float z,float mmPerUnit,vec3 S,float rcpPdf) { #ifndef SSS_BILATERAL_FILTER z=0.; #endif float r=sqrt(xy2+(z*mmPerUnit)*(z*mmPerUnit));float area=rcpPdf; #if SSS_CLAMP_ARTIFACT return clamp(EvalBurleyDiffusionProfile(r,S)*area,0.0,1.0); #else return EvalBurleyDiffusionProfile(r,S)*area; #endif } void EvaluateSample(int i,int n,vec3 S,float d,vec3 centerPosVS,float mmPerUnit,float pixelsPerMm, float phase,inout vec3 totalIrradiance,inout vec3 totalWeight) {float scale =rcp(float(n));float offset=rcp(float(n))*0.5;float sinPhase,cosPhase;sinPhase=sin(phase);cosPhase=cos(phase);vec2 bdp=SampleBurleyDiffusionProfile(float(i)*scale+offset,d);float r=bdp.x;float rcpPdf=bdp.y;float phi=SampleDiskGolden(i,n).y;float sinPhi,cosPhi;sinPhi=sin(phi);cosPhi=cos(phi);float sinPsi=cosPhase*sinPhi+sinPhase*cosPhi; float cosPsi=cosPhase*cosPhi-sinPhase*sinPhi; vec2 vec=r*vec2(cosPsi,sinPsi);vec2 position; float xy2;position=vUV+round((pixelsPerMm*r)*vec2(cosPsi,sinPsi))*texelSize;xy2 =r*r;vec4 textureSample=texture2D(irradianceSampler,position);float viewZ=texture2D(depthSampler,position).r;vec3 irradiance =textureSample.rgb;if (testLightingForSSS(textureSample.a)) {float relZ=viewZ-centerPosVS.z;vec3 weight=ComputeBilateralWeight(xy2,relZ,mmPerUnit,S,rcpPdf);totalIrradiance+=weight*irradiance;totalWeight +=weight;} else {}} #define CUSTOM_FRAGMENT_DEFINITIONS void main(void) {vec4 irradianceAndDiffusionProfile =texture2D(irradianceSampler,vUV);vec3 centerIrradiance=irradianceAndDiffusionProfile.rgb;int diffusionProfileIndex=int(round(irradianceAndDiffusionProfile.a*255.));float centerDepth =0.;vec4 inputColor=texture2D(textureSampler,vUV);bool passedStencilTest=testLightingForSSS(irradianceAndDiffusionProfile.a);if (passedStencilTest) {centerDepth=texture2D(depthSampler,vUV).r;} if (!passedStencilTest) { gl_FragColor=inputColor;return;} float distScale =1.;vec3 S =diffusionS[diffusionProfileIndex];float d =diffusionD[diffusionProfileIndex];float filterRadius=filterRadii[diffusionProfileIndex];vec2 centerPosNDC=vUV;vec2 cornerPosNDC=vUV+0.5*texelSize;vec3 centerPosVS =vec3(centerPosNDC*viewportSize,1.0)*centerDepth; vec3 cornerPosVS =vec3(cornerPosNDC*viewportSize,1.0)*centerDepth; float mmPerUnit =1000.*(metersPerUnit*rcp(distScale));float unitsPerMm=rcp(mmPerUnit);float unitsPerPixel=2.*abs(cornerPosVS.x-centerPosVS.x);float pixelsPerMm =rcp(unitsPerPixel)*unitsPerMm;float filterArea =PI*Sq(filterRadius*pixelsPerMm);int sampleCount =int(filterArea*rcp(SSS_PIXELS_PER_SAMPLE));int sampleBudget=_SssSampleBudget;int texturingMode=0;vec3 albedo =texture2D(albedoSampler,vUV).rgb;if (distScale==0. || sampleCount<1) { #ifdef DEBUG_SSS_SAMPLES vec3 green=vec3(0.,1.,0.);gl_FragColor=vec4(green,1.0);return; #endif gl_FragColor=vec4(inputColor.rgb+albedo*centerIrradiance,1.0);return;} #ifdef DEBUG_SSS_SAMPLES vec3 red =vec3(1.,0.,0.);vec3 blue=vec3(0.,0.,1.);gl_FragColor=vec4(mix(blue,red,clamp(float(sampleCount)/float(sampleBudget),0.0,1.0)),1.0);return; #endif float phase=0.;int n=min(sampleCount,sampleBudget);vec3 centerWeight =vec3(0.); vec3 totalIrradiance=vec3(0.);vec3 totalWeight =vec3(0.);for (int i=0; i