Browse Source

adding backbone of ss pp

Benjamin Guignabert 5 years ago
parent
commit
135c2ce747

+ 43 - 0
src/PostProcesses/SubSurfaceScatteringPostProcess.ts

@@ -0,0 +1,43 @@
+import { Nullable } from "../types";
+import { Camera } from "../Cameras/camera";
+import { Effect } from "../Materials/effect";
+import { Texture } from "../Materials/Textures/texture";
+import { PostProcess, PostProcessOptions } from "./postProcess";
+import { Engine } from "../Engines/engine";
+import { Scene } from "../scene";
+import { Constants } from "../Engines/constants";
+
+import "../Shaders/sceneCompositor.fragment";
+import "../Shaders/postprocess.vertex";
+
+/**
+ * Scene compositor post process
+ */
+export class SubSurfaceScatteringPostProcess extends PostProcess {
+    /** @hidden */
+    public texelWidth: number;
+    /** @hidden */
+    public texelHeight: 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"], ["irradianceSampler"], options, camera, samplingMode || Texture.BILINEAR_SAMPLINGMODE, engine, reusable, null, textureType, "postprocess", undefined, true);
+
+        const defines = this._getDefines();
+        this.updateEffect(defines);
+
+        this.onApplyObservable.add((effect: Effect) => {
+            var texelSize = this.texelSize;
+            effect.setFloat2("texelSize", texelSize.x, texelSize.y);
+            effect.setTexture("irradianceSampler", scene.highDefinitionMRT.textures[2]);
+        });
+    }
+
+    private _getDefines(): Nullable<string> {
+        const engine = this.getEngine();
+        if (!engine) {
+            return null;
+        }
+
+        return "";
+    }
+}

+ 14 - 4
src/Shaders/pbr.fragment.fx

@@ -1,4 +1,4 @@
-#if defined(BUMP) || !defined(NORMAL) || defined(FORCENORMALFORWARD) || defined(SPECULARAA) || defined(CLEARCOAT_BUMP) || defined(ANISOTROPIC)
+#if defined(BUMP) || !defined(NORMAL) || defined(FORCENORMALFORWARD) || defined(SPECULARAA) || defined(CLEARCOAT_BUMP) || defined(ANISOTROPIC)
 #extension GL_OES_standard_derivatives : enable
 #endif
 
@@ -487,16 +487,26 @@ void main(void) {
 
     #include<pbrBlockFinalColorComposition>
 
-        #include<logDepthFragment>
+        #include<logDepthFragment>yes 
     #include<fogFragment>(color, finalColor)
 
     #include<pbrBlockImageProcessing>
 
 
 #ifdef HIGH_DEFINITION_PIPELINE
+    vec3 irradiance = finalDiffuse;
+    #ifndef UNLIT
+        #ifdef REFLECTION
+            irradiance += finalIrradiance;
+        #endif
+    #endif
+    // finalDiffuse and finalIrradiance are already multiplied by surfaceAlbedo
+    // What about :
+    // Lightmaps ? (can we consider them as pure diffuse ?)
+    // AO and shadows, should they dim the diffuseLight ? (right now they are)
     gl_FragData[0] = finalColor;
-    gl_FragData[1] = vec4(1.0, 0.0, 0.0, 1.0);
-    gl_FragData[2] = vec4(1.0, 0.0, 0.0, 1.0);
+    gl_FragData[1] = vec4(irradiance, 1.0);
+    gl_FragData[2] = vec4(0.0, 1.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);
 #else

+ 9 - 0
src/Shaders/subSurfaceScattering.fragment.fx

@@ -0,0 +1,9 @@
+// Samplers
+varying vec2 vUV;
+uniform sampler2D textureSampler;
+uniform sampler2D irradianceSampler;
+
+void main(void) 
+{
+	gl_FragColor = mix(texture2D(textureSampler, vUV), texture2D(irradianceSampler, vUV), 0.5);
+}

+ 9 - 1
src/scene.ts

@@ -23,6 +23,7 @@ import { Texture } from "./Materials/Textures/texture";
 import { RenderTargetTexture } from "./Materials/Textures/renderTargetTexture";
 import { MultiRenderTarget } from "./Materials/Textures/multiRenderTarget";
 import { SceneCompositorPostProcess } from "./PostProcesses/sceneCompositorPostProcess";
+import { SubSurfaceScatteringPostProcess } from "./PostProcesses/subSurfaceScatteringPostProcess";
 import { Material } from "./Materials/material";
 import { ImageProcessingConfiguration } from "./Materials/imageProcessingConfiguration";
 import { Effect } from "./Materials/effect";
@@ -256,6 +257,7 @@ export class Scene extends AbstractScene implements IAnimatable {
 
     public highDefinitionMRT: MultiRenderTarget;
     public sceneCompositorPostProcess: SceneCompositorPostProcess;
+    public subSurfaceScatteringPostProcess: SubSurfaceScatteringPostProcess;
 
     private _forceWireframe = false;
     /**
@@ -1445,6 +1447,7 @@ export class Scene extends AbstractScene implements IAnimatable {
         this.highDefinitionMRT.samples = 1;
         this.sceneCompositorPostProcess = new SceneCompositorPostProcess("sceneCompositor", 1, null, undefined, this._engine);
         this.sceneCompositorPostProcess.inputTexture = this.highDefinitionMRT.getInternalTexture()!;
+        this.subSurfaceScatteringPostProcess = new SubSurfaceScatteringPostProcess("subSurfaceScattering", this, 1, null, undefined, this._engine);
     }
 
     /**
@@ -3787,7 +3790,12 @@ export class Scene extends AbstractScene implements IAnimatable {
 
         if (this.highDefinitionPipeline) {
             // this.sceneCompositorPostProcess.activate(this.activeCamera);
-            this.postProcessManager.directRender([this.sceneCompositorPostProcess]);
+            this.sceneCompositorPostProcess.autoClear = false;
+            this.sceneCompositorPostProcess.activate(this.activeCamera);
+            this.subSurfaceScatteringPostProcess.activate(this.activeCamera);
+            this.postProcessManager.directRender([this.sceneCompositorPostProcess], this.subSurfaceScatteringPostProcess.inputTexture);
+            // this.getEngine().restoreDefaultFramebuffer(); // Restore back buffer if needed
+            this.postProcessManager.directRender([this.subSurfaceScatteringPostProcess]);
         }
 
         // Finalize frame