Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export class SubSurfaceBlock extends NodeMaterialBlock {
NodeMaterialBlockTargets.Fragment,
new NodeMaterialConnectionPointCustomObject("refraction", this, NodeMaterialConnectionPointDirection.Input, RefractionBlock, "RefractionBlock")
);
this.registerInput("dispersion", NodeMaterialBlockConnectionPointTypes.Float, true, NodeMaterialBlockTargets.Fragment);

this.registerOutput(
"subsurface",
Expand All @@ -55,6 +56,7 @@ export class SubSurfaceBlock extends NodeMaterialBlock {
state._excludeVariableName("vThicknessParam");
state._excludeVariableName("vTintColor");
state._excludeVariableName("vSubSurfaceIntensity");
state._excludeVariableName("dispersion");
}

/**
Expand Down Expand Up @@ -100,6 +102,13 @@ export class SubSurfaceBlock extends NodeMaterialBlock {
return this._inputs[4];
}

/**
* Gets the dispersion input component
*/
public get dispersion(): NodeMaterialConnectionPoint {
return this._inputs[5];
}

/**
* Gets the sub surface object output component
*/
Expand Down Expand Up @@ -127,6 +136,7 @@ export class SubSurfaceBlock extends NodeMaterialBlock {
defines.setValue("SS_TRANSLUCENCYINTENSITY_TEXTURE", false, true);
defines.setValue("SS_MASK_FROM_THICKNESS_TEXTURE", false, true);
defines.setValue("SS_USE_GLTF_TEXTURES", false, true);
defines.setValue("SS_DISPERSION", this.dispersion.isConnected, true);
}

/**
Expand All @@ -151,6 +161,8 @@ export class SubSurfaceBlock extends NodeMaterialBlock {
const refractionIntensity = refractionBlock?.intensity.isConnected ? refractionBlock.intensity.associatedVariableName : "1.";
const refractionView = refractionBlock?.view.isConnected ? refractionBlock.view.associatedVariableName : "";

const dispersion = ssBlock?.dispersion.isConnected ? ssBlock?.dispersion.associatedVariableName : "0.0";

code += refractionBlock?.getCode(state) ?? "";

code += `subSurfaceOutParams subSurfaceOut;
Expand All @@ -159,7 +171,7 @@ export class SubSurfaceBlock extends NodeMaterialBlock {
vec2 vThicknessParam = vec2(0., ${thickness});
vec4 vTintColor = vec4(${tintColor}, ${refractionTintAtDistance});
vec3 vSubSurfaceIntensity = vec3(${refractionIntensity}, ${translucencyIntensity}, 0.);

float dispersion = ${dispersion};
subSurfaceBlock(
vSubSurfaceIntensity,
vThicknessParam,
Expand Down Expand Up @@ -231,6 +243,9 @@ export class SubSurfaceBlock extends NodeMaterialBlock {
vRefractionPosition,
vRefractionSize,
#endif
#ifdef SS_DISPERSION
dispersion,
#endif
#endif
#ifdef SS_TRANSLUCENCY
${translucencyDiffusionDistance},
Expand Down
20 changes: 20 additions & 0 deletions packages/dev/core/src/Materials/PBR/pbrSubSurfaceConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export class MaterialSubSurfaceDefines extends MaterialDefines {
public SS_TRANSLUCENCY = false;
public SS_TRANSLUCENCY_USE_INTENSITY_FROM_TEXTURE = false;
public SS_SCATTERING = false;
public SS_DISPERSION = false;

public SS_THICKNESSANDMASK_TEXTURE = false;
public SS_THICKNESSANDMASK_TEXTUREDIRECTUV = 0;
Expand Down Expand Up @@ -80,6 +81,14 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase {
@expandToProperty("_markAllSubMeshesAsTexturesDirty")
public isTranslucencyEnabled = false;

private _isDispersionEnabled = false;
/**
* Defines if dispersion is enabled in the material.
*/
@serialize()
@expandToProperty("_markAllSubMeshesAsTexturesDirty")
public isDispersionEnabled = false;

private _isScatteringEnabled = false;
/**
* Defines if the sub surface scattering is enabled in the material.
Expand Down Expand Up @@ -253,6 +262,12 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase {
@serialize()
public tintColorAtDistance = 1;

/**
* Defines the Abbe number for the volume.
*/
@serialize()
public dispersion = 0;

/**
* Defines how far each channel transmit through the media.
* It is defined as a color to simplify it selection.
Expand Down Expand Up @@ -354,6 +369,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase {
public prepareDefinesBeforeAttributes(defines: MaterialSubSurfaceDefines, scene: Scene): void {
if (!this._isRefractionEnabled && !this._isTranslucencyEnabled && !this._isScatteringEnabled) {
defines.SUBSURFACE = false;
defines.SS_DISPERSION = false;
defines.SS_TRANSLUCENCY = false;
defines.SS_SCATTERING = false;
defines.SS_REFRACTION = false;
Expand Down Expand Up @@ -385,6 +401,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase {
if (defines._areTexturesDirty) {
defines.SUBSURFACE = true;

defines.SS_DISPERSION = this._isDispersionEnabled;
defines.SS_TRANSLUCENCY = this._isTranslucencyEnabled;
defines.SS_TRANSLUCENCY_USE_INTENSITY_FROM_TEXTURE = false;
defines.SS_SCATTERING = this._isScatteringEnabled;
Expand Down Expand Up @@ -562,6 +579,8 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase {
uniformBuffer.updateFloat4("vTintColor", this.tintColor.r, this.tintColor.g, this.tintColor.b, Math.max(0.00001, this.tintColorAtDistance));

uniformBuffer.updateFloat3("vSubSurfaceIntensity", this.refractionIntensity, this.translucencyIntensity, 0);

uniformBuffer.updateFloat("dispersion", this.dispersion);
}

// Textures
Expand Down Expand Up @@ -715,6 +734,7 @@ export class PBRSubSurfaceConfiguration extends MaterialPluginBase {
{ name: "vRefractionPosition", size: 3, type: "vec3" },
{ name: "vRefractionSize", size: 3, type: "vec3" },
{ name: "scatteringDiffusionProfile", size: 1, type: "float" },
{ name: "dispersion", size: 1, type: "float" },
],
};
}
Expand Down
Loading