浏览代码

updated blurred shadow shader to work on all platforms

/main
Dan 4 年前
当前提交
9d6a627b
共有 12 个文件被更改,包括 53 次插入355 次删除
  1. 5
      Assets/Shaders/Shadows/Materials/BlurredShadowMat.mat
  2. 2
      Assets/Shaders/Shadows/Prefabs/ShadowObject.prefab
  3. 2
      Assets/Shaders/Shadows/Scenes/ShadowPlacement.unity
  4. 107
      Assets/Shaders/Shadows/ShaderGraphs/BlurredShadowPlaneLighting.hlsl
  5. 5
      ProjectSettings/EditorBuildSettings.asset
  6. 3
      ProjectSettings/GraphicsSettings.asset
  7. 2
      ProjectSettings/ProjectSettings.asset
  8. 8
      Assets/ARFoundationDemos.meta
  9. 200
      Assets/Shaders/Shadows/BlurredShadowPlane.shadergraph
  10. 54
      Assets/Shaders/Shadows/BlurredShadowPlaneLighting.hlsl
  11. 10
      Assets/Shaders/Shadows/BlurredShadowPlane.shadergraph.meta
  12. 10
      Assets/Shaders/Shadows/BlurredShadowPlaneLighting.hlsl.meta

5
Assets/Shaders/Shadows/Materials/BlurredShadowMat.mat


m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- BlurRadius: 0.1
- BlurRadius: 0.05
- MultiplyStrength: 0.4
- MultiplyStrength: 0.5
- ShadowStrength: 0.5
- _AlphaClip: 0
- _Blend: 0

- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
--- !u!114 &3665358235902547080
MonoBehaviour:
m_ObjectHideFlags: 11

2
Assets/Shaders/Shadows/Prefabs/ShadowObject.prefab


m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4216103412072782249}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0.328, y: 0.18, z: 0.61}
m_LocalPosition: {x: 0.328, y: 0.217, z: 0.61}
m_LocalScale: {x: 0.34722, y: 0.34722, z: 0.34722}
m_Children: []
m_Father: {fileID: 8658607402519927358}

2
Assets/Shaders/Shadows/Scenes/ShadowPlacement.unity


