浏览代码

HDRenderLoop: Add more lightmap suport (need testing)

/main
Sebastien Lagarde 8 年前
当前提交
f1a08280
共有 2 个文件被更改,包括 81 次插入58 次删除
  1. 105
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitData.hlsl
  2. 34
      Assets/ScriptableRenderLoop/ShaderLibrary/EntityLighting.hlsl

105
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitData.hlsl


// Fill SurfaceData/Builtin data function
//-------------------------------------------------------------------------------------
// Should SH (light probe / ambient) calculations be performed?
// - Presence of *either* of static or dynamic lightmaps means that diffuse indirect ambient is already in them, so no need for SH.
// - Passes that don't do ambient (additive, shadowcaster etc.) should not do SH either.
#define UNITY_SHOULD_SAMPLE_SH (!defined(LIGHTMAP_ON) && !defined(DYNAMICLIGHTMAP_ON) && !defined(UNITY_PASS_FORWARDADD) && !defined(UNITY_PASS_PREPASSBASE) && !defined(UNITY_PASS_SHADOWCASTER) && !defined(UNITY_PASS_META))
// In unity we can have a mix of fully baked lightmap (static lightmap) + enlighten realtime lightmap (dynamic lightmap)
// for each case we can have directional lightmap or not.
// Else we have lightprobe for dynamic/moving entity. Either SH9 per object lightprobe or SH4 per pixel per object volume probe
float3 SampleBakedGI(float3 positionWS, float3 normalWS, float2 uvStaticLightmap, float2 uvDynamicLightmap)
{
// If there is no lightmap, it assume lightprobe
#if (!defined(LIGHTMAP_ON) && !defined(DYNAMICLIGHTMAP_ON))
//Check that it is always the case
// UNITY_SAMPLE_FULL_SH_PER_PIXEL
// TODO: Confirm with Ionut but it seems that UNITY_LIGHT_PROBE_PROXY_VOLUME is always define for high end and
// unity_ProbeVolumeParams always bind.
if (unity_ProbeVolumeParams.x == 0.0)
{
// TODO: pass a tab of coefficient instead!
float4 SHCoefficients[7];
SHCoefficients[0] = unity_SHAr;
SHCoefficients[1] = unity_SHAg;
SHCoefficients[2] = unity_SHAb;
SHCoefficients[3] = unity_SHBr;
SHCoefficients[4] = unity_SHBg;
SHCoefficients[5] = unity_SHBb;
SHCoefficients[6] = unity_SHC;
float3 SampleBakedGI(float3 positionWS, float3 normalWS)
{
#if UNITY_SHOULD_SAMPLE_SH
#if UNITY_LIGHT_PROBE_PROXY_VOLUME
if (unity_ProbeVolumeParams.x == 1.0)
return SampleSH9(SHCoefficients, normalWS);
}
else
{
// TODO: Move all this to C++!
float4x4 identity = 0;

float4x4 translation = identity;
translation._m30_m31_m32 = -unity_ProbeVolumeMin.xyz;
return SampleProbeVolumeL0L1(TEXTURE3D_PASS(unity_ProbeVolumeSH, samplerunity_ProbeVolumeSH), positionWS, normalWS, WorldToTexture, unity_ProbeVolumeParams.z);
return SampleProbeVolumeSH4(TEXTURE3D_PASS(unity_ProbeVolumeSH, samplerunity_ProbeVolumeSH), positionWS, normalWS, WorldToTexture, unity_ProbeVolumeParams.z);
#else
// TODO: pass a tab of coefficient instead!
float4 SHCoefficients[7];
SHCoefficients[0] = unity_SHAr;
SHCoefficients[1] = unity_SHAg;
SHCoefficients[2] = unity_SHAb;
SHCoefficients[3] = unity_SHBr;
SHCoefficients[4] = unity_SHBg;
SHCoefficients[5] = unity_SHBb;
SHCoefficients[6] = unity_SHC;
return SampleSH9(SHCoefficients, normalWS);
#else
float3 bakeDiffuseLighting = float3(0.0, 0.0, 0.0);
#ifdef LIGHTMAP_ON
#ifdef DIRLIGHTMAP_COMBINED
bakeDiffuseLighting += SampleDirectionalLightmap(TEXTURE2D_PASS(unity_Lightmap, samplerunity_Lightmap),
TEXTURE2D_PASS(unity_LightmapInd, samplerunity_Lightmap),
uvStaticLightmap, unity_LightmapST);
#else
bakeDiffuseLighting += SampleSingleLightmap(TEXTURE2D_PASS(unity_Lightmap, samplerunity_Lightmap), uvStaticLightmap, unity_LightmapST);
#endif
#elif defined(LIGHTMAP_ON)
/*
float2 = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
#ifdef DYNAMICLIGHTMAP_ON
#ifdef DIRLIGHTMAP_COMBINED
bakeDiffuseLighting += SampleDirectionalLightmap(TEXTURE2D_PASS(unity_DynamicLightmap, samplerunity_DynamicLightmap),
TEXTURE2D_PASS(unity_DynamicDirectionality, samplerunity_DynamicLightmap),
uvDynamicLightmap, unity_DynamicLightmapST);
#else
bakeDiffuseLighting += SampleSingleLightmap(TEXTURE2D_PASS(unity_DynamicLightmap, samplerunity_DynamicLightmap), uvDynamicLightmap, unity_DynamicLightmapST);
#endif
#endif
// Baked lightmaps
half4 bakedColorTex = UNITY_SAMPLE_TEX2D(unity_Lightmap, data.lightmapUV.xy);
half3 bakedColor = DecodeLightmap(bakedColorTex);
return bakeDiffuseLighting;
#ifdef DIRLIGHTMAP_COMBINED
fixed4 bakedDirTex = UNITY_SAMPLE_TEX2D_SAMPLER(unity_LightmapInd, unity_Lightmap, data.lightmapUV.xy);
o_gi.indirect.diffuse = DecodeDirectionalLightmap(bakedColor, bakedDirTex, normalWorld);
#else // not directional lightmap
o_gi.indirect.diffuse = bakedColor;
#endif
#endif
#ifdef DYNAMICLIGHTMAP_ON
// Dynamic lightmaps
fixed4 realtimeColorTex = UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, data.lightmapUV.zw);
half3 realtimeColor = DecodeRealtimeLightmap(realtimeColorTex);
#ifdef DIRLIGHTMAP_COMBINED
half4 realtimeDirTex = UNITY_SAMPLE_TEX2D_SAMPLER(unity_DynamicDirectionality, unity_DynamicLightmap, data.lightmapUV.zw);
o_gi.indirect.diffuse += DecodeDirectionalLightmap(realtimeColor, realtimeDirTex, normalWorld);
#else
o_gi.indirect.diffuse += realtimeColor;
#endif
#endif
*/
#else
return float3(0.0, 0.0, 0.0);
#endif
}

// TODO: Sample lightmap/lightprobe/volume proxy
// This should also handle projective lightmap
// Note that data input above can be use to sample into lightmap (like normal)
builtinData.bakeDiffuseLighting = SampleBakedGI(input.positionWS, surfaceData.normalWS);
builtinData.bakeDiffuseLighting = SampleBakedGI(input.positionWS, surfaceData.normalWS, input.texCoord1, input.texCoord2);
// If we chose an emissive color, we have a dedicated texture for it and don't use MaskMap
#ifdef _EMISSIVE_COLOR

34
Assets/ScriptableRenderLoop/ShaderLibrary/EntityLighting.hlsl


// Volume is store as 3D texture with 4 R, G, B, X set of 4 coefficient store atlas in same 3D texture. X unused.
// TODO: the packing here is innefficient as we will fetch values far away from each other and they may not fit into the cache
// Suggest we pack only RGB not X and continuous
float3 SampleProbeVolumeL0L1(TEXTURE3D_ARGS(SHVolumeTexture, SHVolumeSampler), float3 positionWS, float3 normalWS, float4x4 WorldToTexture, float texelSizeX)
float3 SampleProbeVolumeSH4(TEXTURE3D_ARGS(SHVolumeTexture, SHVolumeSampler), float3 positionWS, float3 normalWS, float4x4 WorldToTexture, float texelSizeX)
{
float3 texCoord = mul(WorldToTexture, float4(positionWS, 1.0)).xyz;
// Each component is store in the same texture 3D. Each use one quater on the x axis

float4 shAb = SAMPLE_TEXTURE3D(SHVolumeTexture, SHVolumeSampler, texCoord);
return SHEvalLinearL0L1(normalWS, shAr, shAg, shAb);
}
// Following functions are to sample enlighten lightmaps (or lightmaps encoded the same way as our
// enlighten implementation). They assume use of RGB9E5 for illuminance map.
// It is required for other platform that aren't supporting this format to implement variant of these functions
// (But these kind of platform should use regular render loop and not news shaders).
float3 SampleSingleLightmap(TEXTURE2D_ARGS(lightmapTex, lightmapSampler), float2 uv, float4 transform)
{
// transform is scale and bias
uv = uv * transform.xy + transform.zw;
// Remark: Lightmap is RGB9E5
return SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgb;
}
float3 SampleDirectionalLightmap(TEXTURE2D_ARGS(lightmapTex, lightmapSampler), TEXTURE2D_ARGS(lightmapDirTex, lightmapDirSampler), float2 uv, float4 transform, float3 normalWS)
{
// In directional mode Enlighten bakes dominant light direction
// in a way, that using it for half Lambert and then dividing by a "rebalancing coefficient"
// gives a result close to plain diffuse response lightmaps, but normalmapped.
// Note that dir is not unit length on purpose. Its length is "directionality", like
// for the directional specular lightmaps.
// transform is scale and bias
uv = uv * transform.xy + transform.zw;
float4 direction = SAMPLE_TEXTURE2D(lightmapDirTex, lightmapDirSampler, uv);
// Remark: Lightmap is RGB9E5
float3 illuminance = SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgb;
float halfLambert = dot(normalWS, direction.xyz - 0.5) + 0.5;
return illuminance * halfLambert / max(1e-4, direction.w);
}
#endif // UNITY_ENTITY_LIGHTING_INCLUDED
正在加载...
取消
保存