Browse Source

splitting prepass and subsurface scattering infos

Benjamin Guignabert 5 năm trước cách đây
mục cha
commit
645d76a548

+ 1 - 1
src/Materials/PBR/pbrSubSurfaceConfiguration.ts

@@ -90,7 +90,7 @@ export class PBRSubSurfaceConfiguration {
         }
 
         // addDiffusionProfile automatically checks for doubles
-        this._scatteringDiffusionProfileIndex = this._scene.prePassRenderer!.addDiffusionProfile(c);
+        this._scatteringDiffusionProfileIndex = this._scene.prePassRenderer!.subSurfaceConfiguration.addDiffusionProfile(c);
     }
 
     /**

+ 3 - 3
src/PostProcesses/subSurfaceScatteringPostProcess.ts

@@ -41,9 +41,9 @@ export class SubSurfaceScatteringPostProcess extends PostProcess {
             effect.setFloat2("viewportSize",
                 Math.tan(scene.activeCamera!.fov / 2) * scene.getEngine().getAspectRatio(scene.activeCamera!, true),
                 Math.tan(scene.activeCamera!.fov / 2));
-            effect.setArray3("diffusionS", scene.prePassRenderer.ssDiffusionS);
-            effect.setArray("diffusionD", scene.prePassRenderer.ssDiffusionD);
-            effect.setArray("filterRadii", scene.prePassRenderer.ssFilterRadii);
+            effect.setArray3("diffusionS", scene.prePassRenderer.subSurfaceConfiguration.ssDiffusionS);
+            effect.setArray("diffusionD", scene.prePassRenderer.subSurfaceConfiguration.ssDiffusionD);
+            effect.setArray("filterRadii", scene.prePassRenderer.subSurfaceConfiguration.ssFilterRadii);
         });
 
     }

+ 11 - 110
src/Rendering/prePassRenderer.ts

@@ -6,9 +6,9 @@ import { Constants } from "../Engines/constants";
 import { ImageProcessingPostProcess } from "../PostProcesses/imageProcessingPostProcess";
 import { SubSurfaceScatteringPostProcess } from "../PostProcesses/subSurfaceScatteringPostProcess";
 import { Effect } from "../Materials/effect";
-import { Logger } from "../Misc/logger";
 import { _DevTools } from '../Misc/devTools';
-import { Color3, Color4 } from "../Maths/math.color";
+import { Color4 } from "../Maths/math.color";
+import { SubSurfaceConfiguration } from "./subSurfaceConfiguration";
 
 /**
  * Renders a pre pass of the scene
@@ -47,31 +47,6 @@ export class PrePassRenderer {
 
     private readonly _clearColor = new Color4(0, 0, 0, 0);
 
-    private _ssDiffusionS: number[] = [];
-    private _ssFilterRadii: number[] = [];
-    private _ssDiffusionD: number[] = [];
-
-    /**
-     * Diffusion profile color for subsurface scattering
-     */
-    public get ssDiffusionS() {
-        return this._ssDiffusionS;
-    }
-
-    /**
-     * Diffusion profile max color channel value for subsurface scattering
-     */
-    public get ssDiffusionD() {
-        return this._ssDiffusionD;
-    }
-
-    /**
-     * Diffusion profile filter radius for subsurface scattering
-     */
-    public get ssFilterRadii() {
-        return this._ssFilterRadii;
-    }
-
     /**
      * Defines the ratio real world => scene units.
      * Used for subsurface scattering
@@ -85,8 +60,14 @@ export class PrePassRenderer {
 
     /**
      * Post process for subsurface scattering
-     */
+     */    
     public subSurfaceScatteringPostProcess: SubSurfaceScatteringPostProcess;
