Sebastien Lagarde
7 年前
当前提交
2d0640a5
共有 37 个文件被更改,包括 437 次插入 和 265 次删除
-
2ScriptableRenderPipeline/Core/ShaderLibrary/API/D3D11.hlsl
-
2ScriptableRenderPipeline/Core/ShaderLibrary/API/Metal.hlsl
-
2ScriptableRenderPipeline/Core/ShaderLibrary/API/PSSL.hlsl
-
2ScriptableRenderPipeline/Core/ShaderLibrary/API/Vulkan.hlsl
-
68ScriptableRenderPipeline/Core/ShaderLibrary/CommonMaterial.hlsl
-
35ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
-
9ScriptableRenderPipeline/HDRenderPipeline/HDStringConstants.cs
-
5ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader
-
5ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader
-
86ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
-
5ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader
-
5ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.shader
-
16ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.compute
-
17ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.shader
-
29ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/ShaderPassForward.hlsl
-
8ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering.meta
-
8ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering/Editor.meta
-
20ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering/SubsurfaceScattering.cs
-
11ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering/SubsurfaceScattering.cs.meta
-
225ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl
-
9ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl.meta
-
9ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering/SubsurfaceScatteringSettings.cs.hlsl.meta
-
11ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering/SubsurfaceScatteringSettings.cs.meta
-
11ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering/Editor/SubsurfaceScatteringSettingsEditor.Styles.cs.meta
-
11ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering/Editor/SubsurfaceScatteringSettingsEditor.cs.meta
-
13ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringSettingsEditor.Styles.cs.meta
-
13ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/SubsurfaceScatteringSettingsEditor.cs.meta
-
13ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringSettings.cs.meta
-
10ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringSettings.cs.hlsl.meta
-
42ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering/SubsurfaceScatteringUtilities.hlsl
-
0/ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering/Editor/SubsurfaceScatteringSettingsEditor.cs
-
0/ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering/Editor/SubsurfaceScatteringSettingsEditor.Styles.cs
-
0/ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering/SSSProfile.meta
-
0/ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering/SSSProfile
-
0/ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering/SubsurfaceScatteringSettings.cs
-
0/ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering/SubsurfaceScatteringSettings.cs.hlsl
|
|||
fileFormatVersion: 2 |
|||
guid: 25455a79ee8c96d4fb3ca2e64d8092e1 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: fb3f658c087068440b2c5063fc3abaed |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using UnityEngine.Rendering; |
|||
using System; |
|||
|
|||
namespace UnityEngine.Experimental.Rendering.HDPipeline |
|||
{ |
|||
public class SubsurfaceScatteringManager |
|||
{ |
|||
public const int k_MaxGbuffer = 2; |
|||
|
|||
public int sssbufferCount { get; set; } |
|||
|
|||
RenderTargetIdentifier[] m_ColorMRTs; |
|||
RenderTargetIdentifier[] m_RTIDs = new RenderTargetIdentifier[k_MaxGbuffer]; |
|||
|
|||
|
|||
// public RenderTargetIdentifier SSSBuffer[2];
|
|||
|
|||
// public SetSSSBuffer();
|
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 26e79cea58f13e241ba3ecee1a281ebc |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
#include "SubsurfaceScatteringSettings.cs.hlsl" |
|||
|
|||
CBUFFER_START(UnitySSSParameters) |
|||
// Warning: Unity is not able to losslessly transfer integers larger than 2^24 to the shader system. |
|||
// Therefore, we bitcast uint to float in C#, and bitcast back to uint in the shader. |
|||
uint _EnableSSSAndTransmission; // Globally toggles subsurface and transmission scattering on/off |
|||
float _TexturingModeFlags; // 1 bit/profile; 0 = PreAndPostScatter, 1 = PostScatter |
|||
float _TransmissionFlags; // 2 bit/profile; 0 = inf. thick, 1 = thin, 2 = regular |
|||
// Old SSS Model >>> |
|||
uint _UseDisneySSS; |
|||
float4 _HalfRcpVariancesAndWeights[SSS_N_PROFILES][2]; // 2x Gaussians in RGB, A is interpolation weights |
|||
// <<< Old SSS Model |
|||
// Use float4 to avoid any packing issue between compute and pixel shaders |
|||
float4 _ThicknessRemaps[SSS_N_PROFILES]; // R: start, G = end - start, BA unused |
|||
float4 _ShapeParams[SSS_N_PROFILES]; // RGB = S = 1 / D, A = filter radius |
|||
float4 _TransmissionTints[SSS_N_PROFILES]; // RGB = 1/4 * color, A = unused |
|||
CBUFFER_END |
|||
|
|||
// Subsurface scattering constant |
|||
#define SSS_WRAP_ANGLE (PI/12) // 15 degrees |
|||
#define SSS_WRAP_LIGHT cos(PI/2 - SSS_WRAP_ANGLE) |
|||
|
|||
// ---------------------------------------------------------------------------- |
|||
// SSS/Transmittance helper |
|||
// ---------------------------------------------------------------------------- |
|||
|
|||
// Computes the fraction of light passing through the object. |
|||
// Evaluate Int{0, inf}{2 * Pi * r * R(sqrt(r^2 + d^2))}, where R is the diffusion profile. |
|||
// Note: 'volumeAlbedo' should be premultiplied by 0.25. |
|||
// Ref: Approximate Reflectance Profiles for Efficient Subsurface Scattering by Pixar (BSSRDF only). |
|||
float3 ComputeTransmittanceDisney(float3 S, float3 volumeAlbedo, float thickness, float radiusScale) |
|||
{ |
|||
// Thickness and SSS radius are decoupled for artists. |
|||
// In theory, we should modify the thickness by the inverse of the radius scale of the profile. |
|||
// thickness /= radiusScale; |
|||
|
|||
#if 0 |
|||
float3 expOneThird = exp(((-1.0 / 3.0) * thickness) * S); |
|||
#else |
|||
// Help the compiler. |
|||
float k = (-1.0 / 3.0) * LOG2_E; |
|||
float3 p = (k * thickness) * S; |
|||
float3 expOneThird = exp2(p); |
|||
#endif |
|||
|
|||
// Premultiply & optimize: T = (1/4 * A) * (e^(-t * S) + 3 * e^(-1/3 * t * S)) |
|||
return volumeAlbedo * (expOneThird * expOneThird * expOneThird + 3 * expOneThird); |
|||
} |
|||
|
|||
// Evaluates transmittance for a linear combination of two normalized 2D Gaussians. |
|||
// Ref: Real-Time Realistic Skin Translucency (2010), equation 9 (modified). |
|||
// Note: 'volumeAlbedo' should be premultiplied by 0.25, correspondingly 'lerpWeight' by 4, |
|||
// and 'halfRcpVariance1' should be prescaled by (0.1 * SssConstants.SSS_BASIC_DISTANCE_SCALE)^2. |
|||
float3 ComputeTransmittanceJimenez(float3 halfRcpVariance1, float lerpWeight1, |
|||
float3 halfRcpVariance2, float lerpWeight2, |
|||
float3 volumeAlbedo, float thickness, float radiusScale) |
|||
{ |
|||
// Thickness and SSS radius are decoupled for artists. |
|||
// In theory, we should modify the thickness by the inverse of the radius scale of the profile. |
|||
// thickness /= radiusScale; |
|||
|
|||
float t2 = thickness * thickness; |
|||
|
|||
// T = A * lerp(exp(-t2 * halfRcpVariance1), exp(-t2 * halfRcpVariance2), lerpWeight2) |
|||
return volumeAlbedo * (exp(-t2 * halfRcpVariance1) * lerpWeight1 + exp(-t2 * halfRcpVariance2) * lerpWeight2); |
|||
} |
|||
|
|||
// Ref: Steve McAuley - Energy-Conserving Wrapped Diffuse |
|||
float ComputeWrappedDiffuseLighting(float NdotL, float w) |
|||
{ |
|||
return saturate((NdotL + w) / ((1 + w) * (1 + w))); |
|||
} |
|||
|
|||
// In order to support subsurface scattering, we need to know which pixels have an SSS material. |
|||
// It can be accomplished by reading the stencil buffer. |
|||
// A faster solution (which avoids an extra texture fetch) is to simply make sure that |
|||
// all pixels which belong to an SSS material are not black (those that don't always are). |
|||
// We choose the blue color channel since it's perceptually the least noticeable. |
|||
float3 TagLightingForSSS(float3 subsurfaceLighting) |
|||
{ |
|||
subsurfaceLighting.b = max(subsurfaceLighting.b, HALF_MIN); |
|||
return subsurfaceLighting; |
|||
} |
|||
|
|||
// See TagLightingForSSS() for details. |
|||
bool TestLightingForSSS(float3 subsurfaceLighting) |
|||
{ |
|||
return subsurfaceLighting.b > 0; |
|||
} |
|||
|
|||
// Returns the modified albedo (diffuse color) for materials with subsurface scattering. |
|||
// Ref: Advanced Techniques for Realistic Real-Time Skin Rendering. |
|||
float3 ApplyDiffuseTexturingMode(float3 color, bool isSSSMaterial, int subsurfaceProfile) |
|||
{ |
|||
float3 albedo = color; |
|||
|
|||
if (isSSSMaterial) |
|||
{ |
|||
#if defined(SHADERPASS) && (SHADERPASS == SHADERPASS_SUBSURFACE_SCATTERING) |
|||
// If the SSS pass is executed, we know we have SSS enabled. |
|||
bool enableSssAndTransmission = true; |
|||
#else |
|||
bool enableSssAndTransmission = _EnableSSSAndTransmission != 0; |
|||
#endif |
|||
|
|||
if (enableSssAndTransmission) |
|||
{ |
|||
bool performPostScatterTexturing = IsBitSet(asuint(_TexturingModeFlags), subsurfaceProfile); |
|||
|
|||
if (performPostScatterTexturing) |
|||
{ |
|||
// Post-scatter texturing mode: the albedo is only applied during the SSS pass. |
|||
#if !defined(SHADERPASS) || (SHADERPASS != SHADERPASS_SUBSURFACE_SCATTERING) |
|||
albedo = float3(1, 1, 1); |
|||
#endif |
|||
} |
|||
else |
|||
{ |
|||
// Pre- and post- scatter texturing mode. |
|||
albedo = sqrt(albedo); |
|||
} |
|||
} |
|||
} |
|||
|
|||
return albedo; |
|||
} |
|||
|
|||
// ---------------------------------------------------------------------------- |
|||
// Encoding/decoding SSS buffer functions |
|||
// ---------------------------------------------------------------------------- |
|||
|
|||
struct SSSData |
|||
{ |
|||
float3 diffuseColor; |
|||
float subsurfaceRadius; |
|||
float subsurfaceProfile; |
|||
}; |
|||
|
|||
//#define USE_COMPACT_SSS_BUFFER |
|||
|
|||
#ifdef USE_COMPACT_SSS_BUFFER |
|||
|
|||
// SSSBuffer texture declaration |
|||
TEXTURE2D(_SSSBufferTexture0); |
|||
|
|||
void EncodeIntoSSSBuffer(SSSData sssData, uint2 positionSS, out SSSBufferType0 outSSSBuffer0) |
|||
{ |
|||
// RGBToYCoCg have better precision with a sRGB color, use cheap gamma 2 instead |
|||
// Take care that the render target use linear format |
|||
float3 YCoCg = RGBToYCoCg(LinearToGamma20(sssData.diffuseColor)); |
|||
|
|||
// Note: when we are in forward we don't need to store the thickness as it is already apply. So a potential optimization |
|||
// when we know that we are in full forward only is to not store the thickness and store the full baseColor (so not cost at decode) |
|||
// as this function aim to be share between hybrid deferred/forward, we can't assume it. |
|||
|
|||
// subsurfaceRadius is like a mask (a bit like metal parameters and don't need a lot of precision, store it on 4 bit |
|||
// currently we support up to 16 SSS profile (SSS_N_PROFILES) - caution if this number change (for a higher value), code below must change! |
|||
outSSSBuffer0 = float4((positionSS.x & 1) == (positionSS.y & 1) ? YCoCg.rb : YCoCg.rg, PackFloatInt8bit(sssData.subsurfaceRadius, sssData.subsurfaceProfile, 16.0), 0.0); |
|||
} |
|||
|
|||
void DecodeSSSProfileFromSSSBuffer(SSSBufferType0 inSSSBuffer0, uint2 positionSS, out int subsurfaceProfile) |
|||
{ |
|||
float unused; |
|||
UnpackFloatInt8bit(inSSSBuffer0.b, 16.0, unused, subsurfaceProfile); |
|||
} |
|||
|
|||
void DecodeFromSSSBuffer(uint2 positionSS, out SSSData sssData) |
|||
{ |
|||
// unpack |
|||
float4 inBuffer = LOAD_TEXTURE2D(_SSSBufferTexture0, positionSS); |
|||
float2 YChroma0 = inBuffer.rg; |
|||
UnpackFloatInt8bit(inBuffer.b, 16.0, sssData.subsurfaceRadius, sssData.subsurfaceProfile); |
|||
// Note: nothing in a, reserved for thickness in case of GBuffer rendering |
|||
|
|||
// Reconstruct color |
|||
// Note: We don't care about pixel at border, will be handled by the edge filter (as it will be black) |
|||
float2 a0 = LOAD_TEXTURE2D(_SSSBufferTexture0, positionSS + uint2(1, 0)).rg; |
|||
float2 a1 = LOAD_TEXTURE2D(_SSSBufferTexture0, positionSS - uint2(1, 0)).rg; |
|||
float2 a2 = LOAD_TEXTURE2D(_SSSBufferTexture0, positionSS + uint2(0, 1)).rg; |
|||
float2 a3 = LOAD_TEXTURE2D(_SSSBufferTexture0, positionSS - uint2(0, 1)).rg; |
|||
float chroma1 = YCoCgCheckBoardEdgeFilter(YChroma0.r, a0, a1, a2, a3); |
|||
float3 YCoCg = (positionSS.x & 1) == (positionSS.y & 1) ? float3(YChroma0.r, chroma1, YChroma0.g) : float3(YChroma0.rg, chroma1); |
|||
sssData.diffuseColor = Gamma20ToLinear(YCoCgToRGB(YCoCg)); |
|||
} |
|||
|
|||
#define OUTPUT_SSSBUFFER(NAME) out GBufferType0 MERGE_NAME(NAME, 0) : SV_Target0 |
|||
#define ENCODE_INTO_SSSBUFFER(SURFACE_DATA, UNPOSITIONSS, NAME) EncodeIntoSSSBuffer(SURFACE_DATA, UNPOSITIONSS, MERGE_NAME(NAME, 0)) |
|||
|
|||
#else |
|||
|
|||
// SSSBuffer texture declaration |
|||
TEXTURE2D(_SSSBufferTexture0); |
|||
TEXTURE2D(_SSSBufferTexture1); |
|||
|
|||
void EncodeIntoSSSBuffer(SSSData sssData, uint2 positionSS, out SSSBufferType0 outSSSBuffer0, out SSSBufferType1 outSSSBuffer1) |
|||
{ |
|||
outSSSBuffer0 = float4(0.0, sssData.subsurfaceRadius, PackByte(sssData.subsurfaceProfile), 0.0); |
|||
outSSSBuffer1 = float4(sssData.diffuseColor, 0.0); |
|||
} |
|||
|
|||
void DecodeSSSProfileFromSSSBuffer(SSSBufferType0 inSSSBuffer0, uint2 positionSS, out int subsurfaceProfile) |
|||
{ |
|||
subsurfaceProfile = UnpackByte(inSSSBuffer0.b); |
|||
} |
|||
|
|||
void DecodeFromSSSBuffer(uint2 positionSS, out SSSData sssData) |
|||
{ |
|||
// unpack |
|||
float4 inBuffer = LOAD_TEXTURE2D(_SSSBufferTexture0, positionSS); |
|||
sssData.subsurfaceRadius = inBuffer.g; |
|||
sssData.subsurfaceProfile = UnpackByte(inBuffer.b); |
|||
// Note: nothing in a, reserved for thickness in case of GBuffer rendering |
|||
|
|||
sssData.diffuseColor = LOAD_TEXTURE2D(_SSSBufferTexture1, positionSS).rgb; |
|||
} |
|||
|
|||
#define OUTPUT_SSSBUFFER(NAME) \ |
|||
out GBufferType0 MERGE_NAME(NAME, 0) : SV_Target0, \ |
|||
out GBufferType1 MERGE_NAME(NAME, 1) : SV_Target1 |
|||
|
|||
#define ENCODE_INTO_SSSBUFFER(SURFACE_DATA, UNPOSITIONSS, NAME) EncodeIntoSSSBuffer(ConvertSurfaceDataToSSSData(SURFACE_DATA), UNPOSITIONSS, MERGE_NAME(NAME, 0), MERGE_NAME(NAME, 1)) |
|||
|
|||
#endif |
|||
|
|||
#define DECODE_FROM_SSSBUFFER(UNPOSITIONSS, SSS_DATA) DecodeFromSSSBuffer(UNPOSITIONSS, SSS_DATA) |
|
|||
fileFormatVersion: 2 |
|||
guid: a9f89d53a380e274590d02ddfabce53e |
|||
ShaderImporter: |
|||
externalObjects: {} |
|||
defaultTextures: [] |
|||
nonModifiableTextures: [] |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: a68623b64163f324da6b52463c8a8aa7 |
|||
ShaderImporter: |
|||
externalObjects: {} |
|||
defaultTextures: [] |
|||
nonModifiableTextures: [] |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: b2686e09ec7aef44bad2843e4416f057 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 4073853f945109f47901ba54281a18af |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 5fbf42188568d5247aae2304fc8c805e |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 95517c3b2f4a014468289c3f5eb6d03c |
|||
timeCreated: 1507562538 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: a61a2437dcee4e54393f8f65ccf726ab |
|||
timeCreated: 1507562486 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 3418a08abd15e9a49af3ccbc9e15b5ea |
|||
timeCreated: 1507538042 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 86fe0068e2ac49e4d99882aaa40fa522 |
|||
timeCreated: 1507935155 |
|||
licenseType: Pro |
|||
ShaderImporter: |
|||
externalObjects: {} |
|||
defaultTextures: [] |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
// To use in case the color have already been encoded in checkboard YCoCg |
|||
float4 EncodeSSSDataToBuffer(float2 Ychroma, float subsurfaceRadius, uint subsurfaceProfile, float thickness) |
|||
{ |
|||
// subsurfaceRadius is like a mask (a bit like metal parameters and don't need a lot of precision, store it on 4 bit |
|||
// currently we support up to 16 SSS profile (SSS_N_PROFILES) - caution if this number change (for a higher value), code below must change! |
|||
return float4(Ychroma, thickness, PackFloatInt8bit(subsurfaceRadius, subsurfaceProfile, 16.0)); |
|||
} |
|||
|
|||
// This function encode all data require for ScreenSpace SubsurfaceScattering (SSSSS) |
|||
// Aim to be use with a GBuffer |
|||
float4 EncodeSSSDataToBuffer(float3 color, float subsurfaceRadius, uint subsurfaceProfile, float thickness, uint2 positionSS) |
|||
{ |
|||
// RGBToYCoCg have better precision with a sRGB color, use cheap gamma 2 instead |
|||
// Take care that the render target use linear format |
|||
float3 YCoCg = RGBToYCoCg(LinearToGamma20(color)); |
|||
|
|||
// Note: when we are in forward we don't need to store the thickness as it is already apply. So a potential optimization |
|||
// when we know that we are in full forward only is to not store the thickness and store the full baseColor (so not cost at decode) |
|||
// as this function aim to be share between hybrid deferred/forward, we can't assume it. |
|||
|
|||
// subsurfaceRadius is like a mask (a bit like metal parameters and don't need a lot of precision, store it on 4 bit |
|||
// currently we support up to 16 SSS profile (SSS_N_PROFILES) - caution if this number change (for a higher value), code below must change! |
|||
return EncodeSSSDataToBuffer((positionSS.x & 1) == (positionSS.y & 1) ? YCoCg.rb : YCoCg.rg, subsurfaceRadius, thickness, subsurfaceProfile, thickness); |
|||
} |
|||
|
|||
float4 DecodeSSSDataFromBuffer(TEXTURE2D_ARGS_NOSAMPLER(SSSBuffer), uint2 positionSS, float4 inBuffer, out float3 color, out float subsurfaceRadius, out int subsurfaceProfileout, out float thickness) |
|||
{ |
|||
// unpack |
|||
float2 YChroma0 = inBuffer.rg; |
|||
thickness = inBuffer.b; |
|||
UnpackFloatInt8bit(inBuffer.a, 16.0, subsurfaceRadius, subsurfaceProfile); |
|||
|
|||
// Reconstruct color |
|||
// Note: We don't care about pixel at border, will be handled by the edge filter (as it will be black) |
|||
float2 a0 = LOAD_TEXTURE2D(SSSBuffer, positionSS + uint2(1, 0)).rg; |
|||
float2 a1 = LOAD_TEXTURE2D(SSSBuffer, positionSS - uint2(1, 0)).rg; |
|||
float2 a2 = LOAD_TEXTURE2D(SSSBuffer, positionSS + uint2(0, 1)).rg; |
|||
float2 a3 = LOAD_TEXTURE2D(SSSBuffer, positionSS - uint2(0, 1)).rg; |
|||
float chroma1 = YCoCgCheckBoardEdgeFilter(YChroma0.r, a0, a1, a2, a3); |
|||
float3 YCoCg = (positionSS.x & 1) == (positionSS.y & 1) ? float3(YChroma0.r, chroma1, YChroma0.g) : float3(YChroma0.rg, chroma1); |
|||
color = Gamma20ToLinear(YCoCgToRGB(YCoCg)); |
|||
} |
撰写
预览
正在加载...
取消
保存
Reference in new issue