浏览代码

Implement ray-cone intersection

/Yibing-Project-2
Evgenii Golubev 7 年前
当前提交
bb677806
共有 4 个文件被更改,包括 84 次插入7 次删除
  1. 59
      ScriptableRenderPipeline/Core/ShaderLibrary/GeometricTools.hlsl
  2. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  3. 4
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs
  4. 22
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/Resources/VolumetricLighting.compute

59
ScriptableRenderPipeline/Core/ShaderLibrary/GeometricTools.hlsl


return rayOrigin + rayDirection * dist;
}
// Solves the quadratic equation of the form: a*t^2 + b*t + c = 0.
// Returns 'false' if there are no real roots, 'true' otherwise.
// Ref: Numerical Recipes in C++ (3rd Edition)
bool SolveQuadraticEquation(float a, float b, float c, out float2 roots)
{
float d = b * b - 4 * a * c;
float q = -0.5 * (b + FastSign(b) * sqrt(d));
roots = float2(q / a, c / q);
return (d >= 0);
}
// 'coneAxisX' and 'coneAxisY' should be pre-scaled by by cot(halfAngle).
// Returns parametric distances 'tEntr' and 'tExit' along the ray,
// subject to constraints 'tMin' and 'tMax'.
bool ConeRayIntersect(float3 rayOrigin, float3 rayDirection,
float3 coneOrigin, float3 coneDirection,
float3 coneAxisX, float3 coneAxisY,
float tMin, float tMax,
inout float tEntr, inout float tExit)
{
// Inverse transform the ray into a coordinate system with the cone at the origin facing along the Z axis.
float3x3 rotMat = float3x3(coneAxisX, coneAxisY, coneDirection);
float3 o = mul(rotMat, rayOrigin - coneOrigin);
float3 d = mul(rotMat, rayDirection);
// Cone equation (facing along Z): (h/r*x)^2 + (h/r*y)^2 - z^2 = 0.
// Cone axes are premultiplied with (h/r).
// Set up the quadratic equation: a*t^2 + b*t + c = 0.
float a = d.x * d.x + d.y * d.y - d.z * d.z;
float b = o.x * d.x + o.y * d.y - o.z * d.z;
float c = o.x * o.x + o.y * o.y - o.z * o.z;
float2 roots;
// Check whether we have at least 1 root.
bool hit = SolveQuadraticEquation(a, 2 * b, c, roots);
tEntr = min(roots.x, roots.y);
tExit = max(roots.x, roots.y);
float3 pEntr = o + tEntr * d;
float3 pExit = o + tExit * d;
// Clip the negative cone.
if (max(pEntr.z, pExit.z) < 0) { hit = false; }
if (pEntr.z < 0) { tEntr = tExit; tExit = tMax; }
if (pExit.z < 0) { tExit = tEntr; tEntr = tMin; }
// Clamp using the values passed into the function.
tEntr = clamp(tEntr, tMin, tMax);
tExit = clamp(tExit, tMin, tMax);
// Check for grazing intersections.
if (tEntr == tExit) { hit = false; }
return hit;
}
//-----------------------------------------------------------------------------
// Miscellaneous functions
//-----------------------------------------------------------------------------

6
ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


UpdateSkyEnvironment(hdCamera, cmd);
}
// Render volumetric lighting
VolumetricLightingPass(hdCamera, cmd);
RenderDeferredLighting(hdCamera, cmd);
// We compute subsurface scattering here. Therefore, no objects rendered afterwards will exhibit SSS.

// Render all type of transparent forward (unlit, lit, complex (hair...)) to keep the sorting between transparent objects.
RenderForward(m_CullResults, camera, renderContext, cmd, ForwardPass.Transparent);
RenderForwardError(m_CullResults, camera, renderContext, cmd, ForwardPass.Transparent);
// Render volumetric lighting
VolumetricLightingPass(hdCamera, cmd);
PushFullScreenDebugTexture(cmd, m_CameraColorBuffer, camera, renderContext, FullScreenDebugMode.NanTracker);

4
ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs


public Vector3 right; // If spot: rescaled by cot(outerHalfAngle); if projector: rescaled by (2 / shapeLenght)
public float specularScale;
public Vector3 up; // If spot: rescaled by cot(outerHalfAngle); if projector: rescaled by * (2 / shapeWidth)
public Vector3 up; // If spot: rescaled by cot(outerHalfAngle); if projector: rescaled by (2 / shapeWidth)
public float diffuseScale;
public float angleScale; // Spot light

public Vector2 size; // Used by area, frustum projector and spot lights (x = cot(outerHalfAngle))
public Vector2 size; // Used by area and pyramid projector lights
public GPULightType lightType;
public float minRoughness; // This is use to give a small "area" to punctual light, as if we have a light with a radius.

22
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/Resources/VolumetricLighting.compute


int lightType = lightData.lightType;
// TODO...
if (lightType != GPULIGHTTYPE_POINT) continue;
if (lightType != GPULIGHTTYPE_POINT && lightType != GPULIGHTTYPE_SPOT) continue;
float tEntr, tExit;
if (lightType == GPULIGHTTYPE_SPOT)
{
if (!ConeRayIntersect(ray.originWS, ray.directionWS,
lightData.positionWS, lightData.forward,
lightData.right, lightData.up,
tMin, tMax, tEntr, tExit))
{
continue;
}
}
else
{
tEntr = tMin;
tExit = tMax;
}
tMin, tMax, t, distSq, rcpPdf);
tEntr, tExit, t, distSq, rcpPdf);
float3 positionWS = GetPointAtDistance(ray, t);

正在加载...
取消
保存