+
+    /**
+     * Configuration for sub surface scattering post process
+     */
+    public subSurfaceConfiguration: SubSurfaceConfiguration;
+
     private _enabled: boolean = false;
 
     /**
@@ -121,8 +102,7 @@ export class PrePassRenderer {
 
         PrePassRenderer._SceneComponentInitialization(this._scene);
 
-        // Adding default diffusion profile
-        this.addDiffusionProfile(new Color3(1, 1, 1));
+        this.subSurfaceConfiguration = new SubSurfaceConfiguration(this._scene);
     }
 
     private _initializeAttachments() {
@@ -288,92 +268,13 @@ export class PrePassRenderer {
     }
 
     /**
-     * Adds a new diffusion profile.
-     * Useful for more realistic subsurface scattering on diverse materials.
-     * @param color The color of the diffusion profile. Should be the average color of the material.
-     * @return The index of the diffusion profile for the material subsurface configuration
-     */
-    public addDiffusionProfile(color: Color3) : number {
-        if (this.ssDiffusionD.length >= 5) {
-            // We only suppport 5 diffusion profiles
-            Logger.Error("You already reached the maximum number of diffusion profiles.");
-            return 0; // default profile
-        }
-
-        // Do not add doubles
-        for (let i = 0; i < this._ssDiffusionS.length / 3; i++) {
-            if (this._ssDiffusionS[i * 3] === color.r &&
-                this._ssDiffusionS[i * 3 + 1] === color.g &&
-                this._ssDiffusionS[i * 3 + 2] === color.b) {
-                return i;
-            }
-        }
-
-        this._ssDiffusionS.push(color.r, color.b, color.g);
-        this._ssDiffusionD.push(Math.max(Math.max(color.r, color.b), color.g));
-        this._ssFilterRadii.push(this.getDiffusionProfileParameters(color));
-        this._scene.ssDiffusionProfileColors.push(color);
-
-        return this._ssDiffusionD.length - 1;
-    }
-
-    /**
-     * Deletes all diffusion profiles.
-     * Note that in order to render subsurface scattering, you should have at least 1 diffusion profile.
-     */
-    public clearAllDiffusionProfiles() {
-        this._ssDiffusionD = [];
-        this._ssDiffusionS = [];
-        this._ssFilterRadii = [];
-        this._scene.ssDiffusionProfileColors = [];
-    }
-
-    /**
-     * @hidden
-     * https://zero-radiance.github.io/post/sampling-diffusion/
-     *
-     * Importance sample the normalized diffuse reflectance profile for the computed value of 's'.
-     * ------------------------------------------------------------------------------------
-     * R[r, phi, s]   = s * (Exp[-r * s] + Exp[-r * s / 3]) / (8 * Pi * r)
-     * PDF[r, phi, s] = r * R[r, phi, s]
-     * CDF[r, s]      = 1 - 1/4 * Exp[-r * s] - 3/4 * Exp[-r * s / 3]
-     * ------------------------------------------------------------------------------------
-     * We importance sample the color channel with the widest scattering distance.
-     */
-    public getDiffusionProfileParameters(color: Color3)
-    {
-        const cdf = 0.997;
-        const maxScatteringDistance = Math.max(color.r, color.g, color.b);
-
-        return this._sampleBurleyDiffusionProfile(cdf, maxScatteringDistance);
-    }
-
-    /**
-     * Performs sampling of a Normalized Burley diffusion profile in polar coordinates.
-     * 'u' is the random number (the value of the CDF): [0, 1).
-     * rcp(s) = 1 / ShapeParam = ScatteringDistance.
-     * Returns the sampled radial distance, s.t. (u = 0 -> r = 0) and (u = 1 -> r = Inf).
-     */
-    private _sampleBurleyDiffusionProfile(u: number, rcpS: number)
-    {
-        u = 1 - u; // Convert CDF to CCDF
-
-        let g = 1 + (4 * u) * (2 * u + Math.sqrt(1 + (4 * u) * u));
-        let n = Math.pow(g, -1.0 / 3.0);                      // g^(-1/3)
-        let p = (g * n) * n;                                   // g^(+1/3)
-        let c = 1 + p + n;                                     // 1 + g^(+1/3) + g^(-1/3)
-        let x = 3 * Math.log(c / (4 * u));
-
-        return x * rcpS;
-    }
-
-    /**
      * Disposes the prepass renderer.
      */
     public dispose() {
         this.imageProcessingPostProcess.dispose();
         this.subSurfaceScatteringPostProcess.dispose();
         this.prePassRT.dispose();
+        this.subSurfaceConfiguration.dispose();
     }
 
 }

+ 2 - 2
src/Rendering/prePassRendererSceneComponent.ts

@@ -154,7 +154,7 @@ export class PrePassRendererSceneComponent implements ISceneSerializableComponen
 
         if (this.scene.prePassRenderer) {
             container.ssDiffusionProfileColors.forEach((color) => {
-                this.scene.prePassRenderer!.addDiffusionProfile(color);
+                this.scene.prePassRenderer!.subSurfaceConfiguration.addDiffusionProfile(color);
             });
         }
     }
@@ -170,7 +170,7 @@ export class PrePassRendererSceneComponent implements ISceneSerializableComponen
         }
 
         if (this.scene.prePassRenderer) {
-            this.scene.prePassRenderer.clearAllDiffusionProfiles();
+            this.scene.prePassRenderer.subSurfaceConfiguration.clearAllDiffusionProfiles();
         }
     }
 

+ 126 - 0
src/Rendering/subSurfaceConfiguration.ts

