More then one detailtexture on terrain

hello



It's any way to add more then one detailtexture on a terrainpage?

I look in the source of terrainpage and not find the code that apply the first detailtexture  :roll:






it's not done in the terrainpage code but in your class using the terrainpage

have a look in TestTerrainPage.java to see how it's done.



snip:


    Texture t2 = TextureManager.loadTexture(TestTerrain.class.getClassLoader().
                                            getResource(
        "jmetest/data/texture/Detail.jpg"),
                                            Texture.MM_LINEAR_LINEAR,
                                            Texture.FM_LINEAR);
    ts.setTexture(t2, 1);
    t2.setWrap(Texture.WM_WRAP_S_WRAP_T);

    t2.setApply(Texture.AM_COMBINE);
    t2.setCombineFuncRGB(Texture.ACF_ADD_SIGNED);
    t2.setCombineSrc0RGB(Texture.ACS_TEXTURE);
    t2.setCombineOp0RGB(Texture.ACO_SRC_COLOR);
    t2.setCombineSrc1RGB(Texture.ACS_PREVIOUS);
    t2.setCombineOp1RGB(Texture.ACO_SRC_COLOR);
    t2.setCombineScaleRGB(1.0f);

...

page = new TerrainPage("Terrain", 33, heightMap.getSize(), terrainScale,
                                     heightMap.getHeightMap(), false);

    page.setDetailTexture(1, 16);
 
...

    ts.setTexture(t2, 1);

...



set the detailtexture to texture unit 1 on terrainpage.
It's any way to set a second one for detail with blend?

duplicating that code and changing t2 to t3 and 1 to 2 in setDetailTexture and setTexture should work (not tested)

You may have to play with the combine settings to make it work the way you expect.

yes! it's works, THX


/*
 * Copyright (c) 2003-2006 jMonkeyEngine
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package jmetest.terrain;

import javax.swing.ImageIcon;

import com.jme.app.SimpleGame;
import com.jme.image.Texture;
import com.jme.input.NodeHandler;
import com.jme.light.DirectionalLight;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.CameraNode;
import com.jme.scene.state.CullState;
import com.jme.scene.state.TextureState;
import com.jme.util.TextureManager;
import com.jmex.terrain.TerrainPage;
import com.jmex.terrain.util.FaultFractalHeightMap;
import com.jmex.terrain.util.ProceduralTextureGenerator;

/**
 * <code>TestTerrainPageMultiDetail </code>
 *
 * @author Lutz Guettler
 *
 */
public class TestTerrainPageMultiDetail extends SimpleGame {

  private CameraNode camNode;
private TerrainPage page;

