1
1
/*
2
- * Copyright (c) 2009-2021 jMonkeyEngine
2
+ * Copyright (c) 2009-2025 jMonkeyEngine
3
3
* All rights reserved.
4
4
*
5
5
* Redistribution and use in source and binary forms, with or without
40
40
import com .jme3 .math .Vector2f ;
41
41
import com .jme3 .math .Vector3f ;
42
42
import com .jme3 .post .Filter ;
43
- import com .jme3 .post .Filter .Pass ;
44
43
import com .jme3 .renderer .RenderManager ;
45
44
import com .jme3 .renderer .Renderer ;
46
45
import com .jme3 .renderer .ViewPort ;
62
61
public class SSAOFilter extends Filter {
63
62
64
63
private Pass normalPass ;
65
- private Vector3f frustumCorner ;
66
- private Vector2f frustumNearFar ;
67
- private Vector2f [] samples = {new Vector2f (1.0f , 0.0f ), new Vector2f (-1.0f , 0.0f ), new Vector2f (0.0f , 1.0f ), new Vector2f (0.0f , -1.0f )};
64
+ private final Vector2f [] samples = {
65
+ new Vector2f (1.0f , 0.0f ),
66
+ new Vector2f (-1.0f , 0.0f ),
67
+ new Vector2f (0.0f , 1.0f ),
68
+ new Vector2f (0.0f , -1.0f )
69
+ };
68
70
private float sampleRadius = 5.1f ;
69
71
private float intensity = 1.5f ;
70
72
private float scale = 0.2f ;
71
73
private float bias = 0.1f ;
74
+ private boolean approximateNormals = false ;
72
75
private boolean useOnlyAo = false ;
73
76
private boolean useAo = true ;
74
77
private Material ssaoMat ;
75
- private Pass ssaoPass ;
76
- // private Material downSampleMat;
77
- // private Pass downSamplePass;
78
- private float downSampleFactor = 1f ;
79
78
private RenderManager renderManager ;
80
79
private ViewPort viewPort ;
81
- private boolean approximateNormals = false ;
82
80
83
81
/**
84
82
* Create a Screen Space Ambient Occlusion Filter
@@ -89,10 +87,11 @@ public SSAOFilter() {
89
87
90
88
/**
91
89
* Create a Screen Space Ambient Occlusion Filter
90
+ *
92
91
* @param sampleRadius The radius of the area where random samples will be picked. default 5.1f
93
- * @param intensity intensity of the resulting AO. default 1.2f
94
- * @param scale distance between occluders and occludee. default 0.2f
95
- * @param bias the width of the occlusion cone considered by the occludee. default 0.1f
92
+ * @param intensity intensity of the resulting AO. default 1.5f
93
+ * @param scale distance between occluders and occludee. default 0.2f
94
+ * @param bias the width of the occlusion cone considered by the occludee. default 0.1f
96
95
*/
97
96
public SSAOFilter (float sampleRadius , float intensity , float scale , float bias ) {
98
97
this ();
@@ -126,38 +125,32 @@ protected Material getMaterial() {
126
125
}
127
126
128
127
@ Override
129
- protected void initFilter (AssetManager manager , RenderManager renderManager , ViewPort vp , int w , int h ) {
128
+ protected void initFilter (AssetManager assetManager , RenderManager renderManager , ViewPort vp , int w , int h ) {
130
129
this .renderManager = renderManager ;
131
130
this .viewPort = vp ;
132
131
int screenWidth = w ;
133
132
int screenHeight = h ;
133
+ float downSampleFactor = 1f ;
134
134
postRenderPasses = new ArrayList <Pass >();
135
135
136
136
normalPass = new Pass ();
137
137
normalPass .init (renderManager .getRenderer (), (int ) (screenWidth / downSampleFactor ), (int ) (screenHeight / downSampleFactor ), Format .RGBA8 , Format .Depth );
138
138
139
-
140
- frustumNearFar = new Vector2f ();
141
-
139
+ Vector2f frustumNearFar = new Vector2f ();
142
140
float farY = (vp .getCamera ().getFrustumTop () / vp .getCamera ().getFrustumNear ()) * vp .getCamera ().getFrustumFar ();
143
141
float farX = farY * (screenWidth / (float ) screenHeight );
144
- frustumCorner = new Vector3f (farX , farY , vp .getCamera ().getFrustumFar ());
142
+ Vector3f frustumCorner = new Vector3f (farX , farY , vp .getCamera ().getFrustumFar ());
145
143
frustumNearFar .x = vp .getCamera ().getFrustumNear ();
146
144
frustumNearFar .y = vp .getCamera ().getFrustumFar ();
147
145
148
-
149
-
150
-
151
-
152
146
//ssao Pass
153
- ssaoMat = new Material (manager , "Common/MatDefs/SSAO/ssao.j3md" );
147
+ ssaoMat = new Material (assetManager , "Common/MatDefs/SSAO/ssao.j3md" );
154
148
ssaoMat .setTexture ("Normals" , normalPass .getRenderedTexture ());
155
- Texture random = manager .loadTexture ("Common/MatDefs/SSAO/Textures/random.png" );
149
+ Texture random = assetManager .loadTexture ("Common/MatDefs/SSAO/Textures/random.png" );
156
150
random .setWrap (Texture .WrapMode .Repeat );
157
151
ssaoMat .setTexture ("RandomMap" , random );
158
152
159
- ssaoPass = new Pass ("SSAO pass" ) {
160
-
153
+ Pass ssaoPass = new Pass ("SSAO pass" ) {
161
154
@ Override
162
155
public boolean requiresDepthAsTexture () {
163
156
return true ;
@@ -168,18 +161,18 @@ public boolean requiresDepthAsTexture() {
168
161
// ssaoPass.getRenderedTexture().setMinFilter(Texture.MinFilter.Trilinear);
169
162
// ssaoPass.getRenderedTexture().setMagFilter(Texture.MagFilter.Bilinear);
170
163
postRenderPasses .add (ssaoPass );
171
- material = new Material (manager , "Common/MatDefs/SSAO/ssaoBlur.j3md" );
164
+ material = new Material (assetManager , "Common/MatDefs/SSAO/ssaoBlur.j3md" );
172
165
material .setTexture ("SSAOMap" , ssaoPass .getRenderedTexture ());
166
+ material .setVector2 ("FrustumNearFar" , frustumNearFar );
167
+ material .setBoolean ("UseAo" , useAo );
168
+ material .setBoolean ("UseOnlyAo" , useOnlyAo );
173
169
174
170
ssaoMat .setVector3 ("FrustumCorner" , frustumCorner );
175
171
ssaoMat .setFloat ("SampleRadius" , sampleRadius );
176
172
ssaoMat .setFloat ("Intensity" , intensity );
177
173
ssaoMat .setFloat ("Scale" , scale );
178
174
ssaoMat .setFloat ("Bias" , bias );
179
- material .setBoolean ("UseAo" , useAo );
180
- material .setBoolean ("UseOnlyAo" , useOnlyAo );
181
175
ssaoMat .setVector2 ("FrustumNearFar" , frustumNearFar );
182
- material .setVector2 ("FrustumNearFar" , frustumNearFar );
183
176
ssaoMat .setParam ("Samples" , VarType .Vector2Array , samples );
184
177
ssaoMat .setBoolean ("ApproximateNormals" , approximateNormals );
185
178
@@ -189,7 +182,6 @@ public boolean requiresDepthAsTexture() {
189
182
float blurScale = 2f ;
190
183
material .setFloat ("XScale" , blurScale * xScale );
191
184
material .setFloat ("YScale" , blurScale * yScale );
192
-
193
185
}
194
186
195
187
@ Override
@@ -198,18 +190,20 @@ protected void cleanUpFilter(Renderer r) {
198
190
}
199
191
200
192
/**
201
- * Return the bias<br>
202
- * see {@link #setBias(float bias)}
203
- * @return bias
193
+ * Returns the bias value used in the SSAO calculation.
194
+ *
195
+ * @return The bias value.
196
+ * @see #setBias(float)
204
197
*/
205
198
public float getBias () {
206
199
return bias ;
207
200
}
208
201
209
202
/**
210
- * Sets the width of the occlusion cone considered by the occludee default is 0.1f
203
+ * Sets the width of the occlusion cone considered by the occludee.
204
+ * A higher bias means a wider cone, resulting in less self-occlusion.
211
205
*
212
- * @param bias the desired width (default=0.1)
206
+ * @param bias The desired bias value (default: 0.1f).
213
207
*/
214
208
public void setBias (float bias ) {
215
209
this .bias = bias ;
@@ -219,62 +213,65 @@ public void setBias(float bias) {
219
213
}
220
214
221
215
/**
222
- * returns the ambient occlusion intensity
223
- * @return intensity
216
+ * Returns the ambient occlusion intensity.
217
+ *
218
+ * @return The intensity value.
224
219
*/
225
220
public float getIntensity () {
226
221
return intensity ;
227
222
}
228
223
229
224
/**
230
- * Sets the Ambient occlusion intensity default is 1.5
225
+ * Sets the ambient occlusion intensity. A higher intensity makes the ambient
226
+ * occlusion effect more pronounced.
231
227
*
232
- * @param intensity the desired intensity (default=1.5)
228
+ * @param intensity The desired intensity (default: 1.5f).
233
229
*/
234
230
public void setIntensity (float intensity ) {
235
231
this .intensity = intensity ;
236
232
if (ssaoMat != null ) {
237
233
ssaoMat .setFloat ("Intensity" , intensity );
238
234
}
239
-
240
235
}
241
236
242
237
/**
243
- * returns the sample radius<br>
244
- * see {link setSampleRadius(float sampleRadius)}
245
- * @return the sample radius
238
+ * Returns the sample radius used in the SSAO calculation.
239
+ *
240
+ * @return The sample radius.
241
+ * @see #setSampleRadius(float)
246
242
*/
247
243
public float getSampleRadius () {
248
244
return sampleRadius ;
249
245
}
250
246
251
247
/**
252
- * Sets the radius of the area where random samples will be picked default 5.1f
248
+ * Sets the radius of the area where random samples will be picked for SSAO.
249
+ * A larger radius considers more distant occluders.
253
250
*
254
- * @param sampleRadius the desired radius (default=5.1)
251
+ * @param sampleRadius The desired radius (default: 5.1f).
255
252
*/
256
253
public void setSampleRadius (float sampleRadius ) {
257
254
this .sampleRadius = sampleRadius ;
258
255
if (ssaoMat != null ) {
259
256
ssaoMat .setFloat ("SampleRadius" , sampleRadius );
260
257
}
261
-
262
258
}
263
259
264
260
/**
265
- * returns the scale<br>
266
- * see {@link #setScale(float scale)}
267
- * @return scale
261
+ * Returns the scale value used in the SSAO calculation.
262
+ *
263
+ * @return The scale value.
264
+ * @see #setScale(float)
268
265
*/
269
266
public float getScale () {
270
267
return scale ;
271
268
}
272
269
273
270
/**
274
- *
275
- * Returns the distance between occluders and occludee. default 0.2f
271
+ * Sets the distance between occluders and occludee for SSAO.
272
+ * This essentially controls the "thickness" of the ambient occlusion.
276
273
*
277
- * @param scale the desired distance (default=0.2)
274
+ * @param scale The desired distance (default: 0.2f).
278
275
*/
279
276
public void setScale (float scale ) {
280
277
this .scale = scale ;
@@ -284,15 +281,38 @@ public void setScale(float scale) {
284
281
}
285
282
286
283
/**
287
- * debugging only , will be removed
284
+ * Sets whether to use approximate normals for the SSAO calculation.
285
+ * If `true`, normals are derived from the depth buffer. If `false`, a separate
286
+ * normal pass is rendered.
287
+ *
288
+ * @param approximateNormals `true` to use approximate normals, `false` to use a normal pass.
289
+ */
290
+ public void setApproximateNormals (boolean approximateNormals ) {
291
+ this .approximateNormals = approximateNormals ;
292
+ if (ssaoMat != null ) {
293
+ ssaoMat .setBoolean ("ApproximateNormals" , approximateNormals );
294
+ }
295
+ }
296
+
297
+ /**
298
+ * Checks if approximate normals are being used for SSAO calculation.
299
+ *
300
+ * @return `true` if approximate normals are used, `false` otherwise.
301
+ */
302
+ public boolean isApproximateNormals () {
303
+ return approximateNormals ;
304
+ }
305
+
306
+ /**
307
+ * debugging only, will be removed
288
308
* @return true if using ambient occlusion
289
309
*/
290
310
public boolean isUseAo () {
291
311
return useAo ;
292
312
}
293
313
294
314
/**
295
- * debugging only , will be removed
315
+ * debugging only, will be removed
296
316
*
297
317
* @param useAo true to enable, false to disable (default=true)
298
318
*/
@@ -301,30 +321,18 @@ public void setUseAo(boolean useAo) {
301
321
if (material != null ) {
302
322
material .setBoolean ("UseAo" , useAo );
303
323
}
304
-
305
- }
306
-
307
- public void setApproximateNormals (boolean approximateNormals ) {
308
- this .approximateNormals = approximateNormals ;
309
- if (ssaoMat != null ) {
310
- ssaoMat .setBoolean ("ApproximateNormals" , approximateNormals );
311
- }
312
- }
313
-
314
- public boolean isApproximateNormals () {
315
- return approximateNormals ;
316
324
}
317
325
318
326
/**
319
- * debugging only , will be removed
327
+ * debugging only, will be removed
320
328
* @return useOnlyAo
321
329
*/
322
330
public boolean isUseOnlyAo () {
323
331
return useOnlyAo ;
324
332
}
325
333
326
334
/**
327
- * debugging only , will be removed
335
+ * debugging only, will be removed
328
336
*
329
337
* @param useOnlyAo true to enable, false to disable (default=false)
330
338
*/
@@ -343,6 +351,7 @@ public void write(JmeExporter ex) throws IOException {
343
351
oc .write (intensity , "intensity" , 1.5f );
344
352
oc .write (scale , "scale" , 0.2f );
345
353
oc .write (bias , "bias" , 0.1f );
354
+ oc .write (approximateNormals , "approximateNormals" , false );
346
355
}
347
356
348
357
@ Override
@@ -353,5 +362,6 @@ public void read(JmeImporter im) throws IOException {
353
362
intensity = ic .readFloat ("intensity" , 1.5f );
354
363
scale = ic .readFloat ("scale" , 0.2f );
355
364
bias = ic .readFloat ("bias" , 0.1f );
365
+ approximateNormals = ic .readBoolean ("approximateNormals" , false );
356
366
}
357
367
}
0 commit comments