@@ -0,0 +1,126 @@
+import { Logger } from "../Misc/logger";
+import { Color3 } from "../Maths/math.color";
+import { Scene } from "../scene";
+
+/**
+ * Contains all parameters needed for the prepass to perform
+ * screen space subsurface scattering
+ */
+export class SubSurfaceConfiguration {
+	private _scene: Scene;
+
+	private _ssDiffusionS: number[] = [];
+	private _ssFilterRadii: number[] = [];
+	private _ssDiffusionD: number[] = [];
+
+	/**
+	 * Diffusion profile color for subsurface scattering
+	 */
+	public get ssDiffusionS() {
+	    return this._ssDiffusionS;
+	}
+
+	/**
+	 * Diffusion profile max color channel value for subsurface scattering
+	 */
+	public get ssDiffusionD() {
+	    return this._ssDiffusionD;
+	}
+
+	/**
+	 * Diffusion profile filter radius for subsurface scattering
+	 */
+	public get ssFilterRadii() {
+	    return this._ssFilterRadii;
+	}
+
+	constructor(scene: Scene) {
+		// Adding default diffusion profile
+		this._scene = scene;
+		this.addDiffusionProfile(new Color3(1, 1, 1));
+	}
+
+	/**
+	 * Adds a new diffusion profile.
+	 * Useful for more realistic subsurface scattering on diverse materials.
+	 * @param color The color of the diffusion profile. Should be the average color of the material.
+	 * @return The index of the diffusion profile for the material subsurface configuration
+	 */
+	public addDiffusionProfile(color: Color3) : number {
+	    if (this.ssDiffusionD.length >= 5) {
+	        // We only suppport 5 diffusion profiles
+	        Logger.Error("You already reached the maximum number of diffusion profiles.");
+	        return 0; // default profile
+	    }
+
+	    // Do not add doubles
+	    for (let i = 0; i < this._ssDiffusionS.length / 3; i++) {
+	        if (this._ssDiffusionS[i * 3] === color.r &&
+	            this._ssDiffusionS[i * 3 + 1] === color.g &&
+	            this._ssDiffusionS[i * 3 + 2] === color.b) {
+	            return i;
+	        }
+	    }
+
+	    this._ssDiffusionS.push(color.r, color.b, color.g);
+	    this._ssDiffusionD.push(Math.max(Math.max(color.r, color.b), color.g));
+	    this._ssFilterRadii.push(this.getDiffusionProfileParameters(color));
+	    this._scene.ssDiffusionProfileColors.push(color);
+
+	    return this._ssDiffusionD.length - 1;
+	}
+
+	/**
+	 * Deletes all diffusion profiles.
+	 * Note that in order to render subsurface scattering, you should have at least 1 diffusion profile.
+	 */
+	public clearAllDiffusionProfiles() {
+	    this._ssDiffusionD = [];
+	    this._ssDiffusionS = [];
+	    this._ssFilterRadii = [];
+	    this._scene.ssDiffusionProfileColors = [];
+	}
+
+	public dispose() {
+		this.clearAllDiffusionProfiles();
+	}
+
+	/**
+	 * @hidden
+	 * https://zero-radiance.github.io/post/sampling-diffusion/
+	 *
+	 * Importance sample the normalized diffuse reflectance profile for the computed value of 's'.
+	 * ------------------------------------------------------------------------------------
+	 * R[r, phi, s]   = s * (Exp[-r * s] + Exp[-r * s / 3]) / (8 * Pi * r)
+	 * PDF[r, phi, s] = r * R[r, phi, s]
+	 * CDF[r, s]      = 1 - 1/4 * Exp[-r * s] - 3/4 * Exp[-r * s / 3]
+	 * ------------------------------------------------------------------------------------
+	 * We importance sample the color channel with the widest scattering distance.
+	 */
+	public getDiffusionProfileParameters(color: Color3)
+	{
+	    const cdf = 0.997;
+	    const maxScatteringDistance = Math.max(color.r, color.g, color.b);
+
+	    return this._sampleBurleyDiffusionProfile(cdf, maxScatteringDistance);
+	}
+
+	/**
+	 * Performs sampling of a Normalized Burley diffusion profile in polar coordinates.
+	 * 'u' is the random number (the value of the CDF): [0, 1).
+	 * rcp(s) = 1 / ShapeParam = ScatteringDistance.
+	 * Returns the sampled radial distance, s.t. (u = 0 -> r = 0) and (u = 1 -> r = Inf).
+	 */
+	private _sampleBurleyDiffusionProfile(u: number, rcpS: number)
+	{
+	    u = 1 - u; // Convert CDF to CCDF
+
+	    let g = 1 + (4 * u) * (2 * u + Math.sqrt(1 + (4 * u) * u));
+	    let n = Math.pow(g, -1.0 / 3.0);                      // g^(-1/3)
+	    let p = (g * n) * n;                                   // g^(+1/3)
+	    let c = 1 + p + n;                                     // 1 + g^(+1/3) + g^(-1/3)
+	    let x = 3 * Math.log(c / (4 * u));
+
+	    return x * rcpS;
+	}
+}