public const int SSS_NEUTRAL_PROFILE_ID = SSS_N_PROFILES - 1 ; // Does not result in blurring
public const int SSS_N_SAMPLES_NEAR_FIELD = 5 5 ; // Used for extreme close ups; must be a Fibonacci number
public const int SSS_N_SAMPLES_FAR_FIELD = 2 1 ; // Used at a regular distance; must be a Fibonacci number
public const int SSS_LOD_THRESHOLD = 4 ; // The LoD threshold of the near-field kernel (in pixels)
public const int SSS_TRSM_MODE_NONE = 0 ;
public const int SSS_TRSM_MODE_THIN = 1 ;
}
public enum TransmissionMode : uint { None = SssConstants . SSS_TRSM_MODE_NONE , ThinObject = SssConstants . SSS_TRSM_MODE_THIN , Regular } ;
public Color surfaceAlbedo ; // Color, 0 to 1
public Color volumeAlbedo ; // Color, 0 to 1
public float lenVolMeanFreePath ; // Length of the volume mean free path (in millimeters)
public TexturingMode texturingMode ;
public TransmissionMode transmissionMode ;
public SubsurfaceScatteringProfile ( )
{
surfaceAlbedo = Color . white ;
volumeAlbedo = Color . white ;
lenVolMeanFreePath = 0.5f ;
texturingMode = TexturingMode . PreAndPostScatter ;
transmissionMode = TransmissionMode . None ;
[NonSerialized] public uint transmissionFlags ; // 2 bit/profile; 0 = inf. thick, 1 = thin, 2 = regular
[NonSerialized] public float [ ] thicknessRemaps ; // Remap: 0 = start, 1 = end - start
[NonSerialized] public Vector4 [ ] shapeParameters ; // RGB = S = 1 / D, A = filter radius
[NonSerialized] public Vector4 [ ] surfaceAlbedos ; // RGB = color, A = unused
[NonSerialized] public Vector4 [ ] volumeAlbedos ; // RGB = color, A = unused
[NonSerialized] public float [ ] worldScales ; // Size of the world unit in meters
[NonSerialized] public float [ ] filterKernelsNearField ; // 0 = radius, 1 = reciprocal of the PDF
[NonSerialized] public float [ ] filterKernelsFarField ; // 0 = radius, 1 = reciprocal of the PDF
shapeParameters = new Vector4 [ shapeParametersLen ] ;
}
const int surfac eAlbedosLen = SssConstants . SSS_N_PROFILES ;
if ( surfac eAlbedos = = null | | surfac eAlbedos. Length ! = surfac eAlbedosLen)
const int volum eAlbedosLen = SssConstants . SSS_N_PROFILES ;
if ( volum eAlbedos = = null | | volum eAlbedos. Length ! = volum eAlbedosLen)
surfac eAlbedos = new Vector4 [ surfac eAlbedosLen] ;
volum eAlbedos = new Vector4 [ volum eAlbedosLen] ;
}
const int filterKernelsNearFieldLen = 2 * SssConstants . SSS_N_PROFILES * SssConstants . SSS_N_SAMPLES_NEAR_FIELD ;
worldScales [ i ] = profiles [ i ] . worldScale ;
shapeParameters [ i ] = profiles [ i ] . shapeParameter ;
shapeParameters [ i ] . w = profiles [ i ] . scatteringDistance ;
surfac eAlbedos[ i ] = profiles [ i ] . surfac eAlbedo;
volum eAlbedos[ i ] = profiles [ i ] . volum eAlbedo;
for ( int j = 0 , n = SssConstants . SSS_N_SAMPLES_NEAR_FIELD ; j < n ; j + + )
{
int i = SssConstants . SSS_NEUTRAL_PROFILE_ID ;
shapeParameters [ i ] = Vector4 . zero ;
surfac eAlbedos[ i ] = Vector4 . zero ;
volum eAlbedos[ i ] = Vector4 . zero ;
worldScales [ i ] = 1.0f ;
for ( int j = 0 , n = SssConstants . SSS_N_SAMPLES_NEAR_FIELD ; j < n ; j + + )
public readonly GUIContent sssTransmittancePreview1 = new GUIContent ( "Shows the fraction of light passing through the object for thickness values from the remap." ) ;
public readonly GUIContent sssTransmittancePreview2 = new GUIContent ( "Can be viewed as a cross section of a slab of material illuminated by white light from the left." ) ;
public readonly GUIContent sssProfileSurfaceAlbedo = new GUIContent ( "Surface Albedo" , "Color which determines the shape of the profile. Alpha is ignored." ) ;
public readonly GUIContent sssProfileVolumeAlbedo = new GUIContent ( "Volume Albedo" , "Color which tints transmitted light. Alpha is ignored." ) ;
public readonly GUIContent sssProfileLenVolMeanFreePath = new GUIContent ( "Volume Mean Free Path" , "The length of the volume mean free path (in millimeters) describes the average distance a photon travels within the volume before an extinction event occurs. Determines the effective radius of the filter." ) ;
public readonly GUIContent sssProfileScatteringDistance = new GUIContent ( "Scattering Distance" , "Effective radius of the filter (in millimeters). The blur is energy-preserving, so a wide filter results in a large area with small contributions of individual samples. Reducing the distance increases the sharpness of the result." ) ;
public readonly GUIContent sssTexturingMode = new GUIContent ( "Texturing Mode" , "Specifies when the diffuse texture should be applied." ) ;
private RenderTexture m_ProfileImage , m_TransmittanceImage ;
private Material m_ProfileMaterial , m_TransmittanceMaterial ;
private SerializedProperty m_LenVolMeanFreePath , m_ScatteringDistance , m_SurfaceAlbedo , m_S ,
private SerializedProperty m_LenVolMeanFreePath , m_ScatteringDistance , m_SurfaceAlbedo , m_VolumeAlbedo , m_S ,
m_VolumeAlbedo = serializedObject . FindProperty ( "volumeAlbedo" ) ;
m_LenVolMeanFreePath = serializedObject . FindProperty ( "lenVolMeanFreePath" ) ;
m_ScatteringDistance = serializedObject . FindProperty ( "m_ScatteringDistance" ) ;
m_S = serializedObject . FindProperty ( "m_S" ) ;
EditorGUI . BeginChangeCheck ( ) ;
{
EditorGUILayout . PropertyField ( m_SurfaceAlbedo , styles . sssProfileSurfaceAlbedo ) ;
EditorGUILayout . PropertyField ( m_SurfaceAlbedo , styles . sssProfileSurfaceAlbedo ) ;
m_LenVolMeanFreePath . floatValue = EditorGUILayout . Slider ( styles . sssProfileLenVolMeanFreePath , m_LenVolMeanFreePath . floatValue , 0.01f , 1.0f ) ;
GUI . enabled = false ;
m_TexturingMode . intValue = EditorGUILayout . Popup ( styles . sssTexturingMode , m_TexturingMode . intValue , styles . sssTexturingModeOptions ) ;
m_TransmissionMode . intValue = EditorGUILayout . Popup ( styles . sssProfileTransmissionMode , m_TransmissionMode . intValue , styles . sssTransmissionModeOptions ) ;
EditorGUILayout . PropertyField ( m_VolumeAlbedo , styles . sssProfileVolumeAlbedo ) ;
EditorGUILayout . PropertyField ( m_ThicknessRemap , styles . sssProfileMinMaxThickness ) ;
Vector2 thicknessRemap = m_ThicknessRemap . vector2Value ;
EditorGUILayout . MinMaxSlider ( styles . sssProfileThicknessRemap , ref thicknessRemap . x , ref thicknessRemap . y , 0.0f , 5 0.0f ) ;
float d = m_ScatteringDistance . floatValue ;
Vector4 A = m_SurfaceAlbedo . colorValue ;
Vector4 V = m_VolumeAlbedo . colorValue ;
bool transmissionEnabled = m_TransmissionMode . intValue ! = ( int ) SubsurfaceScatteringProfile . TransmissionMode . None ;
// Draw the profile.
m_ProfileMaterial . SetFloat ( "_ScatteringDistance" , d ) ;
EditorGUILayout . LabelField ( styles . sssTransmittancePreview2 , EditorStyles . centeredGreyMiniLabel ) ;
EditorGUILayout . Space ( ) ;
bool transmissionEnabled = m_TransmissionMode . intValue ! = ( int ) SubsurfaceScatteringProfile . TransmissionMode . None ;
m_TransmittanceMaterial . SetVector ( "_SurfaceAlbedo" , transmissionEnabled ? A : Vector4 . zero ) ;
m_TransmittanceMaterial . SetVector ( "_VolumeAlbedo" , transmissionEnabled ? V : Vector4 . zero ) ;
m_TransmittanceMaterial . SetVector ( "_ShapeParameter" , S ) ;
m_TransmittanceMaterial . SetVector ( "_ThicknessRemap" , R ) ;
EditorGUI . DrawPreviewTexture ( GUILayoutUtility . GetRect ( 1 6 , 1 6 ) , m_TransmittanceImage , m_TransmittanceMaterial , ScaleMode . ScaleToFit , 1 6.0f ) ;