matthew-r
3/23/2018 - 1:02 AM

deferred-lighting-point-combine-stages-cone-lights

\\TouchDesigner glsl TOP

uniform int numLights;

uniform vec3 viewDirection;             // camera location
uniform vec3 specularColor;

uniform float shininess;

uniform sampler2D samplerPos;
uniform sampler2D samplerNorm;
uniform sampler2D samplerColor;
uniform sampler2D samplerUv;

uniform samplerBuffer lightPos;         // position as xyz
uniform samplerBuffer lightColor;       // color as rgb
uniform samplerBuffer lightFalloff;     // falloff constant, linear, quadratic
uniform samplerBuffer lightLookat;      // lookat position xyz
uniform samplerBuffer lightCone;        // angle, delta, and falloff

out vec4 fragColor;

#define PI 3.14159265359

void main()
{
    vec2 screenSpaceUV      = vUV.st;
    vec2 resolution         = uTD2DInfos[0].res.zw;

    // parse data from g-buffer
    vec3 position       = texture( sTD2DInputs[0], screenSpaceUV ).xyz;
    vec3 normal         = texture( sTD2DInputs[1], screenSpaceUV ).xyz;
    vec4 color          = texture( sTD2DInputs[2], screenSpaceUV );
    vec2 uv             = texture( sTD2DInputs[3], screenSpaceUV ).rg;

    vec3 cameraVec      = normalize(viewDirection - position);

    // set up placeholder for final color
    vec3 finalColor     = vec3(0.0);

    // loop through all lights
    for ( int light = 0; light < numLights; ++light ){

        // parse lighitng data based on the current light index
        vec3 currentLightPos        = texelFetchBuffer( lightPos, light ).xyz;
        vec3 currentLightColor      = texelFetchBuffer( lightColor, light ).xyz;
        vec3 currentLightFalloff    = texelFetchBuffer( lightFalloff, light ).xyz;
        vec3 currentLightLookat     = texelFetchBuffer( lightLookat, light ).xyz;
        vec3 currentLightCone       = texelFetchBuffer( lightCone, light ).xyz;

        // cone attributes
        float uConeAngle            = currentLightCone.x;
        float uConeDelta            = currentLightCone.y;
        float uConeRolloff          = currentLightCone.z;   

        // calculate the distance between the current fragment and the light source
        float lightDist             = length( currentLightPos - position );
        vec3 lightVec               = normalize( currentLightPos - position );

        // spot
        float fullcos               = cos(radians((uConeAngle / 2.0) + uConeDelta));
        fullcos                     = (fullcos * 0.5) + 0.5;
        float scale                 = 0.5 / (1.0 - fullcos);
        float bias                  = (0.5 - fullcos) / (1.0 - fullcos);
        vec2 coneLookupScaleBias    = vec2(scale, bias);
        
        vec3 spot                   = normalize( currentLightLookat - currentLightPos );
        float spotEffect            = dot( spot, -lightVec );
        float coneAngle             = radians( uConeAngle / 2.0);
        float ang                   = acos(spotEffect);

        float dimmer;
        if( ang > coneAngle )
            dimmer                  = 0.0;
        else
            dimmer                  = texture( sTDSineLookup, 1.0 - ( ang / coneAngle ) ).r;


        vec3 toLight                = normalize( currentLightPos - position );
        vec3 diffuse                = max( dot( normal, toLight ), 0.0 ) * color.rgb * currentLightColor;

        float diffuseDot            = clamp(dot(lightVec, normal), 0.0, 1.0);
        vec3 colorSum               = diffuseDot * currentLightColor;
        vec3 halfAng                = normalize((cameraVec + lightVec).xyz);
        float specDot               = pow(clamp(dot(halfAng, normal), 0.0, 1.0), shininess);

        colorSum                    += specDot * currentLightColor * 0.3 * diffuse;
        colorSum                    *= dimmer;


        // accumulate lighting
        finalColor                  += colorSum;

    }

    // final color out 
    fragColor = TDOutputSwizzle( vec4( finalColor, color.a ) );
}