浏览代码

HDRenderLoop: Continue to add misc function (intersection, aniso support)

/main
sebastienlagarde 8 年前
当前提交
dc88f7bf
共有 10 个文件被更改,包括 239 次插入102 次删除
  1. 66
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/LightDefinition.cs.hlsl
  2. 4
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/LightingForward.hlsl
  3. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/LitTemplate.hlsl
  4. 16
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/BuiltinData.cs.hlsl
  5. 1
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit.cs
  6. 78
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit.cs.hlsl
  7. 85
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit.hlsl
  8. 8
      Assets/ScriptableRenderLoop/ShaderLibrary/CommonLighting.hlsl
  9. 72
      Assets/ScriptableRenderLoop/ShaderLibrary/GeometricTools.hlsl
  10. 9
      Assets/ScriptableRenderLoop/ShaderLibrary/ImageBasedLighting.hlsl

66
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/LightDefinition.cs.hlsl


// PackingRules = Exact
struct PunctualLightData
{
float3 positionWS;
float invSqrAttenuationRadius;
float3 color;
float useDistanceAttenuation;
float3 forward;
float diffuseScale;
float3 up;
float specularScale;
float3 right;
float shadowDimmer;
float angleScale;
float angleOffset;
float2 unused2;
float3 positionWS;
float invSqrAttenuationRadius;
float3 color;
float useDistanceAttenuation;
float3 forward;
float diffuseScale;
float3 up;
float specularScale;
float3 right;
float shadowDimmer;
float angleScale;
float angleOffset;
float2 unused2;
};
// Generated from UnityEngine.ScriptableRenderLoop.AreaLightData

float3 positionWS;
float3 positionWS;
};
// Generated from UnityEngine.ScriptableRenderLoop.EnvLightData

float3 positionWS;
float3 positionWS;
};
// Generated from UnityEngine.ScriptableRenderLoop.PlanarLightData

float3 positionWS;
float3 positionWS;
};
//

{
return value.positionWS;
return value.positionWS;
return value.invSqrAttenuationRadius;
return value.invSqrAttenuationRadius;
return value.color;
return value.color;
return value.useDistanceAttenuation;
return value.useDistanceAttenuation;
return value.forward;
return value.forward;
return value.diffuseScale;
return value.diffuseScale;
return value.up;
return value.up;
return value.specularScale;
return value.specularScale;
return value.right;
return value.right;
return value.shadowDimmer;
return value.shadowDimmer;
return value.angleScale;
return value.angleScale;
return value.angleOffset;
return value.angleOffset;
return value.unused2;
return value.unused2;
}
//

{
return value.positionWS;
return value.positionWS;
}
//

{
return value.positionWS;
return value.positionWS;
}
//

{
return value.positionWS;
return value.positionWS;

4
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/LightingForward.hlsl


}
*/
for (int i = 0; i < _EnvLightCount; ++i)
for (int j = 0; j < _EnvLightCount; ++j)
EvaluateBSDF_Env(V, positionWS, prelightData, _EnvLightList[i], bsdfData, UNITY_PASS_ENV(_ReflCubeTextures), localDiffuseLighting, localSpecularLighting);
EvaluateBSDF_Env(V, positionWS, prelightData, _EnvLightList[j], bsdfData, UNITY_PASS_ENV(_ReflCubeTextures), localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}

2
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/LitTemplate.hlsl


surfaceData.metalic *= _Metalic;
surfaceData.tangentWS = float3(1.0, 0.0, 0.0);
surfaceData.tangentWS = input.tangentToWorld[0].xyz;
surfaceData.anisotropy = 0;
surfaceData.specular = 0.04;

16
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/BuiltinData.cs.hlsl


