Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ apply from: file('version.gradle')

allprojects {
repositories {
mavenLocal()
mavenCentral()
google()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Caps;
import com.jme3.renderer.RenderManager;
Expand Down Expand Up @@ -98,7 +97,6 @@ public void bakeSphericalHarmonicsCoefficients() {

Material mat = new Material(assetManager, "Common/IBLSphH/IBLSphH.j3md");
mat.setTexture("Texture", envMap);
mat.setVector2("Resolution", new Vector2f(envMap.getImage().getWidth(), envMap.getImage().getHeight()));
screen.setMaterial(mat);

float remapMaxValue = 0;
Expand All @@ -117,38 +115,21 @@ public void bakeSphericalHarmonicsCoefficients() {
mat.clearParam("RemapMaxValue");
}

Texture2D shCoefTx[] = { new Texture2D(NUM_SH_COEFFICIENT, 1, 1, format), new Texture2D(NUM_SH_COEFFICIENT, 1, 1, format) };
Texture2D shCoefTx = new Texture2D(NUM_SH_COEFFICIENT, 1, 1, format);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The shCoefTx texture is created here but is never disposed. Since this baking process can be triggered multiple times, this will lead to a leak of GPU resources. You should call shCoefTx.getImage().dispose() at the end of the method.


FrameBuffer shbaker[] = { new FrameBuffer(NUM_SH_COEFFICIENT, 1, 1), new FrameBuffer(NUM_SH_COEFFICIENT, 1, 1) };
shbaker[0].setSrgb(false);
shbaker[0].addColorTarget(FrameBufferTarget.newTarget(shCoefTx[0]));
FrameBuffer shbaker = new FrameBuffer(NUM_SH_COEFFICIENT, 1, 1);
shbaker.setSrgb(false);
shbaker.addColorTarget(FrameBufferTarget.newTarget(shCoefTx));

shbaker[1].setSrgb(false);
shbaker[1].addColorTarget(FrameBufferTarget.newTarget(shCoefTx[1]));
screen.updateLogicalState(0);
screen.updateGeometricState();

int renderOnT = -1;
renderManager.setCamera(updateAndGetInternalCamera(0, shbaker.getWidth(), shbaker.getHeight(), Vector3f.ZERO, 1, 1000), false);
renderManager.getRenderer().setFrameBuffer(shbaker);
renderManager.renderGeometry(screen);

for (int faceId = 0; faceId < 6; faceId++) {
if (renderOnT != -1) {
int s = renderOnT;
renderOnT = renderOnT == 0 ? 1 : 0;
mat.setTexture("ShCoef", shCoefTx[s]);
} else {
renderOnT = 0;
}

mat.setInt("FaceId", faceId);

screen.updateLogicalState(0);
screen.updateGeometricState();

renderManager.setCamera(updateAndGetInternalCamera(0, shbaker[renderOnT].getWidth(), shbaker[renderOnT].getHeight(), Vector3f.ZERO, 1, 1000), false);
renderManager.getRenderer().setFrameBuffer(shbaker[renderOnT]);
renderManager.renderGeometry(screen);
}

ByteBuffer shCoefRaw = BufferUtils.createByteBuffer(NUM_SH_COEFFICIENT * 1 * (shbaker[renderOnT].getColorTarget().getFormat().getBitsPerPixel() / 8));
renderManager.getRenderer().readFrameBufferWithFormat(shbaker[renderOnT], shCoefRaw, shbaker[renderOnT].getColorTarget().getFormat());
ByteBuffer shCoefRaw = BufferUtils.createByteBuffer(NUM_SH_COEFFICIENT * 1 * (shbaker.getColorTarget().getFormat().getBitsPerPixel() / 8));
renderManager.getRenderer().readFrameBufferWithFormat(shbaker, shCoefRaw, shbaker.getColorTarget().getFormat());
shCoefRaw.rewind();

Image img = new Image(format, NUM_SH_COEFFICIENT, 1, shCoefRaw, ColorSpace.Linear);
Expand All @@ -164,7 +145,6 @@ public void bakeSphericalHarmonicsCoefficients() {
else if (weightAccum != c.a) {
LOG.warning("SH weight is not uniform, this may cause issues.");
}

}

if (remapMaxValue > 0) weightAccum /= remapMaxValue;
Expand All @@ -176,6 +156,7 @@ else if (weightAccum != c.a) {
}
EnvMapUtils.prepareShCoefs(shCoef);
img.dispose();
shbaker.dispose();

}
}
5 changes: 5 additions & 0 deletions jme3-core/src/main/java/com/jme3/renderer/Caps.java
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,11 @@ public enum Caps {
*/
DepthTexture,

/**
* Supports hardware depth texture comparison for shadow maps.
*/
TextureShadowCompare,

/**
* Supports 32-bit index buffers.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,10 @@ private void loadCapabilitiesCommon() {
caps.add(Caps.DepthTexture);
}

if (gl2 != null || caps.contains(Caps.OpenGLES30)) {
caps.add(Caps.TextureShadowCompare);
}

if (caps.contains(Caps.OpenGL20) || caps.contains(Caps.OpenGLES30) || caps.contains(Caps.WebGL)
|| hasExtension("GL_OES_depth24")) {
caps.add(Caps.Depth24);
Expand Down Expand Up @@ -2673,7 +2677,7 @@ && isMipmapGenerationSupported(image.getFormat(),
}

ShadowCompareMode texCompareMode = tex.getShadowCompareMode();
if ( (gl2 != null || caps.contains(Caps.OpenGLES30)) && curState.shadowCompareMode != texCompareMode) {
if (caps.contains(Caps.TextureShadowCompare) && curState.shadowCompareMode != texCompareMode) {
bindTextureAndUnit(target, image, unit);
if (texCompareMode != ShadowCompareMode.Off) {
gl.glTexParameteri(target, GL2.GL_TEXTURE_COMPARE_MODE, GL2.GL_COMPARE_REF_TO_TEXTURE);
Expand Down
13 changes: 10 additions & 3 deletions jme3-core/src/main/java/com/jme3/util/MaterialDebugAppState.java
Original file line number Diff line number Diff line change
Expand Up @@ -377,16 +377,23 @@ public void init() {
file = new File(url.getFile());
fileLastM = file.lastModified();

} catch (NoSuchFieldException
| SecurityException
} catch (NoSuchFieldException ex) {
Logger.getLogger(MaterialDebugAppState.class.getName()).log(Level.FINE,
"Material hot reload disabled for {0}; asset URL is not reflectively available.",
fileName);
} catch (SecurityException
| IllegalArgumentException
| IllegalAccessException ex) {
Logger.getLogger(MaterialDebugAppState.class.getName()).log(Level.SEVERE, null, ex);
Logger.getLogger(MaterialDebugAppState.class.getName()).log(Level.FINE,
"Material hot reload disabled for " + fileName, ex);
}
}
}

public boolean shouldFire() {
if (file == null || fileLastM == null) {
return false;
}
if (file.lastModified() != fileLastM) {
fileLastM = file.lastModified();
return true;
Expand Down
140 changes: 17 additions & 123 deletions jme3-core/src/main/resources/Common/IBLSphH/IBLSphH.frag
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@ in vec3 LocalPos;


uniform samplerCube m_Texture;
#ifdef SH_COEF
uniform sampler2D m_ShCoef;
#endif
uniform vec2 m_Resolution;
uniform int m_FaceId;

const float sqrtPi = sqrt(PI);
const float sqrt3Pi = sqrt(3. / PI);
Expand All @@ -30,80 +25,6 @@ const float sqrt15Pi = sqrt(15. / PI);
uniform float m_RemapMaxValue;
#endif


vec3 getVectorFromCubemapFaceTexCoord(float x, float y, float mapSize, int face) {
float u;
float v;

/* transform from [0..res - 1] to [- (1 - 1 / res) .. (1 - 1 / res)]
* (+ 0.5f is for texel center addressing) */
u = (2.0 * (x + 0.5) / mapSize) - 1.0;
v = (2.0 * (y + 0.5) / mapSize) - 1.0;


// Warp texel centers in the proximity of the edges.
float warpDenom = max(mapSize - 1.0, 1.0);
float a = (mapSize * mapSize) / (warpDenom * warpDenom * warpDenom);

u = a * u * u * u + u;
v = a * v * v * v + v;
//compute vector depending on the face
// Code from Nvtt : https://github.com/castano/nvidia-texture-tools/blob/master/src/nvtt/CubeSurface.cpp#L101
vec3 o =vec3(0);
switch(face) {
case 0:
o= normalize(vec3(1., -v, -u));
break;
case 1:
o= normalize(vec3(-1., -v, u));
break;
case 2:
o= normalize(vec3(u, 1., v));
break;
case 3:
o= normalize(vec3(u, -1., -v));
break;
case 4:
o= normalize(vec3(u, -v, 1.));
break;
case 5:
o= normalize(vec3(-u, -v, -1.));
break;
}

return o;
}

float atan2(in float y, in float x) {
bool s = (abs(x) > abs(y));
return mix(PI / 2.0 - atan(x, y), atan(y, x), s);
}

float areaElement(float x, float y) {
return atan2(x * y, sqrt(x * x + y * y + 1.));
}

float getSolidAngleAndVector(float x, float y, float mapSize, int face, out vec3 store) {
/* transform from [0..res - 1] to [- (1 - 1 / res) .. (1 - 1 / res)]
(+ 0.5f is for texel center addressing) */
float u = (2.0 * (x + 0.5) / mapSize) - 1.0;
float v = (2.0 * (y + 0.5) / mapSize) - 1.0;

store = getVectorFromCubemapFaceTexCoord(x, y, mapSize, face);

/* Solid angle weight approximation :
* U and V are the -1..1 texture coordinate on the current face.
* Get projected area for this texel */
float x0, y0, x1, y1;
float invRes = 1.0 / mapSize;
x0 = u - invRes;
y0 = v - invRes;
x1 = u + invRes;
y1 = v + invRes;

return areaElement(x0, y0) - areaElement(x0, y1) - areaElement(x1, y0) + areaElement(x1, y1);
}

void evalShBasis(vec3 texelVect, int i, out float shDir) {
float xV = texelVect.x;
float yV = texelVect.y;
Expand All @@ -124,56 +45,29 @@ void evalShBasis(vec3 texelVect, int i, out float shDir) {
else shDir = sqrt15Pi * (x2 - y2) / 4.;
}

vec3 pixelFaceToV(int faceId, float pixelX, float pixelY, float cubeMapSize) {
vec2 normalizedCoords = vec2((2.0 * pixelX + 1.0) / cubeMapSize, (2.0 * pixelY + 1.0) / cubeMapSize);

vec3 direction;
if(faceId == 0) {
direction = vec3(1.0, -normalizedCoords.y, -normalizedCoords.x);
} else if(faceId == 1) {
direction = vec3(-1.0, -normalizedCoords.y, normalizedCoords.x);
} else if(faceId == 2) {
direction = vec3(normalizedCoords.x, 1.0, normalizedCoords.y);
} else if(faceId == 3) {
direction = vec3(normalizedCoords.x, -1.0, -normalizedCoords.y);
} else if(faceId == 4) {
direction = vec3(normalizedCoords.x, -normalizedCoords.y, 1.0);
} else if(faceId == 5) {
direction = vec3(-normalizedCoords.x, -normalizedCoords.y, -1.0);
}

return normalize(direction);
}

void sphKernel() {
int width = int(m_Resolution.x);
int height = int(m_Resolution.y);
vec3 texelVect=vec3(0);
float shDir=0.;
float weight=0.;
vec4 color=vec4(0);

int i=int(gl_FragCoord.x);

#ifdef SH_COEF
vec4 r=texelFetch(m_ShCoef, ivec2(i, 0), 0);
vec3 shCoef=r.rgb;
float weightAccum = r.a;
#else
vec3 shCoef=vec3(0.0);
float weightAccum = 0.0;
#endif

for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
weight = getSolidAngleAndVector(float(x), float(y), float(width), m_FaceId, texelVect);
evalShBasis(texelVect, i, shDir);
color = texture(m_Texture, texelVect);
shCoef.x = (shCoef.x + color.r * shDir * weight);
shCoef.y = (shCoef.y + color.g * shDir * weight);
shCoef.z = (shCoef.z + color.b * shDir * weight);
weightAccum += weight;
}
vec3 shCoef=vec3(0.0);
float weightAccum = 0.0;

const uint SAMPLE_COUNT = 4096u;
for(uint sampleIndex = 0u; sampleIndex < SAMPLE_COUNT; sampleIndex++) {
vec4 xi = Hammersley(sampleIndex, SAMPLE_COUNT);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The function Hammersley is used here but it is neither defined in this shader nor imported via #import. This will cause a shader compilation error. Furthermore, the standard Hammersley implementation in jMonkeyEngine's shader library returns a vec2, which would cause a type mismatch error when assigned to a vec4.

float z = 1.0 - 2.0 * xi.x;
float r = sqrt(max(0.0, 1.0 - z * z));
float phi = 2.0 * PI * xi.y;
texelVect = vec3(r * cos(phi), z, r * sin(phi));
evalShBasis(texelVect, i, shDir);
color = texture(m_Texture, texelVect);
shCoef.x = (shCoef.x + color.r * shDir);
shCoef.y = (shCoef.y + color.g * shDir);
shCoef.z = (shCoef.z + color.b * shDir);
weightAccum += 1.0;
}


Expand All @@ -189,4 +83,4 @@ void sphKernel() {

void main() {
sphKernel();
}
}
6 changes: 1 addition & 5 deletions jme3-core/src/main/resources/Common/IBLSphH/IBLSphH.j3md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ MaterialDef IBLSphH {
MaterialParameters {
Int BoundDrawBuffer
TextureCubeMap Texture -LINEAR
Int FaceId : 0
Texture2D ShCoef -LINEAR
Vector2 Resolution
Float RemapMaxValue
}

Expand All @@ -27,8 +24,7 @@ MaterialDef IBLSphH {
Defines {
BOUND_DRAW_BUFFER: BoundDrawBuffer
REMAP_MAX_VALUE: RemapMaxValue
SH_COEF: ShCoef
}

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ public void simpleInitApp() {

updateMaterial();


}


Expand Down Expand Up @@ -135,4 +134,5 @@ private void updateMaterial() {
System.out.println(
"Tank material -> metallic: " + metallic + ", roughness: " + roughness + " (N/P)");
}

}
Loading
Loading