Browse Source

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

AzaezelX 1 year ago
parent
commit
8c38448428

+ 5 - 1
Engine/source/T3D/lighting/reflectionProbe.cpp

@@ -184,6 +184,10 @@ void ReflectionProbe::initPersistFields()
       "@note Only works for shadow mapped lights.\n\n"
       "@note Only works for shadow mapped lights.\n\n"
       "@ingroup Lighting");
       "@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,
    Con::addVariable("$Light::renderPreviewProbes", TypeBool, &ReflectionProbe::smRenderPreviewProbes,
       "Toggles rendering of light frustums when the light is selected in the editor.\n\n"
       "Toggles rendering of light frustums when the light is selected in the editor.\n\n"
       "@note Only works for shadow mapped lights.\n\n"
       "@note Only works for shadow mapped lights.\n\n"
@@ -823,7 +827,7 @@ void ReflectionProbe::createEditorResources()
 
 
 void ReflectionProbe::prepRenderImage(SceneRenderState *state)
 void ReflectionProbe::prepRenderImage(SceneRenderState *state)
 {
 {
-   if (!mEnabled || (!RenderProbeMgr::smRenderReflectionProbes && !dStrcmp(Con::getVariable("$Probes::Capturing", "0"),"1")))
+   if (!mEnabled || (!RenderProbeMgr::smRenderReflectionProbes || RenderProbeMgr::smBakeReflectionProbes))
       return;
       return;
 
 
    Point3F distVec = getRenderPosition() - state->getCameraPosition();
    Point3F distVec = getRenderPosition() - state->getCameraPosition();

+ 7 - 8
Engine/source/gfx/gl/gfxGLShader.cpp

@@ -1109,9 +1109,12 @@ bool GFXGLShader::initShader( const Torque::Path &file,
       return false;
       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;
       return false;
-   
+   }
    GLint compile;
    GLint compile;
    glGetShaderiv(activeShader, GL_COMPILE_STATUS, &compile);
    glGetShaderiv(activeShader, GL_COMPILE_STATUS, &compile);
 
 
@@ -1119,17 +1122,13 @@ bool GFXGLShader::initShader( const Torque::Path &file,
    U32 logLength = 0;
    U32 logLength = 0;
    glGetShaderiv(activeShader, GL_INFO_LOG_LENGTH, (GLint*)&logLength);
    glGetShaderiv(activeShader, GL_INFO_LOG_LENGTH, (GLint*)&logLength);
    
    
-   GLint compileStatus = GL_TRUE;
    if ( logLength )
    if ( logLength )
    {
    {
       FrameAllocatorMarker fam;
       FrameAllocatorMarker fam;
       char* log = (char*)fam.alloc(logLength);
       char* log = (char*)fam.alloc(logLength);
       glGetShaderInfoLog(activeShader, logLength, NULL, log);
       glGetShaderInfoLog(activeShader, logLength, NULL, log);
 
 
-      // Always print errors
-      glGetShaderiv( activeShader, GL_COMPILE_STATUS, &compileStatus );
-
-      if ( compileStatus == GL_FALSE )
+      if (compile == GL_FALSE )
       {
       {
          if ( smLogErrors )
          if ( smLogErrors )
          {
          {
@@ -1141,7 +1140,7 @@ bool GFXGLShader::initShader( const Torque::Path &file,
          Con::warnf( "Program %s: %s", file.getFullPath().c_str(), log );
          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
 /// Returns our list of shader constants, the material can get this and just set the constants it knows about

+ 40 - 9
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
 // This variable is a global toggle on if reflection probes should be rendered or not
 bool RenderProbeMgr::smRenderReflectionProbes = true;
 bool RenderProbeMgr::smRenderReflectionProbes = true;
 
 
+bool RenderProbeMgr::smBakeReflectionProbes = false;
+
 // This variable defines the maximum draw distance of a probe.
 // This variable defines the maximum draw distance of a probe.
 F32 RenderProbeMgr::smMaxProbeDrawDistance = 100;
 F32 RenderProbeMgr::smMaxProbeDrawDistance = 100;
 
 
@@ -500,19 +502,50 @@ void RenderProbeMgr::reloadTextures()
 
 
 void RenderProbeMgr::preBake()
 void RenderProbeMgr::preBake()
 {
 {
-   Con::setVariable("$Probes::Capturing", "1");
+   RenderProbeMgr::smBakeReflectionProbes = true;
+   GFXShader::addGlobalMacro("CAPTURING", String("1"));
+
+   //Con::setVariable("$Probes::Capturing", "1");
    mRenderMaximumNumOfLights = AdvancedLightBinManager::smMaximumNumOfLights;
    mRenderMaximumNumOfLights = AdvancedLightBinManager::smMaximumNumOfLights;
    mRenderUseLightFade = AdvancedLightBinManager::smUseLightFade;
    mRenderUseLightFade = AdvancedLightBinManager::smUseLightFade;
 
 
    AdvancedLightBinManager::smMaximumNumOfLights = -1;
    AdvancedLightBinManager::smMaximumNumOfLights = -1;
    AdvancedLightBinManager::smUseLightFade = false;
    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()
 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::smMaximumNumOfLights = mRenderMaximumNumOfLights;
    AdvancedLightBinManager::smUseLightFade = mRenderUseLightFade;
    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)
 void RenderProbeMgr::bakeProbe(ReflectionProbe* probe)
 {
 {
    GFXDEBUGEVENT_SCOPE(RenderProbeMgr_Bake, ColorI::WHITE);
    GFXDEBUGEVENT_SCOPE(RenderProbeMgr_Bake, ColorI::WHITE);
@@ -520,8 +553,6 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe)
    Con::warnf("RenderProbeMgr::bakeProbe() - Beginning bake!");
    Con::warnf("RenderProbeMgr::bakeProbe() - Beginning bake!");
    U32 startMSTime = Platform::getRealMilliseconds();
    U32 startMSTime = Platform::getRealMilliseconds();
 
 
-   preBake();
-
    String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/");
    String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/");
    U32 resolution = Con::getIntVariable("$pref::ReflectionProbes::BakeResolution", 64);
    U32 resolution = Con::getIntVariable("$pref::ReflectionProbes::BakeResolution", 64);
    U32 prefilterMipLevels = mLog2(F32(resolution)) + 1;
    U32 prefilterMipLevels = mLog2(F32(resolution)) + 1;
@@ -641,7 +672,6 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe)
    if (!renderWithProbes)
    if (!renderWithProbes)
       RenderProbeMgr::smRenderReflectionProbes = probeRenderState;
       RenderProbeMgr::smRenderReflectionProbes = probeRenderState;
 
 
-   postBake();
 
 
    cubeRefl.unregisterReflector();
    cubeRefl.unregisterReflector();
 
 
@@ -845,7 +875,7 @@ void RenderProbeMgr::render( SceneRenderState *state )
    _setupPerFrameParameters(state);
    _setupPerFrameParameters(state);
 
 
    // Early out if nothing to draw.
    // 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);
       getProbeArrayEffect()->setSkip(true);
       mActiveProbes.clear();
       mActiveProbes.clear();
@@ -875,9 +905,6 @@ void RenderProbeMgr::render( SceneRenderState *state )
    String probePerFrame = Con::getVariable("$pref::MaxProbesPerFrame", "8");
    String probePerFrame = Con::getVariable("$pref::MaxProbesPerFrame", "8");
    mProbeArrayEffect->setShaderMacro("MAX_PROBES", probePerFrame);
    mProbeArrayEffect->setShaderMacro("MAX_PROBES", probePerFrame);
 
 
-   String probeCapturing = Con::getVariable("$Probes::Capturing", "0");
-   mProbeArrayEffect->setShaderMacro("CAPTURING", probeCapturing);
-   
    mProbeArrayEffect->setTexture(3, mBRDFTexture);
    mProbeArrayEffect->setTexture(3, mBRDFTexture);
    mProbeArrayEffect->setCubemapArrayTexture(4, mPrefilterArray);
    mProbeArrayEffect->setCubemapArrayTexture(4, mPrefilterArray);
    mProbeArrayEffect->setCubemapArrayTexture(5, mIrradianceArray);
    mProbeArrayEffect->setCubemapArrayTexture(5, mIrradianceArray);
@@ -953,11 +980,15 @@ void RenderProbeMgr::render( SceneRenderState *state )
 DefineEngineMethod(RenderProbeMgr, bakeProbe, void, (ReflectionProbe* probe), (nullAsType< ReflectionProbe*>()),
 DefineEngineMethod(RenderProbeMgr, bakeProbe, void, (ReflectionProbe* probe), (nullAsType< ReflectionProbe*>()),
    "@brief Bakes the cubemaps for a reflection probe\n\n.")
    "@brief Bakes the cubemaps for a reflection probe\n\n.")
 {
 {
+   object->preBake();
    if(probe != nullptr)
    if(probe != nullptr)
       object->bakeProbe(probe);
       object->bakeProbe(probe);
+   object->postBake();
 }
 }
 
 
 DefineEngineMethod(RenderProbeMgr, bakeProbes, void, (),, "@brief Iterates over all reflection probes in the scene and bakes their cubemaps\n\n.")
 DefineEngineMethod(RenderProbeMgr, bakeProbes, void, (),, "@brief Iterates over all reflection probes in the scene and bakes their cubemaps\n\n.")
 {
 {
+   object->preBake();
    object->bakeProbes();
    object->bakeProbes();
+   object->postBake();
 }
 }

+ 1 - 0
Engine/source/renderInstance/renderProbeMgr.h

@@ -357,6 +357,7 @@ public:
    /// </summary>
    /// </summary>
    static bool smRenderReflectionProbes;
    static bool smRenderReflectionProbes;
 
 
+   static bool smBakeReflectionProbes;
    //=============================================================================
    //=============================================================================
    // Utility functions for processing and setting up the probes for rendering
    // Utility functions for processing and setting up the probes for rendering
    //=============================================================================
    //=============================================================================

+ 23 - 4
Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl

@@ -66,6 +66,10 @@ uniform vec4 albedo;
 #define DEBUGVIZ_CONTRIB 0
 #define DEBUGVIZ_CONTRIB 0
 #endif
 #endif
 
 
+#ifndef CAPTURE_LIGHT_FLOOR
+#define CAPTURE_LIGHT_FLOOR 0.04
+#endif
+
 vec3 getDistanceVectorToPlane( vec3 origin, vec3 direction, vec4 plane )
 vec3 getDistanceVectorToPlane( vec3 origin, vec3 direction, vec4 plane )
 {
 {
    float denum = dot( plane.xyz, direction.xyz );
    float denum = dot( plane.xyz, direction.xyz );
@@ -234,7 +238,7 @@ vec3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
    vec3 Fr = D * F * Vis;
    vec3 Fr = D * F * Vis;
 
 
 #if CAPTURING == 1
 #if CAPTURING == 1
-   return saturate(mix(Fd + Fr,surface.f0,surface.metalness));
+   return mix(Fd + Fr, surface.baseColor.rgb, surface.metalness);
 #else
 #else
    return Fd + Fr;
    return Fd + Fr;
 #endif
 #endif
@@ -243,23 +247,38 @@ vec3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
 
 
 vec3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float shadow)
 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;
    return evaluateStandardBRDF(surface,surfaceToLight) * factor;
 }
 }
 
 
 vec3 getPunctualLight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float radius, float shadow)
 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);
    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;
    return evaluateStandardBRDF(surface,surfaceToLight) * factor;
 }
 }
 
 
 vec3 getSpotlight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float radius, vec3 lightDir, vec2 lightSpotParams, float shadow)
 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;
    float attenuation = 1.0f;
    attenuation *= getDistanceAtt(surfaceToLight.Lu, radius);
    attenuation *= getDistanceAtt(surfaceToLight.Lu, radius);
    attenuation *= getSpotAngleAtt(-surfaceToLight.L, lightDir, lightSpotParams.xy);
    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;
    return evaluateStandardBRDF(surface,surfaceToLight) * factor;
 }
 }
 
 

+ 24 - 4
Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl

@@ -68,6 +68,10 @@ uniform float4 albedo;
 #define DEBUGVIZ_CONTRIB 0
 #define DEBUGVIZ_CONTRIB 0
 #endif
 #endif
 
 
+#ifndef CAPTURE_LIGHT_FLOOR
+#define CAPTURE_LIGHT_FLOOR 0.04
+#endif
+
 inline float3 getDistanceVectorToPlane( float3 origin, float3 direction, float4 plane )
 inline float3 getDistanceVectorToPlane( float3 origin, float3 direction, float4 plane )
 {
 {
    float denum = dot( plane.xyz, direction.xyz );
    float denum = dot( plane.xyz, direction.xyz );
@@ -235,7 +239,7 @@ float3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
    float3 Fr = D * F * Vis;
    float3 Fr = D * F * Vis;
 
 
 #if CAPTURING == 1
 #if CAPTURING == 1
-    return saturate(lerp(Fd + Fr,surface.f0,surface.metalness));
+    return lerp(Fd + Fr,surface.baseColor.rgb,surface.metalness);
 #else
 #else
    return Fd + Fr;
    return Fd + Fr;
 #endif
 #endif
@@ -244,25 +248,41 @@ float3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
 
 
 float3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float shadow)
 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;
    return evaluateStandardBRDF(surface,surfaceToLight) * factor;
 }
 }
 
 
 float3 getPunctualLight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float radius, float shadow)
 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);
    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;
    return evaluateStandardBRDF(surface,surfaceToLight) * factor;
 }
 }
 
 
 float3 getSpotlight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float radius, float3 lightDir, float2 lightSpotParams, float shadow)
 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;
    float attenuation = 1.0f;
    attenuation *= getDistanceAtt(surfaceToLight.Lu, radius);
    attenuation *= getDistanceAtt(surfaceToLight.Lu, radius);
    attenuation *= getSpotAngleAtt(-surfaceToLight.L, lightDir, lightSpotParams.xy);
    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;
    return evaluateStandardBRDF(surface,surfaceToLight) * factor;
 }
 }
