|
@@ -18,7 +18,7 @@ uniform float cubeMips;
|
|
|
#define MAX_PROBES 50
|
|
|
|
|
|
uniform float numProbes;
|
|
|
-TORQUE_UNIFORM_SAMPLERCUBEARRAY(cubeMapAR, 4);
|
|
|
+TORQUE_UNIFORM_SAMPLERCUBEARRAY(specularCubemapAR, 4);
|
|
|
TORQUE_UNIFORM_SAMPLERCUBEARRAY(irradianceCubemapAR, 5);
|
|
|
|
|
|
uniform float4 inProbePosArray[MAX_PROBES];
|
|
@@ -36,95 +36,6 @@ TORQUE_UNIFORM_SAMPLERCUBE(skylightPrefilterMap, 6);
|
|
|
TORQUE_UNIFORM_SAMPLERCUBE(skylightIrradMap, 7);
|
|
|
uniform float hasSkylight;
|
|
|
|
|
|
-//Probe IBL stuff
|
|
|
-float defineSphereSpaceInfluence(Surface surface, int ID)
|
|
|
-{
|
|
|
- float3 L = inProbePosArray[ID].xyz.xyz - surface.P;
|
|
|
- float contribution = 1.0 - length(L) / probeConfigData[ID].g;
|
|
|
- return contribution;
|
|
|
-}
|
|
|
-
|
|
|
-float getDistBoxToPoint(float3 pt, float3 extents)
|
|
|
-{
|
|
|
- float3 d = max(max(-extents - pt, 0), pt - extents);
|
|
|
- return max(max(d.x, d.y), d.z);
|
|
|
-}
|
|
|
-
|
|
|
-float defineBoxSpaceInfluence(Surface surface, int ID)
|
|
|
-{
|
|
|
- float3 surfPosLS = mul(worldToObjArray[ID], float4(surface.P, 1.0)).xyz;
|
|
|
- float atten = 1.0-probeConfigData[ID].b;
|
|
|
- float baseVal = 0.25;
|
|
|
- float dist = getDistBoxToPoint(surfPosLS,float3(baseVal,baseVal,baseVal));
|
|
|
- return saturate(smoothstep(baseVal+0.0001,atten*baseVal,dist));
|
|
|
-}
|
|
|
-
|
|
|
-// 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, int ID)
|
|
|
-{
|
|
|
- float3 RayLS = mul(worldToObjArray[ID], float4(surface.R, 0.0)).xyz;
|
|
|
- float3 PositionLS = mul(worldToObjArray[ID], float4(surface.P, 1.0)).xyz;
|
|
|
-
|
|
|
- float3 unit = bbMaxArray[ID].xyz - bbMinArray[ID].xyz;
|
|
|
- float3 plane1vec = (unit / 2 - PositionLS) / RayLS;
|
|
|
- float3 plane2vec = (-unit / 2 - PositionLS) / RayLS;
|
|
|
- float3 furthestPlane = max(plane1vec, plane2vec);
|
|
|
- float dist = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z);
|
|
|
- float3 posonbox = surface.P + surface.R * dist;
|
|
|
-
|
|
|
- return posonbox - inRefPosArray[ID].xyz;
|
|
|
-}
|
|
|
-
|
|
|
-float3 iblBoxDiffuse(Surface surface, int ID)
|
|
|
-{
|
|
|
- float3 dir = boxProject(surface, ID);
|
|
|
-
|
|
|
- float3 color = TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, probeConfigData[ID].a, 0).xyz;
|
|
|
- return color;
|
|
|
-}
|
|
|
-
|
|
|
-float3 iblBoxSpecular(Surface surface, int ID)
|
|
|
-{
|
|
|
- // BRDF
|
|
|
- //float2 brdf = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.roughness, surface.NdotV, 0.0, 0.0)).xy;
|
|
|
-
|
|
|
- float3 dir = boxProject(surface, ID);
|
|
|
-
|
|
|
- // 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, probeConfigData[ID].a, lod).xyz;
|
|
|
- return color;
|
|
|
-}
|
|
|
-
|
|
|
-float3 iblSkylightDiffuse(Surface surface)
|
|
|
-{
|
|
|
- float3 color = TORQUE_TEXCUBELOD(skylightIrradMap, float4(surface.R, 0)).xyz;
|
|
|
- return color;
|
|
|
-}
|
|
|
-
|
|
|
-float3 iblSkylightSpecular(Surface surface)
|
|
|
-{
|
|
|
- // BRDF
|
|
|
- //float2 brdf = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.roughness, surface.NdotV, 0.0, 0.0)).xy;
|
|
|
-
|
|
|
- // Radiance (Specular)
|
|
|
-#if DEBUGVIZ_SPECCUBEMAP == 0
|
|
|
- float lod = surface.roughness*cubeMips;
|
|
|
-#elif DEBUGVIZ_SPECCUBEMAP == 1
|
|
|
- float lod = 0;
|
|
|
-#endif
|
|
|
-
|
|
|
- float3 color = TORQUE_TEXCUBELOD(skylightPrefilterMap, float4(surface.R, lod)).xyz;
|
|
|
- return color;
|
|
|
-}
|
|
|
-
|
|
|
float4 main(PFXVertToPix IN) : SV_TARGET
|
|
|
{
|
|
|
//unpack normal and linear depth
|
|
@@ -159,13 +70,13 @@ float4 main(PFXVertToPix IN) : SV_TARGET
|
|
|
|
|
|
if (probeConfigData[i].r == 0) //box
|
|
|
{
|
|
|
- contribution[i] = defineBoxSpaceInfluence(surface, i);
|
|
|
+ contribution[i] = defineBoxSpaceInfluence(surface, worldToObjArray[i], probeConfigData[i].b);
|
|
|
if (contribution[i]>0.0)
|
|
|
probehits++;
|
|
|
}
|
|
|
else if (probeConfigData[i].r == 1) //sphere
|
|
|
{
|
|
|
- contribution[i] = defineSphereSpaceInfluence(surface, i);
|
|
|
+ contribution[i] = defineSphereSpaceInfluence(surface, inProbePosArray[i].xyz, probeConfigData[i].g);
|
|
|
if (contribution[i]>0.0)
|
|
|
probehits++;
|
|
|
}
|
|
@@ -211,49 +122,68 @@ float4 main(PFXVertToPix IN) : SV_TARGET
|
|
|
alpha -= blendSum;
|
|
|
|
|
|
#if DEBUGVIZ_ATTENUATION == 1
|
|
|
- float attenVis = 0;
|
|
|
- for (i = 0; i < numProbes; ++i)
|
|
|
- {
|
|
|
- attenVis += contribution[i];
|
|
|
- }
|
|
|
-
|
|
|
- //return float4(attenVis, attenVis, attenVis, 1);
|
|
|
- return float4(blendSum, blendSum, blendSum, 1);
|
|
|
+ float contribAlpha = 1;
|
|
|
+ for (i = 0; i < numProbes; ++i)
|
|
|
+ {
|
|
|
+ contribAlpha -= contribution[i];
|
|
|
+ }
|
|
|
+
|
|
|
+ return float4(1 - contribAlpha, 1 - contribAlpha, 1 - contribAlpha, 1);
|
|
|
#endif
|
|
|
|
|
|
#if DEBUGVIZ_CONTRIB == 1
|
|
|
float3 finalContribColor = float3(0, 0, 0);
|
|
|
+ float contribAlpha = 1;
|
|
|
for (i = 0; i < numProbes; ++i)
|
|
|
{
|
|
|
finalContribColor += contribution[i] *probeContribColors[i].rgb;
|
|
|
+ contribAlpha -= contribution[i];
|
|
|
}
|
|
|
|
|
|
+ //Skylight coloration for anything not covered by probes above
|
|
|
+ finalContribColor += float3(0.3, 0.3, 0.3) * contribAlpha;
|
|
|
+
|
|
|
return float4(finalContribColor, 1);
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
-#if DEBUGVIZ_SPECCUBEMAP == 0 && DEBUGVIZ_DIFFCUBEMAP == 0
|
|
|
-
|
|
|
float3 irradiance = float3(0, 0, 0);
|
|
|
float3 specular = float3(0, 0, 0);
|
|
|
|
|
|
- float contrib = 0;
|
|
|
+ // Radiance (Specular)
|
|
|
+#if DEBUGVIZ_SPECCUBEMAP == 0
|
|
|
+ float lod = surface.roughness*cubeMips;
|
|
|
+#elif DEBUGVIZ_SPECCUBEMAP == 1
|
|
|
+ float lod = 0;
|
|
|
+#endif
|
|
|
+
|
|
|
+ alpha = 1;
|
|
|
for (i = 0; i < numProbes; ++i)
|
|
|
{
|
|
|
- if (contribution[i] == 0)
|
|
|
- continue;
|
|
|
+ float contrib = contribution[i];
|
|
|
+ if (contrib != 0)
|
|
|
+ {
|
|
|
+ int cubemapIdx = probeConfigData[i].a;
|
|
|
+ float3 dir = boxProject(surface, worldToObjArray[i], bbMinArray[i].xyz, bbMaxArray[i].xyz, inRefPosArray[i].xyz);
|
|
|
|
|
|
- irradiance += iblBoxDiffuse(surface, i) * contribution[i];
|
|
|
- specular += iblBoxSpecular(surface, i) * contribution[i];
|
|
|
- contrib +=contribution[i];
|
|
|
+ irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib;
|
|
|
+ specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib;
|
|
|
+ alpha -= contrib;
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- if (hasSkylight && alpha != 0)
|
|
|
+
|
|
|
+ if (hasSkylight && alpha > 0.001)
|
|
|
{
|
|
|
- irradiance = lerp(irradiance, iblSkylightDiffuse(surface), alpha);
|
|
|
- specular = lerp(specular, iblSkylightSpecular(surface), alpha);
|
|
|
+ irradiance += TORQUE_TEXCUBELOD(skylightIrradMap, float4(surface.R, 0)).xyz * alpha;
|
|
|
+ specular += TORQUE_TEXCUBELOD(skylightPrefilterMap, float4(surface.R, lod)).xyz * alpha;
|
|
|
}
|
|
|
|
|
|
+#if DEBUGVIZ_SPECCUBEMAP == 1 && DEBUGVIZ_DIFFCUBEMAP == 0
|
|
|
+ return float4(specular, 1);
|
|
|
+#elif DEBUGVIZ_DIFFCUBEMAP == 1
|
|
|
+ return float4(irradiance, 1);
|
|
|
+#endif
|
|
|
+
|
|
|
float3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness);
|
|
|
|
|
|
//energy conservation
|
|
@@ -263,47 +193,11 @@ float4 main(PFXVertToPix IN) : SV_TARGET
|
|
|
//apply brdf
|
|
|
//Do it once to save on texture samples
|
|
|
float2 brdf = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.roughness, surface.NdotV, 0.0, 0.0)).xy;
|
|
|
- specular *= (brdf.x + brdf.y)* F;
|
|
|
+ specular *= brdf.x * F + brdf.y;
|
|
|
|
|
|
//final diffuse color
|
|
|
float3 diffuse = kD * irradiance * surface.baseColor.rgb;
|
|
|
float4 finalColor = float4(diffuse + specular * surface.ao, 1.0);
|
|
|
|
|
|
return finalColor;
|
|
|
-
|
|
|
-#elif DEBUGVIZ_SPECCUBEMAP == 1 && DEBUGVIZ_DIFFCUBEMAP == 0
|
|
|
-
|
|
|
- float3 cubeColor = float3(0, 0, 0);
|
|
|
- for (i = 0; i < numProbes; ++i)
|
|
|
- {
|
|
|
- if (probeConfigData[i].r == 2) //skylight
|
|
|
- {
|
|
|
- cubeColor += iblSkylightSpecular(surface, i);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- cubeColor += iblBoxSpecular(surface, i);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return float4(cubeColor, 1);
|
|
|
-
|
|
|
-#elif DEBUGVIZ_DIFFCUBEMAP == 1
|
|
|
-
|
|
|
- float3 cubeColor = float3(0, 0, 0);
|
|
|
- for (i = 0; i < numProbes; ++i)
|
|
|
- {
|
|
|
- if (probeConfigData[i].r == 2) //skylight
|
|
|
- {
|
|
|
- cubeColor += iblSkylightDiffuse(surface);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- cubeColor += iblBoxDiffuse(surface);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return float4(cubeColor, 1);
|
|
|
-
|
|
|
-#endif
|
|
|
}
|