but0n / Ashes

WebGL2.0 3D Engine - Global Illumination - RayTracing
https://codepen.io/but0n/pen/jddYoX
MIT License
331 stars 15 forks source link

How to display a triangle without using glTF in Ashes? #18

Closed cx20 closed 5 years ago

cx20 commented 5 years ago

I tried to display a triangle without using glTF in Ashes. It is now displayed, but I am not confident in the code. I would be happy if you can check if there is any problem with usage.

Ashes + Triangle sample http://jsdo.it/cx20/uG69

image

but0n commented 5 years ago

Nice work! I will export bufferView and trying to add some basical meshes in the next version.

cx20 commented 5 years ago

I created the following three samples and added Ashes to the WebGL list. When bufferView is exported, it modifies the sample again.

Ashes + Colored Squares http://jsdo.it/cx20/uJua image

Ashes + Colored Cube http://jsdo.it/cx20/GCxHp image

Ashes + Cube with Texture http://jsdo.it/cx20/wp46 image

Comparison of every WebGL libraries with rendering basic primitives. https://qiita.com/cx20/items/0fa19c96aa6470d98807#using-vbo

Please tell me if there is any mistake.

but0n commented 5 years ago

Thanks for you adding Ashes to the WebGL list!

I noticed you are manually setting up the matrix of camera, actually this is not necessary if you bind this camera as the main camera of this screen:

screen.mainCamera = cam; // it will allow the system automatically update the VP matrix of this camera

I didn't mention about this before because it is still WIP, and it is not required when you are using orbitControl component. Ashes is supposed to support multiple cameras in the future.

Here is my fork of Ashes + Colored Cube: http://jsdo.it/but0n/w5zt

Ashes has Entity-Component-System framework like Unity, I think it will be better to create a System to control the entity in the future:

class testSystem extends ComponentSystem {
    group = [];
    depends = [
        Transform.name,
    ];
    onUpdate() {
        for(let {components} of this.group) {
            // do something
        }
    };
} System.registSystem(new testSystem());
cx20 commented 5 years ago

I changed the library to v0.0.49 and removed the definition of the bufferView class from the sample. I would like to rotate using quaternion if possible, but how do I write code?

The following is a sample for comparison of Euler angle and quaternion rotation. http://jsdo.it/cx20/gJ6T

but0n commented 5 years ago

@cx20 I have rewrite the animation part with a component: http://jsdo.it/but0n/w5zt

class animComponent {
        angle = 0;
}
class animSystem extends ComponentSystem {
    group = [];
    depends = [
        animComponent.name,
    ];
    onUpdate() {
        for(let {components} of this.group) {
            // do something
            let animcomp = components.animComponent;
            let trans = components.Transform
            quat.fromEuler(trans.quaternion, animcomp.angle++, animcomp.angle++, animcomp.angle++);
        }
    };
} System.registSystem(new animSystem());

Attach this component:

EntityMgr.addComponent(custom, new animComponent());

I would like to rotate using quaternion if possible, but how do I write code?

transform.ts#L83

mat4.fromRotationTranslationScale(trans.localMatrix, trans.quaternion, trans.translate, trans.scale);

The local matrix of entities is calculate from RTS, you can modify trans.quaternion directly:

quat.fromEuler(trans.quaternion, animcomp.angle++, animcomp.angle++, animcomp.angle++);
quat.rotateX(trans.quaternion, trans.quaternion, 0.01);
quat.rotateY(trans.quaternion, trans.quaternion, 0.01);
quat.rotateZ(trans.quaternion, trans.quaternion, 0.01);
cx20 commented 5 years ago

@but0n I tried to make samples of Euler angles and quaternions using ComponentSystem. Is the usage method right? http://jsdo.it/cx20/oIQq

but0n commented 5 years ago

Yeah, that's correct! I think this translate setting here is unnecessary, considering the translate property won't be modified.

vec3.set(trans.translate, 1.0, 0, 0);

it will be executed every frame, but it's doesn't matter.

My fork: http://jsdo.it/but0n/Uitp

cx20 commented 5 years ago

