Corrected probe init'ing so they don't fight for the cubemap idx order

Also correct deleting behavior so it updates indicies when a probe is removed
Updated forward lighting to utilize the same math as deferred
This commit is contained in:
Areloch 2019-06-30 23:04:16 -05:00
parent 37461b4768
commit a1ecc98c87
21 changed files with 440 additions and 389 deletions

View file

@ -28,12 +28,12 @@
// These are the uniforms used by most lighting shaders.
uniform float4 inLightPos[3];
uniform float4 inLightInvRadiusSq;
uniform float4 inLightPos[4];
uniform float4 inLightConfigData[4];
uniform float4 inLightColor[4];
#ifndef TORQUE_BL_NOSPOTLIGHT
uniform float4 inLightSpotDir[3];
uniform float4 inLightSpotDir[4];
uniform float4 inLightSpotAngle;
uniform float4 inLightSpotFalloff;
#endif
@ -48,6 +48,8 @@ uniform float4 albedo;
#define MAX_PROBES 50
#define MAX_FORWARD_PROBES 4
#define MAX_FORWARD_LIGHT 4
inline float3 getDistanceVectorToPlane( float3 origin, float3 direction, float4 plane )
{
float denum = dot( plane.xyz, direction.xyz );
@ -65,146 +67,6 @@ inline float3 getDistanceVectorToPlane( float negFarPlaneDotEye, float3 directio
return direction.xyz * t;
}
//TODO fix compute 4 lights
void compute4Lights( float3 wsView,
float3 wsPosition,
float3 wsNormal,
float4 shadowMask,
#ifdef TORQUE_SHADERGEN
float4 inLightPos[3],
float4 inLightInvRadiusSq,
float4 inLightColor[4],
float4 inLightSpotDir[3],
float4 inLightSpotAngle,
float4 inLightSpotFalloff,
float smoothness,
float metalness,
float4 albedo,
#endif // TORQUE_SHADERGEN
out float4 outDiffuse,
out float4 outSpecular )
{
// NOTE: The light positions and spotlight directions
// are stored in SoA order, so inLightPos[0] is the
// x coord for all 4 lights... inLightPos[1] is y... etc.
//
// This is the key to fully utilizing the vector units and
// saving a huge amount of instructions.
//
// For example this change saved more than 10 instructions
// over a simple for loop for each light.
int i;
float4 lightVectors[3];
for ( i = 0; i < 3; i++ )
lightVectors[i] = wsPosition[i] - inLightPos[i];
float4 squareDists = 0;
for ( i = 0; i < 3; i++ )
squareDists += lightVectors[i] * lightVectors[i];
// Accumulate the dot product between the light
// vector and the normal.
//
// The normal is negated because it faces away from
// the surface and the light faces towards the
// surface... this keeps us from needing to flip
// the light vector direction which complicates
// the spot light calculations.
//
// We normalize the result a little later.
//
float4 nDotL = 0;
for ( i = 0; i < 3; i++ )
nDotL += lightVectors[i] * -wsNormal[i];
float4 rDotL = 0;
#ifndef TORQUE_BL_NOSPECULAR
// We're using the Phong specular reflection model
// here where traditionally Torque has used Blinn-Phong
// which has proven to be more accurate to real materials.
//
// We do so because its cheaper as do not need to
// calculate the half angle for all 4 lights.
//
// Advanced Lighting still uses Blinn-Phong, but the
// specular reconstruction it does looks fairly similar
// to this.
//
float3 R = reflect( wsView, -wsNormal );
for ( i = 0; i < 3; i++ )
rDotL += lightVectors[i] * R[i];
#endif
// Normalize the dots.
//
// Notice we're using the half type here to get a
// much faster sqrt via the rsq_pp instruction at
// the loss of some precision.
//
// Unless we have some extremely large point lights
// i don't believe the precision loss will matter.
//
half4 correction = (half4)rsqrt( squareDists );
nDotL = saturate( nDotL * correction );
rDotL = clamp( rDotL * correction, 0.00001, 1.0 );
// First calculate a simple point light linear
// attenuation factor.
//
// If this is a directional light the inverse
// radius should be greater than the distance
// causing the attenuation to have no affect.
//
float4 atten = saturate( 1.0 - ( squareDists * inLightInvRadiusSq ) );
#ifndef TORQUE_BL_NOSPOTLIGHT
// The spotlight attenuation factor. This is really
// fast for what it does... 6 instructions for 4 spots.
float4 spotAtten = 0;
for ( i = 0; i < 3; i++ )
spotAtten += lightVectors[i] * inLightSpotDir[i];
float4 cosAngle = ( spotAtten * correction ) - inLightSpotAngle;
atten *= saturate( cosAngle * inLightSpotFalloff );
#endif
// Finally apply the shadow masking on the attenuation.
atten *= shadowMask;
// Get the final light intensity.
float4 intensity = nDotL * atten;
// Combine the light colors for output.
outDiffuse = 0;
for ( i = 0; i < 4; i++ )
outDiffuse += intensity[i] * inLightColor[i];
// Output the specular power.
float4 specularIntensity = pow( rDotL, float4(1,1,1,1) ) * atten;
// Apply the per-light specular attenuation.
float4 specular = float4(0,0,0,1);
for ( i = 0; i < 4; i++ )
specular += float4( inLightColor[i].rgb * inLightColor[i].a * specularIntensity[i], 1 );
// Add the final specular intensity values together
// using a single dot product operation then get the
// final specular lighting color.
outSpecular = float4(1,1,1,1) * specular;
}
struct Surface
{
float3 P; // world space position
@ -372,6 +234,57 @@ inline float3 getPunctualLight(in Surface surface, in SurfaceToLight surfaceToLi
return final;
}
float4 compute4Lights( Surface surface,
float4 shadowMask,
float4 inLightPos[4],
float4 inLightConfigData[4],
float4 inLightColor[4],
float4 inLightSpotDir[4],
float4 lightSpotParams[4] )
{
float3 finalLighting = 0.0.xxx;
int i;
for(i = 0; i < MAX_FORWARD_LIGHT; i++)
{
float3 L = inLightPos[i].xyz - surface.P;
float dist = length(L);
float lightRange = inLightConfigData[i].z;
SurfaceToLight surfaceToLight = createSurfaceToLight(surface, L);
float shadowed = 1.0;
float3 lightCol = inLightColor[i].rgb;
float lightBrightness = inLightConfigData[i].y;
float lightInvSqrRange= inLightConfigData[i].a;
float3 lighting = 0.0.xxx;
[branch]
if(dist < lightRange)
{
[branch]
if(inLightConfigData[i].x == 0) //point
{
//get punctual light contribution
lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed);
}
else //spot
{
//get Punctual light contribution
lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed);
//get spot angle attenuation
lighting *= getSpotAngleAtt(-surfaceToLight.L, inLightSpotDir[i].xyz, lightSpotParams[i].xy );
}
}
finalLighting += lighting;
}
return float4(finalLighting,1);
}
//Probe IBL stuff
float defineSphereSpaceInfluence(float3 wsPosition, float3 wsProbePosition, float radius)
{

View file

@ -32,7 +32,7 @@ uniform float4 probeConfigData[MAX_PROBES]; //r,g,b/mode,radius,atten
uniform float4 probeContribColors[MAX_PROBES];
#endif
uniform float skylightCubemapIdx;
uniform int skylightCubemapIdx;
float4 main(PFXVertToPix IN) : SV_TARGET
{
@ -140,7 +140,7 @@ float4 main(PFXVertToPix IN) : SV_TARGET
//Skylight coloration for anything not covered by probes above
if(skylightCubemapIdx != -1)
finalContribColor += float3(0.3, 0.3, 0.3) * contribAlpha;
finalContribColor += float3(0, 1, 0) * contribAlpha;
return float4(finalContribColor, 1);
#endif