shift the wip code back out of lighting.hlsl till were sure of it, and while we're at it, shove the probe methods into the probe class to more easily differentiate between blend-val and raw contribution factors

This commit is contained in:
Azaezel 2019-02-25 02:39:00 -06:00
parent df8864659a
commit 89fb367f6a
2 changed files with 90 additions and 144 deletions

View file

@ -235,90 +235,3 @@ inline float3 getPunctualLight(in Surface surface, in SurfaceToLight surfaceToLi
float3 final = max(0.0f, diffuse + spec * surface.ao * surface.F);
return final;
}
//Probe IBL stuff
struct ProbeData
{
float3 wsPosition;
float radius;
float3 boxMin;
float3 boxMax;
float attenuation;
float4x4 worldToLocal;
uint probeIdx;
uint type; //box = 0, sphere = 1
float contribution;
float3 refPosition;
float3 pad;
};
// Box Projected IBL Lighting
// Based on: http://www.gamedev.net/topic/568829-box-projected-cubemap-environment-mapping/
// and https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
float3 boxProject(Surface surface, ProbeData probe) //float3 wsPosition, float3 wsEyeRay, float3 reflectDir, float3 boxWSPos, float3 boxMin, float3 boxMax
{
//float3 rayLS = mul(worldToObjArray[id], float4(wsEyeRay, 1.0)).xyz;
//float3 reflCameraLS = mul(worldToObjArray[id], float4(reflectDir), 1.0)).xyz;
float3 nrdir = surface.R;
float3 offset = surface.P;
float3 plane1vec = (probe.boxMax - offset) / nrdir;
float3 plane2vec = (probe.boxMin - offset) / nrdir;
float3 furthestPlane = max(plane1vec, plane2vec);
float dist = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z);
float3 posonbox = offset + nrdir * dist;
return posonbox - probe.refPosition;
}
float defineSphereSpaceInfluence(Surface surface, ProbeData probe, float3 wsEyeRay)
{
float3 L = probe.wsPosition.xyz - surface.P;
return 1.0 - length(L) / probe.radius;
}
float defineBoxSpaceInfluence(Surface surface, ProbeData probe, float3 wsEyeRay)
{
/*float3 lsPos = mul(probe.worldToLocal, float4(surface.P, 1.0)).xyz;
float3 lsDir = mul(probe.worldToLocal, float4(wsEyeRay, 0)).xyz;
float3 lsInvDir = rcp(lsDir);
float3 intersectsMax = lsInvDir - lsPos * lsInvDir;
float3 intersectsMin = -lsInvDir - lsPos * lsInvDir;
float3 positiveIntersections = max(intersectsMax, intersectsMin);
float intersectDist = min(positiveIntersections.x, min(positiveIntersections.y, positiveIntersections.z));
float3 wsIntersectPosition = surface.P + intersectDist * wsEyeRay;
float3 lookupDir = wsIntersectPosition - probe.wsPosition;
//replace this mess with a second pair of minmaxes
float atten = probe.radius - probe.radius*probe.attenuation / 2;
float rad = probe.radius * 2;
float3 atten3 = float3(atten, atten, atten); // atten as a % of box
float3 reducedExtents = float3(rad, rad, rad) - atten3;
float distToBox = getDistBoxToPoint(lsPos*probe.boxExtents, float3(rad, rad, rad));
float normalizedDistance = distToBox / length(rad);
float t = saturate(3.3333 - 3.3333 * normalizedDistance);
contribution = t * t * (3.0 - 2.0 * t);
return lookupDir;*/
float3 surfPosLS = mul(probe.worldToLocal, float4(surface.P, 1.0)).xyz;
float3 boxMinLS = probe.wsPosition.xyz - (float3(1, 1, 1)*probe.radius);
float3 boxMaxLS = probe.wsPosition.xyz + (float3(1, 1, 1)*probe.radius);
float boxOuterRange = length(boxMaxLS - boxMinLS);
float boxInnerRange = boxOuterRange / probe.attenuation;
float3 localDir = float3(abs(surfPosLS.x), abs(surfPosLS.y), abs(surfPosLS.z));
localDir = (localDir - boxInnerRange) / (boxOuterRange - boxInnerRange);
return max(localDir.x, max(localDir.y, localDir.z)) * -1;
}

