mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 23:54:35 +00:00
Cleanup/consolidation of shader logic. moved the common methods over to lighting.hlsl
Did all the setup work to feed data for forward probestuffs, just have to rewrite the shaderFeature to replicate the regular probe array logic.
This commit is contained in:
parent
f722e06980
commit
283348f7bc
8 changed files with 241 additions and 255 deletions
|
|
@ -237,3 +237,42 @@ inline float3 getPunctualLight(in Surface surface, in SurfaceToLight surfaceToLi
|
|||
}
|
||||
|
||||
//Probe IBL stuff
|
||||
float defineSphereSpaceInfluence(Surface surface, float3 wsProbePosition, float radius)
|
||||
{
|
||||
float3 L = wsProbePosition.xyz - surface.P;
|
||||
float contribution = 1.0 - length(L) / radius;
|
||||
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, float4x4 worldToObj, float attenuation)
|
||||
{
|
||||
float3 surfPosLS = mul(worldToObj, float4(surface.P, 1.0)).xyz;
|
||||
float atten = 1.0 - attenuation;
|
||||
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, float4x4 worldToObj, float3 bbMin, float3 bbMax, float3 refPosition)
|
||||
{
|
||||
float3 RayLS = mul(worldToObj, float4(surface.R, 0.0)).xyz;
|
||||
float3 PositionLS = mul(worldToObj, float4(surface.P, 1.0)).xyz;
|
||||
|
||||
float3 unit = bbMax.xyz - bbMin.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 - refPosition.xyz;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
float contribAlpha = 1;
|
||||
for (i = 0; i < numProbes; ++i)
|
||||
{
|
||||
contribAlpha -= contribution[i];
|
||||
}
|
||||
|
||||
//return float4(attenVis, attenVis, attenVis, 1);
|
||||
return float4(blendSum, blendSum, blendSum, 1);
|
||||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@
|
|||
//Cube
|
||||
#define TORQUE_SAMPLERCUBE(tex) TextureCube texture_##tex, SamplerState tex
|
||||
#define TORQUE_SAMPLERCUBE_MAKEARG(tex) texture_##tex, tex
|
||||
#define TORQUE_SAMPLERCUBEARRAY(tex) TextureCubeArray texture_##tex, SamplerState tex
|
||||
#define TORQUE_SAMPLERCUBEARRAY_MAKEARG(tex) texture_##tex, tex
|
||||
|
||||
#endif // _TORQUE_SHADERMODEL_
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue