diff --git a/Engine/source/T3D/lighting/reflectionProbe.cpp b/Engine/source/T3D/lighting/reflectionProbe.cpp index f993b795c..6b1fe2fef 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.cpp +++ b/Engine/source/T3D/lighting/reflectionProbe.cpp @@ -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(); diff --git a/Engine/source/gfx/gl/gfxGLShader.cpp b/Engine/source/gfx/gl/gfxGLShader.cpp index 8595a96d4..c8366ed56 100644 --- a/Engine/source/gfx/gl/gfxGLShader.cpp +++ b/Engine/source/gfx/gl/gfxGLShader.cpp @@ -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 diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp index 0f1ce87f6..954d199e2 100644 --- a/Engine/source/renderInstance/renderProbeMgr.cpp +++ b/Engine/source/renderInstance/renderProbeMgr.cpp @@ -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(); } diff --git a/Engine/source/renderInstance/renderProbeMgr.h b/Engine/source/renderInstance/renderProbeMgr.h index 4f64eaf95..94b8f7167 100644 --- a/Engine/source/renderInstance/renderProbeMgr.h +++ b/Engine/source/renderInstance/renderProbeMgr.h @@ -357,6 +357,7 @@ public: /// static bool smRenderReflectionProbes; + static bool smBakeReflectionProbes; //============================================================================= // Utility functions for processing and setting up the probes for rendering //============================================================================= diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl index f430c0e35..723a62511 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl @@ -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; } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl index a2004bd4d..3ec490af1 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl @@ -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 ); diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/prefilterP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/prefilterP.glsl index 1a2be0d2a..d83ee249a 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/prefilterP.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/prefilterP.glsl @@ -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); diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/prefilterP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/prefilterP.hlsl index fbacdadc9..b1f485e91 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/prefilterP.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/prefilterP.hlsl @@ -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);