Hi!
Can I use a texture instead of color in ribbon.js?
var Ribbon = pc.createScript('ribbon');
Ribbon.attributes.add("lifetime", {type:"number", default:0.5});
Ribbon.attributes.add("xoffset", {type:"number", default:-0.8});
Ribbon.attributes.add("yoffset", {type:"number", default:1});
Ribbon.attributes.add("height", {type:"number", default:0.4});
Ribbon.attributes.add('texture', { type: 'asset', assetType: 'texture'});
var MAX_VERTICES = 600;//150;//600;
var VERTEX_SIZE = 4;
Ribbon.prototype.create = function (entity) {
// this.entity = entity;
this.timer = 0;
// The node generating this ribbon
this.node = null;
// The generated ribbon vertices
this.vertices = [];
// Vertex array to receive ribbon vertices
this.vertexData = new Float32Array(MAX_VERTICES * VERTEX_SIZE);
this.entity.model = null;
};
Ribbon.prototype.initialize = function () {
this.create();
console.log(this.texture.resource);
var shaderDefinition = {
attributes: {
aPositionAge: pc.SEMANTIC_POSITION,
//texture:this.texture
},
vshader: [
"attribute vec4 aPositionAge;",
"",
"uniform mat4 matrix_viewProjection;",
"uniform float trail_time;",
"",
"varying float vAge;",
"",
"void main(void)",
"{",
" vAge = trail_time - aPositionAge.w;",
" gl_Position = matrix_viewProjection * vec4(aPositionAge.xyz, 1.0);",
"}"
].join("\n"),
fshader: [
"precision mediump float;",
"",
"varying float vAge;",
"",
"uniform float trail_lifetime;",
"",
"vec3 rainbow(float x)",
"{",
"float level = floor(x * 1.0);",
"float r = float(level <= 2.0) + float(level > 4.0) * 0.5;",
"float g = max(1.0 - abs(level - 2.0) * 0.5, 0.0);",
"float b = (1.0 - (level - 4.0) * 0.5) * float(level >= 4.0);",
"return vec3(r, g, b);",
"}",
"void main(void)",
"{",
" gl_FragColor = vec4(rainbow(vAge / trail_lifetime), (1.0 - (vAge / trail_lifetime)) * 0.5);",
"}"
].join("\n")
};
// var shader = new pc.Shader(context.graphicsDevice, shaderDefinition);
var shader = new pc.Shader(this.app.graphicsDevice, shaderDefinition);
var material = new pc.scene.Material();
material.setShader(shader);
material.setParameter('trail_time', 0);
material.setParameter('trail_lifetime', this.lifetime);
material.cull = pc.CULLFACE_NONE;
material.blend = true;
material.blendSrc = pc.BLENDMODE_SRC_ALPHA;
material.blendDst = pc.BLENDMODE_ONE_MINUS_SRC_ALPHA;
material.blendEquation = pc.BLENDEQUATION_ADD;
material.depthWrite = false;
// Create the vertex format
var vertexFormat = new pc.VertexFormat(this.app.context.graphicsDevice, [
{ semantic: pc.SEMANTIC_POSITION, components: 4, type: pc.ELEMENTTYPE_FLOAT32 }
]);
// Create a vertex buffer
var vertexBuffer = new pc.VertexBuffer(this.app.context.graphicsDevice, vertexFormat, MAX_VERTICES * VERTEX_SIZE, pc.USAGE_DYNAMIC);
var mesh = new pc.scene.Mesh();
mesh.vertexBuffer = vertexBuffer;
mesh.indexBuffer[0] = null;
mesh.primitive[0].type = pc.PRIMITIVE_TRISTRIP;
mesh.primitive[0].base = 0;
mesh.primitive[0].count = 0;
mesh.primitive[0].indexed = false;
var node = new pc.scene.GraphNode();
var meshInstance = new pc.scene.MeshInstance(node, mesh, material);
meshInstance.layer = pc.scene.LAYER_WORLD;
meshInstance.updateKey();
this.entity.model = new pc.scene.Model();
this.entity.model.graph = node;
this.entity.model.meshInstances.push(meshInstance);
this.model = this.entity.model;
this.setNode(this.entity);
};
Ribbon.prototype.reset = function () {
this.timer = 0;
this.vertices = [];
};
Ribbon.prototype.spawn = function () {
var node = this.node;
var pos = node.getPosition();
var yaxis = node.up.clone().scale(this.height);
var s = this.xoffset;
var e = this.yoffset;
this.vertices.unshift({
spawnTime: this.timer,
vertexPair: [
pos.x + yaxis.x * s, pos.y + yaxis.y * s, pos.z + yaxis.z * s,
pos.x + yaxis.x * e, pos.y + yaxis.y * e, pos.z + yaxis.z * e
]
});
};
Ribbon.prototype.clearOld = function () {
for (var i = this.vertices.length - 1; i >= 0; i--) {
var vp = this.vertices[i];
if (this.timer - vp.spawnTime >= this.lifetime) {
this.vertices.pop();
} else {
return;
}
}
};
Ribbon.prototype.copyToArrayBuffer = function () {
for (var i = 0; i < this.vertices.length; i++) {
var vp = this.vertices[i];
this.vertexData[i * 8 + 0] = vp.vertexPair[0];
this.vertexData[i * 8 + 1] = vp.vertexPair[1];
this.vertexData[i * 8 + 2] = vp.vertexPair[2];
this.vertexData[i * 8 + 3] = vp.spawnTime;
this.vertexData[i * 8 + 4] = vp.vertexPair[3];
this.vertexData[i * 8 + 5] = vp.vertexPair[4];
this.vertexData[i * 8 + 6] = vp.vertexPair[5];
this.vertexData[i * 8 + 7] = vp.spawnTime;
}
};
Ribbon.prototype.updateNumActive = function () {
this.model.meshInstances[0].mesh.primitive[0].count = this.vertices.length * 2;
};
Ribbon.prototype.update = function (dt) {
this.timer += dt;
var material = this.model.meshInstances[0].material;
material.setParameter('trail_time', this.timer);
this.clearOld();
this.spawn();
if (this.vertices.length > 1) {
this.copyToArrayBuffer();
this.updateNumActive();
var vertexBuffer = this.model.meshInstances[0].mesh.vertexBuffer;
var vertices = new Float32Array(vertexBuffer.lock());
vertices.set(this.vertexData);
vertexBuffer.unlock();
if (!this.app.scene.containsModel(this.model)) {
console.log("Added model");
this.app.scene.addModel(this.model);
}
} else {
if (this.app.scene.containsModel(this.model)) {
console.log("Removed model");
this.app.scene.removeModel(this.model);
}
}
};
Ribbon.prototype.setNode = function (node) {
this.node = node;
};