浏览代码

Optimized spotlight attenuation to be done with a DP3 and MAD instrucitons.

/Add-support-for-light-specular-color-tint
Felipe Lira 7 年前
当前提交
98bc9a10
共有 2 个文件被更改,包括 32 次插入8 次删除
  1. 25
      ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs
  2. 15
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightLighting.cginc

25
ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs


Vector4 dir = light.localToWorld.GetColumn(2);
lightSpotDir = new Vector4(-dir.x, -dir.y, -dir.z, 0.0f);
// Spot light attenuation with a smooth angle border is computed as follows:
// ( dot(spotDir, lightDir) - cosOuterAngle ) / smoothAngleRange
// we can rewrite that as
// invSmoothAngleRange = 1.0 / smoothAngleRange
// dot(spotDir, lightDir) * invSmoothAngleRange + (-cosOuterAngle * invSmoothAngleRange)
// and this will fit into a single MAD instruction
// Spot Attenuation with a linear falloff can be defined as
// (SdotL - cosOuterAngle) / (cosInnerAngle - cosOuterAngle)
// This can be rewritten as
// invAngleRange = 1.0 / (cosInnerAngle - cosOuterAngle)
// SdotL * invAngleRange + (-cosOuterAngle * invAngleRange)
// If we precompute the terms in a MAD instruction
float angleRange = cosInneAngle - cosOuterAngle;
lightAttenuationParams = new Vector4(cosOuterAngle,
Mathf.Approximately(angleRange, 0.0f) ? 1.0f : angleRange, quadAtten, rangeSq);
float smoothAngleRange = cosInneAngle - cosOuterAngle;
if (Mathf.Approximately(smoothAngleRange, 0.0f))
smoothAngleRange = 1.0f;
float invAngleRange = 1.0f / smoothAngleRange;
float add = -cosOuterAngle * invAngleRange;
lightAttenuationParams = new Vector4(invAngleRange, add, quadAtten, rangeSq);
lightAttenuationParams = new Vector4(-1.0f, 1.0f, quadAtten, rangeSq);
lightAttenuationParams = new Vector4(0.0f, 1.0f, quadAtten, rangeSq);
}
}

15
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightLighting.cginc


half SpotAttenuation(half3 spotDirection, half3 lightDirection, float4 attenuationParams)
{
// attenuationParams.x = cos(spotAngle * 0.5)
// attenuationParams.y = cos(innerSpotAngle * 0.5)
half SdotL = saturate(dot(spotDirection, lightDirection));
return saturate((SdotL - attenuationParams.x) / attenuationParams.y);
// Spot Attenuation with a linear falloff can be defined as
// (SdotL - cosOuterAngle) / (cosInnerAngle - cosOuterAngle)
// This can be rewritten as
// invAngleRange = 1.0 / (cosInnerAngle - cosOuterAngle)
// SdotL * invAngleRange + (-cosOuterAngle * invAngleRange)
// If we precompute the terms in a MAD instruction
half SdotL = dot(spotDirection, lightDirection);
// attenuationParams.x = invAngleRange
// attenuationParams.y = (-cosOuterAngle invAngleRange)
return saturate(SdotL * attenuationParams.x + attenuationParams.y);
}
// In per-vertex falloff there's no smooth falloff to light range. A hard cut will be noticed

正在加载...
取消
保存