分析GlobalIllumination函数的实现

代码在:
E:\OGL\scriptable-render-pipeline-08-global-illumination\Assets\My Pipeline\ShaderLibrary


float3 GlobalIllumination (VertexOutput input, LitSurface surface) 
{
	#if defined(LIGHTMAP_ON)
		float3 gi = SampleLightmap(input.lightmapUV);
		#if defined(DYNAMICLIGHTMAP_ON)
			gi += SampleDynamicLightmap(input.dynamicLightmapUV);
		#endif
		return gi;
	#elif defined(DYNAMICLIGHTMAP_ON)
		return SampleDynamicLightmap(input.dynamicLightmapUV);
	#else
		return SampleLightProbes(surface);
	#endif
}

三种情况:
第1:如果打开了静态光照,那么进行静态光照的采样。如果而且打开了动态光照,那么继续动态光照的采样。
第2:只打开动态光照,采用动态光照。
第3:动静都没有打开,则默认采样灯光探头。

采样静态光照的方法:

float3 SampleLightmap (float2 uv) 
{
	return SampleSingleLightmap(
		TEXTURE2D_PARAM(unity_Lightmap, samplerunity_Lightmap), uv,
		float4(1, 1, 0, 0),
		#if defined(UNITY_LIGHTMAP_FULL_HDR)
			false,
		#else
			true,
		#endif
		float4(LIGHTMAP_HDR_MULTIPLIER, LIGHTMAP_HDR_EXPONENT, 0.0, 0.0)
	);
}

这里调用函数SampleSingleLightmap函数,此函数在:
D:\Program Files\Unity2018.3.0f2\Unity\Editor\Data\Resources\PackageManager\Editor\package\ShaderLibrary\EntityLighting.hlsl

real3 SampleSingleLightmap(
TEXTURE2D_ARGS(lightmapTex, lightmapSampler), 
float2 uv, float4 transform, bool encodedLightmap, real4 decodeInstructions)
{
    // transform is scale and bias
    uv = uv * transform.xy + transform.zw;
    real3 illuminance = real3(0.0, 0.0, 0.0);
    // Remark: baked lightmap is RGBM for now, dynamic lightmap is RGB9E5
    if (encodedLightmap)
    {
        real4 encodedIlluminance = SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgba;
        illuminance = DecodeLightmap(encodedIlluminance, decodeInstructions);
    }
    else
    {
        illuminance = SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgb;
    }
    return illuminance;
}

TEXTURE2D_PARAM和TEXTURE2D_ARGS的宏定义:

#define TEXTURE2D_PARAM(textureName, samplerName)                textureName, samplerName
#define TEXTURE2D_ARGS(textureName, samplerName)                 TEXTURE2D(textureName),         SAMPLER(samplerName)

这里的第四个参数:float4 transform是对uv进行缩放和偏移。

// transform is scale and bias
uv = uv * transform.xy + transform.zw;

由于我们传递尽量的uv是已经经过缩放和偏移的(在顶点着色器中进行了处理),所以传递进去的transform是(1,1,0,0),前两个是uv的缩放,后两个是uv的偏移。

#if defined(LIGHTMAP_ON)
	output.lightmapUV = input.lightmapUV * unity_LightmapST.xy + unity_LightmapST.zw;
#endif

第5个参数:encodedLightmap
如果为true:

if (encodedLightmap)
{
    real4 encodedIlluminance = SAMPLE_TEXTURE2D(lightmapTex, lightmapSampler, uv).rgba;
    illuminance = DecodeLightmap(encodedIlluminance, decodeInstructions);
}

SAMPLE_TEXTURE2D定义如下:

#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2)                               textureName.Sample(samplerName, coord2)

采样返回的是#define real4 half4(手机平台)或者是#define real4 float4
DecodeLightmap函数如下:
// Remark: baked lightmap is RGBM for now, dynamic lightmap is RGB9E5

real3 DecodeLightmap(real4 encodedIlluminance, real4 decodeInstructions)
{
	#if defined(UNITY_LIGHTMAP_RGBM_ENCODING)
	    return UnpackLightmapRGBM(encodedIlluminance, decodeInstructions);
	#elif defined(UNITY_LIGHTMAP_DLDR_ENCODING) //双倍低动态double low dynamic range(色值乘二...)
	    return UnpackLightmapDoubleLDR(encodedIlluminance, decodeInstructions);
	#else // (UNITY_LIGHTMAP_FULL_HDR)
	    return encodedIlluminance.rgb;
	#endif
}