// PackingRules = Exact
struct BuiltinData
{
float opacity;
float3 bakeDiffuseLighting;
float3 emissiveColor;
float emissiveIntensity;
float2 velocity;
float2 distortion;
float distortionBlur;
float opacity;
float3 bakeDiffuseLighting;
float3 emissiveColor;
float emissiveIntensity;
float2 velocity;
float2 distortion;
float distortionBlur;

1
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit.cs


public Vector3 bitangentWS;
public float roughnessT;
public float roughnessB;
public float anisotropy;
// fold into fresnel0

78
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit.cs.hlsl


#define DEBUGVIEW_LIT_BSDFDATA_BITANGENT_WS (1038)
#define DEBUGVIEW_LIT_BSDFDATA_ROUGHNESS_T (1039)
#define DEBUGVIEW_LIT_BSDFDATA_ROUGHNESS_B (1040)
#define DEBUGVIEW_LIT_BSDFDATA_SUB_SURFACE_RADIUS (1041)
#define DEBUGVIEW_LIT_BSDFDATA_THICKNESS (1042)
#define DEBUGVIEW_LIT_BSDFDATA_SUB_SURFACE_PROFILE (1043)
#define DEBUGVIEW_LIT_BSDFDATA_COAT_NORMAL_WS (1044)
#define DEBUGVIEW_LIT_BSDFDATA_COAT_ROUGHNESS (1045)
#define DEBUGVIEW_LIT_BSDFDATA_ANISOTROPY (1041)
#define DEBUGVIEW_LIT_BSDFDATA_SUB_SURFACE_RADIUS (1042)
#define DEBUGVIEW_LIT_BSDFDATA_THICKNESS (1043)
#define DEBUGVIEW_LIT_BSDFDATA_SUB_SURFACE_PROFILE (1044)
#define DEBUGVIEW_LIT_BSDFDATA_COAT_NORMAL_WS (1045)
#define DEBUGVIEW_LIT_BSDFDATA_COAT_ROUGHNESS (1046)
float3 baseColor;
float specularOcclusion;
float3 normalWS;
float perceptualSmoothness;
int materialId;
float ambientOcclusion;
float3 tangentWS;
float anisotropy;
float metalic;
float specular;
float subSurfaceRadius;
float thickness;
int subSurfaceProfile;
float3 coatNormalWS;
float coatPerceptualSmoothness;
float3 specularColor;
float3 baseColor;
float specularOcclusion;
float3 normalWS;
float perceptualSmoothness;
int materialId;
float ambientOcclusion;
float3 tangentWS;
float anisotropy;
float metalic;
float specular;
float subSurfaceRadius;
float thickness;
int subSurfaceProfile;
float3 coatNormalWS;
float coatPerceptualSmoothness;
float3 specularColor;
};
// Generated from UnityEngine.ScriptableRenderLoop.Lit.BSDFData

float3 diffuseColor;
float3 fresnel0;
float specularOcclusion;
float3 normalWS;
float perceptualRoughness;
float roughness;
float materialId;
float3 tangentWS;
float3 bitangentWS;
float roughnessT;
float roughnessB;
float subSurfaceRadius;
float thickness;
int subSurfaceProfile;
float3 coatNormalWS;
float coatRoughness;
float3 diffuseColor;
float3 fresnel0;
float specularOcclusion;
float3 normalWS;
float perceptualRoughness;
float roughness;
float materialId;
float3 tangentWS;
float3 bitangentWS;
float roughnessT;
float roughnessB;
float anisotropy;
float subSurfaceRadius;
float thickness;
int subSurfaceProfile;
float3 coatNormalWS;
float coatRoughness;

85
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit.hlsl


bsdfData.fresnel0 = lerp(float3(surfaceData.specular, surfaceData.specular, surfaceData.specular), surfaceData.baseColor, surfaceData.metalic);
bsdfData.tangentWS = surfaceData.tangentWS;
bsdfData.bitangentWS = cross(surfaceData.normalWS, surfaceData.tangentWS);
bsdfData.bitangentWS = cross(surfaceData.normalWS, surfaceData.tangentWS);
bsdfData.anisotropy = surfaceData.anisotropy;
bsdfData.materialId = surfaceData.anisotropy > 0 ? MATERIALID_LIT_ANISO : bsdfData.materialId;
}

