mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-19 20:24:49 +00:00
probe capture fixes
review of per and post bake protocols showed that the CAPTURING shader macro was not being properly recompiled in. as opengl was not playing nice with a simple batch shader recompilation for all effected shaders, a full lightmanager restart is at time of writing required. once we have a proper globally cached scene structure stored off GPU side, we'll want to change GFXShader::addGlobalMacro("CAPTURING", String("1")); on over to dirtying that value in the cached buffer via setting a shader global uniform
review of prefilter examples shows a fixed sample count of 1024 across multiple implementations, so we'll use the standard barring further research into where that number is comming from for a scalar approach
review of gl shaders shows a doubleup in compiled state testing, so slimmed that down and added additional debugging reports
This commit is contained in:
parent
97de2e6b60
commit
8c38448428
|
|
@ -184,6 +184,10 @@ void ReflectionProbe::initPersistFields()
|
|||
"@note Only works for shadow mapped lights.\n\n"
|
||||
"@ingroup Lighting");
|
||||
|
||||
Con::addVariable("$Probes::Capturing", TypeBool, &RenderProbeMgr::smBakeReflectionProbes,
|
||||
"Toggles probe rendering capture state.\n\n"
|
||||
"@ingroup Lighting");
|
||||
|
||||
Con::addVariable("$Light::renderPreviewProbes", TypeBool, &ReflectionProbe::smRenderPreviewProbes,
|
||||
"Toggles rendering of light frustums when the light is selected in the editor.\n\n"
|
||||
"@note Only works for shadow mapped lights.\n\n"
|
||||
|
|
@ -823,7 +827,7 @@ void ReflectionProbe::createEditorResources()
|
|||
|
||||
void ReflectionProbe::prepRenderImage(SceneRenderState *state)
|
||||
{
|
||||
if (!mEnabled || (!RenderProbeMgr::smRenderReflectionProbes && !dStrcmp(Con::getVariable("$Probes::Capturing", "0"),"1")))
|
||||
if (!mEnabled || (!RenderProbeMgr::smRenderReflectionProbes || RenderProbeMgr::smBakeReflectionProbes))
|
||||
return;
|
||||
|
||||
Point3F distVec = getRenderPosition() - state->getCameraPosition();
|
||||
|
|
|
|||
|
|
@ -1109,9 +1109,12 @@ bool GFXGLShader::initShader( const Torque::Path &file,
|
|||
return false;
|
||||
}
|
||||
|
||||
if ( !_loadShaderFromStream( activeShader, file, &stream, macros ) )
|
||||
if (!_loadShaderFromStream(activeShader, file, &stream, macros))
|
||||
{
|
||||
if (smLogErrors)
|
||||
Con::errorf("GFXGLShader::initShader - unable to load shader from stream: '%s'.", file.getFullPath().c_str());
|
||||
return false;
|
||||
|
||||
}
|
||||
GLint compile;
|
||||
glGetShaderiv(activeShader, GL_COMPILE_STATUS, &compile);
|
||||
|
||||
|
|
@ -1119,17 +1122,13 @@ bool GFXGLShader::initShader( const Torque::Path &file,
|
|||
U32 logLength = 0;
|
||||
glGetShaderiv(activeShader, GL_INFO_LOG_LENGTH, (GLint*)&logLength);
|
||||
|
||||
GLint compileStatus = GL_TRUE;
|
||||
if ( logLength )
|
||||
{
|
||||
FrameAllocatorMarker fam;
|
||||
char* log = (char*)fam.alloc(logLength);
|
||||
glGetShaderInfoLog(activeShader, logLength, NULL, log);
|
||||
|
||||
// Always print errors
|
||||
glGetShaderiv( activeShader, GL_COMPILE_STATUS, &compileStatus );
|
||||
|
||||
if ( compileStatus == GL_FALSE )
|
||||
if (compile == GL_FALSE )
|
||||
{
|
||||
if ( smLogErrors )
|
||||
{
|
||||
|
|
@ -1141,7 +1140,7 @@ bool GFXGLShader::initShader( const Torque::Path &file,
|
|||
Con::warnf( "Program %s: %s", file.getFullPath().c_str(), log );
|
||||
}
|
||||
|
||||
return compileStatus != GL_FALSE;
|
||||
return compile != GL_FALSE;
|
||||
}
|
||||
|
||||
/// Returns our list of shader constants, the material can get this and just set the constants it knows about
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ RenderProbeMgr *RenderProbeMgr::smProbeManager = NULL;
|
|||
// This variable is a global toggle on if reflection probes should be rendered or not
|
||||
bool RenderProbeMgr::smRenderReflectionProbes = true;
|
||||
|
||||
bool RenderProbeMgr::smBakeReflectionProbes = false;
|
||||
|
||||
// This variable defines the maximum draw distance of a probe.
|
||||
F32 RenderProbeMgr::smMaxProbeDrawDistance = 100;
|
||||
|
||||
|
|
@ -500,19 +502,50 @@ void RenderProbeMgr::reloadTextures()
|
|||
|
||||
void RenderProbeMgr::preBake()
|
||||
{
|
||||
Con::setVariable("$Probes::Capturing", "1");
|
||||
RenderProbeMgr::smBakeReflectionProbes = true;
|
||||
GFXShader::addGlobalMacro("CAPTURING", String("1"));
|
||||
|
||||
//Con::setVariable("$Probes::Capturing", "1");
|
||||
mRenderMaximumNumOfLights = AdvancedLightBinManager::smMaximumNumOfLights;
|
||||
mRenderUseLightFade = AdvancedLightBinManager::smUseLightFade;
|
||||
|
||||
AdvancedLightBinManager::smMaximumNumOfLights = -1;
|
||||
AdvancedLightBinManager::smUseLightFade = false;
|
||||
|
||||
//kickstart rendering
|
||||
LightManager* lm = LIGHTMGR;
|
||||
if (lm)
|
||||
{
|
||||
SceneManager* sm = lm->getSceneManager();
|
||||
if (sm && sm->getContainer() == &gClientContainer)
|
||||
{
|
||||
lm->deactivate();
|
||||
lm->activate(sm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderProbeMgr::postBake()
|
||||
{
|
||||
Con::setVariable("$Probes::Capturing", "0");
|
||||
RenderProbeMgr::smBakeReflectionProbes = false;
|
||||
GFXShader::addGlobalMacro("CAPTURING", String("0"));
|
||||
//Con::setVariable("$Probes::Capturing", "0");
|
||||
AdvancedLightBinManager::smMaximumNumOfLights = mRenderMaximumNumOfLights;
|
||||
AdvancedLightBinManager::smUseLightFade = mRenderUseLightFade;
|
||||
|
||||
//kickstart rendering
|
||||
LightManager* lm = LIGHTMGR;
|
||||
if (lm)
|
||||
{
|
||||
SceneManager* sm = lm->getSceneManager();
|
||||
if (sm && sm->getContainer() == &gClientContainer)
|
||||
{
|
||||
lm->deactivate();
|
||||
lm->activate(sm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderProbeMgr::bakeProbe(ReflectionProbe* probe)
|
||||
{
|
||||
GFXDEBUGEVENT_SCOPE(RenderProbeMgr_Bake, ColorI::WHITE);
|
||||
|
|
@ -520,8 +553,6 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe)
|
|||
Con::warnf("RenderProbeMgr::bakeProbe() - Beginning bake!");
|
||||
U32 startMSTime = Platform::getRealMilliseconds();
|
||||
|
||||
preBake();
|
||||
|
||||
String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/");
|
||||
U32 resolution = Con::getIntVariable("$pref::ReflectionProbes::BakeResolution", 64);
|
||||
U32 prefilterMipLevels = mLog2(F32(resolution)) + 1;
|
||||
|
|
@ -641,7 +672,6 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe)
|
|||
if (!renderWithProbes)
|
||||
RenderProbeMgr::smRenderReflectionProbes = probeRenderState;
|
||||
|
||||
postBake();
|
||||
|
||||
cubeRefl.unregisterReflector();
|
||||
|
||||
|
|
@ -845,7 +875,7 @@ void RenderProbeMgr::render( SceneRenderState *state )
|
|||
_setupPerFrameParameters(state);
|
||||
|
||||
// Early out if nothing to draw.
|
||||
if ((!RenderProbeMgr::smRenderReflectionProbes && !dStrcmp(Con::getVariable("$Probes::Capturing", "0"), "1")) || (!mHasSkylight && mProbeData.effectiveProbeCount == 0))
|
||||
if (!RenderProbeMgr::smRenderReflectionProbes || (!mHasSkylight && mProbeData.effectiveProbeCount == 0))
|
||||
{
|
||||
getProbeArrayEffect()->setSkip(true);
|
||||
mActiveProbes.clear();
|
||||
|
|
@ -875,9 +905,6 @@ void RenderProbeMgr::render( SceneRenderState *state )
|
|||
String probePerFrame = Con::getVariable("$pref::MaxProbesPerFrame", "8");
|
||||
mProbeArrayEffect->setShaderMacro("MAX_PROBES", probePerFrame);
|
||||
|
||||
String probeCapturing = Con::getVariable("$Probes::Capturing", "0");
|
||||
mProbeArrayEffect->setShaderMacro("CAPTURING", probeCapturing);
|
||||
|
||||
mProbeArrayEffect->setTexture(3, mBRDFTexture);
|
||||
mProbeArrayEffect->setCubemapArrayTexture(4, mPrefilterArray);
|
||||
mProbeArrayEffect->setCubemapArrayTexture(5, mIrradianceArray);
|
||||
|
|
@ -953,11 +980,15 @@ void RenderProbeMgr::render( SceneRenderState *state )
|
|||
DefineEngineMethod(RenderProbeMgr, bakeProbe, void, (ReflectionProbe* probe), (nullAsType< ReflectionProbe*>()),
|
||||
"@brief Bakes the cubemaps for a reflection probe\n\n.")
|
||||
{
|
||||
object->preBake();
|
||||
if(probe != nullptr)
|
||||
object->bakeProbe(probe);
|
||||
object->postBake();
|
||||
}
|
||||
|
||||
DefineEngineMethod(RenderProbeMgr, bakeProbes, void, (),, "@brief Iterates over all reflection probes in the scene and bakes their cubemaps\n\n.")
|
||||
{
|
||||
object->preBake();
|
||||
object->bakeProbes();
|
||||
object->postBake();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -357,6 +357,7 @@ public:
|
|||
/// </summary>
|
||||
static bool smRenderReflectionProbes;
|
||||
|
||||
static bool smBakeReflectionProbes;
|
||||
//=============================================================================
|
||||
// Utility functions for processing and setting up the probes for rendering
|
||||
//=============================================================================
|
||||
|
|
|
|||
|
|
@ -66,6 +66,10 @@ uniform vec4 albedo;
|
|||
#define DEBUGVIZ_CONTRIB 0
|
||||
#endif
|
||||
|
||||
#ifndef CAPTURE_LIGHT_FLOOR
|
||||
#define CAPTURE_LIGHT_FLOOR 0.04
|
||||
#endif
|
||||
|
||||
vec3 getDistanceVectorToPlane( vec3 origin, vec3 direction, vec4 plane )
|
||||
{
|
||||
float denum = dot( plane.xyz, direction.xyz );
|
||||
|
|
@ -234,7 +238,7 @@ vec3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
|
|||
vec3 Fr = D * F * Vis;
|
||||
|
||||
#if CAPTURING == 1
|
||||
return saturate(mix(Fd + Fr,surface.f0,surface.metalness));
|
||||
return mix(Fd + Fr, surface.baseColor.rgb, surface.metalness);
|
||||
#else
|
||||
return Fd + Fr;
|
||||
#endif
|
||||
|
|
@ -243,23 +247,38 @@ vec3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
|
|||
|
||||
vec3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float shadow)
|
||||
{
|
||||
vec3 factor = lightColor * max(surfaceToLight.NdotL * shadow * lightIntensity, 0.0f);
|
||||
#if CAPTURING == 1
|
||||
float lightfloor = CAPTURE_LIGHT_FLOOR;
|
||||
#else
|
||||
float lightfloor = 0.0;
|
||||
#endif
|
||||
vec3 factor = lightColor * max(surfaceToLight.NdotL * shadow * lightIntensity, lightfloor);
|
||||
return evaluateStandardBRDF(surface,surfaceToLight) * factor;
|
||||
}
|
||||
|
||||
vec3 getPunctualLight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float radius, float shadow)
|
||||
{
|
||||
#if CAPTURING == 1
|
||||
float lightfloor = CAPTURE_LIGHT_FLOOR;
|
||||
#else
|
||||
float lightfloor = 0.0;
|
||||
#endif
|
||||
float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
|
||||
vec3 factor = lightColor * max(surfaceToLight.NdotL * shadow * lightIntensity * attenuation, 0.0f);
|
||||
vec3 factor = lightColor * max(surfaceToLight.NdotL * shadow * lightIntensity * attenuation, lightfloor);
|
||||
return evaluateStandardBRDF(surface,surfaceToLight) * factor;
|
||||
}
|
||||
|
||||
vec3 getSpotlight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float radius, vec3 lightDir, vec2 lightSpotParams, float shadow)
|
||||
{
|
||||
#if CAPTURING == 1
|
||||
float lightfloor = CAPTURE_LIGHT_FLOOR;
|
||||
#else
|
||||
float lightfloor = 0.0;
|
||||
#endif
|
||||
float attenuation = 1.0f;
|
||||
attenuation *= getDistanceAtt(surfaceToLight.Lu, radius);
|
||||
attenuation *= getSpotAngleAtt(-surfaceToLight.L, lightDir, lightSpotParams.xy);
|
||||
vec3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, 0.0f) ;
|
||||
vec3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, lightfloor);
|
||||
return evaluateStandardBRDF(surface,surfaceToLight) * factor;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,10 @@ uniform float4 albedo;
|
|||
#define DEBUGVIZ_CONTRIB 0
|
||||
#endif
|
||||
|
||||
#ifndef CAPTURE_LIGHT_FLOOR
|
||||
#define CAPTURE_LIGHT_FLOOR 0.04
|
||||
#endif
|
||||
|
||||
inline float3 getDistanceVectorToPlane( float3 origin, float3 direction, float4 plane )
|
||||
{
|
||||
float denum = dot( plane.xyz, direction.xyz );
|
||||
|
|
@ -235,7 +239,7 @@ float3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
|
|||
float3 Fr = D * F * Vis;
|
||||
|
||||
#if CAPTURING == 1
|
||||
return saturate(lerp(Fd + Fr,surface.f0,surface.metalness));
|
||||
return lerp(Fd + Fr,surface.baseColor.rgb,surface.metalness);
|
||||
#else
|
||||
return Fd + Fr;
|
||||
#endif
|
||||
|
|
@ -244,25 +248,41 @@ float3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
|
|||
|
||||
float3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float shadow)
|
||||
{
|
||||
float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity, 0.0f) ;
|
||||
#if CAPTURING == 1
|
||||
float lightfloor = CAPTURE_LIGHT_FLOOR;
|
||||
#else
|
||||
float lightfloor = 0.0;
|
||||
#endif
|
||||
float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity, lightfloor) ;
|
||||
return evaluateStandardBRDF(surface,surfaceToLight) * factor;
|
||||
}
|
||||
|
||||
float3 getPunctualLight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float radius, float shadow)
|
||||
{
|
||||
#if CAPTURING == 1
|
||||
float lightfloor = CAPTURE_LIGHT_FLOOR;
|
||||
#else
|
||||
float lightfloor = 0.0;
|
||||
#endif
|
||||
float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
|
||||
float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, 0.0f) ;
|
||||
float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, lightfloor) ;
|
||||
return evaluateStandardBRDF(surface,surfaceToLight) * factor;
|
||||
}
|
||||
|
||||
float3 getSpotlight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float radius, float3 lightDir, float2 lightSpotParams, float shadow)
|
||||
{
|
||||
#if CAPTURING == 1
|
||||
float lightfloor = CAPTURE_LIGHT_FLOOR;
|
||||
#else
|
||||
float lightfloor = 0.0;
|
||||
#endif
|
||||
float attenuation = 1.0f;
|
||||
attenuation *= getDistanceAtt(surfaceToLight.Lu, radius);
|
||||
attenuation *= getSpotAngleAtt(-surfaceToLight.L, lightDir, lightSpotParams.xy);
|
||||
float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, 0.0f) ;
|
||||
float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, lightfloor) ;
|
||||
return evaluateStandardBRDF(surface,surfaceToLight) * factor;
|
||||
}
|
||||
|
||||
float computeSpecOcclusion( float NdotV , float AO , float roughness )
|
||||
{
|
||||
return saturate (pow( abs(NdotV + AO) , exp2 ( -16.0f * roughness - 1.0f )) - 1.0f + AO );
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ vec3 ImportanceSampleGGX(vec2 Xi, vec3 N)
|
|||
|
||||
vec3 prefilterEnvMap(vec3 R)
|
||||
{
|
||||
int sampleCount = resolution*2;
|
||||
int sampleCount = 1024;
|
||||
vec3 N = R;
|
||||
vec3 V = R;
|
||||
float totalWeight = 0.0;
|
||||
|
|
@ -107,7 +107,7 @@ vec3 prefilterEnvMap(vec3 R)
|
|||
float HdotV = max(dot(H, V), 0.0);
|
||||
float pdf = D * NdotH / (4.0 * HdotV) + 0.0001;
|
||||
|
||||
float saTexel = 4.0 * M_PI_F / float(6.0 * sampleCount * sampleCount);
|
||||
float saTexel = 4.0 * M_PI_F / float(6.0 * resolution * resolution);
|
||||
float saSample = 1.0 / (float(sampleCount) * pdf + 0.0001);
|
||||
|
||||
float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel);
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ float3 ImportanceSampleGGX(float2 Xi, float3 N)
|
|||
|
||||
float4 prefilterEnvMap(float3 R)
|
||||
{
|
||||
int sampleCount = resolution*2;
|
||||
int sampleCount = 1024;
|
||||
float3 N = R;
|
||||
float3 V = R;
|
||||
float totalWeight = 0.0;
|
||||
|
|
@ -109,7 +109,7 @@ float4 prefilterEnvMap(float3 R)
|
|||
float HdotV = max(dot(H, V), 0.0);
|
||||
float pdf = D * NdotH / (4.0 * HdotV) + 0.0001;
|
||||
|
||||
float saTexel = 4.0 * M_PI_F / (6.0 * sampleCount * sampleCount);
|
||||
float saTexel = 4.0 * M_PI_F / (6.0 * resolution * resolution);
|
||||
float saSample = 1.0 / (float(sampleCount) * pdf + 0.0001);
|
||||
|
||||
float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel);
|
||||
|
|
|
|||
Loading…
Reference in a new issue