第一个:UnpackLightmapRGBM

real3 UnpackLightmapRGBM(real4 rgbmInput, real4 decodeInstructions)
{
	#ifdef UNITY_COLORSPACE_GAMMA
	    return rgbmInput.rgb * (rgbmInput.a * decodeInstructions.x);
	#else
	    return rgbmInput.rgb * (PositivePow(rgbmInput.a, decodeInstructions.y) * decodeInstructions.x);
	#endif
}

第二个:UnpackLightmapDoubleLDR

real3 UnpackLightmapDoubleLDR(real4 encodedColor, real4 decodeInstructions)
{
    return encodedColor.rgb * decodeInstructions.x;
}

看两个宏:LIGHTMAP_HDR_MULTIPLIER 和 LIGHTMAP_HDR_EXPONENT

#define LIGHTMAP_RGBM_MAX_GAMMA     real(5.0)       // NB: Must match value in RGBMRanges.h
#define LIGHTMAP_RGBM_MAX_LINEAR    real(34.493242) // LIGHTMAP_RGBM_MAX_GAMMA ^ 2.2

#ifdef UNITY_LIGHTMAP_RGBM_ENCODING
    #ifdef UNITY_COLORSPACE_GAMMA
        #define LIGHTMAP_HDR_MULTIPLIER LIGHTMAP_RGBM_MAX_GAMMA
        #define LIGHTMAP_HDR_EXPONENT   real(1.0)   // Not used in gamma color space
    #else
        #define LIGHTMAP_HDR_MULTIPLIER LIGHTMAP_RGBM_MAX_LINEAR
        #define LIGHTMAP_HDR_EXPONENT   real(2.2)
    #endif
#elif defined(UNITY_LIGHTMAP_DLDR_ENCODING)
    #ifdef UNITY_COLORSPACE_GAMMA
        #define LIGHTMAP_HDR_MULTIPLIER real(2.0)
    #else
        #define LIGHTMAP_HDR_MULTIPLIER real(4.59) // 2.0 ^ 2.2
    #endif
    #define LIGHTMAP_HDR_EXPONENT real(0.0)
#else // (UNITY_LIGHTMAP_FULL_HDR)
    #define LIGHTMAP_HDR_MULTIPLIER real(1.0)
    #define LIGHTMAP_HDR_EXPONENT real(1.0)
#endif

SampleDynamicLightmap

float3 SampleDynamicLightmap (float2 uv) 
{
	return SampleSingleLightmap(
		TEXTURE2D_PARAM(unity_DynamicLightmap, samplerunity_DynamicLightmap), uv,
		float4(1, 1, 0, 0), false,
		float4(LIGHTMAP_HDR_MULTIPLIER, LIGHTMAP_HDR_EXPONENT, 0.0, 0.0)
	);
}

SampleLightProbes

float3 SampleLightProbes (LitSurface s) 
{
	if (unity_ProbeVolumeParams.x) 
	{
		return SampleProbeVolumeSH4(
			TEXTURE3D_PARAM(unity_ProbeVolumeSH, samplerunity_ProbeVolumeSH),
			s.position, s.normal, unity_ProbeVolumeWorldToObject,
			unity_ProbeVolumeParams.y, unity_ProbeVolumeParams.z,
			unity_ProbeVolumeMin, unity_ProbeVolumeSizeInv
		);
	}
	else {
		float4 coefficients[7];
		coefficients[0] = unity_SHAr;
		coefficients[1] = unity_SHAg;
		coefficients[2] = unity_SHAb;
		coefficients[3] = unity_SHBr;
		coefficients[4] = unity_SHBg;
		coefficients[5] = unity_SHBb;
		coefficients[6] = unity_SHC;
		return max(0.0, SampleSH9(coefficients, s.normal));
	}

这里拒绝追踪了,再见!!!

发布了656 篇原创文章 · 获赞 111 · 访问量 37万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 酷酷鲨 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览