bsdfData.tangentWS = UnpackNormalOctEncode(float2(inGBuffer2.rg * 2.0 - 1.0));
bsdfData.bitangentWS = cross(bsdfData.normalWS, bsdfData.tangentWS);
ConvertAnisotropyToRoughness(bsdfData.roughness, anisotropy, bsdfData.roughnessT, bsdfData.roughnessB);
bsdfData.anisotropy = anisotropy;
bsdfData.materialId = anisotropy > 0 ? MATERIALID_LIT_ANISO : bsdfData.materialId;
}

case DEBUGVIEW_LIT_BSDFDATA_ROUGHNESS_B:
result = bsdfData.roughnessB.xxx;
break;
case DEBUGVIEW_LIT_BSDFDATA_ANISOTROPY:
result = bsdfData.anisotropy.xxx;
break;
case DEBUGVIEW_LIT_BSDFDATA_SUB_SURFACE_RADIUS:
result = bsdfData.subSurfaceRadius.xxx;
break;

struct PreLightData
{
float NdotV;
float3 R;
float ggxLambdaV;
float ggxLambdaV;
float3 anisoNormalWS;
float3 anisoR; // TODO: check if this is needed, I don't think we use R anymore for other thing than imagebased lighting
// image based lighting
float3 R;
// image based lighting
float3 specularDFG;
float diffuseDFG;

preLightData.NdotV = GetNdotV(bsdfData.normalWS, V);
#endif
preLightData.R = reflect(-V, bsdfData.normalWS);
preLightData.ggxLambdaV = GetSmithJointGGXLambdaV(preLightData.NdotV, bsdfData.roughness);
// Check if we precompute anisotropy too (should not be necessary as if the variables are not used they will be optimize out, but may avoid

preLightData.BdotV = dot(bsdfData.bitangentWS, bsdfData.normalWS);
preLightData.anisoGGXLambdaV = GetSmithJointGGXAnisoLambdaV(preLightData.TdotV, preLightData.BdotV, preLightData.NdotV, bsdfData.roughnessT, bsdfData.roughnessB);
preLightData.anisoNormalWS = GetAnisotropicModifiedNormal(bsdfData.normalWS, bsdfData.tangentWS, V, bsdfData.anisotropy);
preLightData.anisoGGXLambdaV = GetSmithJointGGXAnisoLambdaV(preLightData.TdotV, preLightData.BdotV, preLightData.NdotV, bsdfData.roughnessT, bsdfData.roughnessB);
// We need to take into account the modified normal for faking anisotropic here.
float anisoNdotV = GetNdotV(preLightData.anisoNormalWS, V); // TODO: is it necessary here to use the GetNDotV function
preLightData.anisoR = reflect(-V, preLightData.anisoNormalWS); // TODO: check if this is needed, I don't think we use R anymore for other thing than imagebased lighting
GetPreIntegratedDFG(anisoNdotV, bsdfData.roughness, bsdfData.fresnel0, preLightData.specularDFG, preLightData.diffuseDFG);
}
else
{
GetPreIntegratedDFG(preLightData.NdotV, bsdfData.roughness, bsdfData.fresnel0, preLightData.specularDFG, preLightData.diffuseDFG);
preLightData.R = reflect(-V, bsdfData.normalWS);
GetPreIntegratedDFG(preLightData.NdotV, bsdfData.roughness, bsdfData.fresnel0, preLightData.specularDFG, preLightData.diffuseDFG);
// #if SHADERPASS == SHADERPASS_GBUFFER
// preLightData.ambientOcclusion = _AmbientOcclusion.Load(uint3(coord.unPositionSS, 0)).x;

}
}
// TODO: We need to change this hard limit!
#define UNITY_SPECCUBE_LOD_STEPS (6)
float perceptualRoughnessToMipmapLevel(float perceptualRoughness)
{
// TODO: Clean a bit this code
// CAUTION: remap from Morten may work only with offline convolution, see impact with runtime convolution!
// For now disabled
#if 0
float m = PerceptualRoughnessToRoughness(perceptualRoughness); // m is the real roughness parameter
const float fEps = 1.192092896e-07F; // smallest such that 1.0+FLT_EPSILON != 1.0 (+1e-4h is NOT good here. is visibly very wrong)
float n = (2.0 / max(fEps, m*m)) - 2.0; // remap to spec power. See eq. 21 in --> https://dl.dropboxusercontent.com/u/55891920/papers/mm_brdf.pdf
n /= 4; // remap from n_dot_h formulatino to n_dot_r. See section "Pre-convolved Cube Maps vs Path Tracers" --> https://s3.amazonaws.com/docs.knaldtech.com/knald/1.0.0/lys_power_drops.html
perceptualRoughness = pow(2 / (n + 2), 0.25); // remap back to square root of real roughness (0.25 include both the sqrt root of the conversion and sqrt for going from roughness to perceptualRoughness)
#else
// MM: came up with a surprisingly close approximation to what the #if 0'ed out code above does.
perceptualRoughness = perceptualRoughness*(1.7 - 0.7*perceptualRoughness);
#endif
return perceptualRoughness * UNITY_SPECCUBE_LOD_STEPS;
}
// _preIntegratedFG and _CubemapLD are unique for each BRDF
void EvaluateBSDF_Env( float3 V, float3 positionWS, PreLightData prelightData, EnvLightData lightData, BSDFData bsdfData,
UNITY_ARGS_ENV(_ReflCubeTextures),

/*
if (bsdfData.materialId == MATERIALID_LIT_ANISO)
{
// Use fake aniso normal
// We can overwrite locally the normal without problem
bsdfData.normalWS = bsdfData.anisoNormalWS;
prelightData.R = prelightData.anisoR;
}
float3 positionLS = mul(float4(positionWS, 1.0), light.invTransform).xyz;
float3 dirLS = mul(prelightData.R, (float3x3)light.invTransform);
float2 intersections = boxRayIntersect(positionLS, dirLS, -light.extend, light.extend);
float3 positionLS = mul(float4(positionWS, 1.0), lightData.invTransform).xyz;
float3 dirLS = mul(prelightData.R, (float3x3)lightData.invTransform);
float2 intersections = BoxRayIntersect(positionLS, dirLS, -lightData.extend, lightData.extend);
diffuseLighting = float4(0.0, 0.0, 0.0, 1.0);
specularLighting = float4(0.0, 0.0, 0.0, 1.0);

// local offset
R = R - light.localOffset;
float mipmapLevel = roughnessToMipmapLevel(bsdfData.roughness);
half4 rgbm = UNITY_SAMPLE_TEXCUBEARRAY_LOD(tex, float4(glossIn.reflUVW.xyz, sliceIndex), mip);
float3 preLD = texCube(_CubemapLD, float4(R, textureIndex), mipmapLevel);
float mip = perceptualRoughnessToMipmapLevel(bsdfData.perceptualRoughness);
R = GetSpecularDominantDir(bsdfData.normalWS, R, bsdfData.roughness);
float4 preLD = UNITY_SAMPLE_ENV_LOD(tex, float4(R, lightData.sliceIndex), mip);
// Apply specular occlusion on it
}*/
}
*/
diffuseLighting = float4(0.0, 0.0, 0.0, 1.0);
specularLighting = float4(0.0, 0.0, 0.0, 1.0);

