浏览代码

First draft

/main
Sebastien Lagarde 7 年前
当前提交
0cdbadfa
共有 7 个文件被更改,包括 57 次插入90 次删除
  1. 2
      ScriptableRenderPipeline/Core/ShaderLibrary/API/D3D11.hlsl
  2. 2
      ScriptableRenderPipeline/Core/ShaderLibrary/API/Metal.hlsl
  3. 2
      ScriptableRenderPipeline/Core/ShaderLibrary/API/PSSL.hlsl
  4. 2
      ScriptableRenderPipeline/Core/ShaderLibrary/API/Vulkan.hlsl
  5. 97
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  6. 42
      ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering/SubsurfaceScatteringUtilities.hlsl

2
ScriptableRenderPipeline/Core/ShaderLibrary/API/D3D11.hlsl


#define SAMPLERCUBE_SHADOW(samplerName) SamplerComparisonState samplerName
#define TEXTURE2D_ARGS(textureName, samplerName) Texture2D textureName, SamplerState samplerName
#define TEXTURE2D_ARGS_NOSAMPLER(textureName) Texture2D textureName
#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) Texture2DArray textureName, SamplerState samplerName
#define TEXTURECUBE_ARGS(textureName, samplerName) TextureCube textureName, SamplerState samplerName
#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) TextureCubeArray textureName, SamplerState samplerName

#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) TextureCube textureName, SamplerComparisonState samplerName
#define TEXTURE2D_PARAM(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_PARAM_NOSAMPLER(textureName) textureName
#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_PARAM(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) textureName, samplerName

2
ScriptableRenderPipeline/Core/ShaderLibrary/API/Metal.hlsl


#define SAMPLERCUBE_SHADOW(samplerName) SamplerComparisonState samplerName
#define TEXTURE2D_ARGS(textureName, samplerName) Texture2D textureName, SamplerState samplerName
#define TEXTURE2D_ARGS_NOSAMPLER(textureName) Texture2D textureName
#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) Texture2DArray textureName, SamplerState samplerName
#define TEXTURECUBE_ARGS(textureName, samplerName) TextureCube textureName, SamplerState samplerName
#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) TextureCubeArray textureName, SamplerState samplerName

#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) TextureCube textureName, SamplerComparisonState samplerName
#define TEXTURE2D_PARAM(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_PARAM_NOSAMPLER(textureName) textureName
#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_PARAM(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) textureName, samplerName

2
ScriptableRenderPipeline/Core/ShaderLibrary/API/PSSL.hlsl


#define SAMPLERCUBE_SHADOW(samplerName) SamplerComparisonState samplerName
#define TEXTURE2D_ARGS(textureName, samplerName) Texture2D textureName, SamplerState samplerName
#define TEXTURE2D_ARGS_NOSAMPLER(textureName) Texture2D textureName
#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) Texture2DArray textureName, SamplerState samplerName
#define TEXTURECUBE_ARGS(textureName, samplerName) TextureCube textureName, SamplerState samplerName
#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) TextureCubeArray textureName, SamplerState samplerName

#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) TextureCube textureName, SamplerComparisonState samplerName
#define TEXTURE2D_PARAM(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_PARAM_NOSAMPLER(textureName) textureName
#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_PARAM(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) textureName, samplerName

2
ScriptableRenderPipeline/Core/ShaderLibrary/API/Vulkan.hlsl


#define SAMPLERCUBE_SHADOW(samplerName) SamplerComparisonState samplerName
#define TEXTURE2D_ARGS(textureName, samplerName) Texture2D textureName, SamplerState samplerName
#define TEXTURE2D_ARGS_NOSAMPLER(textureName) Texture2D textureName
#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) Texture2DArray textureName, SamplerState samplerName
#define TEXTURECUBE_ARGS(textureName, samplerName) TextureCube textureName, SamplerState samplerName
#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) TextureCubeArray textureName, SamplerState samplerName