m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.17276844, g: 0.21589246, b: 0.2978263, a: 1}
m_IndirectSpecularColor: {r: 0.1727681, g: 0.21589199, b: 0.29782572, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:

107
Assets/Shaders/Shadows/ShaderGraphs/BlurredShadowPlaneLighting.hlsl


/*#ifndef SHADERGRAPH_PREVIEW
real SampleShadowmapDirect(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), SamplerState PointClamp, float4 shadowCoord, ShadowSamplingData samplingData, bool isPerspectiveProjection = true)
{
// Compiler will optimize this branch away as long as isPerspectiveProjection is known at compile time
if (isPerspectiveProjection)
shadowCoord.xyz /= shadowCoord.w;
real distance;
// Instead of getting a value of 0 or 1 depending on a shadowmap comparison, we want to actually sample the shadowmap's values
distance = SAMPLE_TEXTURE2D_LOD(ShadowMap, PointClamp, shadowCoord.xy, 0);
//int smWidth, smHeight;
//ShadowMap.GetDimensions(smWidth, smHeight);
//shadowCoord = saturate(shadowCoord);
//distance = ShadowMap[int2(smWidth * shadowCoord.x, smHeight * shadowCoord.y)];
return distance;
}
#endif*/
void MainLightBlurShadow_half(half rand, half fadeTightness, SamplerState pointClamp, half blurRadius, half3 worldPos, out half shadowAtten)
{
#if SHADERGRAPH_PREVIEW
shadowAtten = 1;
#else
const int NUM_STEPS = 40;
float oneDivNumSteps = 1.0 / NUM_STEPS;
Light mainLight = GetMainLight();
shadowAtten = 1;
ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData();
for (int i = 0; i < NUM_STEPS; i++)
{
//Instead of sampling the position of the current pixel, sample a point that's a i steps away, in a semi-randomized direction
//the starting direction is randomized and then the direction is rotated by "i" radians every iteration
half3 newWorldPos = worldPos + half3(sin(rand + i), 0, cos(rand + i)) * i * oneDivNumSteps * blurRadius;
#if SHADOWS_SCREEN
half4 clipPos = TransformWorldToHClip(newWorldPos);
half4 shadowCoord = ComputeScreenPos(clipPos);
#else
half4 shadowCoord = TransformWorldToShadowCoord(newWorldPos);
#endif
#ifdef _MAIN_LIGHT_SHADOWS_CASCADE
half cascadeIndex = ComputeCascadeIndex(newWorldPos);
#else
half cascadeIndex = 0;
#endif
float shadowScale = pow(_MainLightWorldToShadow[cascadeIndex], 0.7) * 20; // Some "Magic Math" to try to make transitions between cascades smoother
//float shadowMapSample = SampleShadowmapDirect(TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_MainLightShadowmapTexture), pointClamp, shadowCoord, shadowSamplingData, false);
float shadowMapSample = SAMPLE_TEXTURE2D_LOD(_MainLightShadowmapTexture, pointClamp, shadowCoord.xy, 0);
#if defined(SHADER_API_GLES3) || defined(SHADER_API_GLES) || defined(SHADER_API_GLCORE)
shadowMapSample = 1 - shadowMapSample;
shadowCoord.z = 1 - shadowCoord.z;
#endif
float shadowCoordPos = shadowCoord.z / shadowScale; //Divide by shadowScale to get transitions more close-ish when using shadow cascades
float shadowMapPos = shadowMapSample / shadowScale;
//blurAmount is a value between 0 and 1 expressing how much to blur
float blurAmount = max(0.01, ((shadowMapPos - shadowCoordPos) * fadeTightness));
float oneDivBlurAmount = 1 / saturate(blurAmount);
//0 or 1 depending on whether a shadow is being cast
float isInShadow = step(shadowCoord.z, shadowMapSample);
// reduce the influence of higher iterations (further out samples) if the sampled shadowmap value is close to our position
float tightenCloseShadows = clamp((NUM_STEPS - i * oneDivBlurAmount), 0, oneDivBlurAmount * 2);
// reduce the influence of lower iterations (closer in samples) if the sampled shadowmap value is far way from our position
float reduceInnerIterations = max(step(saturate(blurAmount) * NUM_STEPS / 4, i + 1), 0.3);
shadowAtten -= isInShadow * oneDivNumSteps * tightenCloseShadows * reduceInnerIterations;
// If the position is out of shadow distance, just return 1
shadowAtten = BEYOND_SHADOW_FAR(shadowCoord) ? 1.0 : saturate(shadowAtten);
}
#endif
void MainLightBlurShadow_half(half rand, half fadeTightness, SamplerState pointClamp, half blurRadius, half3 worldPos, out half shadowAtten)
{
#if SHADERGRAPH_PREVIEW
shadowAtten = 1;
#else
const int NUM_STEPS = 10;
float oneDivNumSteps = 1.0 / NUM_STEPS;
Light mainLight = GetMainLight();
shadowAtten = 1;
ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData();
for (int i = NUM_STEPS / 4; i < NUM_STEPS; i++)
{
//Instead of sampling the position of the current pixel, sample a point that's a i steps away, in a semi-randomized direction
//the starting direction is randomized and then the direction is rotated by "i" radians every iteration
half3 newWorldPos = worldPos + half3(sin(rand + i), 0, cos(rand + i)) * i * oneDivNumSteps * blurRadius;
#if SHADOWS_SCREEN
half4 clipPos = TransformWorldToHClip(newWorldPos);
half4 shadowCoord = ComputeScreenPos(clipPos);
#else
half4 shadowCoord = TransformWorldToShadowCoord(newWorldPos);
#endif
#ifdef _MAIN_LIGHT_SHADOWS_CASCADE
half cascadeIndex = ComputeCascadeIndex(newWorldPos);
#else
half cascadeIndex = 0;
#endif
float shadowMapSample = SAMPLE_TEXTURE2D_SHADOW(_MainLightShadowmapTexture, sampler_MainLightShadowmapTexture, shadowCoord.xyz);
//0 or 1 depending on whether a shadow is being cast
float isInShadow = step(shadowMapSample, shadowCoord.z);
shadowAtten -= isInShadow * oneDivNumSteps;
// If the position is out of shadow distance, just return 1
shadowAtten = BEYOND_SHADOW_FAR(shadowCoord) ? 1.0 : saturate(shadowAtten);
}
#endif
}

5
ProjectSettings/EditorBuildSettings.asset


EditorBuildSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Scenes: []
m_Scenes:
- enabled: 1
path: Assets/Shaders/Shadows/Scenes/ShadowPlacement.unity
guid: d88edf08dec76432fb75bc510222417f
m_configObjects:
UnityEditor.XR.ARCore.ARCoreSettings: {fileID: 11400000, guid: 0f640456e31a1497aa336938d310040e,
type: 2}

3
ProjectSettings/GraphicsSettings.asset


m_PreloadedShaders: []
m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,
type: 0}
m_CustomRenderPipeline: {fileID: 11400000, guid: efc9f20e6a4b0423ebd19efb551d21a0,
type: 2}
m_CustomRenderPipeline: {fileID: 0}
m_TransparencySortMode: 0
m_TransparencySortAxis: {x: 0, y: 0, z: 1}
m_DefaultRenderingPath: 1

2
ProjectSettings/ProjectSettings.asset


m_APIs: 1000000011000000
m_Automatic: 1
- m_BuildTarget: WindowsStandaloneSupport
m_APIs: 0b00000002000000
m_APIs: 02000000
m_Automatic: 0
m_BuildTargetVRSettings:
- m_BuildTarget: Standalone

8
Assets/ARFoundationDemos.meta


fileFormatVersion: 2
guid: faeaceca7df854ff49277ef3f74f530f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

200
Assets/Shaders/Shadows/BlurredShadowPlane.shadergraph
文件差异内容过多而无法显示
查看文件

54
Assets/Shaders/Shadows/BlurredShadowPlaneLighting.hlsl


#ifndef SHADERGRAPH_PREVIEW
real SampleShadowmapDirect(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), SamplerState PointClamp, float4 shadowCoord, ShadowSamplingData samplingData, half4 shadowParams, bool isPerspectiveProjection = true)
{
// Compiler will optimize this branch away as long as isPerspectiveProjection is known at compile time
if (isPerspectiveProjection)
shadowCoord.xyz /= shadowCoord.w;
real distance;
real shadowStrength = shadowParams.x;
distance = SAMPLE_TEXTURE2D_LOD(ShadowMap, PointClamp, shadowCoord.xy, 0);
// Shadow coords that fall out of the light frustum volume must always return attenuation 1.0
// TODO: We could use branch here to save some perf on some platforms.
return BEYOND_SHADOW_FAR(shadowCoord) ? 1.0 : distance;
}
#endif
void MainLightBlurShadow_half(half RandSeed, half FadeTightness, SamplerState PointClamp, half BlurRadius, half3 WorldPos, out half3 Direction, out half3 Color, out half DistanceAtten, out half ShadowAtten)
{
#if SHADERGRAPH_PREVIEW
Direction = half3(0.5, 0.5, 0);
Color = 1;
DistanceAtten = 1;
ShadowAtten = 1;
#else
Light mainLight = GetMainLight();
Direction = mainLight.direction;
Color = mainLight.color;
DistanceAtten = mainLight.distanceAttenuation;
ShadowAtten = 1;
ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData();
half4 shadowParams = GetMainLightShadowParams();
for (int i = 1; i < 41; i++)
{
half3 newWorldPos = WorldPos + half3(sin(RandSeed + i), 0, cos(RandSeed + i)) * i * 0.025 * BlurRadius;
#if SHADOWS_SCREEN
half4 clipPos = TransformWorldToHClip(newWorldPos);
half4 shadowCoord = ComputeScreenPos(clipPos);
#else
half4 shadowCoord = TransformWorldToShadowCoord(newWorldPos);
#endif
//mainLight = GetMainLight(shadowCoord);
float shadowMapSample = SampleShadowmapDirect(TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_MainLightShadowmapTexture), PointClamp, shadowCoord, shadowSamplingData, shadowParams, false);
float shadowCoordPos = shadowCoord.z;
float shadowMapPos = shadowMapSample;
float fade = ((shadowMapPos - shadowCoordPos) * FadeTightness);
float onedivfade = 1 / min(fade, 0.7);
ShadowAtten -= step(shadowCoord.z, shadowMapSample) * 0.0025 * lerp(max((41 - i* onedivfade)*onedivfade,0), i, saturate(fade));// *(1 - saturate(fade / 3));
ShadowAtten = saturate(ShadowAtten);
}
#endif
}

10
Assets/Shaders/Shadows/BlurredShadowPlane.shadergraph.meta


fileFormatVersion: 2
guid: f0bde5b6bb8a34f8ba81588243c89255
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3}

10
Assets/Shaders/Shadows/BlurredShadowPlaneLighting.hlsl.meta


fileFormatVersion: 2
guid: 1a92b7d3830524d19b674be48dff68ea
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存