diff --git a/jme3-core/src/main/java/com/jme3/environment/EnvironmentProbeControl.java b/jme3-core/src/main/java/com/jme3/environment/EnvironmentProbeControl.java index d07a039995..6f07fd1c1c 100644 --- a/jme3-core/src/main/java/com/jme3/environment/EnvironmentProbeControl.java +++ b/jme3-core/src/main/java/com/jme3/environment/EnvironmentProbeControl.java @@ -287,8 +287,9 @@ public void setAssetManager(AssetManager assetManager) { } void rebakeNow(RenderManager renderManager) { - IBLHybridEnvBakerLight baker = new IBLGLEnvBakerLight(renderManager, assetManager, Format.RGB16F, Format.Depth, - envMapSize, envMapSize); + IBLHybridEnvBakerLight baker = new IBLGLEnvBakerLight(renderManager, assetManager, Format.RGB16F, + Format.Depth, + envMapSize, envMapSize); baker.setTexturePulling(isRequiredSavableResults()); baker.bakeEnvironment(spatial, getPosition(), frustumNear, frustumFar, filter); diff --git a/jme3-core/src/main/java/com/jme3/environment/FastLightProbeFactory.java b/jme3-core/src/main/java/com/jme3/environment/FastLightProbeFactory.java index d78edc561e..12ba5e99c1 100644 --- a/jme3-core/src/main/java/com/jme3/environment/FastLightProbeFactory.java +++ b/jme3-core/src/main/java/com/jme3/environment/FastLightProbeFactory.java @@ -33,6 +33,7 @@ import com.jme3.asset.AssetManager; import com.jme3.environment.baker.IBLGLEnvBakerLight; +import com.jme3.environment.baker.IBLHybridEnvBakerLight; import com.jme3.environment.util.EnvMapUtils; import com.jme3.light.LightProbe; import com.jme3.math.Vector3f; @@ -74,7 +75,8 @@ public class FastLightProbeFactory { * @return The baked LightProbe */ public static LightProbe makeProbe(RenderManager rm, AssetManager am, int size, Vector3f pos, float frustumNear, float frustumFar, Spatial scene) { - IBLGLEnvBakerLight baker = new IBLGLEnvBakerLight(rm, am, Format.RGB16F, Format.Depth, size, size); + IBLHybridEnvBakerLight baker = new IBLGLEnvBakerLight(rm, am, Format.RGB16F, Format.Depth, size, + size); baker.setTexturePulling(true); baker.bakeEnvironment(scene, pos, frustumNear, frustumFar, null); diff --git a/jme3-core/src/main/java/com/jme3/environment/baker/IBLGLEnvBakerLight.java b/jme3-core/src/main/java/com/jme3/environment/baker/IBLGLEnvBakerLight.java index 8daa62ef40..f6284f14ea 100644 --- a/jme3-core/src/main/java/com/jme3/environment/baker/IBLGLEnvBakerLight.java +++ b/jme3-core/src/main/java/com/jme3/environment/baker/IBLGLEnvBakerLight.java @@ -34,6 +34,7 @@ import java.nio.ByteBuffer; import java.util.logging.Logger; import com.jme3.asset.AssetManager; +import com.jme3.environment.util.EnvMapUtils; import com.jme3.material.Material; import com.jme3.math.ColorRGBA; import com.jme3.math.FastMath; @@ -130,11 +131,12 @@ public void bakeSphericalHarmonicsCoefficients() { int s = renderOnT; renderOnT = renderOnT == 0 ? 1 : 0; mat.setTexture("ShCoef", shCoefTx[s]); - mat.setInt("FaceId", faceId); } else { renderOnT = 0; } + mat.setInt("FaceId", faceId); + screen.updateLogicalState(0); screen.updateGeometricState(); @@ -169,7 +171,7 @@ else if (weightAccum != c.a) { if (remapMaxValue > 0) shCoef[i].divideLocal(remapMaxValue); shCoef[i].multLocal(4.0f * FastMath.PI / weightAccum); } - + EnvMapUtils.prepareShCoefs(shCoef); img.dispose(); } diff --git a/jme3-core/src/main/java/com/jme3/environment/baker/IBLHybridEnvBakerLight.java b/jme3-core/src/main/java/com/jme3/environment/baker/IBLHybridEnvBakerLight.java index d72e0dc30f..26b3c1cd65 100644 --- a/jme3-core/src/main/java/com/jme3/environment/baker/IBLHybridEnvBakerLight.java +++ b/jme3-core/src/main/java/com/jme3/environment/baker/IBLHybridEnvBakerLight.java @@ -200,6 +200,7 @@ public TextureCubeMap getSpecularIBL() { @Override public void bakeSphericalHarmonicsCoefficients() { shCoef = EnvMapUtils.getSphericalHarmonicsCoefficents(getEnvMap()); + EnvMapUtils.prepareShCoefs(shCoef); } @Override diff --git a/jme3-core/src/main/resources/Common/IBL/IBLKernels.frag b/jme3-core/src/main/resources/Common/IBL/IBLKernels.frag index 7f32c0ae01..e9fb4645f5 100644 --- a/jme3-core/src/main/resources/Common/IBL/IBLKernels.frag +++ b/jme3-core/src/main/resources/Common/IBL/IBLKernels.frag @@ -34,7 +34,7 @@ void brdfKernel(){ float NdotH = max(H.z, 0.0); float VdotH = max(dot(V, H), 0.0); if(NdotL > 0.0){ - float G = GeometrySmith(N, V, L, m_Roughness); + float G = GeometrySmith(N, V, L, m_Roughness*m_Roughness); float G_Vis = (G * VdotH) / (NdotH * NdotV); float Fc = pow(1.0 - VdotH, 5.0); A += (1.0 - Fc) * G_Vis; @@ -75,9 +75,7 @@ void prefilteredEnvKernel(){ vec3 R = N; vec3 V = R; - // float a2 = m_Roughness; - float a2 = m_Roughness * m_Roughness; // jme impl, why? - a2 *= a2; + float a2 = m_Roughness * m_Roughness; const uint SAMPLE_COUNT = 1024u; float totalWeight = 0.0; @@ -85,16 +83,25 @@ void prefilteredEnvKernel(){ for(uint i = 0u; i < SAMPLE_COUNT; ++i) { vec4 Xi = Hammersley(i, SAMPLE_COUNT); vec3 H = ImportanceSampleGGX(Xi, a2, N); - float VoH = dot(V,H); + float VoH = max(dot(V, H), 0.0); vec3 L = normalize(2.0 * VoH * H - V); float NdotL = max(dot(N, L), 0.0); if(NdotL > 0.0) { + vec3 sampleColor = texture(m_EnvMap, L).rgb; + + float luminance = dot(sampleColor, vec3(0.2126, 0.7152, 0.0722)); + if (luminance > 64.0) { // TODO use average? + sampleColor *= 64.0/luminance; + } + // TODO: use mipmap - prefilteredColor += texture(m_EnvMap, L).rgb * NdotL; + prefilteredColor += sampleColor * NdotL; totalWeight += NdotL; } + } - prefilteredColor = prefilteredColor / totalWeight; + + if(totalWeight > 0.001) prefilteredColor /= totalWeight; outFragColor = vec4(prefilteredColor, 1.0); }