浏览代码

Merge branch 'LightCookies'

/main
Evgenii Golubev 8 年前
当前提交
d68924b2
共有 9 个文件被更改,包括 197 次插入52 次删除
  1. 5
      .gitignore
  2. 1
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset
  3. 53
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  4. 32
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs
  5. 26
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs.hlsl
  6. 30
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.hlsl
  7. 89
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.hlsl
  8. 10
      Assets/ScriptableRenderLoop/ShaderLibrary/AreaLighting.hlsl
  9. 3
      Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl

5
.gitignore


Library/*
Temp/*
obj/*
*.csproj
*.sln
*.suo

*.aspx
*.sdf
*.userprefs
Assets/UnityHDRI.meta
Assets/UnityHDRI/Gareoult/GareoultWhiteBalanced.exr
obj/Debug/Assembly-CSharp.csproj.FileListAbsolute.txt

1
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset


rotation: 0
exposure: 0
multiplier: 1
skyResolution: 256
m_ShadowSettings:
enabled: 1
shadowAtlasWidth: 4096

53
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


var directionalLightData = new DirectionalLightData();
// Light direction for directional and is opposite to the forward direction
directionalLightData.direction = -light.light.transform.forward;
directionalLightData.direction = -light.light.transform.forward;
directionalLightData.up = -light.light.transform.up;
directionalLightData.positionWS = light.light.transform.position;
directionalLightData.invScaleX = 1.0f / light.light.transform.localScale.x;
directionalLightData.invScaleY = 1.0f / light.light.transform.localScale.y;
directionalLightData.cookieIndex = Int32.MinValue;
if (light.light.cookie != null)
{
if (light.light.cookie.dimension == TextureDimension.Tex2D)
{
directionalLightData.cookieIndex = m_CookieTexArray.FetchSlice(light.light.cookie);
}
else // Cube
{
// Note the bitwise (one's) complement operator which flips the bits.
directionalLightData.cookieIndex = ~m_CubeCookieTexArray.FetchSlice(light.light.cookie);
}
}
bool hasDirectionalShadows = light.light.shadows != LightShadows.None && shadowOutput.GetShadowSliceCountLightIndex(lightIndex) != 0;
bool hasDirectionalNotReachMaxLimit = lightList.directionalShadows.Count == 0; // Only one cascade shadow allowed

var innerConePercent = additionalData.GetInnerSpotPercent01();
var cosSpotOuterHalfAngle = Mathf.Clamp(Mathf.Cos(spotAngle * 0.5f * Mathf.Deg2Rad), 0.0f, 1.0f);
var sinSpotOuterHalfAngle = Mathf.Sqrt(1.0f - cosSpotOuterHalfAngle * cosSpotOuterHalfAngle);
// TODO: find a proper place to store the cotangent.
lightData.size.x = cosSpotOuterHalfAngle / sinSpotOuterHalfAngle;
}
else
{

lightData.cookieIndex = -1;
lightData.shadowIndex = -1;
bool hasCookie = light.light.cookie != null;
if (hasCookie)
if (light.light.cookie != null)
if (light.lightType == LightType.Point)
{
lightData.cookieIndex = m_CubeCookieTexArray.FetchSlice(light.light.cookie);
}
else if (light.lightType == LightType.Spot)
// TODO: add texture atlas support for cookie textures.
switch (light.lightType)
lightData.cookieIndex = m_CookieTexArray.FetchSlice(light.light.cookie);
case LightType.Spot:
lightData.cookieIndex = m_CookieTexArray.FetchSlice(light.light.cookie);
break;
case LightType.Point:
lightData.cookieIndex = m_CubeCookieTexArray.FetchSlice(light.light.cookie);
break;
}
}

}
}
lightData.size = new Vector2(additionalData.areaLightLength, additionalData.areaLightWidth);
lightData.twoSided = additionalData.isDoubleSided;
if (additionalData.archetype == LightArchetype.Punctual)
{
lightList.punctualLights.Add(lightData);

{
lightData.twoSided = additionalData.isDoubleSided;
lightData.size = new Vector2(additionalData.areaLightLength,
additionalData.areaLightWidth);
// Area and line lights are both currently stored as area lights on the GPU.
lightList.areaLights.Add(lightData);
lightList.areaCullIndices.Add(lightIndex);

public void PushGlobalParams(Camera camera, RenderLoop renderLoop, HDRenderLoop.LightList lightList)
{
//Shader.SetGlobalTexture("_CookieTextures", m_CookieTexArray.GetTexCache());
//Shader.SetGlobalTexture("_CubeCookieTextures", m_CubeCookieTexArray.GetTexCache());
Shader.SetGlobalTexture("_CookieTextures", m_CookieTexArray.GetTexCache());
Shader.SetGlobalTexture("_CookieCubeTextures", m_CubeCookieTexArray.GetTexCache());
Shader.SetGlobalTexture("_EnvTextures", m_CubeReflTexArray.GetTexCache());
if (m_SkyRenderer.IsSkyValid(m_SkyParameters))

32
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs


public enum GPULightType
{
Directional,
Spot,
Spot,
Point,
ProjectorOrtho,
ProjectorPyramid,

public float invSqrAttenuationRadius;
public Vector3 color;
public float angleScale; // Spot light
public float angleScale; // Spot light
public float angleOffset;
public float angleOffset; // Spot light
public float diffuseScale; // Spot light
public float diffuseScale;
public float shadowDimmer;
// index are -1 if not used
public int shadowIndex;

public GPULightType lightType;
public GPULightType lightType;
public Vector2 size;
public Vector2 size; // x = cot(outerHalfAngle) for spot lights
public bool twoSided;
};

public Vector3 direction;
public float diffuseScale;
public Vector3 up;
public float invScaleX;
public Vector3 positionWS;
public float invScaleY;
public float specularScale;
public float specularScale;
// Sun disc size
public float cosAngle; // Distance to disk
public float sinAngle; // Disk radius
public int shadowIndex;
public float unused;
// Sun disc size
public float cosAngle; // Distance to the disk
public float sinAngle; // Disk radius
public int shadowIndex; // -1 if unused
public int cookieIndex; // INT_MIN if unused; (i >= 0) ? (i2D = i) : (iCube = ~i)
};

26
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs.hlsl


{
float3 direction;
float diffuseScale;
float3 up;
float invScaleX;
float3 positionWS;
float invScaleY;
float unused;
int cookieIndex;
};
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.PunctualShadowData

{
return value.diffuseScale;
}
float3 GetUp(DirectionalLightData value)
{
return value.up;
}
float GetInvScaleX(DirectionalLightData value)
{
return value.invScaleX;
}
float3 GetPositionWS(DirectionalLightData value)
{
return value.positionWS;
}
float GetInvScaleY(DirectionalLightData value)
{
return value.invScaleY;
}
float3 GetColor(DirectionalLightData value)
{
return value.color;

{
return value.shadowIndex;
}
float GetUnused(DirectionalLightData value)
int GetCookieIndex(DirectionalLightData value)
return value.unused;
return value.cookieIndex;
}
//

30
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.hlsl


TEXTURE2D_ARRAY(_IESArray);
SAMPLER2D(sampler_IESArray);
// Used by directional and spot lights
TEXTURE2D_ARRAY(_CookieTextures);
SAMPLER2D(sampler_CookieTextures);
// Used by directional and point lights
TEXTURECUBE_ARRAY(_CookieCubeTextures);
SAMPLERCUBE(sampler_CookieCubeTextures);
// Use texture array for reflection
TEXTURECUBE_ARRAY(_EnvTextures);
SAMPLERCUBE(sampler_EnvTextures);

// float3 shadowPosDY = ddy_fine(positionTXS);
return SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, positionTXS);
}
//-----------------------------------------------------------------------------
// Cookie sampling functions
// ----------------------------------------------------------------------------
#define SINGLE_PASS_CONTEXT_SAMPLE_COOKIE_TEXTURES 0
// Used by directional and spot lights.
// Returns the color in the RGB components, and the transparency (lack of occlusion) in A.
float4 SampleCookie2D(LightLoopContext lightLoopContext, float2 coord, int index)
{
return SAMPLE_TEXTURE2D_ARRAY_LOD(_CookieTextures, sampler_CookieTextures, coord, index, 0);
}
#define SINGLE_PASS_CONTEXT_SAMPLE_COOKIE_CUBE_TEXTURES 0
// Used by directional and point lights.
// Returns the color in the RGB components, and the transparency (lack of occlusion) in A.
float4 SampleCookieCube(LightLoopContext lightLoopContext, float3 coord, int index)
{
return SAMPLE_TEXTURECUBE_ARRAY_LOD(_CookieCubeTextures, sampler_CookieCubeTextures, coord, index, 0);
}
//-----------------------------------------------------------------------------

89
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.hlsl


float3 L = lightData.direction;
float illuminance = saturate(dot(bsdfData.normalWS, L));
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
float3 cookieColor = float3(1.0, 1.0, 1.0);
[branch] if (lightData.shadowIndex >= 0 && illuminance > 0.0f)
{

}
[branch] if (lightData.cookieIndex != INT_MIN && illuminance > 0.0)
{
float4 cookie;
[branch] if (lightData.cookieIndex >= 0)
{
// The cookie is a 2D texture.
float3 unL = positionWS - lightData.positionWS;
// Project 'unL' onto the light's axes.
float3 right = cross(lightData.up, lightData.direction);
float2 coord = float2(dot(unL, right), dot(unL, lightData.up));
// Rescale the texture.
coord.x *= lightData.invScaleX;
coord.y *= lightData.invScaleY;
// Remap the texture coordinates from [-1, 1]^2 to [0, 1]^2.
coord = coord * 0.5 + 0.5;
// Tile the texture via wrapping. TODO: the sampler should do this for us.
cookie = SampleCookie2D(lightLoopContext, frac(coord), lightData.cookieIndex);
}
else
{
// The cookie is a cubemap. We flip the bits to get the real index.
lightData.cookieIndex = ~lightData.cookieIndex;
cookie = SampleCookieCube(lightLoopContext, L, lightData.cookieIndex);
}
cookieColor = cookie.rgb;
illuminance *= cookie.a;
}
[branch] if (illuminance > 0.0f)
{
BSDF(V, L, positionWS, preLightData, bsdfData, diffuseLighting, specularLighting);

attenuation *= GetAngleAttenuation(L, -lightData.forward, lightData.angleScale, lightData.angleOffset);
float illuminance = saturate(dot(bsdfData.normalWS, L)) * attenuation;
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
float3 cookieColor = float3(1.0, 1.0, 1.0);
/*
[branch] if (lightData.cookieIndex && illuminance > 0.0f)
[branch] if (lightData.cookieIndex >= 0 && illuminance > 0.0)
illuminance *= SampleCookie(lightData.cookieIndex, lightToWorld, L);
// Rotate 'L' into the light space.
// We perform the negation because lights are oriented backwards (-Z).
float3 coord = mul(-L, transpose(lightToWorld));
float4 cookie;
[branch] if (lightData.lightType == GPULIGHTTYPE_SPOT)
{
// Perform the perspective projection of the hemisphere onto the disk.
coord.xy /= coord.z;
// Rescale the projective coordinates to fit into the [-1, 1]^2 range.
float cotOuterHalfAngle = lightData.size.x;
coord.xy *= cotOuterHalfAngle;
// Remap the texture coordinates from [-1, 1]^2 to [0, 1]^2.
coord.xy = coord.xy * 0.5 + 0.5;
cookie = SampleCookie2D(lightLoopContext, coord.xy, lightData.cookieIndex);
}
else // GPULIGHTTYPE_POINT
{
cookie = SampleCookieCube(lightLoopContext, coord, lightData.cookieIndex);
}
cookieColor = cookie.rgb;
illuminance *= cookie.a;
*/
[branch] if (lightData.IESIndex >= 0 && illuminance > 0.0f)
[branch] if (lightData.IESIndex >= 0 && illuminance > 0.0)
{
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);
float2 sphericalCoord = GetIESTextureCoordinate(lightToWorld, L);