+
 float computeSpecOcclusion( float NdotV , float AO , float roughness )
 float computeSpecOcclusion( float NdotV , float AO , float roughness )
 {
 {
    return saturate (pow( abs(NdotV + AO) , exp2 ( -16.0f * roughness - 1.0f )) - 1.0f + AO );
    return saturate (pow( abs(NdotV + AO) , exp2 ( -16.0f * roughness - 1.0f )) - 1.0f + AO );

+ 2 - 2
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)
 vec3 prefilterEnvMap(vec3 R)
 {
 {
-    int sampleCount = resolution*2;
+    int sampleCount = 1024;
 	vec3 N = R;
 	vec3 N = R;
 	vec3 V = R;
 	vec3 V = R;
 	float totalWeight = 0.0;
 	float totalWeight = 0.0;
@@ -107,7 +107,7 @@ vec3 prefilterEnvMap(vec3 R)
 				float HdotV = max(dot(H, V), 0.0);
 				float HdotV = max(dot(H, V), 0.0);
 				float pdf = D * NdotH / (4.0 * HdotV) + 0.0001;
 				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 saSample = 1.0 / (float(sampleCount) * pdf + 0.0001);
 
 
 				float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel);
 				float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel);

+ 2 - 2
Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/prefilterP.hlsl

@@ -88,7 +88,7 @@ float3 ImportanceSampleGGX(float2 Xi, float3 N)
 
 
 float4 prefilterEnvMap(float3 R)
 float4 prefilterEnvMap(float3 R)
 {
 {
-    int sampleCount = resolution*2;
+    int sampleCount = 1024;
 	float3 N = R;
 	float3 N = R;
 	float3 V = R;
 	float3 V = R;
 	float totalWeight = 0.0;
 	float totalWeight = 0.0;
@@ -109,7 +109,7 @@ float4 prefilterEnvMap(float3 R)
 				float HdotV = max(dot(H, V), 0.0);
 				float HdotV = max(dot(H, V), 0.0);
 				float pdf = D * NdotH / (4.0 * HdotV) + 0.0001;
 				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 saSample = 1.0 / (float(sampleCount) * pdf + 0.0001);
 
 
 				float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel);
 				float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel);