瀏覽代碼

first results of SSS

Benjamin Guignabert 5 年之前
父節點
當前提交
85458b25fa

+ 6 - 6
src/Materials/PBR/pbrBaseMaterial.ts

@@ -1284,6 +1284,12 @@ export abstract class PBRBaseMaterial extends PushMaterial {
         const scene = this.getScene();
         const engine = scene.getEngine();
 
+        if (scene.highDefinitionPipeline) {
+            defines.HIGH_DEFINITION_PIPELINE = true;
+        } else {
+            defines.HIGH_DEFINITION_PIPELINE = false;
+        }
+
         // Lights
         MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, true, this._maxSimultaneousLights, this._disableLighting);
         defines._needNormals = true;
@@ -1548,12 +1554,6 @@ export abstract class PBRBaseMaterial extends PushMaterial {
             this._imageProcessingConfiguration.prepareDefines(defines);
         }
 
-        if (scene.highDefinitionPipeline) {
-            defines.HIGH_DEFINITION_PIPELINE = true;
-        } else {
-            defines.HIGH_DEFINITION_PIPELINE = false;
-        }
-
         defines.FORCENORMALFORWARD = this._forceNormalForward;
 
         defines.RADIANCEOCCLUSION = this._useRadianceOcclusion;

+ 3 - 1
src/PostProcesses/SubSurfaceScatteringPostProcess.ts

@@ -24,7 +24,7 @@ export class SubSurfaceScatteringPostProcess extends PostProcess {
     private _filterRadius: number;
 
     constructor(name: string, scene: Scene, options: number | PostProcessOptions, camera: Nullable<Camera> = null, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT) {
-        super(name, "subSurfaceScattering", ["texelSize", "filterRadius", "viewportSize"], ["irradianceSampler", "depthSampler"], options, camera, samplingMode || Texture.BILINEAR_SAMPLINGMODE, engine, reusable, null, textureType, "postprocess", undefined, true);
+        super(name, "subSurfaceScattering", ["texelSize", "filterRadius", "viewportSize"], ["inputSampler", "irradianceSampler", "depthSampler", "albedoSampler"], options, camera, samplingMode || Texture.BILINEAR_SAMPLINGMODE, engine, reusable, null, textureType, "postprocess", undefined, true);
 
         const defines = this._getDefines();
         this.updateEffect(defines);
@@ -32,8 +32,10 @@ export class SubSurfaceScatteringPostProcess extends PostProcess {
         this.onApplyObservable.add((effect: Effect) => {
             var texelSize = this.texelSize;
             effect.setFloat2("texelSize", texelSize.x, texelSize.y);
+            effect.setTexture("inputSampler", scene.highDefinitionMRT.textures[4]);
             effect.setTexture("irradianceSampler", scene.highDefinitionMRT.textures[1]);
             effect.setTexture("depthSampler", scene.highDefinitionMRT.textures[2]);
+            effect.setTexture("albedoSampler", scene.highDefinitionMRT.textures[3]);
             effect.setFloat("filterRadius", this._filterRadius);
             effect.setFloat2("viewportSize", 
                 Math.tan(scene.activeCamera!.fov / 2) * scene.getEngine().getAspectRatio(scene.activeCamera!, true),

+ 2 - 2
src/Shaders/pbr.fragment.fx

@@ -507,8 +507,8 @@ void main(void) {
     gl_FragData[0] = finalColor;
     gl_FragData[1] = vec4(irradiance, 1.0);
     gl_FragData[2] = vec4(vViewPos.z, 0.0, 0.0, 1.0);
-    gl_FragData[3] = vec4(1.0, 0.0, 0.0, 1.0);
-    gl_FragData[4] = vec4(1.0, 0.0, 0.0, 1.0);
+    gl_FragData[3] = vec4(surfaceAlbedo, 1.0);
+    gl_FragData[4] = vec4(finalColor.rgb - irradiance, 1.0);
 #else
     // #define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR
     gl_FragColor = finalColor;

+ 8 - 10
src/Shaders/subSurfaceScattering.fragment.fx

@@ -4,16 +4,18 @@
 varying vec2 vUV;
 uniform vec2 texelSize;
 uniform sampler2D textureSampler;
+uniform sampler2D inputSampler;
 uniform sampler2D irradianceSampler;
 uniform sampler2D depthSampler;
+uniform sampler2D albedoSampler;
 
 uniform float filterRadius;
 uniform vec2 viewportSize;
 
 const float LOG2_E = 1.4426950408889634;
 const float PI = 3.1415926535897932;
-const float SSS_PIXELS_PER_SAMPLE = 1.;
-const int _SssSampleBudget = 32;
+const float SSS_PIXELS_PER_SAMPLE = 4.;
+const int _SssSampleBudget = 40;
 
 #define rcp(x) 1. / x
 #define Sq(x) x * x
@@ -61,7 +63,7 @@ vec2 SampleBurleyDiffusionProfile(float u, float rcpS)
 // TODO : inout vec3 totalIrradiance, inout vec3 totalWeight
 void EvaluateSample(int i, int n, vec3 S, float d, vec3 centerPosVS, float mmPerUnit, float pixelsPerMm,
                     float phase, vec3 tangentX, vec3 tangentY,
-                    vec3 totalIrradiance, vec3 totalWeight)
+                    inout vec3 totalIrradiance, inout vec3 totalWeight)
 {
     // The sample count is loop-invariant.
     float scale  = rcp(float(n));
@@ -155,7 +157,7 @@ void main(void)
 	float  distScale     = 1.; //sssData.subsurfaceMask;
 	vec3 S             = vec3(0.7568628, 0.32156864, 0.20000002); //_ShapeParamsAndMaxScatterDists[profileIndex].rgb diffusion color
 	float  d             = 0.7568628; //_ShapeParamsAndMaxScatterDists[profileIndex].a max scatter dist
-	float  metersPerUnit = 0.01; //_WorldScalesAndFilterRadiiAndThicknessRemaps[profileIndex].x;
+	float  metersPerUnit = 1.; //_WorldScalesAndFilterRadiiAndThicknessRemaps[profileIndex].x;
 
 	// Reconstruct the view-space position corresponding to the central sample.
 	vec2 centerPosNDC = vUV;
@@ -179,12 +181,8 @@ void main(void)
 	int  sampleCount  = int(filterArea * rcp(SSS_PIXELS_PER_SAMPLE));
 	int  sampleBudget = _SssSampleBudget;
 
-	// DEBUG
-	gl_FragColor = vec4(vec3(sampleCount) / 1000000., 1.0);
-	return;
-
 	int texturingMode = 0; // GetSubsurfaceScatteringTexturingMode(profileIndex);
-	vec3 albedo  = vec3(0.5); // texture2D(albedoSampler, vUV); //ApplySubsurfaceScatteringTexturingMode(texturingMode, sssData.diffuseColor);
+	vec3 albedo  = texture2D(albedoSampler, vUV).rgb; //ApplySubsurfaceScatteringTexturingMode(texturingMode, sssData.diffuseColor);
 
 	if (distScale == 0. || sampleCount < 1)
 	{
@@ -217,7 +215,7 @@ void main(void)
     // Total weight is 0 for color channels without scattering.
     totalWeight = max(totalWeight, 1e-12);
 
-    gl_FragColor = vec4(albedo * (totalIrradiance / totalWeight), 1.);
+    gl_FragColor = vec4(texture2D(inputSampler, vUV).rgb + albedo * (totalIrradiance / totalWeight), 1.);
 
 	// gl_FragColor = mix(texture2D(textureSampler, vUV), centerIrradiance, 0.5);
 }

+ 3 - 0
src/scene.ts

@@ -254,6 +254,9 @@ export class Scene extends AbstractScene implements IAnimatable {
     public get highDefinitionPipeline() {
         return this._highDefinitionPipeline;
     }
+    public set highDefinitionPipeline(b: boolean) {
+        this._highDefinitionPipeline = b;
+    }
 
     public highDefinitionMRT: MultiRenderTarget;
     public sceneCompositorPostProcess: SceneCompositorPostProcess;