Skyboxes - Howto

Hi all, im new to work with jme and i have a question:

How to take a skybox from a real photo? from to cut it to render well and not as box segmented photos?

i have tryed some cut from north to south like cross side box render and like:



      T

N E S W

      B



But it can't work correcly… what I wrong?

Thanks in first for any answer  :slight_smile:

what problem do you get on your screen?

I post a shot:







It show the box, not like a sphere.

My problem is “how i can cut a photo” for making skybox from it.

what order i need to cutting it?

I'm just wondering… If you have 6 images that represent views of straight up, straight down, left, right, forward and back…  you should be able to take your best guess and then look at them in jME.  Note which ones are wrong and either swap them around in your usage or if necessary, rotate individual images in your favorite image editor.

Oh! i try to do some test for best result.

If i find a way i come back and i post my result.



Thanks.

I think you have 1 photo, and want to cut it up right?



But it's pretty hard to make a skybox from that, you'd need a panoramic 360 degrees photo. (or maybe a 180, and then mirror it for the other side). If you want a correct top and bottom it's even harder. However there is a lot of software avaible to "stitch" together different picuteres to a 360 full panorama.



If you have one though, an easy way is to divide it up in 3 horizontal bars (I'd make the middle somewhat bigger than the others). Wrap the bar middle part around (N W S E). For the top, use the upper bar, each part above NWSE should be reshaped into equal triangles, the four triangles forming a square without seems. Same for the bottom.

This is not a necisarly a correct perspective, but that's very hard to do with a skybox anyway, and it'll depend on the type of photo you created. A sky dome instead of box may give an (easier) better result.

Yes, but how i can make dome instead of box?

I find only skybox in the javadoc, i need maybe to extend the class or is better making a dome from primitives?

We may not have a SkyDome class, But we have a Dome class. You can like at the SkyBox code to see how to make it behave to stay in the background and such.

Oh! Thanks,  I'm really meaning that :slight_smile:



This is what I do:


/*
 * 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 AchilleTest;

import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.math.Quaternion;
import com.jme.renderer.Renderer;
import com.jme.scene.Spatial;
import com.jme.scene.*;
import com.jme.scene.shape.Dome;
import com.jme.scene.state.LightState;
import com.jme.scene.state.RenderState;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;

/**
 * A Box made of textured quads that simulate having a sky, horizon and so forth
 * around your scene. Either attach to a camera node or update on each frame to
 * set this skybox at the camera's position.
 *
 * @author David Bitkowski
 * @author Jack Lindamood (javadoc only)
 * @version $Id: SkyDome.java,v 1.1 2006/02/27 12:01:25 achilleterzo Exp $
 */
public class SkyDome extends Node {
    private static final long serialVersionUID = 1L;

    private int planes;
    private int radialSamples;
    private float radius;

    private Dome skyboxDome;

    /**
     * Creates a new skyDome. The size of the skyDome and name is specified here.
     * By default, no textures are set.
     *
     * @param name
     *            The name of the skybox.
     * @param planes
     *            The planes of the Dome.
     * @param radialSamples
     *            The radial samples of the Dome.
     * @param radius
     *            The radius of the Dome.
     */
    public SkyDome(String name, int planes, int radialSamples, float radius) {
        super(name);

        this.planes = planes;
        this.radialSamples = radialSamples;
        this.radius = radius;

        initialize();
    }

    public SkyDome(String name, int planes, int radialSamples, float radius, boolean reverse) {
        super(name);

        this.planes = planes;
        this.radialSamples = radialSamples;
        this.radius = radius;

        initialize();
    }   
   
    public int getType() {
       return (Spatial.NODE | Spatial.SKY_BOX);
    }

    /**
     * Set the texture to be displayed on the given side of the skybox. Replaces
     * any existing texture on that side.
     *
     * @param direction
     *            One of Skybox.NORTH, Skybox.SOUTH, and so on...
     * @param texture
     *            The texture for that side to assume.
     */
    public void setTexture(int direction, Texture texture) {
        if (direction < 0 || direction > 5) {
            throw new JmeException("Direction " + direction
                    + " is not a valid side for the skybox");
        }

        skyboxDome.clearRenderState(RenderState.RS_TEXTURE);
        setTexture(0, texture, 0);
    }

    /**
     * Set the texture to be displayed on the given side of the skybox. Only
     * replaces the texture at the index specified by textureUnit.
     *
     * @param direction
     *            One of Skybox.NORTH, Skybox.SOUTH, and so on...
     * @param texture
     *            The texture for that side to assume.
     * @param textureUnit
     *            The texture unite of the given side's TextureState the texture
     *            will assume.
     */
    public void setTexture(int direction, Texture texture, int textureUnit) {
        // Validate
        if (direction < 0 || direction > 5) {
            throw new JmeException("Direction " + direction
                    + " is not a valid side for the skybox");
        }

        TextureState ts = (TextureState) skyboxDome.getRenderState(RenderState.RS_TEXTURE);
        if (ts == null) {
            ts = DisplaySystem.getDisplaySystem().getRenderer()
                    .createTextureState();
        }

        // Initialize the texture state
        ts.setTexture(texture, textureUnit);
        ts.setEnabled(true);

        // Set the texture to the quad
        skyboxDome.setRenderState(ts);

        return;
    }

    private void initialize() {
        DisplaySystem display = DisplaySystem.getDisplaySystem();

        // Create Dome
        skyboxDome = new Dome("topSkyDome", planes, radialSamples, radius);
        skyboxDome.setLocalRotation(new Quaternion(new float[] { 0,
                (float) Math.toRadians(180), 0 }));

        // We don't want the light to effect our skybox
        LightState lightState = display.getRenderer().createLightState();
        lightState.setEnabled(false);
        setRenderState(lightState);
        setLightCombineMode(LightState.REPLACE);
        setTextureCombineMode(TextureState.REPLACE);

        ZBufferState zbuff = display.getRenderer().createZBufferState();
        zbuff.setWritable(false);
        zbuff.setEnabled(true);
        zbuff.setFunction(ZBufferState.CF_LEQUAL);
        setRenderState(zbuff);

        // We don't want it making our skybox disapear, so force view
        setCullMode(Spatial.CULL_NEVER);

        // Make sure texture is only what is set.
        skyboxDome.setTextureCombineMode(TextureState.REPLACE);

        // Make sure no lighting on the skybox
        skyboxDome.setLightCombineMode(LightState.REPLACE);

        // Make sure the quad is viewable
        skyboxDome.setCullMode(Spatial.CULL_NEVER);

        // Set a bounding volume
        skyboxDome.setModelBound(new BoundingBox());
        skyboxDome.updateModelBound();

        skyboxDome.setRenderQueueMode(Renderer.QUEUE_SKIP);
        skyboxDome.setVBOInfo(null);

        // And attach the skybox as a child
        attachChild(skyboxDome);
    }

    /**
     * Force all of the textures to load. This prevents pauses later during the
     * application as you pan around the world.
     */
    public void preloadTextures()
    {
        TextureState ts = (TextureState) skyboxDome
                .getRenderState(RenderState.RS_TEXTURE);
        if (ts != null)
            ts.apply();
    }
}



Now im just think if make 2 constructors, one for making a skyDome, one for making double skyDome with upper and inverse-lower textured domes.

This is the test result with a lowRes jpg:

looks nice. :slight_smile:



darkfrog

the skydome could enable really nice atmospheric effects like multiple cloud layers.

testing on a hi-res sky:



very nice

nice one…

I have been a lurker here for quite awhile and finally I have gotten rolling with a project of my own…



I'm currently working on a dynamic skydome for my Land Rover based game. The sky gradient updates based on time of day, with perlin noise based cloud layers. Its still in the early stages, but I just thought I would chime in here with a screencap

Nice rover!  :-o



darkfrog

Thanks! If anyone is looking for auto models, I found my rover models here:

http://dmi.chez-alice.fr/models1.html



They have some really nice high poly (in lwo format) models archived there, so a bit of work is required to get them to a useable state. Blender has helped a bit in that respect. They are all free for private and non-commercial use.



Here is another screencap:





and a closeup of the Defender 90 model:

Love the license plate :slight_smile:

lo all



can i ask what sky textures you used ,and where you found them? im struggling to find one that looks nice!



very trivial question for my first post , but ah well :slight_smile:



best of luck

mtm

Try google images, its a great source if you quickly want an image but be carefull with copyrighted content.