浏览代码

HDRenderLoop: Add LightProbe + ProbeVolume support (not tested)

/main
Sebastien Lagarde 8 年前
当前提交
d75972a9
共有 7 个文件被更改,包括 210 次插入2 次删除
  1. 82
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitData.hlsl
  2. 1
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Material.hlsl
  3. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/ShaderPass/ShaderPassGBuffer.hlsl
  4. 27
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/ShaderVariables.hlsl
  5. 11
      Assets/ScriptableRenderLoop/ShaderLibrary/API/D3D11.hlsl
  6. 80
      Assets/ScriptableRenderLoop/ShaderLibrary/EntityLighting.hlsl
  7. 9
      Assets/ScriptableRenderLoop/ShaderLibrary/EntityLighting.hlsl.meta

82
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))
//Check that it is always the case
// UNITY_SAMPLE_FULL_SH_PER_PIXEL
float3 SampleBakedGI(float3 positionWS, float3 normalWS)
{
#if UNITY_SHOULD_SAMPLE_SH
#if UNITY_LIGHT_PROBE_PROXY_VOLUME
if (unity_ProbeVolumeParams.x == 1.0)
{
// TODO: Move all this to C++!
float4x4 identity = 0;
identity._m00_m11_m22_m33 = 1.0;
float4x4 WorldToTexture = (unity_ProbeVolumeParams.y == 1.0f) ? unity_ProbeVolumeWorldToObject : identity;
float4x4 translation = identity;
translation._m30_m31_m32 = -unity_ProbeVolumeMin.xyz;
float4x4 scale = 0;
scale._m00_m11_m22_m33 = float4(unity_ProbeVolumeSizeInv.xyz, 1.0);
WorldToTexture = mul(mul(scale, translation), WorldToTexture);
return SampleProbeVolumeL0L1(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);
#endif
#elif defined(LIGHTMAP_ON)
/*
float2 = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
// Baked lightmaps
half4 bakedColorTex = UNITY_SAMPLE_TEX2D(unity_Lightmap, data.lightmapUV.xy);
half3 bakedColor = DecodeLightmap(bakedColorTex);
#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
}
void GetSurfaceAndBuiltinData(FragInput input, out SurfaceData surfaceData, out BuiltinData builtinData)
{
#ifdef _HEIGHTMAP

// 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 = UNITY_SAMPLE_TEX2D(_DiffuseLightingMap, input.texCoord1).rgb;
builtinData.bakeDiffuseLighting = SampleBakedGI(input.positionWS, surfaceData.normalWS);
// If we chose an emissive color, we have a dedicated texture for it and don't use MaskMap
#ifdef _EMISSIVE_COLOR

1
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Material.hlsl


#include "Debug.hlsl"
#include "GeometricTools.hlsl"
#include "CommonMaterial.hlsl"
#include "EntityLighting.hlsl"
//-----------------------------------------------------------------------------
// common Encode/Decode functions

2
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/ShaderPass/ShaderPassGBuffer.hlsl


GetSurfaceAndBuiltinData(input, surfaceData, builtinData);
BSDFData bsdfData = ConvertSurfaceDataToBSDFData(surfaceData);
Coordinate coord = GetCoordinate(input.unPositionSS, _ScreenSize.zw);
Coordinate coord = GetCoordinate(input.unPositionSS.xy, _ScreenSize.zw);
PreLightData preLightData = GetPreLightData(V, positionWS, coord, bsdfData);
ENCODE_INTO_GBUFFER(surfaceData, outGBuffer);

27
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/ShaderVariables.hlsl


CBUFFER_END
CBUFFER_START(UnityLighting)
// SH lighting environment
float4 unity_SHAr;
float4 unity_SHAg;
float4 unity_SHAb;
float4 unity_SHBr;
float4 unity_SHBg;
float4 unity_SHBb;
float4 unity_SHC;
CBUFFER_END
// Main lightmap
UNITY_DECLARE_TEX2D_HALF(unity_Lightmap);
// Dual or directional lightmap (always used with unity_Lightmap, so can share sampler)

CBUFFER_START(UnityLightmaps)
float4 unity_LightmapST;
float4 unity_DynamicLightmapST;
CBUFFER_END
// TODO: Change code here so probe volume use only one transform instead of all this parameters!
TEXTURE3D(unity_ProbeVolumeSH);
SAMPLER3D(samplerunity_ProbeVolumeSH)
CBUFFER_START(UnityProbeVolume)
// x = Disabled(0)/Enabled(1)
// y = Computation are done in global space(0) or local space(1)
// z = Texel size on U texture coordinate
float4 unity_ProbeVolumeParams;
float4x4 unity_ProbeVolumeWorldToObject;
float3 unity_ProbeVolumeSizeInv;
float3 unity_ProbeVolumeMin;
CBUFFER_END
// ----------------------------------------------------------------------------

11
Assets/ScriptableRenderLoop/ShaderLibrary/API/D3D11.hlsl


#define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex.SampleLevel (sampler##tex,coord, lod)
#define UNITY_SAMPLE_TEX2D_SAMPLER(tex,samplertex,coord) tex.Sample (sampler##samplertex,coord)
#define UNITY_DECLARE_TEX2D_HALF(tex) Texture2D tex; SamplerState sampler##tex
#define UNITY_DECLARE_TEX2D_FLOAT(tex) Texture2D tex; SamplerState sampler##tex
#define UNITY_DECLARE_TEX2D_NOSAMPLER_HALF(tex) Texture2D tex
#define UNITY_DECLARE_TEX2D_NOSAMPLER_FLOAT(tex) Texture2D tex
// Cubemaps
#define UNITY_DECLARE_TEXCUBE(tex) TextureCube tex; SamplerState sampler##tex
#define UNITY_ARGS_TEXCUBE(tex) TextureCube tex, SamplerState sampler##tex

#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3) textureName.SampleLevel(samplerName, coord3, lod)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3) textureName.Sample(samplerName, float4((coord3).xyz, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, float4((coord3).xyz, index), lod)
#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
#define TEXTURE2D_HALF TEXTURE2D
#define TEXTURE2D_FLOAT TEXTURE2D
#define SAMPLER2D_HALF SAMPLER2D
#define SAMPLER2D_FLOAT SAMPLER2D

80
Assets/ScriptableRenderLoop/ShaderLibrary/EntityLighting.hlsl


#ifndef UNITY_ENTITY_LIGHTING_INCLUDED
#define UNITY_ENTITY_LIGHTING_INCLUDED
#include "common.hlsl"
// TODO: Check if PI is correctly handled!
// Ref: "Efficient Evaluation of Irradiance Environment Maps" from ShaderX 2
float3 SHEvalLinearL0L1(float3 N, float4 shAr, float4 shAg, float4 shAb)
{
float4 vA = float4(N, 1.0);
float3 x1;
// Linear (L1) + constant (L0) polynomial terms
x1.r = dot(shAr, vA);
x1.g = dot(shAg, vA);
x1.b = dot(shAb, vA);
return x1;
}
float3 SHEvalLinearL2(float3 N, float4 shBr, float4 shBg, float4 shBb, float4 shC)
{
float3 x2;
// 4 of the quadratic (L2) polynomials
float4 vB = N.xyzz * N.yzzx;
x2.r = dot(shBr, vB);
x2.g = dot(shBg, vB);
x2.b = dot(shBb, vB);
// Final (5th) quadratic (L2) polynomial
float vC = N.x * N.x - N.y * N.y;
float3 x3 = shC.rgb * vC;
return x2 + x3;
}
float3 SampleSH9(float4 SHCoefficients[7], float3 N)
{
float4 shAr = SHCoefficients[0];
float4 shAg = SHCoefficients[1];
float4 shAb = SHCoefficients[2];
float4 shBr = SHCoefficients[3];
float4 shBg = SHCoefficients[4];
float4 shBb = SHCoefficients[5];
float4 shCr = SHCoefficients[6];
// Linear + constant polynomial terms
float3 res = SHEvalLinearL0L1(N, shAr, shAg, shAb);
// Quadratic polynomials
res += SHEvalLinearL2(N, shBr, shBg, shBb, shCr);
return res;
}
// This sample a 3D volume storing SH
// 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 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
// Here we get R component then increase by step size (0.25) to get other component. This assume 4 component
// but last one is not used.
// Clamp to edge of the "internal" texture, as R is from half texel to size of R texture minus half texel.
// This avoid leaking
texCoord.x = clamp(texCoord.x * 0.25, 0.5 * texelSizeX, 0.25 - 0.5 * texelSizeX);
float4 shAr = SAMPLE_TEXTURE3D(SHVolumeTexture, SHVolumeSampler, texCoord);
texCoord.x += 0.25;
float4 shAg = SAMPLE_TEXTURE3D(SHVolumeTexture, SHVolumeSampler, texCoord);
texCoord.x += 0.25;
float4 shAb = SAMPLE_TEXTURE3D(SHVolumeTexture, SHVolumeSampler, texCoord);
return SHEvalLinearL0L1(normalWS, shAr, shAg, shAb);
}
#endif // UNITY_ENTITY_LIGHTING_INCLUDED

9
Assets/ScriptableRenderLoop/ShaderLibrary/EntityLighting.hlsl.meta


fileFormatVersion: 2
guid: 0303be75670325342b4bf5697686e77b
timeCreated: 1477930471
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存