浏览代码

HDRenderLoop: Add shadow.hlsl - refine design of shadowmap (not working yet)

/main
Sebastien Lagarde 8 年前
当前提交
55ac2b41
共有 8 个文件被更改,包括 111 次插入83 次删除
  1. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  2. 21
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/Shadow.hlsl
  3. 8
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/ShadowDefinition.cs
  4. 21
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/ShadowDefinition.cs.hlsl
  5. 13
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/SinglePass/SinglePass.hlsl
  6. 59
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/Lit.hlsl
  7. 61
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Material.hlsl
  8. 2
      Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl

9
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


for (int sliceIndex = 0; sliceIndex < shadowOutput.GetShadowSliceCountLightIndex(lightIndex); ++sliceIndex)
{
var shadowSliceIndex = shadowOutput.GetShadowSliceIndex(lightIndex, sliceIndex);
Matrix4x4 worldToShadow = shadowOutput.shadowSlices[shadowSliceIndex].shadowTransform.transpose;
s.worldToShadow0 = worldToShadow.GetRow(0);
s.worldToShadow1 = worldToShadow.GetRow(1);
s.worldToShadow2 = worldToShadow.GetRow(2);
s.worldToShadow3 = worldToShadow.GetRow(3);
int shadowSliceIndex = shadowOutput.GetShadowSliceIndex(lightIndex, sliceIndex);
s.worldToShadow = shadowOutput.shadowSlices[shadowSliceIndex].shadowTransform.transpose; // Transpose to go from ShadowToWorld to WorldToShadow
if (light.lightType == LightType.Spot)
{

21
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/Shadow.hlsl


//-----------------------------------------------------------------------------
// Shadow
// Ref: https://mynameismjp.wordpress.com/2015/02/18/shadow-sample-update/
//-------------------------------------------------------------------------------------------------
// Calculates the offset to use for sampling the shadow map, based on the surface normal
//-------------------------------------------------------------------------------------------------
float3 GetShadowPosOffset(float NdotL, float3 normalWS, float2 invShadowMapSize)
{
float texelSize = 2.0 * invShadowMapSize.x;
float offsetScaleNormalize = saturate(1.0 - NdotL);
// return texelSize * OffsetScale * offsetScaleNormalize * normalWS;
return texelSize * offsetScaleNormalize * normalWS;
}
// TODO: implement various algorithm
// GetShadowAttenuation is the "default" algorithm use, material can code explicitely a particular algorithm if required.
// TODO: how this work related to shadow format ?
float GetShadowAttenuation(LightLoopContext lightLoopContext, int index, float3 shadowCoord, float3 shadowPosDX, float3 shadowPosDY, float2 unPositionSS)
{
// TODO: How to support a Gather sampling with such abstraction...
return SampleShadowCompare(lightLoopContext, index, shadowCoord);
}

8
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/ShadowDefinition.cs


{
// World to ShadowMap matrix
// Include scale and bias for shadow atlas if any
public Vector4 worldToShadow0;
public Vector4 worldToShadow1;
public Vector4 worldToShadow2;
public Vector4 worldToShadow3;
public Matrix4x4 worldToShadow;
public Vector3 unused;
public float bias;
public Vector2 unused;
};
} // namespace UnityEngine.Experimental.ScriptableRenderLoop

21
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/ShadowDefinition.cs.hlsl


// PackingRules = Exact
struct PunctualShadowData
{
float4 worldToShadow0;
float4 worldToShadow1;
float4 worldToShadow2;
float4 worldToShadow3;
float4x4 worldToShadow;
int shadowType;
float3 unused;
};

//
float4 GetWorldToShadow0(PunctualShadowData value)
float4x4 GetWorldToShadow(PunctualShadowData value)
return value.worldToShadow0;
}
float4 GetWorldToShadow1(PunctualShadowData value)
{
return value.worldToShadow1;
}
float4 GetWorldToShadow2(PunctualShadowData value)
{
return value.worldToShadow2;
}
float4 GetWorldToShadow3(PunctualShadowData value)
{
return value.worldToShadow3;
return value.worldToShadow;
}
int GetShadowType(PunctualShadowData value)
{

13
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/SinglePass/SinglePass.hlsl


// Use texture atlas for shadow map
StructuredBuffer<PunctualShadowData> _PunctualShadowList;
float4x4 GetShadowTransform(LightLoopContext lightLoopContext, int index, float3 L)
float3 GetShadowTextureCoordinate(LightLoopContext lightLoopContext, int index, float3 positionWS, float3 L)
{
int faceIndex;
if (_PunctualShadowList[index].shadowType == SHADOWTYPE_POINT)

int fetchIndex = index + faceIndex;
return float4x4(_PunctualShadowList[fetchIndex].worldToShadow0, _PunctualShadowList[fetchIndex].worldToShadow1, _PunctualShadowList[fetchIndex].worldToShadow2, _PunctualShadowList[fetchIndex].worldToShadow3);
// Note: scale and bias of shadow atlas are included in ShadowTransform
float4x4 shadowTransform = _PunctualShadowList[index + faceIndex].worldToShadow;
float4 positionTXS = mul(float4(positionWS, 1.0), shadowTransform);
return positionTXS.xyz / positionTXS.w;
float4 SampleShadowCompare(LightLoopContext lightLoopContext, int index, float3 texCoord)
float SampleShadowCompare(LightLoopContext lightLoopContext, int index, float3 texCoord)
{
// if (lightLoopContext.sampleShadow == SINGLE_PASS_CONTEXT_SAMPLE_SHADOWATLAS)
{

}
/*
float4 SampleShadow(LightLoopContext lightLoopContext, int index, float2 texCoord)
float SampleShadow(LightLoopContext lightLoopContext, int index, float2 texCoord)
{
if (lightLoopContext.sampleShadow == SINGLE_PASS_CONTEXT_SAMPLE_SHADOWATLAS)
{

59
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/Lit.hlsl


// area light
float3x3 minV;
float ltcGGXMagnitude;
// Shadow (sampling rotation disc)
float2 unPositionSS;
};
PreLightData GetPreLightData(float3 V, float3 positionWS, Coordinate coord, BSDFData bsdfData)

preLightData.ltcGGXMagnitude = UNITY_SAMPLE_TEX2D_LOD(_LtcGGXMagnitude, uv, 0).w;
// Shadow
preLightData.unPositionSS = coord.unPositionSS;
return preLightData;
}

// GetBakedDiffuseLigthing function compute the bake lighting + emissive color to be store in emissive buffer (Deferred case)
// In forward it must be add to the final contribution.
// This function require the 3 structure surfaceData, builtinData, bsdfData because it may require both the engine side data, and data that will not be store inside the gbuffer.
float3 GetBakedDiffuseLigthing(PreLightData prelightData, SurfaceData surfaceData, BuiltinData builtinData, BSDFData bsdfData)
float3 GetBakedDiffuseLigthing(PreLightData preLightData, SurfaceData surfaceData, BuiltinData builtinData, BSDFData bsdfData)
return builtinData.bakeDiffuseLighting * prelightData.diffuseFGD * surfaceData.ambientOcclusion * bsdfData.diffuseColor + builtinData.emissiveColor * builtinData.emissiveIntensity;
return builtinData.bakeDiffuseLighting * preLightData.diffuseFGD * surfaceData.ambientOcclusion * bsdfData.diffuseColor + builtinData.emissiveColor * builtinData.emissiveIntensity;
}
//-----------------------------------------------------------------------------

// BSDF share between area light (reference) and punctual light
//-----------------------------------------------------------------------------
void BSDF( float3 V, float3 L, float3 positionWS, PreLightData prelightData, BSDFData bsdfData,
void BSDF( float3 V, float3 L, float3 positionWS, PreLightData preLightData, BSDFData bsdfData,
out float3 diffuseLighting,
out float3 specularLighting)
{

float BdotL = saturate(dot(bsdfData.bitangentWS, L));
#ifdef USE_BSDF_PRE_LAMBDAV
Vis = V_SmithJointGGXAnisoLambdaV( prelightData.TdotV, prelightData.BdotV, prelightData.NdotV, TdotL, BdotL, NdotL,
bsdfData.roughnessT, bsdfData.roughnessB, prelightData.anisoGGXlambdaV);
Vis = V_SmithJointGGXAnisoLambdaV( preLightData.TdotV, preLightData.BdotV, preLightData.NdotV, TdotL, BdotL, NdotL,
bsdfData.roughnessT, bsdfData.roughnessB, preLightData.anisoGGXlambdaV);
Vis = V_SmithJointGGXAniso( prelightData.TdotV, prelightData.BdotV, prelightData.NdotV, TdotL, BdotL, NdotL,
Vis = V_SmithJointGGXAniso( preLightData.TdotV, preLightData.BdotV, preLightData.NdotV, TdotL, BdotL, NdotL,
bsdfData.roughnessT, bsdfData.roughnessB);
#endif

else
{
#ifdef USE_BSDF_PRE_LAMBDAV
Vis = V_SmithJointGGX(NdotL, prelightData.NdotV, bsdfData.roughness, prelightData.ggxLambdaV);
Vis = V_SmithJointGGX(NdotL, preLightData.NdotV, bsdfData.roughness, preLightData.ggxLambdaV);
Vis = V_SmithJointGGX(NdotL, prelightData.NdotV, bsdfData.roughness);
Vis = V_SmithJointGGX(NdotL, preLightData.NdotV, bsdfData.roughness);
#endif
D = D_GGXDividePI(NdotH, bsdfData.roughness);
}

#else
float diffuseTerm = DisneyDiffuseDividePI(prelightData.NdotV, NdotL, LdotH, bsdfData.perceptualRoughness);
float diffuseTerm = DisneyDiffuseDividePI(preLightData.NdotV, NdotL, LdotH, bsdfData.perceptualRoughness);
#endif
diffuseLighting.rgb = bsdfData.diffuseColor * diffuseTerm;
}

//-----------------------------------------------------------------------------
void EvaluateBSDF_Punctual( LightLoopContext lightLoopContext,
float3 V, float3 positionWS, PreLightData prelightData, PunctualLightData lightData, BSDFData bsdfData,
float3 V, float3 positionWS, PreLightData preLightData, PunctualLightData lightData, BSDFData bsdfData,
out float4 diffuseLighting,
out float4 specularLighting)
{

const bool hasShadow = (lightData.flags & LIGHTFLAGS_HAS_SHADOW) != 0;
[branch] if (hasShadow && illuminance > 0.0f)
{
float4x4 shadowTransform = GetShadowTransform(lightLoopContext, lightData.shadowIndex, L);
float4 positionHS = mul(float4(positionWS, 1), shadowTransform);
float shadowAttenuation = 1; // GetShadowAttenuation(shadowTransform, positionHS.xyz / positionHS.w);
// Apply offset
float3 offset = float3(0.0, 0.0, 0.0); // GetShadowPosOffset(nDotL, normal);
float3 shadowCoord = GetShadowTextureCoordinate(lightLoopContext, lightData.shadowIndex, positionWS + offset, L);
// Caution: formula doesn't work as we are texture atlas...
// if (max3(abs(NDC.x), abs(NDC.y), 1.0f - texCoordXYZ.z) <= 1.0f) return 1.0;
float3 shadowPosDX = ddx_fine(shadowCoord);
float3 shadowPosDY = ddy_fine(shadowCoord);
float shadowAttenuation = GetShadowAttenuation(lightLoopContext, lightData.shadowIndex, shadowCoord, shadowPosDX, shadowPosDY, preLightData.unPositionSS);
if (illuminance > 0.0f)
[branch] if (illuminance > 0.0f)
BSDF(V, L, positionWS, prelightData, bsdfData, diffuseLighting.rgb, specularLighting.rgb);
BSDF(V, L, positionWS, preLightData, bsdfData, diffuseLighting.rgb, specularLighting.rgb);
diffuseLighting.rgb *= lightData.color * illuminance * lightData.diffuseScale;
specularLighting.rgb *= lightData.color * illuminance * lightData.specularScale;
}

// EvaluateBSDF_Area - Reference
//-----------------------------------------------------------------------------
void IntegrateGGXAreaRef( float3 V, float3 positionWS, PreLightData prelightData, AreaLightData lightData, BSDFData bsdfData,
void IntegrateGGXAreaRef( float3 V, float3 positionWS, PreLightData preLightData, AreaLightData lightData, BSDFData bsdfData,
out float4 diffuseLighting,
out float4 specularLighting,
uint sampleCount = 512)

if (illuminance > 0.0)
{
BSDF(V, L, positionWS, prelightData, bsdfData, localDiffuseLighting, localSpecularLighting);
BSDF(V, L, positionWS, preLightData, bsdfData, localDiffuseLighting, localSpecularLighting);
localDiffuseLighting *= lightData.color * illuminance * lightData.diffuseScale;
localSpecularLighting *= lightData.color * illuminance * lightData.specularScale;
}

//-----------------------------------------------------------------------------
void EvaluateBSDF_Area( LightLoopContext lightLoopContext,
float3 V, float3 positionWS, PreLightData prelightData, AreaLightData lightData, BSDFData bsdfData,
float3 V, float3 positionWS, PreLightData preLightData, AreaLightData lightData, BSDFData bsdfData,
IntegrateGGXAreaRef(V, positionWS, prelightData, lightData, bsdfData, diffuseLighting, specularLighting);
IntegrateGGXAreaRef(V, positionWS, preLightData, lightData, bsdfData, diffuseLighting, specularLighting);
#else
// TODO: This could be precomputed

specularLighting = float4(0.0f, 0.0f, 0.0f, 1.0f);
// TODO: Fresnel is missing here but should be present
specularLighting.rgb = LTCEvaluate(V, bsdfData.normalWS, prelightData.minV, L, lightData.twoSided) * prelightData.ltcGGXMagnitude;
specularLighting.rgb = LTCEvaluate(V, bsdfData.normalWS, preLightData.minV, L, lightData.twoSided) * preLightData.ltcGGXMagnitude;
//#ifdef DIFFUSE_LAMBERT_BRDF
// Lambert diffuse term (here it should be Disney)

// _preIntegratedFGD and _CubemapLD are unique for each BRDF
void EvaluateBSDF_Env( LightLoopContext lightLoopContext,
float3 V, float3 positionWS, PreLightData prelightData, EnvLightData lightData, BSDFData bsdfData,
float3 V, float3 positionWS, PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData,
out float4 diffuseLighting,
out float4 specularLighting)
{

// float shrinkedRoughness = AnisotropicStrechAtGrazingAngle(bsdfData.roughness, bsdfData.perceptualRoughness, NdotV);
// Note: As explain in GetPreLightData we use normalWS and not iblNormalWS here (in case of anisotropy)
float3 rayWS = GetSpecularDominantDir(bsdfData.normalWS, prelightData.iblR, bsdfData.roughness);
float3 rayWS = GetSpecularDominantDir(bsdfData.normalWS, preLightData.iblR, bsdfData.roughness);
float3 R = rayWS;
float weight = 1.0;

// We let GetSpecularDominantDir currently as it still an improvement but not as good as it could be
float mip = perceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness);
float4 preLD = SampleEnv(lightLoopContext, lightData.envIndex, R, mip);
specularLighting.rgb = preLD.rgb * prelightData.specularFGD;
specularLighting.rgb = preLD.rgb * preLightData.specularFGD;
// Apply specular occlusion on it
specularLighting.rgb *= bsdfData.specularOcclusion;

61
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Material.hlsl


#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/LightDefinition.cs.hlsl"
//-----------------------------------------------------------------------------
// Lighting part that required to be define to compile without lighting.hlsl
//-----------------------------------------------------------------------------
// In case lighting.hlsl is not include before including material.hlsl, define some neutral function, so it doesn't complain
#ifndef LIGHTING
struct LightLoopContext
{
int unused;
};
float3 GetShadowTextureCoordinate(LightLoopContext lightLoopContext, int index, float3 positionWS, float3 L)
{
return float3(0.0, 0.0, 0.0);
}
float SampleShadowCompare(LightLoopContext lightLoopContext, int index, float3 texCoord)
{
return 0.0;
}
float4 SampleIES(LightLoopContext lightLoopContext, int index, float2 sphericalTexCoord, float lod)
{
return float4(0.0, 0.0, 0.0, 0.0);
}
float4 SampleEnv(LightLoopContext lightLoopContext, int index, float3 texCoord, float lod)
{
return float4(0.0, 0.0, 0.0, 0.0);
}
#endif
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/Shadow.hlsl"
//-----------------------------------------------------------------------------
// common Encode/Decode functions
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Material definition
//-----------------------------------------------------------------------------
// In case lighting.hlsl is not include before including material.hlsl, define some neutral function, so it doesn't complain
#ifndef LIGHTING
struct LightLoopContext
{
int unused;
};
float4 SampleEnv(LightLoopContext lightLoopContext, int index, float3 texCoord, float lod)
{
return float4(0.0, 0.0, 0.0, 0.0);
}
float4 SampleIES(LightLoopContext lightLoopContext, int index, float2 sphericalTexCoord, float lod)
{
return float4(0.0, 0.0, 0.0, 0.0);
}
float4x4 GetShadowTransform(LightLoopContext lightLoopContext, int index, float3 L)
{
return float4x4(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
}
#endif
// Here we include all the different lighting model supported by the renderloop based on define done in .shader
#ifdef UNITY_MATERIAL_LIT

2
Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl


// OS: object space
// HS: Homogenous clip space
// CS: clips space
// TS: tangent space
// TXS: texture space
// Example: NormalWS
// normalized / unormalized vector

正在加载...
取消
保存