8
Assets/ScriptableRenderLoop/ShaderLibrary/CommonLighting.hlsl


// Fake anisotropic by distorting the normal as suggested by:
// Donald Revie - Implementing Fur Using Deferred Shading (GPU Pro 2)
// anisotropic ratio (0->no isotropic; 1->full anisotropy in tangent direction)
float3 GetAnisotropicModifiedNormal(float3 normalWS, float3 tangentWS, float3 viewVector, float anisotropy)
float3 GetAnisotropicModifiedNormal(float3 N, float3 T, float3 V, float anisotropy)
float3 anisoTangentWS = cross(-viewVector, tangentWS);
float3 anisoNormalWS = cross(anisoTangentWS, tangentWS);
float3 anisoT = cross(-V, T);
float3 anisoN = cross(anisoT, T);
return normalize(lerp(normalWS, anisoNormalWS, anisotropy));
return normalize(lerp(N, anisoN, anisotropy));
}
//-----------------------------------------------------------------------------

72
Assets/ScriptableRenderLoop/ShaderLibrary/GeometricTools.hlsl


#include "Common.hlsl"
//-----------------------------------------------------------------------------
// Intersection functions
//-----------------------------------------------------------------------------
// return furthest near intersection in x and closest far intersection in y
float2 BoxRayIntersect(float3 start, float3 dir, float3 boxMin, float3 boxMax)
{
float3 invDir = 1.0 / dir;
// Find the ray intersection with box plane
float3 firstPlaneIntersect = (boxMin - start) * invDir;
float3 secondPlaneIntersect = (boxMax - start) * invDir;
// Get the closest/furthest of these intersections along the ray (Ok because x/0 give +inf and -x/0 give �inf )
float3 closestPlane = min(firstPlaneIntersect, secondPlaneIntersect);
float3 furthestPlane = max(firstPlaneIntersect, secondPlaneIntersect);
float2 intersections;
// Find the furthest near intersection
intersections.x = max(closestPlane.x, max(closestPlane.y, closestPlane.z));
// Find the closest far intersection
intersections.y = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z);
return intersections;
}
// Sphere is at the origin
bool SphereRayIntersect(out float2 intersections, float3 start, float3 dir, float radius)
{
float a = dot(dir, dir);
float b = dot(dir, start) * 2.0;
float c = dot(start, start) - radius * radius;
float discriminant = b * b - 4.0 * a * c;
bool intersect = false;
if (discriminant < 0.0 || a == 0.0)
{
intersections.x = 0.0;
intersections.y = 0.0;
}
else
{
float sqrtDiscriminant = sqrt(discriminant);
intersections.x = (-b - sqrtDiscriminant) / (2.0 * a);
intersections.y = (-b + sqrtDiscriminant) / (2.0 * a);
intersect = true;
}
return intersect;
}
float3 RayPlaneIntersect(in float3 rayOrigin, in float3 rayDirection, in float3 planeOrigin, in float3 planeNormal)
{
float dist = dot(planeNormal, planeOrigin - rayOrigin) / dot(planeNormal, rayDirection);
return rayOrigin + rayDirection * dist;
}
//-----------------------------------------------------------------------------
// Distance functions
//-----------------------------------------------------------------------------
// Ref: real time detection collision page 131
float DistanceBoxPoint(float3 boxMin, float3 boxMax, float3 pos)
{
// Clamp to find closest point then calc distance
float3 distanceToMin = pos < boxMin ? (boxMin - pos) * (boxMin - pos) : 0.0;
float3 distancesToMax = pos > boxMax ? (pos - boxMax) * (pos - boxMax) : 0.0;
float distanceSquare = dot(distanceToMin, float3(1.0, 1.0, 1.0)) + dot(distancesToMax, float3(1.0, 1.0, 1.0));
return sqrt(distanceSquare);
}
#endif // UNITY_GEOMETRICTOOLS_INCLUDED

9
Assets/ScriptableRenderLoop/ShaderLibrary/ImageBasedLighting.hlsl


return float4(acc * (1.0 / accWeight), 1.0);
}
// Ref: See "Moving Frostbite to PBR" Listing 22
float3 GetSpecularDominantDir(float3 N, float3 R, float roughness)
{
float a = 1.0 - roughness;
float lerpFactor = a * (sqrt(a) + roughness);
// The result is not normalized as we fetch in a cubemap
return lerp(N, R, lerpFactor);
}
#endif // UNITY_IMAGE_BASED_LIGHTING_INCLUDED
正在加载...
取消
保存