浏览代码

Merge pull request #534 from Unity-Technologies/Add-refraction-cubemap-support

Add refraction cubemap support
/Yibing-Project-2
GitHub 7 年前
当前提交
01e3b45b
共有 4 个文件被更改,包括 101 次插入22 次删除
  1. 8
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs
  2. 6
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs.hlsl
  3. 45
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl
  4. 64
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl

8
ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs


// Disk,
};
// This is use to distinguish between reflection and refraction probe in LightLoop
[GenerateHLSL]
public enum GPUImageBasedLightingType
{
Reflection,
Refraction
};
// These structures share between C# and hlsl need to be align on float4, so we pad them.
[GenerateHLSL]
public struct DirectionalLightData

6
ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs.hlsl


#define GPULIGHTTYPE_RECTANGLE (6)
//
// UnityEngine.Experimental.Rendering.HDPipeline.GPUImageBasedLightingType: static fields
//
#define GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION (0)
#define GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION (1)
//
// UnityEngine.Experimental.Rendering.HDPipeline.EnvShapeType: static fields
//
#define ENVSHAPETYPE_NONE (0)

45
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl


#else
uint envLightIndex = i;
#endif
IndirectLighting lighting = EvaluateBSDF_Env(context, V, posInput, preLightData, _EnvLightDatas[envLightIndex], bsdfData, _EnvLightDatas[envLightIndex].envShapeType,
reflectionHierarchyWeight);
IndirectLighting lighting = EvaluateBSDF_Env( context, V, posInput, preLightData, _EnvLightDatas[envLightIndex], bsdfData, _EnvLightDatas[envLightIndex].envShapeType,
GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION, reflectionHierarchyWeight);
// Refraction probe and reflection probe will process exactly the same weight. It will be good for performance to be able to share this computation
// However it is hard to deal with the fact that reflectionHierarchyWeight and refractionHierarchyWeight have not the same values, they are independent
// The refraction probe is rarely used and happen only with sphere shape and high IOR. So we accept the slow path that use more simple code and
// doesn't affect the performance of the reflection which is more important.
// We reuse LIGHTFEATUREFLAGS_SSREFRACTION flag as refraction is mainly base on the screen. Would be aa waste to not use screen and only cubemap.
if (featureFlags & LIGHTFEATUREFLAGS_SSREFRACTION)
{
for (i = 0; i < envLightCount && refractionHierarchyWeight < 1.0; ++i)
{
#ifdef LIGHTLOOP_TILE_PASS
uint envLightIndex = FetchIndex(envLightStart, i);
#else
uint envLightIndex = i;
#endif
IndirectLighting lighting = EvaluateBSDF_Env( context, V, posInput, preLightData, _EnvLightDatas[envLightIndex], bsdfData, _EnvLightDatas[envLightIndex].envShapeType,
GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION, refractionHierarchyWeight);
AccumulateIndirectLighting(lighting, aggregateLighting);
}
}
if (featureFlags & LIGHTFEATUREFLAGS_SKY)
// Only apply the sky IBL if the sky texture is available
if (featureFlags & LIGHTFEATUREFLAGS_SKY && _EnvLightSkyEnabled)
// Only apply the sky IBL if the sky texture is available, and if we haven't yet accumulated enough IBL lighting.
if (_EnvLightSkyEnabled && reflectionHierarchyWeight < 1.0)
// Only apply the sky if we haven't yet accumulated enough IBL lighting.
if (reflectionHierarchyWeight < 1.0)
IndirectLighting lighting = EvaluateBSDF_Env(context, V, posInput, preLightData, envLightSky, bsdfData, ENVSHAPETYPE_SKY, reflectionHierarchyWeight);
IndirectLighting lighting = EvaluateBSDF_Env(context, V, posInput, preLightData, envLightSky, bsdfData, ENVSHAPETYPE_SKY, GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION, reflectionHierarchyWeight);
}
if (featureFlags & LIGHTFEATUREFLAGS_SSREFRACTION)
{
if (refractionHierarchyWeight < 1.0)
{
// The sky is a single cubemap texture separate from the reflection probe texture array (different resolution and compression)
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_SKY;
EnvLightData envLightSky = InitSkyEnvLightData(0); // The sky data are generated on the fly so the compiler can optimize the code
IndirectLighting lighting = EvaluateBSDF_Env(context, V, posInput, preLightData, envLightSky, bsdfData, ENVSHAPETYPE_SKY, GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION, refractionHierarchyWeight);
AccumulateIndirectLighting(lighting, aggregateLighting);
}
}
}
}