@but0n Thanks for the advice. Your sample is very smart. I think that Issue is resolved and I will close it.

BTW, I tagged Ashes to the sample I made at jsdo.it. for your information. http://jsdo.it/tag/Ashes

but0n commented 5 years ago

Thanks! I will reference those samples in readme. Please let me know if you have any issues or suggestions while using this library. I'm considering make those statements shorter.

cx20 commented 5 years ago

BTW, I tried to create a sample using a physical engine. I do not understand the component system correctly yet, so I think the sample has room for improvement a bit. Currently, since I did not know the proper place to initialize the rigid body of physical operation, I initialized it with onUpdate(). Please advice if you please.

Ashes + Oimo.js sample: http://jsdo.it/cx20/cCx5

but0n commented 5 years ago

@cx20 I'm intresting to have a physical engine inject! I can not access that sample :(

cx20 commented 5 years ago

Oops, recently, jsdo.it seems to be bad :( I tried uploading a sample to jsfiddle.net. The imageFile variable is the texture of a frog. https://jsfiddle.net/cx20/adfngy13/1/

but0n commented 5 years ago

This demo looks great!

Currently, since I did not know the proper place to initialize the rigid body of physical operation, I initialized it with onUpdate(). Please advice if you please.

Actually, the initialization is usually contained in the constructor of component, and those componentSystem which is associated has registered before, so there are no conflict.

In this example, seems like the initialization required OIMO.World, so you placed the initial code in componentSystem to ensure the World is exist, am I right?

BTW, Ashes has optional texture with RGB data:

let map = new Texture();
map.data = Texture.defaultData;

image

cx20 commented 5 years ago

In this example, seems like the initialization required OIMO.World, so you placed the initial code in componentSystem to ensure the World is exist, am I right?

Yes. Since only one OIMO.World is needed, it was initialized with the constructor of componentSystem.

I think that the usage of Oimo.js below will be helpful. https://github.com/lo-th/Oimo.js

1. Create physics world:

   world = new OIMO.World()

2. Add physics object

   body = world.add(...);

3. Update world

   world.step();

4. Copy position and rotation to three mesh

   mesh.position.copy( body.getPosition() );
   mesh.quaternion.copy( body.getQuaternion() );

I tried to bring world.add to OimoComponent, but because I did not know how to do it smartly, I replaced it by making world a global variable.

https://jsfiddle.net/cx20/adfngy13/32/

class OimoComponent {
    type = "box";
    size = [1, 1, 1];
    pos = [0, 0, 0];
    rot = [0, 0, 0];
    move = false;
    body = null;
    constructor(type, size, pos, rot, move) {
        this.body = OimoSystem.getWorld().add({
          type: type,
          size: size,
          pos: pos,
          rot: rot,
          move: move,
          density: 1
        });
        this.size = size;
    }
}
but0n commented 5 years ago

@cx20

I think you can set the world instance as a static member of OimoSystem:

class OimoSystem extends ComponentSystem {
// ...
    static g_world = new OIMO.World({ 
            timestep: 1/60 * 2, 
            iterations: 8, 
            broadphase: 2, // 1 brute force, 2 sweep and prune, 3 volume tree
            worldscale: 1, // scale full world 
            random: true,  // randomize sample
            info: false,   // calculate statistic or not
            gravity: [0,-9.8,0] 
    });
    static getWorld() { 
        return this.g_world;
    }
    onUpdate() {
// ...

BTW, you can access the deltaTime during onUpdate, which is the time(millisecond) that previous frame costed. This is an example from AnimationSystem:

    onUpdate(dt) {
        for (let { components } of this.group) {
            if(dt > 0.016) dt = 0.016;
            let anim = components.Animation as Animation;
            for(let channel of anim.channels) {
                this.playStep(channel, dt);
            }
        }
    };
cx20 commented 5 years ago

Thanks! I was able to add static members to OimoSystem. https://jsfiddle.net/cx20/adfngy13/55/

I would like to port samples of other physics engines if I have time. https://qiita.com/cx20/items/3ebed669fb9c9e797935