[branch] if (lightData.shadowIndex >= 0 && illuminance > 0.0f)
[branch] if (lightData.shadowIndex >= 0 && illuminance > 0.0)
{
float3 offset = float3(0.0, 0.0, 0.0); // GetShadowPosOffset(nDotL, normal);
float shadowAttenuation = GetPunctualShadowAttenuation(lightLoopContext, positionWS + offset, lightData.shadowIndex, L, preLightData.unPositionSS);

}
[branch] if (illuminance > 0.0f)
[branch] if (illuminance > 0.0)
diffuseLighting *= lightData.color * illuminance * lightData.diffuseScale;
specularLighting *= lightData.color * illuminance * lightData.specularScale;
diffuseLighting *= (cookieColor * lightData.color) * (illuminance * lightData.diffuseScale);
specularLighting *= (cookieColor * lightData.color) * (illuminance * lightData.specularScale);
}
}

10
Assets/ScriptableRenderLoop/ShaderLibrary/AreaLighting.hlsl


float tLDDL2 = l2rcpD / (d * d + l2 * l2);
float intWt = LineFwt(tLDDL2, l2) - LineFwt(tLDDL1, l1);
float intP0 = LineFpo(tLDDL2, l2rcpD, rcp(d)) - LineFpo(tLDDL1, l1rcpD, rcp(d));
// Guard against numerical precision issues.
return max(intP0 * normal.z + intWt * tangent.z, 0.0);
return intP0 * normal.z + intWt * tangent.z;
}
// Computes 1.0 / length(mul(ortho, transpose(inverse(invM)))).

float width = ComputeLineWidthFactor(invM, B);
if (P2.z <= 0.0)
if (P1.z > P2.z)
// Convention: 'P2' is above the horizon.
// Convention: 'P2' is above 'P1', with the tangent pointing upwards.
Swap(P1, P2);
}

// Integrate the clamped cosine over the line segment.
float irradiance = LineIrradiance(l1, l2, P0, T);
return INV_PI * width * irradiance;
// Guard against numerical precision issues.
return max(INV_PI * width * irradiance, 0.0);
}
#endif // UNITY_AREA_LIGHTING_INCLUDED

3
Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl


#define FLT_EPSILON 1.192092896e-07 // Smallest positive number, such that 1.0 + FLT_EPSILON != 1.0
#define FLT_MAX 3.402823466e+38 // Maximum representable floating-point number
#define INT_MIN -2147483648 // Minimum (signed) int value
#define INT_MAX 2147483647 // Maximum (signed) int value
#define MERGE_NAME(X, Y) X##Y
float DegToRad(float deg)

正在加载...
取消
保存