Opengl GPU Pro 5区域灯

Opengl GPU Pro 5区域灯,opengl,graphics,3d,glsl,Opengl,Graphics,3d,Glsl,我正在尝试在GLSL中实现GPU Pro 5中描述的区域光,但是我在投影方面遇到了一些问题 以下是我当前用于漫反射闪电的着色器代码: vec3 linePlaneIntersection ( vec3 linePoint, vec3 lineNormal, vec3 planeCenter, vec3 planeNormal ) { float t = (dot(planeNormal, planeCenter - linePoint) / dot(pl

我正在尝试在GLSL中实现GPU Pro 5中描述的区域光,但是我在投影方面遇到了一些问题

以下是我当前用于漫反射闪电的着色器代码:

vec3 linePlaneIntersection
    (
    vec3 linePoint, vec3 lineNormal, 
    vec3 planeCenter, vec3 planeNormal
    )
{
    float t = (dot(planeNormal, planeCenter - linePoint) / dot(planeNormal, lineNormal));
    return linePoint + lineNormal * t;
}

vec3 projectOnPlane(vec3 point, vec3 planeCenter, vec3 planeNormal)
{
    float distance = dot(planeNormal, point - planeCenter);

    return point - distance * planeNormal;
}

vec3 diffuse_color(vec3 p, vec3 surfaceDiffuseColor, vec3 n)
{
    // for point p with normal n

    vec3 directionToLight = normalize(light.position.xyz - p);
    vec3 planeNormal = directionToLight;
    planeNormal = light.orientation.xyz;

    // intersect a ray from p in direction nII with light plane, 
    // creating point pI

    vec3 nII = n;

    if(dot(n, light.orientation.xyz) > 0.0)
    {
        // light plane points away from n, skew in direction of light plane
        nII = -light.orientation.xyz;
    }

    vec3 pI = linePlaneIntersection(p, nII, light.position.xyz, planeNormal);

    // project point p on the light plane, creating point pII
    vec3 pII = projectOnPlane(p, light.position.xyz, planeNormal);

    // create halfway vector h between ppI and ppII
    vec3 ppI = pI - p;
    vec3 ppII = pII - p;
    vec3 h = normalize(ppI + ppII);

    // intersect ray from p in direction h with the light plane,
    // creating point pd
    vec3 pd = linePlaneIntersection(p, h, light.position.xyz, planeNormal);

    // treat vector ppd as light vector for diffuse equation
    vec3 ppd = normalize(pd - p);

    // distance from point p to point pI on dArea
    float r = distance(p, pI);

    // angle between light vector ppd and surface normal n
    float cosP = clamp(dot(ppd, n), 0.0, 1.0);
    // angle between surface normal and light plane orientation normal
    float cosO = clamp(dot(n, -light.orientation.xyz), 0.0, 1.0);

    float dArea = light.dAreaRadiance.x;
    float radiance = light.dAreaRadiance.y;

    return radiance * surfaceDiffuseColor * cosP * cosO * dArea / (r * r);
}
灯光具有位置{0,100,0}和方向{0,-1,0}

如果我使用灯光方向作为投影的平面法线,灯光总是直接从顶部发出,即使在我更改x轴上的位置时也是如此


当我使用灯光位置的方向作为平面法线时,它似乎起作用,但我很确定它仍然不正确。

我将按照书中描述的路线走很长一段路,看看是否有效。