#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) TextureCube textureName, SamplerComparisonState samplerName
#define TEXTURE2D_PARAM(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_PARAM_NOSAMPLER(textureName) textureName
#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_PARAM(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) textureName, samplerName

97
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


// SurfaceData is define in Lit.cs which generate Lit.cs.hlsl
#include "Lit.cs.hlsl"
#include "SubsurfaceScatteringSettings.cs.hlsl"
#include "../SubsurfaceScattering/SubsurfaceScatteringUtilities.hlsl"
// Define refraction keyword helpers
#define HAS_REFRACTION (defined(_REFRACTION_PLANE) || defined(_REFRACTION_SPHERE))

# endif
#endif
// In case we pack data uint16 buffer we need to change the output render target format to uint16
// TODO: Is there a way to automate these output type based on the format declare in lit.cs ?
#if SHADEROPTIONS_PACK_GBUFFER_IN_U16
#define GBufferType0 uint4
#define GBufferType1 uint4
// TODO: How to abstract that ? We would like to avoid this PS4 test here
#ifdef SHADER_API_PSSL
// On PS4 we need to specify manually the format of the output render target, output type is not enough
#pragma PSSL_target_output_format(target 0 FMT_UINT16_ABGR)
#pragma PSSL_target_output_format(target 1 FMT_UINT16_ABGR)
#endif
#else
#endif
// GBuffer texture declaration
TEXTURE2D(_GBufferTexture0);