View file

@ -32,56 +32,90 @@ uniform float4 probeConfigData[MAX_PROBES]; //r,g,b/mode,radius,atten
uniform float4 probeContribColors[MAX_PROBES];
#endif
// Box Projected IBL Lighting
// Based on: http://www.gamedev.net/topic/568829-box-projected-cubemap-environment-mapping/
// and https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
/*float3 boxProject(float3 wsPosition, float3 wsEyeRay, float3 reflectDir, float3 boxWSPos, float3 boxMin, float3 boxMax)
{
float3 positionLS = mul(worldToObjArray[id], float4(wsEyeRay, 1.0)).xyz;
//float3 rayLS = mul(worldToObjArray[id], float4(wsEyeRay, 1.0)).xyz;
//float3 reflCameraLS = mul(worldToObjArray[id], float4(reflectDir), 1.0)).xyz;
float3 nrdir = reflectDir;
float3 offset = wsPosition;
float3 plane1vec = (boxMax - offset) / nrdir;
float3 plane2vec = (boxMin - offset) / nrdir;
float3 furthestPlane = max(plane1vec, plane2vec);
float dist = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z);
float3 posonbox = offset + nrdir * dist;
return posonbox - boxWSPos;
}*/
float3 iblBoxDiffuse( Surface surface, ProbeData probe)
//Probe IBL stuff
struct ProbeData
{
float3 dir = boxProject(surface, probe);
float3 wsPosition;
float radius;
float3 boxMin;
float3 boxMax;
float attenuation;
float4x4 worldToLocal;
uint probeIdx;
uint type; //box = 0, sphere = 1
float contribution;
float3 refPosition;
float3 pad;
inline void defineSphereSpaceInfluence(Surface surface, float3 wsEyeRay)
{
float3 L = wsPosition.xyz - surface.P;
contribution = 1.0 - length(L) / radius;
}
float lod = surface.roughness*cubeMips;
float3 color = TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, probe.probeIdx, lod).xyz;
inline void defineBoxSpaceInfluence(Surface surface, float3 wsEyeRay)
{
float3 surfPosLS = mul(worldToLocal, float4(surface.P, 1.0)).xyz;
return color;
}
float3 boxMinLS = wsPosition.xyz - (float3(1, 1, 1)*radius);
float3 boxMaxLS = wsPosition.xyz + (float3(1, 1, 1)*radius);
float3 iblBoxSpecular(Surface surface, ProbeData probe)
{
// BRDF
float2 brdf = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.roughness, surface.NdotV,0.0,0.0)).xy;
float boxOuterRange = length(boxMaxLS - boxMinLS);
float boxInnerRange = boxOuterRange / attenuation;
float3 dir = boxProject(surface, probe);
float3 localDir = float3(abs(surfPosLS.x), abs(surfPosLS.y), abs(surfPosLS.z));
localDir = (localDir - boxInnerRange) / (boxOuterRange - boxInnerRange);
// Radiance (Specular)
#if DEBUGVIZ_SPECCUBEMAP == 0
float lod = surface.roughness*cubeMips;
#elif DEBUGVIZ_SPECCUBEMAP == 1
float lod = 0;
#endif
contribution = max(localDir.x, max(localDir.y, localDir.z)) * -1;
}
// Box Projected IBL Lighting
// Based on: http://www.gamedev.net/topic/568829-box-projected-cubemap-environment-mapping/
// and https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
inline float3 boxProject(Surface surface) //float3 wsPosition, float3 wsEyeRay, float3 reflectDir, float3 boxWSPos, float3 boxMin, float3 boxMax
{
float3 nrdir = surface.R;
float3 offset = surface.P;
float3 plane1vec = (boxMax - offset) / nrdir;
float3 plane2vec = (boxMin - offset) / nrdir;
float3 color = TORQUE_TEXCUBEARRAYLOD(cubeMapAR, dir, probe.probeIdx, lod).xyz * (brdf.x + brdf.y);
float3 furthestPlane = max(plane1vec, plane2vec);
float dist = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z);
float3 posonbox = offset + nrdir * dist;
return posonbox - refPosition;
}
float3 iblBoxDiffuse( Surface surface)
{
float3 dir = boxProject(surface);
float lod = surface.roughness*cubeMips;
float3 color = TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, probeIdx, lod).xyz;
return color;
}
float3 iblBoxSpecular(Surface surface)
{
// BRDF
float2 brdf = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.roughness, surface.NdotV,0.0,0.0)).xy;
float3 dir = boxProject(surface);
// Radiance (Specular)
#if DEBUGVIZ_SPECCUBEMAP == 0
float lod = surface.roughness*cubeMips;
#elif DEBUGVIZ_SPECCUBEMAP == 1
float lod = 0;
#endif
float3 color = TORQUE_TEXCUBEARRAYLOD(cubeMapAR, dir, probeIdx, lod).xyz * (brdf.x + brdf.y);
return color;
}
};
return color;
}
float4 main( PFXVertToPix IN ) : SV_TARGET
{
@ -99,7 +133,6 @@ float4 main( PFXVertToPix IN ) : SV_TARGET
}
int i = 0;
float blendVal[MAX_PROBES];
float blendFactor[MAX_PROBES];
float blendSum = 0;
float blendFacSum = 0;
@ -124,16 +157,16 @@ float4 main( PFXVertToPix IN ) : SV_TARGET
if (probes[i].type == 0) //box
{
blendVal[i] = defineBoxSpaceInfluence(surface, probes[i], IN.wsEyeRay);
probes[i].defineBoxSpaceInfluence(surface, IN.wsEyeRay);
}
else
{
blendVal[i] = defineSphereSpaceInfluence(surface, probes[i], IN.wsEyeRay);
probes[i].defineSphereSpaceInfluence(surface,IN.wsEyeRay);
}
blendVal[i] = saturate(blendVal[i]);
blendSum += blendVal[i];
invBlendSum += (1.0f - blendVal[i]);
probes[i].contribution = saturate(probes[i].contribution);
blendSum += probes[i].contribution;
invBlendSum += (1.0f - probes[i].contribution);
}
// Weight0 = normalized NDF, inverted to have 1 at center, 0 at boundary.
@ -145,14 +178,14 @@ float4 main( PFXVertToPix IN ) : SV_TARGET
{
if (numProbes>1)
{
blendFactor[i] = ((1.0f - blendVal[i] / blendSum)) / (numProbes - 1);
blendFactor[i] *= ((1.0f - blendVal[i]) / invBlendSum);
blendFactor[i] = ((1.0f - probes[i].contribution / blendSum)) / (numProbes - 1);
blendFactor[i] *= ((1.0f - probes[i].contribution) / invBlendSum);
blendFacSum += blendFactor[i];
}
else
{
blendFactor[i] = blendVal[i];
blendFacSum = blendVal[i];
blendFactor[i] = probes[i].contribution;
blendFacSum = probes[i].contribution;
}
}
@ -199,12 +232,12 @@ float4 main( PFXVertToPix IN ) : SV_TARGET
kD *= 1.0 - surface.metalness;
for (i = 0; i < numProbes; ++i)
{
if (blendVal[i] == 0)
if (probes[i].contribution == 0)
continue;
irradiance += blendFactor[i]*iblBoxDiffuse(surface, probes[i]);
irradiance += blendFactor[i]*probes[i].iblBoxDiffuse(surface);
specular += blendFactor[i]*F*iblBoxSpecular(surface, probes[i]);
specular += blendFactor[i]*F*probes[i].iblBoxSpecular(surface);
}
//final diffuse color
@ -217,7 +250,7 @@ float4 main( PFXVertToPix IN ) : SV_TARGET
float3 cubeColor = float3(0, 0, 0);
for (i = 0; i < numProbes; ++i)
{
cubeColor += blendFactor[i] * iblBoxSpecular(surface, probes[i]);
cubeColor += blendFactor[i] * probes[i].iblBoxSpecular(surface);
}
return float4(cubeColor, 1);
@ -225,7 +258,7 @@ float4 main( PFXVertToPix IN ) : SV_TARGET
float3 cubeColor = float3(0, 0, 0);
for (i = 0; i < numProbes; ++i)
{
cubeColor += blendFactor[i] * iblBoxDiffuse(surface, probes[i]);
cubeColor += blendFactor[i] * probes[i].iblBoxDiffuse(surface);
}
return float4(cubeColor, 1);