use of com.jme3.post.Filter.Pass in project jmonkeyengine by jMonkeyEngine.
the class Material method render.
/**
* Called by {@link RenderManager} to render the geometry by
* using this material.
* <p>
* The material is rendered as follows:
* <ul>
* <li>Determine which technique to use to render the material -
* either what the user selected via
* {@link #selectTechnique(java.lang.String, com.jme3.renderer.RenderManager)
* Material.selectTechnique()},
* or the first default technique that the renderer supports
* (based on the technique's {@link TechniqueDef#getRequiredCaps() requested rendering capabilities})<ul>
* <li>If the technique has been changed since the last frame, then it is notified via
* {@link Technique#makeCurrent(com.jme3.asset.AssetManager, boolean, java.util.EnumSet)
* Technique.makeCurrent()}.
* If the technique wants to use a shader to render the model, it should load it at this part -
* the shader should have all the proper defines as declared in the technique definition,
* including those that are bound to material parameters.
* The technique can re-use the shader from the last frame if
* no changes to the defines occurred.</li></ul>
* <li>Set the {@link RenderState} to use for rendering. The render states are
* applied in this order (later RenderStates override earlier RenderStates):<ol>
* <li>{@link TechniqueDef#getRenderState() Technique Definition's RenderState}
* - i.e. specific renderstate that is required for the shader.</li>
* <li>{@link #getAdditionalRenderState() Material Instance Additional RenderState}
* - i.e. ad-hoc renderstate set per model</li>
* <li>{@link RenderManager#getForcedRenderState() RenderManager's Forced RenderState}
* - i.e. renderstate requested by a {@link com.jme3.post.SceneProcessor} or
* post-processing filter.</li></ol>
* <li>If the technique {@link TechniqueDef#isUsingShaders() uses a shader}, then the uniforms of the shader must be updated.<ul>
* <li>Uniforms bound to material parameters are updated based on the current material parameter values.</li>
* <li>Uniforms bound to world parameters are updated from the RenderManager.
* Internally {@link UniformBindingManager} is used for this task.</li>
* <li>Uniforms bound to textures will cause the texture to be uploaded as necessary.
* The uniform is set to the texture unit where the texture is bound.</li></ul>
* <li>If the technique uses a shader, the model is then rendered according
* to the lighting mode specified on the technique definition.<ul>
* <li>{@link LightMode#SinglePass single pass light mode} fills the shader's light uniform arrays
* with the first 4 lights and renders the model once.</li>
* <li>{@link LightMode#MultiPass multi pass light mode} light mode renders the model multiple times,
* for the first light it is rendered opaque, on subsequent lights it is
* rendered with {@link BlendMode#AlphaAdditive alpha-additive} blending and depth writing disabled.</li>
* </ul>
* <li>For techniques that do not use shaders,
* fixed function OpenGL is used to render the model (see {@link GL1Renderer} interface):<ul>
* <li>OpenGL state ({@link FixedFuncBinding}) that is bound to material parameters is updated. </li>
* <li>The texture set on the material is uploaded and bound.
* Currently only 1 texture is supported for fixed function techniques.</li>
* <li>If the technique uses lighting, then OpenGL lighting state is updated
* based on the light list on the geometry, otherwise OpenGL lighting is disabled.</li>
* <li>The mesh is uploaded and rendered.</li>
* </ul>
* </ul>
*
* @param geometry The geometry to render
* @param lights Presorted and filtered light list to use for rendering
* @param renderManager The render manager requesting the rendering
*/
public void render(Geometry geometry, LightList lights, RenderManager renderManager) {
if (technique == null) {
selectTechnique(TechniqueDef.DEFAULT_TECHNIQUE_NAME, renderManager);
}
TechniqueDef techniqueDef = technique.getDef();
Renderer renderer = renderManager.getRenderer();
EnumSet<Caps> rendererCaps = renderer.getCaps();
if (techniqueDef.isNoRender()) {
return;
}
// Apply render state
updateRenderState(renderManager, renderer, techniqueDef);
// Get world overrides
SafeArrayList<MatParamOverride> overrides = geometry.getWorldMatParamOverrides();
// Select shader to use
Shader shader = technique.makeCurrent(renderManager, overrides, renderManager.getForcedMatParams(), lights, rendererCaps);
// Begin tracking which uniforms were changed by material.
clearUniformsSetByCurrent(shader);
// Set uniform bindings
renderManager.updateUniformBindings(shader);
// Set material parameters
int unit = updateShaderMaterialParameters(renderer, shader, overrides, renderManager.getForcedMatParams());
// Clear any uniforms not changed by material.
resetUniformsNotSetByCurrent(shader);
// Delegate rendering to the technique
technique.render(renderManager, shader, geometry, lights, unit);
}
use of com.jme3.post.Filter.Pass in project jmonkeyengine by jMonkeyEngine.
the class VertexBuffer method clone.
/**
* Creates a deep clone of this VertexBuffer but overrides the
* {@link Type}.
*
* @param overrideType The type of the cloned VertexBuffer
* @return A deep clone of the buffer
*/
public VertexBuffer clone(Type overrideType) {
VertexBuffer vb = new VertexBuffer(overrideType);
vb.components = components;
vb.componentsLength = componentsLength;
// Make sure to pass a read-only buffer to clone so that
// the position information doesn't get clobbered by another
// reading thread during cloning (and vice versa) since this is
// a purely read-only operation.
vb.data = BufferUtils.clone(getDataReadOnly());
vb.format = format;
vb.handleRef = new Object();
vb.id = -1;
vb.normalized = normalized;
vb.instanceSpan = instanceSpan;
vb.offset = offset;
vb.stride = stride;
vb.updateNeeded = true;
vb.usage = usage;
return vb;
}
use of com.jme3.post.Filter.Pass in project jmonkeyengine by jMonkeyEngine.
the class J3MLoader method loadFromRoot.
private void loadFromRoot(List<Statement> roots) throws IOException {
if (roots.size() == 2) {
Statement exception = roots.get(0);
String line = exception.getLine();
if (line.startsWith("Exception")) {
throw new AssetLoadException(line.substring("Exception ".length()));
} else {
throw new IOException("In multiroot material, expected first statement to be 'Exception'");
}
} else if (roots.size() != 1) {
throw new IOException("Too many roots in J3M/J3MD file");
}
boolean extending = false;
Statement materialStat = roots.get(0);
String materialName = materialStat.getLine();
if (materialName.startsWith("MaterialDef")) {
materialName = materialName.substring("MaterialDef ".length()).trim();
extending = false;
} else if (materialName.startsWith("Material")) {
materialName = materialName.substring("Material ".length()).trim();
extending = true;
} else {
throw new IOException("Specified file is not a Material file");
}
String[] split = materialName.split(":", 2);
if (materialName.equals("")) {
throw new MatParseException("Material name cannot be empty", materialStat);
}
if (split.length == 2) {
if (!extending) {
throw new MatParseException("Must use 'Material' when extending.", materialStat);
}
String extendedMat = split[1].trim();
MaterialDef def = (MaterialDef) assetManager.loadAsset(new AssetKey(extendedMat));
if (def == null) {
throw new MatParseException("Extended material " + extendedMat + " cannot be found.", materialStat);
}
material = new Material(def);
material.setKey(key);
material.setName(split[0].trim());
// material.setAssetName(fileName);
} else if (split.length == 1) {
if (extending) {
throw new MatParseException("Expected ':', got '{'", materialStat);
}
materialDef = new MaterialDef(assetManager, materialName);
// NOTE: pass file name for defs so they can be loaded later
materialDef.setAssetName(key.getName());
} else {
throw new MatParseException("Cannot use colon in material name/path", materialStat);
}
for (Statement statement : materialStat.getContents()) {
split = statement.getLine().split("[ \\{]");
String statType = split[0];
if (extending) {
if (statType.equals("MaterialParameters")) {
readExtendingMaterialParams(statement.getContents());
} else if (statType.equals("AdditionalRenderState")) {
readAdditionalRenderState(statement.getContents());
} else if (statType.equals("Transparent")) {
readTransparentStatement(statement.getLine());
}
} else {
if (statType.equals("Technique")) {
readTechnique(statement);
} else if (statType.equals("MaterialParameters")) {
readMaterialParams(statement.getContents());
} else {
throw new MatParseException("Expected material statement, got '" + statType + "'", statement);
}
}
}
}
use of com.jme3.post.Filter.Pass in project jmonkeyengine by jMonkeyEngine.
the class SSAOFilter method initFilter.
@Override
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
this.renderManager = renderManager;
this.viewPort = vp;
int screenWidth = w;
int screenHeight = h;
postRenderPasses = new ArrayList<Pass>();
normalPass = new Pass();
normalPass.init(renderManager.getRenderer(), (int) (screenWidth / downSampleFactor), (int) (screenHeight / downSampleFactor), Format.RGBA8, Format.Depth);
frustumNearFar = new Vector2f();
float farY = (vp.getCamera().getFrustumTop() / vp.getCamera().getFrustumNear()) * vp.getCamera().getFrustumFar();
float farX = farY * ((float) screenWidth / (float) screenHeight);
frustumCorner = new Vector3f(farX, farY, vp.getCamera().getFrustumFar());
frustumNearFar.x = vp.getCamera().getFrustumNear();
frustumNearFar.y = vp.getCamera().getFrustumFar();
//ssao Pass
ssaoMat = new Material(manager, "Common/MatDefs/SSAO/ssao.j3md");
ssaoMat.setTexture("Normals", normalPass.getRenderedTexture());
Texture random = manager.loadTexture("Common/MatDefs/SSAO/Textures/random.png");
random.setWrap(Texture.WrapMode.Repeat);
ssaoMat.setTexture("RandomMap", random);
ssaoPass = new Pass("SSAO pass") {
@Override
public boolean requiresDepthAsTexture() {
return true;
}
};
ssaoPass.init(renderManager.getRenderer(), (int) (screenWidth / downSampleFactor), (int) (screenHeight / downSampleFactor), Format.RGBA8, Format.Depth, 1, ssaoMat);
// ssaoPass.getRenderedTexture().setMinFilter(Texture.MinFilter.Trilinear);
// ssaoPass.getRenderedTexture().setMagFilter(Texture.MagFilter.Bilinear);
postRenderPasses.add(ssaoPass);
material = new Material(manager, "Common/MatDefs/SSAO/ssaoBlur.j3md");
material.setTexture("SSAOMap", ssaoPass.getRenderedTexture());
ssaoMat.setVector3("FrustumCorner", frustumCorner);
ssaoMat.setFloat("SampleRadius", sampleRadius);
ssaoMat.setFloat("Intensity", intensity);
ssaoMat.setFloat("Scale", scale);
ssaoMat.setFloat("Bias", bias);
material.setBoolean("UseAo", useAo);
material.setBoolean("UseOnlyAo", useOnlyAo);
ssaoMat.setVector2("FrustumNearFar", frustumNearFar);
material.setVector2("FrustumNearFar", frustumNearFar);
ssaoMat.setParam("Samples", VarType.Vector2Array, samples);
ssaoMat.setBoolean("ApproximateNormals", approximateNormals);
float xScale = 1.0f / w;
float yScale = 1.0f / h;
float blurScale = 2f;
material.setFloat("XScale", blurScale * xScale);
material.setFloat("YScale", blurScale * yScale);
}
use of com.jme3.post.Filter.Pass in project jmonkeyengine by jMonkeyEngine.
the class BloomFilter method initFilter.
@Override
protected void initFilter(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
this.renderManager = renderManager;
this.viewPort = vp;
this.assetManager = manager;
this.initalWidth = w;
this.initalHeight = h;
screenWidth = (int) Math.max(1, (w / downSamplingFactor));
screenHeight = (int) Math.max(1, (h / downSamplingFactor));
// System.out.println(screenWidth + " " + screenHeight);
if (glowMode != GlowMode.Scene) {
preGlowPass = new Pass();
preGlowPass.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth);
}
postRenderPasses = new ArrayList<Pass>();
//configuring extractPass
extractMat = new Material(manager, "Common/MatDefs/Post/BloomExtract.j3md");
extractPass = new Pass() {
@Override
public boolean requiresSceneAsTexture() {
return true;
}
@Override
public void beforeRender() {
extractMat.setFloat("ExposurePow", exposurePower);
extractMat.setFloat("ExposureCutoff", exposureCutOff);
if (glowMode != GlowMode.Scene) {
extractMat.setTexture("GlowMap", preGlowPass.getRenderedTexture());
}
extractMat.setBoolean("Extract", glowMode != GlowMode.Objects);
}
};
extractPass.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth, 1, extractMat);
postRenderPasses.add(extractPass);
//configuring horizontal blur pass
hBlurMat = new Material(manager, "Common/MatDefs/Blur/HGaussianBlur.j3md");
horizontalBlur = new Pass() {
@Override
public void beforeRender() {
hBlurMat.setTexture("Texture", extractPass.getRenderedTexture());
hBlurMat.setFloat("Size", screenWidth);
hBlurMat.setFloat("Scale", blurScale);
}
};
horizontalBlur.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth, 1, hBlurMat);
postRenderPasses.add(horizontalBlur);
//configuring vertical blur pass
vBlurMat = new Material(manager, "Common/MatDefs/Blur/VGaussianBlur.j3md");
verticalalBlur = new Pass() {
@Override
public void beforeRender() {
vBlurMat.setTexture("Texture", horizontalBlur.getRenderedTexture());
vBlurMat.setFloat("Size", screenHeight);
vBlurMat.setFloat("Scale", blurScale);
}
};
verticalalBlur.init(renderManager.getRenderer(), screenWidth, screenHeight, Format.RGBA8, Format.Depth, 1, vBlurMat);
postRenderPasses.add(verticalalBlur);
//final material
material = new Material(manager, "Common/MatDefs/Post/BloomFinal.j3md");
material.setTexture("BloomTex", verticalalBlur.getRenderedTexture());
}
Aggregations