void EncodeIntoGBuffer( SurfaceData surfaceData,
float3 bakeDiffuseLighting,
uint2 positionSS,
#if SHADEROPTIONS_PACK_GBUFFER_IN_U16
out GBufferType0 outGBufferU0,
out GBufferType1 outGBufferU1
#else
#endif
#if SHADEROPTIONS_PACK_GBUFFER_IN_U16
float4 outGBuffer0, outGBuffer1, outGBuffer2, outGBuffer3;
#endif
ApplyDebugToSurfaceData(surfaceData);
// RT0 - 8:8:8:8 sRGB

}
else if (surfaceData.materialId == MATERIALID_LIT_SSS)
{
outGBuffer2 = float4(surfaceData.subsurfaceRadius, surfaceData.thickness, 0.0, PackByte(surfaceData.subsurfaceProfile));
outGBuffer2 = EncodeSSSDataToBuffer(surfaceData.baseColor, surfaceData.subsurfaceRadius, surfaceData.subsurfaceProfile, surfaceData.thickness, positionSS);
}
else if (surfaceData.materialId == MATERIALID_LIT_ANISO)
{

// Lighting
outGBuffer3 = float4(bakeDiffuseLighting, 0.0);
#if SHADEROPTIONS_PACK_GBUFFER_IN_U16
// Now pack all buffer into 2 uint buffer
// We don't have hardware sRGB to store base color in case we pack int u16, so rather than perform full sRGB encoding just use cheap gamma20
// TODO: test alternative like FastLinearToSRGB to better match unpacked gbuffer
outGBuffer0.xyz = LinearToGamma20(outGBuffer0.xyz);
uint packedGBuffer1 = PackR10G10B10A2(outGBuffer1);
outGBufferU0 = uint4( PackFloatToUInt(outGBuffer0.x, 8, 0) | PackFloatToUInt(outGBuffer0.y, 8, 8),
PackFloatToUInt(outGBuffer0.z, 8, 0) | PackFloatToUInt(outGBuffer0.w, 8, 8),
(packedGBuffer1 & 0x0000FFFF),
(packedGBuffer1 & 0xFFFF0000) >> 16);
uint packedGBuffer3 = PackToR11G11B10f(outGBuffer3.xyz);
outGBufferU1 = uint4( PackFloatToUInt(outGBuffer2.x, 8, 0) | PackFloatToUInt(outGBuffer2.y, 8, 8),
PackFloatToUInt(outGBuffer2.z, 8, 0) | PackFloatToUInt(outGBuffer2.w, 8, 8),
(packedGBuffer3 & 0x0000FFFF),
(packedGBuffer3 & 0xFFFF0000) >> 16);
#endif
}
float4 DecodeGBuffer0(GBufferType0 encodedGBuffer0)
{
float4 decodedGBuffer0;
#if SHADEROPTIONS_PACK_GBUFFER_IN_U16
decodedGBuffer0.x = UnpackUIntToFloat(encodedGBuffer0.x, 8, 0);
decodedGBuffer0.y = UnpackUIntToFloat(encodedGBuffer0.x, 8, 8);
decodedGBuffer0.z = UnpackUIntToFloat(encodedGBuffer0.y, 8, 0);
decodedGBuffer0.w = UnpackUIntToFloat(encodedGBuffer0.y, 8, 8);
decodedGBuffer0.xyz = Gamma20ToLinear(encodedGBuffer0.xyz);
#else
decodedGBuffer0 = encodedGBuffer0;
#endif
return decodedGBuffer0;
}
void DecodeFromGBuffer(

out float3 bakeDiffuseLighting)
{
#if SHADEROPTIONS_PACK_GBUFFER_IN_U16
GBufferType0 inGBufferU0 = LOAD_TEXTURE2D(_GBufferTexture0, positionSS);
GBufferType1 inGBufferU1 = LOAD_TEXTURE2D(_GBufferTexture1, positionSS);
#else
#endif
#if SHADEROPTIONS_PACK_GBUFFER_IN_U16
float4 inGBuffer0, inGBuffer1, inGBuffer2, inGBuffer3;
inGBuffer0 = DecodeGBuffer0(inGBufferU0);
uint packedGBuffer1 = inGBufferU0.z | inGBufferU0.w << 16;
inGBuffer1 = UnpackR10G10B10A2(packedGBuffer1);
inGBuffer2.x = UnpackUIntToFloat(inGBufferU1.x, 8, 0);
inGBuffer2.y = UnpackUIntToFloat(inGBufferU1.x, 8, 8);
inGBuffer2.z = UnpackUIntToFloat(inGBufferU1.y, 8, 0);
inGBuffer2.w = UnpackUIntToFloat(inGBufferU1.y, 8, 8);
uint packedGBuffer3 = inGBufferU1.z | inGBufferU1.w << 16;
inGBuffer3.xyz = UnpackFromR11G11B10f(packedGBuffer1);
inGBuffer3.w = 0.0;
#endif
float3 baseColor = inGBuffer0.rgb;
bsdfData.specularOcclusion = inGBuffer0.a;

}
else if (bsdfData.materialId == MATERIALID_LIT_SSS && HasMaterialFeatureFlag(MATERIALFEATUREFLAGS_LIT_SSS))
{
float subsurfaceRadius = inGBuffer2.x;
float thickness = inGBuffer2.y;
int subsurfaceProfile = UnpackByte(inGBuffer2.w);
float3 unusedColor; // We have already a base color, no need to retrieve the one from SSS
float subsurfaceRadius;
float thickness;
int subsurfaceProfile;
DecodeSSSDataFromBuffer(TEXTURE2D_PARAM_NOSAMPLER(_GBufferTexture2), positionSS, inGBuffer2, unusedColor, surfaceData.subsurfaceRadius, surfaceData.subsurfaceProfile, surfaceData.thickness);
FillMaterialIdSSSData(baseColor, subsurfaceProfile, subsurfaceRadius, thickness, bsdfData);
}
else if (bsdfData.materialId == MATERIALID_LIT_CLEAR_COAT && HasMaterialFeatureFlag(MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))

42
ScriptableRenderPipeline/HDRenderPipeline/Material/SubsurfaceScattering/SubsurfaceScatteringUtilities.hlsl


// 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));
}
正在加载...
取消
保存