sync
This commit is contained in:
parent
cd647427ca
commit
532647c7b9
@ -3270,7 +3270,7 @@ MonoBehaviour:
|
|||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
TestLightTrans: {fileID: 634813099}
|
TestLightTrans: {fileID: 634813099}
|
||||||
TestCharacterTrans: {fileID: 1880735404}
|
TestCharacterTrans: {fileID: 1880735404}
|
||||||
TestW: 1
|
TestW: 5
|
||||||
--- !u!4 &217261640
|
--- !u!4 &217261640
|
||||||
Transform:
|
Transform:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -4870,6 +4870,10 @@ PrefabInstance:
|
|||||||
propertyPath: m_Name
|
propertyPath: m_Name
|
||||||
value: NestedParentArmature_Unpack
|
value: NestedParentArmature_Unpack
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 8508310942573128499, guid: c708a3b79cd542b42bbfedb17e213bc1, type: 3}
|
||||||
|
propertyPath: m_RenderShadows
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 8508310942573128499, guid: c708a3b79cd542b42bbfedb17e213bc1, type: 3}
|
- target: {fileID: 8508310942573128499, guid: c708a3b79cd542b42bbfedb17e213bc1, type: 3}
|
||||||
propertyPath: m_RenderPostProcessing
|
propertyPath: m_RenderPostProcessing
|
||||||
value: 1
|
value: 1
|
||||||
@ -20029,8 +20033,8 @@ Transform:
|
|||||||
m_GameObject: {fileID: 1215335447}
|
m_GameObject: {fileID: 1215335447}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
m_LocalPosition: {x: -10.14, y: -3.394, z: -136.12}
|
m_LocalPosition: {x: -10.14, y: -3.394, z: -132.664}
|
||||||
m_LocalScale: {x: 0.36361, y: 0.36361, z: 0.36361}
|
m_LocalScale: {x: 0.36361, y: 2.6302094, z: 5.8246684}
|
||||||
m_ConstrainProportionsScale: 0
|
m_ConstrainProportionsScale: 0
|
||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
|
|||||||
@ -142,9 +142,10 @@ MonoBehaviour:
|
|||||||
m_Active: 1
|
m_Active: 1
|
||||||
settings:
|
settings:
|
||||||
RenderPassEvent: 450
|
RenderPassEvent: 450
|
||||||
AmbientIntensity: 0.32
|
AmbientIntensity: 1.63
|
||||||
ShadowIntensity: 0.28
|
ShadowIntensity: 0
|
||||||
ShadowSharpness: 0.27
|
ShadowSharpness: 0
|
||||||
|
ConeAngle: 8.1
|
||||||
CapsuleAOMat: {fileID: 2100000, guid: c90d40f0d9828744b916dbed0eed9db6, type: 2}
|
CapsuleAOMat: {fileID: 2100000, guid: c90d40f0d9828744b916dbed0eed9db6, type: 2}
|
||||||
--- !u!114 &-5418649131825517062
|
--- !u!114 &-5418649131825517062
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
@ -610,7 +611,7 @@ MonoBehaviour:
|
|||||||
MaskMat: {fileID: 2100000, guid: 1368366248809f24e9a110be3075d1b8, type: 2}
|
MaskMat: {fileID: 2100000, guid: 1368366248809f24e9a110be3075d1b8, type: 2}
|
||||||
BlurMat: {fileID: 2100000, guid: 0487cfddca141924d8a1736f6c0b9b7b, type: 2}
|
BlurMat: {fileID: 2100000, guid: 0487cfddca141924d8a1736f6c0b9b7b, type: 2}
|
||||||
BlurIterations: 3
|
BlurIterations: 3
|
||||||
BlurSpread: 0.2
|
BlurSpread: 0.5
|
||||||
--- !u!114 &6334271670068977784
|
--- !u!114 &6334271670068977784
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|||||||
@ -15,7 +15,7 @@ MonoBehaviour:
|
|||||||
version: 7
|
version: 7
|
||||||
--- !u!21 &2100000
|
--- !u!21 &2100000
|
||||||
Material:
|
Material:
|
||||||
serializedVersion: 7
|
serializedVersion: 8
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
m_PrefabInstance: {fileID: 0}
|
m_PrefabInstance: {fileID: 0}
|
||||||
@ -24,7 +24,8 @@ Material:
|
|||||||
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
|
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
|
||||||
m_Parent: {fileID: 0}
|
m_Parent: {fileID: 0}
|
||||||
m_ModifiedSerializedProperties: 0
|
m_ModifiedSerializedProperties: 0
|
||||||
m_ShaderKeywords:
|
m_ValidKeywords: []
|
||||||
|
m_InvalidKeywords: []
|
||||||
m_LightmapFlags: 4
|
m_LightmapFlags: 4
|
||||||
m_EnableInstancingVariants: 0
|
m_EnableInstancingVariants: 0
|
||||||
m_DoubleSidedGI: 0
|
m_DoubleSidedGI: 0
|
||||||
@ -144,8 +145,8 @@ Material:
|
|||||||
- _WorkflowMode: 1
|
- _WorkflowMode: 1
|
||||||
- _ZWrite: 1
|
- _ZWrite: 1
|
||||||
m_Colors:
|
m_Colors:
|
||||||
- _BaseColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
|
- _BaseColor: {r: 0.7830189, g: 0.7830189, b: 0.7830189, a: 1}
|
||||||
- _Color: {r: 0.5, g: 0.5, b: 0.5, a: 1}
|
- _Color: {r: 0.7830188, g: 0.7830188, b: 0.7830188, a: 1}
|
||||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||||
- _SpecColor: {r: 1, g: 1, b: 1, a: 1}
|
- _SpecColor: {r: 1, g: 1, b: 1, a: 1}
|
||||||
m_BuildTextureStacks: []
|
m_BuildTextureStacks: []
|
||||||
|
|||||||
@ -32,6 +32,8 @@ namespace X.Rendering.Feature
|
|||||||
public float AmbientIntensity = 0.2f;
|
public float AmbientIntensity = 0.2f;
|
||||||
public float ShadowIntensity = 0.4f;
|
public float ShadowIntensity = 0.4f;
|
||||||
public float ShadowSharpness = 20;
|
public float ShadowSharpness = 20;
|
||||||
|
[Range(1, 90)]
|
||||||
|
public float ConeAngle = 1;
|
||||||
public Material CapsuleAOMat;
|
public Material CapsuleAOMat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,6 +121,7 @@ namespace X.Rendering.Feature
|
|||||||
cmd.SetGlobalFloat("_AmbientIntensity", settings.AmbientIntensity);
|
cmd.SetGlobalFloat("_AmbientIntensity", settings.AmbientIntensity);
|
||||||
cmd.SetGlobalFloat("_ShadowIntensity", settings.ShadowIntensity);
|
cmd.SetGlobalFloat("_ShadowIntensity", settings.ShadowIntensity);
|
||||||
cmd.SetGlobalFloat("_ShadowSharpness", settings.ShadowSharpness);
|
cmd.SetGlobalFloat("_ShadowSharpness", settings.ShadowSharpness);
|
||||||
|
cmd.SetGlobalFloat("_ConeAngle", settings.ConeAngle);
|
||||||
var renderer = renderingData.cameraData.renderer;
|
var renderer = renderingData.cameraData.renderer;
|
||||||
|
|
||||||
cmd.SetRenderTarget(renderer.cameraColorTargetHandle, loadAction: RenderBufferLoadAction.Load, storeAction: RenderBufferStoreAction.Store);
|
cmd.SetRenderTarget(renderer.cameraColorTargetHandle, loadAction: RenderBufferLoadAction.Load, storeAction: RenderBufferStoreAction.Store);
|
||||||
|
|||||||
@ -48,6 +48,26 @@ Shader "XRP/CapsuleAO"
|
|||||||
float _ShadowIntensity;
|
float _ShadowIntensity;
|
||||||
float _ShadowSharpness;
|
float _ShadowSharpness;
|
||||||
|
|
||||||
|
float _ConeAngle;
|
||||||
|
|
||||||
|
#define sq(x) (x * x)
|
||||||
|
|
||||||
|
float acosFast(float x)
|
||||||
|
{
|
||||||
|
// Lagarde 2014, "Inverse trigonometric functions GPU optimization for AMD GCN architecture"
|
||||||
|
// This is the approximation of degree 1, with a max absolute error of 9.0x10^-3
|
||||||
|
float y = abs(x);
|
||||||
|
float p = -0.1565827 * y + 1.570796;
|
||||||
|
p *= sqrt(1.0 - y);
|
||||||
|
return x >= 0.0 ? p : PI - p;
|
||||||
|
}
|
||||||
|
|
||||||
|
float acosFastPositive(float x)
|
||||||
|
{
|
||||||
|
// Lagarde 2014, "Inverse trigonometric functions GPU optimization for AMD GCN architecture"
|
||||||
|
float p = -0.1565827 * x + 1.570796;
|
||||||
|
return p * sqrt(1.0 - x);
|
||||||
|
}
|
||||||
|
|
||||||
Varyings vert(uint vertexID: SV_VertexID)
|
Varyings vert(uint vertexID: SV_VertexID)
|
||||||
{
|
{
|
||||||
@ -78,8 +98,11 @@ Shader "XRP/CapsuleAO"
|
|||||||
th.x = max(th.x, 0.0001);
|
th.x = max(th.x, 0.0001);
|
||||||
th.y = saturate(th.y);
|
th.y = saturate(th.y);
|
||||||
|
|
||||||
|
//线段ab上离射线最近的点p
|
||||||
float3 p = a + ba * th.y;
|
float3 p = a + ba * th.y;
|
||||||
|
//射线rord 找到距离线段 ab 最近的点q
|
||||||
float3 q = ro + rd * th.x;
|
float3 q = ro + rd * th.x;
|
||||||
|
//沿着光的方向发射射线, 射线离胶囊体最短的距离
|
||||||
float d = length(p - q) - r;
|
float d = length(p - q) - r;
|
||||||
|
|
||||||
float s = saturate(k * d / th.x + 0.3);
|
float s = saturate(k * d / th.x + 0.3);
|
||||||
@ -87,8 +110,37 @@ Shader "XRP/CapsuleAO"
|
|||||||
shadow *= s;
|
shadow *= s;
|
||||||
}
|
}
|
||||||
|
|
||||||
shadow = saturate(lerp(shadow, 1, intensity));
|
shadow = saturate(lerp(1, shadow, intensity));
|
||||||
return saturate(lerp(shadow, 1, _ShadowIntensity));
|
return saturate(lerp(1, shadow, _ShadowIntensity));
|
||||||
|
}
|
||||||
|
|
||||||
|
float _smooth(float x) { return x * x * (3.0 - 2.0 * x); }
|
||||||
|
|
||||||
|
float CalcCapsuleOcclusionFast(float3 p, float3 n, float3 a, float3 b, float r, float maxD)
|
||||||
|
{
|
||||||
|
float r2 = r*r;
|
||||||
|
// Original function but in ^2 space
|
||||||
|
float3 ba = b - a, pa = p - a;
|
||||||
|
float h = saturate(dot(pa,ba)/dot(ba,ba));
|
||||||
|
float3 d = pa - h*ba;
|
||||||
|
float l = dot(d,d);
|
||||||
|
float o = -dot(d,n)*r2*r/(l*l);
|
||||||
|
// Max dist
|
||||||
|
o *= _smooth(saturate(1.0 - (l-r2)/(maxD*maxD)));
|
||||||
|
return saturate(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
float CalcCapsuleOcclusion(float3 p, float3 n, float3 a, float3 b, float r, float maxD)
|
||||||
|
{
|
||||||
|
// closest sphere
|
||||||
|
float3 ba = b - a, pa = p - a;
|
||||||
|
float h = saturate(dot(pa,ba)/dot(ba,ba));
|
||||||
|
float3 d = pa - h*ba;
|
||||||
|
float l = length(d);
|
||||||
|
float o = dot(-d,n)*r*r/(l*l*l); // occlusion of closest sphere
|
||||||
|
o *= 1.0 + r*(l-r)/(l*l); // multiplier
|
||||||
|
// o *= 1.0 - saturate((l - r) / maxD);
|
||||||
|
return saturate(1.0 - o);
|
||||||
}
|
}
|
||||||
|
|
||||||
float CalcCapsuleOcclusionByIndex(float3 p, float3 n, uint s, uint e, float intensity)
|
float CalcCapsuleOcclusionByIndex(float3 p, float3 n, uint s, uint e, float intensity)
|
||||||
@ -103,15 +155,196 @@ Shader "XRP/CapsuleAO"
|
|||||||
float3 ba = b - a;
|
float3 ba = b - a;
|
||||||
float3 pa = p - a;
|
float3 pa = p - a;
|
||||||
float h = saturate(dot(pa, ba) / dot(ba, ba));
|
float h = saturate(dot(pa, ba) / dot(ba, ba));
|
||||||
|
// 地面点 p 到 ab 最近点 x, 向量 xp = d
|
||||||
float3 d = pa - h * ba;
|
float3 d = pa - h * ba;
|
||||||
float l = length(d);
|
float l = length(d);
|
||||||
float o = 1.0 - max(0.0, dot(-d, n)) * r * r / (l * l * l);
|
float o = 1.0 - max(0.0, dot(-d, n)) * r * r / (l * l * l);
|
||||||
|
// multiplier o *= 1.0 + r*(l-r)/(l*l);
|
||||||
o = sqrt(o * o * o);
|
o = sqrt(o * o * o);
|
||||||
ao *= o;
|
ao *= o;
|
||||||
}
|
}
|
||||||
|
ao = saturate(lerp(1, ao, intensity));
|
||||||
|
return clamp(lerp(1, ao, _AmbientIntensity), 0.6, 1);
|
||||||
|
}
|
||||||
|
|
||||||
ao = saturate(lerp(ao, 1, intensity));
|
// Sphere occlusion
|
||||||
return saturate(lerp(ao, 1, _AmbientIntensity));
|
float CalcSphereOcclusion( in float3 pos, in float3 nor, in float4 sph )
|
||||||
|
{
|
||||||
|
float3 di = sph.xyz - pos;
|
||||||
|
float l = length(di);
|
||||||
|
float nl = (dot(nor,di/l));
|
||||||
|
float rad = sph.w;
|
||||||
|
float v = 1 - rad - nl;
|
||||||
|
if(l < 0.55)
|
||||||
|
return abs((1 - rad - nl));// + _ShadowSharpness;
|
||||||
|
|
||||||
|
|
||||||
|
float h = l < rad ? 1.0 : l / rad;
|
||||||
|
|
||||||
|
float h2 = h * h;
|
||||||
|
float k2 = 1.0 - h2*nl*nl;
|
||||||
|
|
||||||
|
// above/below horizon
|
||||||
|
// EXACT: Quilez - https://iquilezles.org/articles/sphereao
|
||||||
|
float res = max(0.0, nl) / h2;
|
||||||
|
|
||||||
|
// intersecting horizon
|
||||||
|
if( k2 > 0.001 )
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
// EXACT : Lagarde/de Rousiers - https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
|
||||||
|
res = nl * acos(-nl * sqrt((h2 - 1.0) / (1.0 - nl * nl))) - sqrt(k2 * (h2 - 1.0));
|
||||||
|
res = res / h2 + atan(sqrt(k2 / (h2 - 1.0)));
|
||||||
|
res /= 3.141593;
|
||||||
|
#else
|
||||||
|
// APPROXIMATED : Quilez - https://iquilezles.org/articles/sphereao
|
||||||
|
res = (nl * h + 1.0) / h2;
|
||||||
|
res = 0.33 * res * res;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return clamp(1.0 - res, 0.6, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
float CalcCapsuleOcclusionByIndexV2(float3 p, float3 n, uint s, uint e, float4 cone, float intensity)
|
||||||
|
{
|
||||||
|
float ao = 1.0;
|
||||||
|
for (uint i = s; i < e; ++i)
|
||||||
|
{
|
||||||
|
Capsule capsule = _CapsuleData[i + int(_ShadowIntensity)];
|
||||||
|
float3 ba = capsule.b - capsule.a;
|
||||||
|
float3 pa = p - capsule.a;
|
||||||
|
float l = dot(ba, ba);
|
||||||
|
// p 在 ba 上投影长度与 ba 长度比值
|
||||||
|
float t = /* abs(l) < 1e-8f ? 0.0 : */ saturate(dot(pa, ba) / l);
|
||||||
|
float3 positionToRay = capsule.a + t * ba;
|
||||||
|
ao = min(ao, CalcSphereOcclusion(p, n, float4(positionToRay, capsule.radius)));
|
||||||
|
}
|
||||||
|
return ao;
|
||||||
|
ao = saturate(lerp(1, ao, intensity));
|
||||||
|
return saturate(lerp(1, ao, _AmbientIntensity));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Approximate the area of intersection of two spherical caps, from 'Ambient Aperture Lighting'
|
||||||
|
// fRadius0 : First caps radius (arc length in radians)
|
||||||
|
// fRadius1 : Second caps radius (in radians)
|
||||||
|
// fDist : Distance between caps (radians between centers of caps)
|
||||||
|
float SphericalCapIntersectionAreaFast(float fRadius0, float fRadius1, float fDist)
|
||||||
|
{
|
||||||
|
float fArea;
|
||||||
|
|
||||||
|
if (fDist <= max(fRadius0, fRadius1) - min(fRadius0, fRadius1))
|
||||||
|
{
|
||||||
|
// One cap is completely inside the other
|
||||||
|
fArea = 6.283185308f - 6.283185308f * cos(min(fRadius0, fRadius1));
|
||||||
|
}
|
||||||
|
else if (fDist >= fRadius0 + fRadius1)
|
||||||
|
{
|
||||||
|
// No intersection exists
|
||||||
|
fArea = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float fDiff = abs(fRadius0 - fRadius1);
|
||||||
|
fArea = smoothstep(0.0f,
|
||||||
|
1.0f,
|
||||||
|
1.0f - saturate((fDist - fDiff) / (fRadius0 + fRadius1 - fDiff)));
|
||||||
|
fArea *= 6.283185308f - 6.283185308f * cos(min(fRadius0, fRadius1));
|
||||||
|
}
|
||||||
|
return fArea;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
ref: https://developer.amd.com/wordpress/media/2012/10/Oat-AmbientApetureLighting.pdf
|
||||||
|
Approximate the area of intersection of two spherical caps.
|
||||||
|
|
||||||
|
With some modifcations proposed by the shadertoy implementation
|
||||||
|
*/
|
||||||
|
float SphericalCapsIntersectionAreaFast(float cosCap1, float cosCap2, float cap2, float cosDistance)
|
||||||
|
{
|
||||||
|
// Precompute constants
|
||||||
|
float radius1 = acosFastPositive(cosCap1); // First caps radius (arc length in radians)
|
||||||
|
float radius2 = cap2; // Second caps radius (in radians)
|
||||||
|
float dist = acosFast(cosDistance); // Distance between caps (radians between centers of caps)
|
||||||
|
|
||||||
|
// Conditional expressions instead of if-else
|
||||||
|
float check1 = min(radius1, radius2) <= max(radius1, radius2) - dist;
|
||||||
|
float check2 = radius1 + radius2 <= dist;
|
||||||
|
|
||||||
|
// Ternary operator to replace if-else
|
||||||
|
float result = check1 ? (1.0 - max(cosCap1, cosCap2)) : (check2 ? 0.0 : 1.0 - max(cosCap1, cosCap2));
|
||||||
|
|
||||||
|
float delta = abs(radius1 - radius2);
|
||||||
|
float x = 1.0 - saturate((dist - delta) / max(radius1 + radius2 - delta, FLT_EPS));
|
||||||
|
|
||||||
|
// simplified smoothstep()
|
||||||
|
float area = sq(x) * (-2.0 * x + 3.0);
|
||||||
|
|
||||||
|
// Multiply by (1.0 - max(cosCap1, cosCap2)) only once
|
||||||
|
return area * result;
|
||||||
|
}
|
||||||
|
|
||||||
|
float DirectionalOcclusionSphere(float3 rayPosition, float3 spherePosition, float sphereRadius, float4 coneProperties)
|
||||||
|
{
|
||||||
|
float3 occluderPosition = spherePosition.xyz - rayPosition;
|
||||||
|
float occluderLength2 = dot(occluderPosition, occluderPosition);
|
||||||
|
float3 occluderDir = occluderPosition * rsqrt(occluderLength2);
|
||||||
|
|
||||||
|
float cosPhi = dot(occluderDir, coneProperties.xyz);
|
||||||
|
// sq(sphere.w) should be a uniform --> capsuleRadius^2
|
||||||
|
float cosTheta = sqrt(occluderLength2 / (sq(sphereRadius) + occluderLength2));
|
||||||
|
float cosCone = cos(coneProperties.w);
|
||||||
|
|
||||||
|
return 1.0 - SphericalCapsIntersectionAreaFast(cosTheta, cosCone, coneProperties.w, cosPhi) / (1.0 - cosCone);
|
||||||
|
}
|
||||||
|
|
||||||
|
//this sort of work but doesn't support rotations
|
||||||
|
float DirectionalOcclusionCube(float3 rayPosition, float3 cubePos, float3 cubeSize, float4 cubeRotation, float4 coneProperties)
|
||||||
|
{
|
||||||
|
float3 occluder = cubePos.xyz - rayPosition;
|
||||||
|
occluder /= cubeSize * 0.5f;
|
||||||
|
|
||||||
|
float occluderLength2 = dot(cubeRotation.xyz, occluder);
|
||||||
|
float3 occluderDir = occluder * rsqrt(occluderLength2);
|
||||||
|
//occluderDir *= cubeRotation;
|
||||||
|
//occluderDir = cross(occluderDir, cubeRotation);
|
||||||
|
|
||||||
|
float cosPhi = dot(occluderDir, coneProperties.xyz);
|
||||||
|
// sq(sphere.w) should be a uniform --> capsuleRadius^2
|
||||||
|
float cosTheta = sqrt(occluderLength2 / (sq(1.0f) + occluderLength2));
|
||||||
|
float cosCone = cos(coneProperties.w);
|
||||||
|
|
||||||
|
return 1.0 - SphericalCapsIntersectionAreaFast(cosTheta, cosCone, coneProperties.w, cosPhi) / (1.0 - cosCone);
|
||||||
|
}
|
||||||
|
|
||||||
|
float DirectionalOcclusionCapsule(float3 rayPosition, float3 capsuleA, float3 capsuleB, float capsuleRadius, float4 coneProperties)
|
||||||
|
{
|
||||||
|
float3 Ld = capsuleB - capsuleA;
|
||||||
|
float3 L0 = capsuleA - rayPosition;
|
||||||
|
float a = dot(coneProperties.xyz, Ld);
|
||||||
|
float t = saturate(dot(L0, a * coneProperties.xyz - Ld) / (dot(Ld, Ld) - a * a));
|
||||||
|
float3 positionToRay = capsuleA + t * Ld;
|
||||||
|
|
||||||
|
return DirectionalOcclusionSphere(rayPosition, positionToRay, capsuleRadius, coneProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 GetConeProperties(float3 lightDir)
|
||||||
|
{
|
||||||
|
float4 cone = float4(lightDir.xyz, radians(_ConeAngle) * 0.5);
|
||||||
|
cone.xyz = normalize(cone.xyz);
|
||||||
|
return cone;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float CalcCapsuleShadowByIndexV2(float3 ro, float4 cone, uint s, uint e, in float k, float intensity)
|
||||||
|
{
|
||||||
|
float shadow = 1.0;
|
||||||
|
for (uint i = s; i < e; ++i)
|
||||||
|
{
|
||||||
|
Capsule c = _CapsuleData[i];
|
||||||
|
shadow*= DirectionalOcclusionCapsule(ro, c.a, c.b, c.radius, cone);
|
||||||
|
}
|
||||||
|
shadow = saturate(lerp(1, shadow, intensity));
|
||||||
|
return saturate(lerp(1, shadow, _ShadowIntensity));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsInBounds(float3 p, float3 c, float b, out float intensity)
|
bool IsInBounds(float3 p, float3 c, float b, out float intensity)
|
||||||
@ -119,7 +352,7 @@ Shader "XRP/CapsuleAO"
|
|||||||
float3 diff = abs(p - c);
|
float3 diff = abs(p - c);
|
||||||
if (diff.x < b && diff.y < b && diff.z < b)
|
if (diff.x < b && diff.y < b && diff.z < b)
|
||||||
{
|
{
|
||||||
intensity = saturate(dot(diff, diff) / dot(b, b));
|
intensity = saturate(dot(b, b) / dot(diff.xz, diff.xz));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
intensity = 0;
|
intensity = 0;
|
||||||
@ -130,21 +363,26 @@ Shader "XRP/CapsuleAO"
|
|||||||
{
|
{
|
||||||
float shadow = 1.0;
|
float shadow = 1.0;
|
||||||
float occlusion = 1.0;
|
float occlusion = 1.0;
|
||||||
|
float4 cone = GetConeProperties(_MainLightPosition.xyz);
|
||||||
|
|
||||||
for (uint i = 0; i < _CharactersCount; ++i)
|
for (uint i = 0; i < _CharactersCount; ++i)
|
||||||
{
|
{
|
||||||
float intensity;
|
float intensity = 1;
|
||||||
Character c = _CharacterData[i];
|
Character c = _CharacterData[i];
|
||||||
if (IsInBounds(worldPos, c.position, c.radius, intensity))
|
// if (IsInBounds(worldPos, c.position, c.radius*10, intensity))
|
||||||
{
|
{
|
||||||
float tempIntensity = intensity / saturate(1 * smoothstep(0.001, 1, c.lightDir.w));
|
float tempIntensity = intensity / saturate(1 * smoothstep(0.1, 2, c.lightDir.w));
|
||||||
float tempShadow = CalcCapsuleShadowByIndex(worldPos, _MainLightPosition.xyz, c.startID, c.endID, _ShadowSharpness, tempIntensity);
|
// float tempShadow = CalcCapsuleShadowByIndex(worldPos, _MainLightPosition.xyz, c.startID, c.endID, _ShadowSharpness, tempIntensity);
|
||||||
shadow = min(shadow, tempShadow);
|
// float tempShadow = CalcCapsuleShadowByIndexV2(worldPos, cone, c.startID, c.endID, _ShadowSharpness, tempIntensity);
|
||||||
occlusion *= CalcCapsuleOcclusionByIndex(worldPos, worldNormal, c.startID, c.endID, intensity);
|
// shadow = min(shadow, tempShadow);
|
||||||
|
// occlusion *= CalcCapsuleOcclusionByIndex(worldPos, worldNormal, c.startID, c.endID, intensity);
|
||||||
|
occlusion *= CalcCapsuleOcclusionByIndexV2(worldPos, worldNormal, c.startID, c.endID,cone, intensity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return shadow * occlusion;
|
return shadow * occlusion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float4 frag(Varyings input) : SV_Target
|
float4 frag(Varyings input) : SV_Target
|
||||||
{
|
{
|
||||||
const float2 uv = input.texcoord;
|
const float2 uv = input.texcoord;
|
||||||
@ -160,6 +398,7 @@ Shader "XRP/CapsuleAO"
|
|||||||
float4 worldPos = mul(UNITY_MATRIX_I_VP, float4(sceneUV, depth, 1));
|
float4 worldPos = mul(UNITY_MATRIX_I_VP, float4(sceneUV, depth, 1));
|
||||||
worldPos /= worldPos.w;
|
worldPos /= worldPos.w;
|
||||||
float3 worldNormal = SampleSceneNormals(uv);
|
float3 worldNormal = SampleSceneNormals(uv);
|
||||||
|
|
||||||
float ao = CalcAmbientOcclusion(worldPos.xyz, worldNormal);
|
float ao = CalcAmbientOcclusion(worldPos.xyz, worldNormal);
|
||||||
|
|
||||||
// float4 shadowCoord = TransformWorldToShadowCoord(worldPos.xyz);
|
// float4 shadowCoord = TransformWorldToShadowCoord(worldPos.xyz);
|
||||||
@ -167,7 +406,7 @@ Shader "XRP/CapsuleAO"
|
|||||||
// //只在阴影处产生AO
|
// //只在阴影处产生AO
|
||||||
// ao = lerp(ao, 1, step(0.5, mainLight.shadowAttenuation));
|
// ao = lerp(ao, 1, step(0.5, mainLight.shadowAttenuation));
|
||||||
|
|
||||||
return half4(1, 0, 0, ao);
|
return half4(ao, 0, 0, ao);
|
||||||
}
|
}
|
||||||
|
|
||||||
ENDHLSL
|
ENDHLSL
|
||||||
|
|||||||
@ -83,8 +83,10 @@ namespace X.Rendering.Feature
|
|||||||
{
|
{
|
||||||
var capsule = item.Value[i];
|
var capsule = item.Value[i];
|
||||||
//capsule.direction
|
//capsule.direction
|
||||||
var a = capsule.center - new Vector3(0, capsule.height / 2, 0);
|
var a = capsule.center - new Vector3(0, capsule.height / 2 - capsule.radius, 0);
|
||||||
var b = capsule.center + new Vector3(0, capsule.height / 2, 0);
|
var b = capsule.center + new Vector3(0, capsule.height / 2 - capsule.radius, 0);
|
||||||
|
//var a = capsule.center - new Vector3(0, capsule.height / 2, 0);
|
||||||
|
//var b = capsule.center + new Vector3(0, capsule.height / 2, 0);
|
||||||
a = capsule.transform.TransformPoint(a);
|
a = capsule.transform.TransformPoint(a);
|
||||||
b = capsule.transform.TransformPoint(b);
|
b = capsule.transform.TransformPoint(b);
|
||||||
CapsuleArray[capsuleArrayIndex++] = new()
|
CapsuleArray[capsuleArrayIndex++] = new()
|
||||||
@ -101,7 +103,7 @@ namespace X.Rendering.Feature
|
|||||||
CharacterArray[characterArrayIndex++] = new()
|
CharacterArray[characterArrayIndex++] = new()
|
||||||
{
|
{
|
||||||
position = transform.position,
|
position = transform.position,
|
||||||
radius = 5,
|
radius = transform.lossyScale.x,
|
||||||
lightDir = -new Vector4(TestLightTrans.position.x, TestLightTrans.position.y, TestLightTrans.position.z, -TestW),
|
lightDir = -new Vector4(TestLightTrans.position.x, TestLightTrans.position.y, TestLightTrans.position.z, -TestW),
|
||||||
startID = startID,
|
startID = startID,
|
||||||
endID = capsuleArrayIndex,
|
endID = capsuleArrayIndex,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user