Open rontrek opened 5 years ago
I think your skybox need to be un cube. I've wrote this for a game prototype few years ago. I think it's a "good" base to solve your problem (I think it's not usable without somme work for you). It use an entity to work with weltmeister :
PLUGIN:
ig.module(
'plugins.igecode.world.skybox'
)
.requires(
'impact.image',
'plugins.twopointfive.renderer.quad'
)
.defines(function(){
ig.Skybox = ig.Class.extend({
boxSize: 4096,
boxPos: {x: 0, y: 0, z:0},
tileSize: 32,
tileScale: 1,
textures: {
/* sky list or tweak it for use image with init(settings)*/
black: new ig.Image('media/skydomes/black.png'),
bluesky: new ig.Image('media/skydomes/bluesky.jpg'),
test: new ig.Image('media/skydomes/test.png')
},
boxFaces: null,
image: null,
init:function(settings){
if(settings != null) {
if(settings.image && this.textures[settings.image]){
this.image = this.textures[settings.image];
}
this.boxPos = {x:settings.x || 0, y:settings.z || 0, z:settings.y || 0};
this.boxSize = settings.boxSize || 2048
this.tileSize = settings.tileSize || 512
}
this.tileScale = this.boxSize / this.tileSize;
if(this.image == null) {
this.image = this.textures.black;
}
// Create faces
this.createGeometry();
},
createGeometry: function(){
// creates tiles
this.boxFaces = [
new tpf.Tile( this.image, 0, this.tileSize, this.tileSize, this.tileScale ),
new tpf.Tile( this.image, 5, this.tileSize, this.tileSize, this.tileScale ),
new tpf.Tile( this.image, 2, this.tileSize, this.tileSize, this.tileScale ),
new tpf.Tile( this.image, 1, this.tileSize, this.tileSize, this.tileScale ),
new tpf.Tile( this.image, 4, this.tileSize, this.tileSize, this.tileScale ),
new tpf.Tile( this.image, 3, this.tileSize, this.tileSize, this.tileScale ),
];
// face 1 (front)
this.boxFaces[0].quad.setPosition(
this.boxPos.x,
this.boxPos.y,
this.boxPos.z + this.boxSize/2
);
this.boxFaces[0].quad.setRotation(0, Math.PI, 0);
// face 2 (left)
this.boxFaces[1].quad.setPosition(
this.boxPos.x - this.boxSize/2,
this.boxPos.y,
this.boxPos.z
);
this.boxFaces[1].quad.setRotation(0, Math.PI/2, 0);
// face 3 (back)
this.boxFaces[2].quad.setPosition(
this.boxPos.x,
this.boxPos.y,
this.boxPos.z - this.boxSize/2
);
// face 4 (right)
this.boxFaces[3].quad.setPosition(
this.boxPos.x + this.boxSize/2,
this.boxPos.y,
this.boxPos.z
);
this.boxFaces[3].quad.setRotation(0, -Math.PI/2, 0);
// face 5 (top)
this.boxFaces[4].quad.setPosition(
this.boxPos.x,
this.boxPos.y + this.boxSize/2,
this.boxPos.z
);
this.boxFaces[4].quad.setRotation(-Math.PI/2, Math.PI, Math.PI/2);
// face 6 (bottom)
this.boxFaces[5].quad.setPosition(
this.boxPos.x,
this.boxPos.y - this.boxSize/2,
this.boxPos.z
);
this.boxFaces[5].quad.setRotation(Math.PI/2, -Math.PI, 0);
},
draw: function(){
if(!this.boxFaces) {
this.createGeometry();
}
var mesh = new tpf.TileMesh(this.boxFaces),
renderer = ig.system.renderer;
renderer.pushMesh(mesh);
renderer.setProgram(renderer.programFog);
}
});
});
ENTITY
ig.module(
'game.entities.skybox-params'
)
.requires(
'impact.entity'
)
.defines(function(){
EntitySkyboxParams = ig.Entity.extend({
type: ig.Entity.TYPE.NONE,
checkAgainst: ig.Entity.TYPE.NONE,
collides: ig.Entity.COLLIDES.NEVER,
size: {x: 8, y: 8},
boxSize: 2048,
_wmDrawBox: true,
_wmBoxColor: '#88f',
init: function(x, y, settings){
this.parent(x, y, settings);
},
update: function(){},
draw: function(){
if(!ig.global.wm){
return;
}
var x = (this.pos.x-this.boxSize/2+this.size.x/2-ig.game.screen.x)*ig.system.scale,
y = (this.pos.y-this.boxSize/2+this.size.y/2-ig.game.screen.y)*ig.system.scale,
boxSize = this.boxSize*ig.system.scale,
alpha = (this == ig.game.entities.selectedEntity)?1: 0.2;
var ctx = ig.system.context;
ctx.globalAlpha = alpha;
ctx.lineWidth = 1;
ctx.strokeStyle = this._wmBoxColor;
ctx.stroke();
ctx.strokeRect( x, y, this.boxSize * ig.system.scale, this.boxSize * ig.system.scale );
ctx.globalAlpha = 1;
}
});
});
GAME EXTEND :
ig.module(
'plugins.igecode.game'
)
.requires(
'plugins.twopointfive.game',
'plugins.igecode.world.skybox'
)
.defines(function(){ "use strict";
ig.GameExtend = tpf.Game.extend({
skybox: null,
clearLevel: function() {
this.parent();
this.skybox = null;
},
loadLevel: function( data ) {
this.parent();
// creation du skybox
// Find the info entity
var skyboxParams = null;
for( var i=0; i<data.entities.length; i++ ) {
if( data.entities[i].settings && data.entities[i].type == 'EntitySkyboxParams' ) {
skyboxParams = data.entities[i].settings;
skyboxParams.x = data.entities[i].x;
skyboxParams.y = data.entities[i].y;
}
}
if(skyboxParams != null) {
this.skybox = new ige.Skybox(skyboxParams);
}
},
drawWorld: function() {
this.parent();
if(this.skybox != null) {
this.skybox.draw();
}
}
});
});
Awesome, Thanks a lot! @SilvRO :smiley:
one small issue I noticed is it is affected by fog, so I have to turn it off. It would be nice though to get this to work with fog.
Anyways, really appreciate this and got it working. thanks again :+1: :+1: :+1:
The quads are very far away from the camera. You need some tweak to disable fog only on skybox.
I'm glad to have helped you 😃
I see and I would assume that would involve tweaking the fog shader. @phoboslab is there a current workaround to exclude an entity/quad set from fog?
Another minor thing would be attaching or parenting the skybox to the player/camera to get that endless horizon effect. I'm fairly new to impact/tpf and tried to copy the x and y player position to the box position and it is not moving at all.. looks like that's not how it works. any tips for that?
My code was really for testing. Normally a skybox is not a "physical" entity that the player can touch. I think we need to review the integration of the skybox to do this. A 3D pass for the skybox with fixed origin and camera angle, then a pass for the level. For fog, perhaps pass a parameter to the shader fragment to disable it (impact\lib\plugins\twopointfive\renderer\render.js: tpf.Renderer.Shaders.vertex.FragmentWithFog). And go up to the Quad object to pass the parameter.
Ok got it. Yes, agreed and what I have proposed there is not having to use shaders as much as possible as this is the go-to method which was used before shaders became available, and that is setting up a large skybox following camera or using pivot attached to player camera. I think your solution here is more practical and simple, but I don't mind going for a shader version either.
As for the fog, I finally figured out a workaround which just involves depth. With the fog near and far default setting to 128 and 512 respectively, I just set the boxSize a little bit bigger around 8000 (so the sky looks bigger/farther with a huge margin just to make sure) and added this on the fog shader.
if(depth > 2000.0) fogFactor = 0.0;
or just 1000, might need some adjustment depending on the map setup, but it works. I still have no clue with interacting with custom quads and passing parameters to shader on Impact, but would be curious to know how this can be done, particularly with entities that are not far but is not affected with fog (items, entities, powerups, etc.).
Hi, I see that the forum is now read only and noted to post here on GitHub for questions, so in particular I'm trying to create a background skybox for a twopointfive level. I did search for previous related post here:
https://impactjs.com/forums/impact-engine/impact-1-24-pseudo-3d-web-audio
but with no luck and somehow can't get it to work. What I have done so far is cleared a part of the ceiling assuming it will be drawn there.
main.js