64
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


|| any(refractedBackPointSS < 0.0)
|| any(refractedBackPointSS > 1.0))
{
lighting.specularTransmitted = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, s_trilinear_clamp_sampler, posInput.positionSS, 0.0).rgb;
// TODO: check with fred. If a pixel is in front of the object we should not sample at all and put hierarchyWeight to 1.0 so we discard the effect as it is occlusion
// Otherwise fallback on cubemap
// Do nothing and don't update the hierarchy weight so we can fall back on refraction probe
return lighting;
}

// _preIntegratedFGD and _CubemapLD are unique for each BRDF
IndirectLighting EvaluateBSDF_Env( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData, int envShapeType,
PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData, int envShapeType, int GPUImageBasedLightingType,
#if !HAS_REFRACTION
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
return lighting;
#endif
float3 envLighting = float3(0.0, 0.0, 0.0);
lighting.specularReflected = IntegrateSpecularGGXIBLRef(lightLoopContext, V, preLightData, lightData, bsdfData);
envLighting = IntegrateSpecularGGXIBLRef(lightLoopContext, V, preLightData, lightData, bsdfData);
/*
#ifdef LIT_DIFFUSE_LAMBERT_BRDF
lighting.directDiffuse += IntegrateLambertIBLRef(lightData, V, bsdfData);
#else
lighting.directDiffuse += IntegrateDisneyDiffuseIBLRef(lightLoopContext, V, preLightData, lightData, bsdfData);
#endif
*/
hierarchyWeight = 0.0;
// TODO: Do refraction reference (is it even possible ?)
// #ifdef LIT_DIFFUSE_LAMBERT_BRDF
// envLighting += IntegrateLambertIBLRef(lightData, V, bsdfData);
// #else
// envLighting += IntegrateDisneyDiffuseIBLRef(lightLoopContext, V, preLightData, lightData, bsdfData);
// #endif
weight = 1.0;
#else

float3 R = preLightData.iblDirWS;
float3 coatR = preLightData.coatIblDirWS;
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
{
// This is the same code than what is use in screen space refraction
// TODO: put this code into a function
#if defined(_REFRACTION_PLANE)
R = refract(-V, bsdfData.normalWS, 1.0 / bsdfData.ior);
#elif defined(_REFRACTION_SPHERE)
float3 R1 = refract(-V, bsdfData.normalWS, 1.0 / bsdfData.ior);
// Center of the tangent sphere
float3 C = posInput.positionWS - bsdfData.normalWS * bsdfData.thickness * 0.5;
// Second refraction (tangent sphere out)
float NoR1 = dot(bsdfData.normalWS, R1);
// Optical depth within the sphere
float opticalDepth = -NoR1 * bsdfData.thickness;
// Out hit point in the tangent sphere
float3 P1 = posInput.positionWS + R1 * opticalDepth;
// Out normal
float3 N1 = normalize(C - P1);
// Out refracted ray
R = refract(R1, N1, bsdfData.ior);
#endif
}
// In Unity the cubemaps are capture with the localToWorld transform of the component.
// This mean that location and orientation matter. So after intersection of proxy volume we need to convert back to world.

// Evaluate the Clear Coat color
float4 preLD = SampleEnv(lightLoopContext, lightData.envIndex, coatR, 0.0);
lighting.specularReflected += F * preLD.rgb * bsdfData.coatCoverage;
envLighting += F * preLD.rgb * bsdfData.coatCoverage;
// Change the Fresnel term to account for transmission through Clear Coat and reflection on the base layer.
F = Sqr(-F * bsdfData.coatCoverage + 1.0);

lighting.specularReflected += F * preLD.rgb * preLightData.specularFGD;
envLighting += F * preLD.rgb * preLightData.specularFGD;
lighting.specularReflected *= weight;
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION)
lighting.specularReflected = envLighting * weight;
else
lighting.specularTransmitted = envLighting * weight;
return lighting;
}

正在加载...
取消
保存