  /**
   * Entry point for the test,
   *
   * @param args
   */
  public static void main(String[] args) {
      TestTerrainPageMultiDetail app = new TestTerrainPageMultiDetail();
    app.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG);
    app.start();
  }

  /**
   * builds the trimesh.
   *
   * @see com.jme.app.SimpleGame#initGame()
   */
  protected void simpleInitGame() {
      rootNode.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
      fpsNode.setRenderQueueMode(Renderer.QUEUE_ORTHO);

    DirectionalLight dl = new DirectionalLight();
    dl.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
    dl.setDirection(new Vector3f(1, -0.5f, 1));
    dl.setEnabled(true);
    lightState.attach(dl);

    cam.setFrustum(1.0f, 5000.0f, -0.55f, 0.55f, 0.4125f, -0.4125f);
    cam.update();

    camNode = new CameraNode("Camera Node", cam);
    camNode.setLocalTranslation(new Vector3f(0, 250, -20));
    camNode.updateWorldData(0);
    input = new NodeHandler(camNode, 150, 1);
    rootNode.attachChild(camNode);
    display.setTitle("Terrain Test");
    display.getRenderer().setBackgroundColor(new ColorRGBA(0.5f,0.5f,0.5f,1));

    DirectionalLight dr = new DirectionalLight();
    dr.setEnabled(true);
    dr.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
    dr.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));
    dr.setDirection(new Vector3f(0.5f, -0.5f, 0));

    CullState cs = display.getRenderer().createCullState();
    cs.setCullMode(CullState.CS_BACK);
    cs.setEnabled(true);
    rootNode.setRenderState(cs);

    lightState.attach(dr);

    FaultFractalHeightMap heightMap = new FaultFractalHeightMap(257, 32, 0, 255,
        0.75f);
    Vector3f terrainScale = new Vector3f(10,1,10);
    heightMap.setHeightScale( 0.001f);
    page = new TerrainPage("Terrain with multi detail", 33, heightMap.getSize(), terrainScale,
                                     heightMap.getHeightMap(), false);

    rootNode.attachChild(page);

    ProceduralTextureGenerator pt = new ProceduralTextureGenerator(heightMap);
    pt.addTexture(new ImageIcon(TestTerrain.class.getClassLoader().getResource(
        "jmetest/data/texture/Detail.jpg")), -128, 0, 128);
    pt.addTexture(new ImageIcon(TestTerrain.class.getClassLoader().getResource(
        "jmetest/data/texture/grass.jpg")), 0, 128, 255);
    pt.addTexture(new ImageIcon(TestTerrain.class.getClassLoader().getResource(
        "jmetest/data/texture/highest.jpg")), 128, 255, 384);

    pt.createTexture(512);
   
    TextureState ts = display.getRenderer().createTextureState();
    ts.setEnabled(true);
   
    Texture t0 = TextureManager.loadTexture(pt.getImageIcon().getImage(),
            Texture.MM_LINEAR_LINEAR,
            Texture.FM_LINEAR,true);
   
    Texture t1 = TextureManager.loadTexture(TestTerrain.class.getClassLoader().
            getResource("jmetest/data/texture/Detail.jpg"),
            Texture.MM_LINEAR_LINEAR,
            Texture.FM_LINEAR);
   
    Texture t2 = TextureManager.loadTexture(TestTerrain.class.getClassLoader().
            getResource("jmetest/data/texture/grass.png"),
            Texture.MM_LINEAR_LINEAR,
            Texture.FM_LINEAR);
   
    page.setDetailTexture(1, 64);
    page.setDetailTexture(2, 128);
   
    ts.setTexture(t0, 0);
    ts.setTexture(t1, 1);
    ts.setTexture(t2, 2);
   
    t0.setApply(Texture.AM_COMBINE);
    t0.setCombineFuncRGB(Texture.ACF_MODULATE);
    t0.setCombineSrc0RGB(Texture.ACS_TEXTURE);
    t0.setCombineOp0RGB(Texture.ACO_SRC_COLOR);
    t0.setCombineSrc1RGB(Texture.ACS_PRIMARY_COLOR);
    t0.setCombineOp1RGB(Texture.ACO_SRC_COLOR);
    t0.setCombineScaleRGB(1.0f);

    t1.setWrap(Texture.WM_WRAP_S_WRAP_T);
    t1.setApply(Texture.AM_COMBINE);
    t1.setCombineFuncRGB(Texture.ACF_ADD_SIGNED);
    t1.setCombineSrc0RGB(Texture.ACS_TEXTURE);
    t1.setCombineOp0RGB(Texture.ACO_SRC_COLOR);
    t1.setCombineSrc1RGB(Texture.ACS_PREVIOUS);
    t1.setCombineOp1RGB(Texture.ACO_SRC_COLOR);
    t1.setCombineScaleRGB(1.0f);
   
    t2.setWrap(Texture.WM_WRAP_S_WRAP_T);
    t2.setApply(Texture.AM_COMBINE);
    t2.setCombineFuncRGB(Texture.ACF_ADD_SIGNED);
    t2.setCombineSrc0RGB(Texture.ACS_TEXTURE);
    t2.setCombineOp0RGB(Texture.ACO_SRC_COLOR);
    t2.setCombineSrc1RGB(Texture.ACS_PREVIOUS);
    t2.setCombineOp1RGB(Texture.ACO_SRC_COLOR);
    t2.setCombineScaleRGB(1.0f);
   
    rootNode.setRenderState(ts);

  }
}


here the texture for overlay



[modified the author tag, sry ;)]

well coded! can we see a real screenshot "in action"? :slight_smile:

ok, look at this









it’s a nice bumpfake 



OK, but the next question is on the horizon  :roll:



I blend the textures over the full terrain. I looking a way to blend it particular over the terrain, using a black/white map…



… and found … the combiner can’t help to do this …

ok the goal is, to create a texture like this …







or this







:-o  ok, two screens from currently released games, but also software and also 3D-graphics  XD

“texture splatting”

http://www.gamedev.net/columns/hardcore/splatting/default.asp



without shaders you have to do it by rendering multiple passes, and setting up each pass to render with two textures, the detailtexture and an alphamap…and setup the combinemodes to render the detailtexture but use the alpha from the alphamap…

Or you can generate the splats at the start. That's quite slow, but there's a jME class for this (hap[pens in software, not on the videocard). You could take a look at TestProceduralSplatTexture.

though, as we have discussed before that's not what those wanted pictures show, and doesnt come anywhere near texturesplatting results

Well, as long as everything is static you can generate it right? The result of hardware or software splatting shouldn't be any different, except that real time hardware splatting is a lot more flexible.

no not really. texturesplatting in my book is tiled detailtextures highly repeated, wich takes it's amount of contribution from an alphamap…to build a pregenerated texture for a terrain with the same amout of detail would require a texture of size 2^30x2^30 or something like that(depending on how detailed and tiled your detailtextures are)

Yes like I said, real time is much more flexible, you can use maps as large as you want. With pre-generated texture you'll be stuck to what you can… well… pre-generate :slight_smile:

ok I'll buy that :slight_smile:



(but for people considering it, the reason for using "real" splatting is the same as not "pre-generating" the detail map as a full texture that covers the whole terrain)