浏览代码

Implement cookie support for point and spot lights

/main
Evgenii Golubev 8 年前
当前提交
4cc31cfe
共有 4 个文件被更改,包括 95 次插入28 次删除
  1. 38
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  2. 6
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs
  3. 30
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.hlsl
  4. 49
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.hlsl

38
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


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)
// TODO: add texture atlas support for cookie textures.
switch (light.lightType)
lightData.cookieIndex = m_CubeCookieTexArray.FetchSlice(light.light.cookie);
}
else if (light.lightType == LightType.Spot)
{
lightData.cookieIndex = m_CookieTexArray.FetchSlice(light.light.cookie);
case LightType.Spot:
lightData.cookieIndex = m_CookieTexArray.FetchSlice(light.light.cookie);
break;
case LightType.Directional:
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);

{
// Area and line lights are both currently stored as area lights on the GPU.
lightData.twoSided = additionalData.isDoubleSided;
lightData.size = new Vector2(additionalData.areaLightLength,
additionalData.areaLightWidth);
// Area and line lights are both currently stored as regular 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))

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


public Vector3 right;
public float specularScale;
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;
};

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);
}
//-----------------------------------------------------------------------------

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


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 a perspective projection of the hemisphere onto the disk.
coord.xy /= coord.z;
// Rescale the projective coordinates into the [0, 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);
}
}

正在加载...
取消
保存