Commit 950374dc authored by wjf's avatar wjf

l

parent 21161f6a
......@@ -16211,9 +16211,9 @@ var D3Renderer = (function (_super) {
glVaoBuffer.indexBuffer = glCore_1.GLBuffer.createIndexBuffer(gl, null, gl.STATIC_DRAW);
if (geo._morphPositions) {
glVaoBuffer.morphTargetBuffers = [];
for (var m = 0; m < geo._morphPositions.length; m++) {
glVaoBuffer.morphTargetBuffers.push(glCore_1.GLBuffer.createVertexBuffer(gl, null, gl.STATIC_DRAW));
}
}
if (geo._morphNormals) {
glVaoBuffer.morphNormalBuffers = [];
}
packGeometry(geo);
}
......@@ -16228,19 +16228,29 @@ var D3Renderer = (function (_super) {
vao.addAttribute(glVaoBuffer.attrBuffer, attrs.aNormal, gl.FLOAT, false, geo._vertByteSize, 8 * 4);
if (geo._indices)
vao.addIndex(glVaoBuffer.indexBuffer);
var uploadBufferDatas;
if (mesh.morphTargetInfluences && mat.morphTargets) {
uploadBufferDatas = addMorphtargetsAttr(mesh.morphTargetInfluences, geo, glVaoBuffer, vao, curShader, gl);
}
this.renderer.bindVao(vao);
glVaoBuffer.attrBuffer.upload(geo._attrBuffer.vertices, 0, false);
if (geo._indices)
glVaoBuffer.indexBuffer.upload(geo._indices, 0, false);
if (geo._morphPositions) {
var len = geo._morphNormals ? 4 : 8;
for (var n = 0; n < len; n++) {
glVaoBuffer.morphTargetBuffers[n];
}
}
if (uploadBufferDatas)
uploadBufferDatas.forEach(function (e) {
e.buffer.upload(e.data, 0, false);
});
}
else {
var uploadBufferDatas;
if (mesh.morphTargetInfluences && mat.morphTargets) {
uploadBufferDatas = addMorphtargetsAttr(mesh.morphTargetInfluences, geo, glVaoBuffer, vao, curShader, gl);
}
this.renderer.bindVao(vao);
if (uploadBufferDatas)
uploadBufferDatas.forEach(function (e) {
e.buffer.upload(e.data, 0, true);
});
}
if (mat.side == BaseMaterial_1.RenderSideType.DoubleSide) {
this.renderer.state.setCullFace(0);
......@@ -16273,6 +16283,91 @@ function packGeometry(geo) {
float32View[count++] = geo._normals[j * 3 + 2];
}
}
var influencesList = {};
var attrChannelHash = {};
var morphInfluences = new Float32Array(8);
function addMorphtargetsAttr(objectInfluences, geo, glVaoBuffer, vao, shader, gl) {
var morphTargets = geo._morphPositions;
var morphNormals = geo._morphNormals;
var length = objectInfluences.length;
var uploadBufferDatas = [];
var influences = influencesList[geo.instanceId];
if (!influences) {
influences = [];
for (var i = 0; i < length; i++) {
influences[i] = [i, 0];
}
influencesList[geo.instanceId] = influences;
}
var attrChannel = attrChannelHash[geo.instanceId];
if (!attrChannel) {
attrChannel = [];
attrChannel.length = 8;
attrChannelHash[geo.instanceId] = attrChannel;
}
for (var i = 0; i < 8; i++) {
var influence = influences[i];
if (influence && influence[1] !== 0) {
if (morphTargets)
vao.removeAttribute('morphTarget' + i);
if (morphNormals && i < 4)
vao.removeAttribute('morphNormal' + i);
}
}
for (var i = 0; i < length; i++) {
var influence = influences[i];
influence[0] = i;
influence[1] = objectInfluences[i];
}
influences.sort(absNumericalSort);
var attrs = shader.attributes;
var attrLen = morphNormals ? 4 : 8;
for (var i = 0; i < attrLen; i++) {
var influence = influences[i];
if (influence) {
var index = influence[0];
var value = influence[1];
if (value) {
if (morphTargets && morphTargets[index]) {
var targetBuffer = glVaoBuffer.morphTargetBuffers[index];
if (!targetBuffer) {
targetBuffer = glVaoBuffer.morphTargetBuffers[index] = glCore_1.GLBuffer.createVertexBuffer(gl, null, gl.STATIC_DRAW);
}
if (attrChannel[i] !== index) {
attrChannel[i] = index;
uploadBufferDatas.push({
buffer: targetBuffer,
data: new Float32Array(morphTargets[index])
});
}
vao.addAttribute(targetBuffer, attrs['morphTarget' + i], gl.FLOAT, false, 0, 0 * 4, 'morphTarget' + i);
}
if (morphNormals && morphNormals[index]) {
var normalBuffer = glVaoBuffer.morphNormalBuffers[index];
if (!normalBuffer) {
normalBuffer = glVaoBuffer.morphNormalBuffers[index] = glCore_1.GLBuffer.createVertexBuffer(gl, null, gl.STATIC_DRAW);
}
if (attrChannel[i] !== index) {
attrChannel[i] = index;
uploadBufferDatas.push({
buffer: normalBuffer,
data: morphNormals[index]
});
}
vao.addAttribute(glVaoBuffer.morphNormalBuffers[index], attrs['morphNormal' + i], gl.FLOAT, false, 0, 0 * 4, 'morphNormal' + i);
}
morphInfluences[i] = value;
continue;
}
}
morphInfluences[i] = 0;
}
shader.uniforms["morphTargetInfluences"] = morphInfluences;
return uploadBufferDatas;
}
function absNumericalSort(a, b) {
return Math.abs(b[1]) - Math.abs(a[1]);
}
WebglRenderer_1.WebglRenderer.registerPlugin('d3', D3Renderer);
......@@ -16493,6 +16588,13 @@ var Mesh3D = (function (_super) {
_this.updateMorphTargets();
return _this;
}
Object.defineProperty(Mesh3D.prototype, "morphTargetInfluences", {
get: function () {
return this._morphTargetInfluences;
},
enumerable: true,
configurable: true
});
Mesh3D.prototype._render = function (renderer) {
if (!this.visible)
return;
......@@ -16502,9 +16604,9 @@ var Mesh3D = (function (_super) {
Mesh3D.prototype.updateMorphTargets = function () {
var morphPositions = this.geometry._morphPositions;
if (morphPositions) {
this.morphTargetInfluences = [];
this._morphTargetInfluences = [];
for (var i = 0; i < morphPositions.length; i++)
this.morphTargetInfluences.push(0);
this._morphTargetInfluences.push(0);
}
};
Mesh3D.prototype.raycast = function (raycaster, intersects) {
......@@ -16560,6 +16662,14 @@ var Mesh3D = (function (_super) {
}
};
;
Mesh3D.prototype.copy = function (source, recursive) {
if (recursive === void 0) { recursive = true; }
_super.prototype.copy.call(this, source, recursive);
if (source.morphTargetInfluences) {
this._morphTargetInfluences = source.morphTargetInfluences.slice();
}
return this;
};
Mesh3D.prototype.clone = function () {
return new Mesh3D(this.geometry, this.material).copy(this);
};
......@@ -21433,7 +21543,7 @@ var VertexArrayObject = (function () {
return this;
};
;
VertexArrayObject.prototype.addAttribute = function (buffer, attribute, type, normalized, stride, start) {
VertexArrayObject.prototype.addAttribute = function (buffer, attribute, type, normalized, stride, start, name) {
this.attributes.push({
buffer: buffer,
attribute: attribute,
......@@ -21441,12 +21551,26 @@ var VertexArrayObject = (function () {
type: type || this.gl.FLOAT,
normalized: normalized || false,
stride: stride || 0,
start: start || 0
start: start || 0,
name: name,
});
this.dirty = true;
return this;
};
;
VertexArrayObject.prototype.removeAttribute = function (name, onlyOne) {
if (onlyOne === void 0) { onlyOne = true; }
var len = this.attributes.length;
for (var i = len - 1; i >= 0; i--) {
var attr = this.attributes[i];
if (attr.name === name) {
this.attributes.splice(i, 1);
if (onlyOne)
break;
}
}
return this;
};
VertexArrayObject.prototype.addIndex = function (buffer) {
this.indexBuffer = buffer;
this.dirty = true;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -2,7 +2,7 @@ import ObjectRenderer from "../2d/renderers/webgl/ObjectRenderer";
import { WebglRenderer } from "../2d/renderers/WebglRenderer";
import { Camera } from "./cameras/Camera";
import { LightsConfig } from "./Scene3D";
import { GLShader, GLBuffer } from "../glCore";
import { GLShader, GLBuffer, VertexArrayObject } from "../glCore";
import { Mesh3D } from "./Mesh3D";
import { BaseShader } from "./shaders/BaseShader";
import { LightShader } from "./shaders/LightShader";
......@@ -12,7 +12,7 @@ import { BLEND_MODES } from "../2d/const";
import { BatchBuffer } from "../2d/renderers/webgl/BatchBuffer";
import { BaseMaterial, RenderSideType } from "./materials/BaseMaterial";
import { getCusShader } from "./shaders/getCusShader";
import { Geometry } from ".";
import { Geometry, VaoBufferInt } from ".";
//需要管理渲染的状态 resetToDefault resetTo3D
......@@ -141,23 +141,23 @@ export class D3Renderer extends ObjectRenderer {
}
//有索引
if (geo._indices) glVaoBuffer.indexBuffer = GLBuffer.createIndexBuffer(gl, null, gl.STATIC_DRAW);
//有变形顶点
if (geo._morphPositions) {//长度可以根据位置,还是根据
glVaoBuffer.morphTargetBuffers = [];mesh.morphTargetInfluences.length
for (let m = 0; m < geo._morphPositions.length; m++) {
glVaoBuffer.morphTargetBuffers.push(
GLBuffer.createVertexBuffer(gl, null, gl.STATIC_DRAW)
)
}
//TODO 有变形顶点,数据直接干进去,有性能问题再说 ,还是先不绑了,影响下面的vao
if (geo._morphPositions) {//长度可以根据位置,还是根据,可能很多,用到时再建
glVaoBuffer.morphTargetBuffers = []; //mesh.morphTargetInfluences.length
// for (let m = 0; m < geo._morphPositions.length; m++) {
// glVaoBuffer.morphTargetBuffers.push(
// GLBuffer.createVertexBuffer(gl, /*geo._morphPositions[m]*/null, gl.STATIC_DRAW)
// )
// }
}
//有变形法线
if (geo._morphNormals) {
glVaoBuffer.morphNormalBuffers = [];
for (let m = 0; m < geo._morphNormals.length; m++) {
glVaoBuffer.morphNormalBuffers.push(
GLBuffer.createVertexBuffer(gl, null, gl.STATIC_DRAW)
)
}
// for (let m = 0; m < geo._morphNormals.length; m++) {
// glVaoBuffer.morphNormalBuffers.push(
// GLBuffer.createVertexBuffer(gl, /*geo._morphNormals[m]*/null, gl.STATIC_DRAW)
// )
// }
}
//计算一次,打包所有的顶点属性,位置,颜色,uv,法线
......@@ -181,33 +181,53 @@ export class D3Renderer extends ObjectRenderer {
if (attrs.aNormal) vao.addAttribute(glVaoBuffer.attrBuffer, attrs.aNormal, gl.FLOAT, false, geo._vertByteSize, 8 * 4);
//索引看情况加
if (geo._indices) vao.addIndex(glVaoBuffer.indexBuffer);
//变形顶点,最多8个,有法线的话传4个
if (geo._morphPositions) {
//变形数据,首次直接addAttribute
var uploadBufferDatas: UploadBufferData[];
if (mesh.morphTargetInfluences && mat.morphTargets) {
uploadBufferDatas = addMorphtargetsAttr(
mesh.morphTargetInfluences,
geo,
glVaoBuffer,
vao,
curShader,
gl
)
}
//变形法线
// 首次需要绑定buffer到vao
// 首次需要绑定buffer到vao,先绑定vao再绑定buffer和上传数据(upload里传false),其实bindVao貌似已经绑定过了,再说吧
this.renderer.bindVao(vao);
//所有数据绑定buffer,其实可以在上面构造GLBuffer里传数据,现在还是单独处理吧,这样判断比较多
//需要分别绑定
glVaoBuffer.attrBuffer.upload(geo._attrBuffer.vertices, 0, false);
glVaoBuffer.attrBuffer.upload(geo._attrBuffer.vertices, 0, false);//首次还是bind吧,必须bind,否则buffer溢出
//有索引才改
if (geo._indices) glVaoBuffer.indexBuffer.upload(geo._indices, 0, false);
//变形顶点
if (geo._morphPositions) {
var len = geo._morphNormals ? 4 : 8;
for (let n = 0; n < len; n++) {
glVaoBuffer.morphTargetBuffers[n]
}
}
if (geo._indices) glVaoBuffer.indexBuffer.upload(geo._indices, 0, false);//首次还是bind吧
//还得在这里做数据的变形
if (uploadBufferDatas) uploadBufferDatas.forEach((e) => {
e.buffer.upload(e.data, 0, false);
})
} else {
//变形数据
var uploadBufferDatas: UploadBufferData[];
if (mesh.morphTargetInfluences && mat.morphTargets) {
uploadBufferDatas = addMorphtargetsAttr(
mesh.morphTargetInfluences,
geo,
glVaoBuffer,
vao,
curShader,
gl
)
}
this.renderer.bindVao(vao);
//不修改,估计都不要变,需要修改时候
// glVaoBuffer.attrBuffer.upload(glVaoBuffer._attrBuffer.vertices, 0, true)
// glVaoBuffer.indexBuffer.upload(glVaoBuffer._indexBuffer, 0, true)
//变形的数据可能传入的会改变,所以需要upload,还要重新修改数据,有removeAttribute的情况,TODO
//变形的数据可能传入的会改变,所以需要upload,还要重新修改数据,有removeAttribute的情况,TODO
//还得在这里做数据的变形,不绑定
if (uploadBufferDatas) uploadBufferDatas.forEach((e) => {
e.buffer.upload(e.data, 0, true);
})
}
//根据材质切换渲染面
if (mat.side == RenderSideType.DoubleSide) {
......@@ -252,8 +272,153 @@ function packGeometry(geo: Geometry): void {
}
}
function updateMorphtargets(morphTargetInfluences:number[],geo:Geometry,){
interface UploadBufferData {
//几何上的GLbuffer的索引
buffer: GLBuffer,
//几何上buffer的数据
data: any//Float32Array | number[],
//是否要绑定
// dontBind: boolean,
}
//每个几何的权重缓存
const influencesList = {};
//每个几何的通道对应数据索引
const attrChannelHash = {}
//给uniform传值用
var morphInfluences = new Float32Array(8);
/**
* 更新变形数据,考虑是否要变动attribute,只有
* 返回要upload的数据
* @param objectInfluences mesh上的权重数组
* @param geo 几何
* @param vao
*/
function addMorphtargetsAttr(
objectInfluences: number[],
geo: Geometry,
glVaoBuffer: VaoBufferInt,
vao: VertexArrayObject,
shader: GLShader,
gl: WebGLRenderingContext,
): UploadBufferData[] {
var morphTargets = geo._morphPositions;
var morphNormals = geo._morphNormals;
var length = objectInfluences.length;//权重数据总长度,基本不会被手动修改,到时排序只取权重大的,最多8
//记录需要修改的数据
var uploadBufferDatas: UploadBufferData[] = [];
//原来几何上的权重,第一个元素标识数据索引,第二个元素标识值,第三个标识现在用的通道
var influences: [number, number][] = influencesList[geo.instanceId];
//如果原先不存在
if (!influences) {
influences = [];
for (var i = 0; i < length; i++) {
influences[i] = [i, 0];
}
influencesList[geo.instanceId] = influences;
}
//通道对应的数据,确定哪些通道的数据要重新upload
var attrChannel: number[] = attrChannelHash[geo.instanceId];
if (!attrChannel) {
attrChannel = [];//通道对应,数据索引
attrChannel.length = 8;
attrChannelHash[geo.instanceId] = attrChannel;
}
//vao上挂着有变形数据的移除,讲道理也是最多8
for (var i = 0; i < 8/*length*/; i++) {
var influence = influences[i];
if (influence && influence[1] !== 0) {
if (morphTargets) vao.removeAttribute('morphTarget' + i);
if (morphNormals && i < 4) vao.removeAttribute('morphNormal' + i);
}
}
//重新处理变形数据,这个得排所有的
for (var i = 0; i < length; i++) {
var influence = influences[i];
influence[0] = i;
influence[1] = objectInfluences[i];
}
//按权重大小排序,大的优先
influences.sort(absNumericalSort);
var attrs = shader.attributes;
//只取8个,不传着色器里计算并不会报错
//有法线时只用4个,
var attrLen = morphNormals ? 4 : 8;
for (var i = 0; i < attrLen; i++) {
var influence = influences[i];
if (influence) {
//索引
var index = influence[0];
var value = influence[1];
if (value) {
if (morphTargets && morphTargets[index]) {
//buffer没有就加
let targetBuffer = glVaoBuffer.morphTargetBuffers[index];
if (!targetBuffer) {
targetBuffer = glVaoBuffer.morphTargetBuffers[index] = GLBuffer.createVertexBuffer(gl, null, gl.STATIC_DRAW)
}
//记录需要修改传数据,通道值对应的buffer值不一致时,需要upload
if (attrChannel[i] !== index) {
attrChannel[i] = index;
uploadBufferDatas.push({
buffer: targetBuffer,
data: new Float32Array(morphTargets[index]) //data.vertices
})
}
vao.addAttribute(
targetBuffer,
attrs['morphTarget' + i],
gl.FLOAT,
false,
0,//3 * 4,
0 * 4,
'morphTarget' + i,
)
}
if (morphNormals && morphNormals[index]) {//法线只有4个
//buffer没有就加
let normalBuffer = glVaoBuffer.morphNormalBuffers[index];
if (!normalBuffer) {
normalBuffer = glVaoBuffer.morphNormalBuffers[index] = GLBuffer.createVertexBuffer(gl, null, gl.STATIC_DRAW)
}
//记录需要修改传数据,通道值对应的buffer值不一致时,需要upload
if (attrChannel[i] !== index) {
attrChannel[i] = index;
uploadBufferDatas.push({
buffer: normalBuffer,
data: morphNormals[index]
})
}
vao.addAttribute(
glVaoBuffer.morphNormalBuffers[index],
attrs['morphNormal' + i],
gl.FLOAT,
false,
0,// 3 * 4,
0 * 4,
'morphNormal' + i,
)
}
morphInfluences[i] = value;
continue;
}
}
morphInfluences[i] = 0;
}
//着色器修改
shader.uniforms["morphTargetInfluences"] = morphInfluences;
//需要修改数据的
return uploadBufferDatas
}
function absNumericalSort(a: [number, number], b: [number, number]) {
return Math.abs(b[1]) - Math.abs(a[1]);
}
interface renderObjInt {
......
......@@ -137,7 +137,7 @@ export class Geometry extends HashObject {
/**
* 根据webglRendererId存一个,vao还需要根据着色器程序缓存
*/
interface VaoBufferInt {
export interface VaoBufferInt {
/**
* 索引
*/
......
......@@ -15,11 +15,12 @@ const tempPoint = new Vector3();
export class Mesh3D extends Object3D {
/**
* 外部可设置
* 用于变形权重,
* 最大长度8
* 用于变形权重,只能获取,修改只能内部修改
*/
public morphTargetInfluences: number[];
private _morphTargetInfluences: number[];
get morphTargetInfluences() {
return this._morphTargetInfluences;
}
//这个暂时不知道有啥用,到时看three的
// morphTargetDictionary
constructor(
......@@ -38,9 +39,9 @@ export class Mesh3D extends Object3D {
updateMorphTargets() {
var morphPositions = this.geometry._morphPositions;
if (morphPositions) {
this.morphTargetInfluences = [];
this._morphTargetInfluences = [];
//根据morphPositions的长度来定权重长度
for (var i = 0; i < morphPositions.length; i++) this.morphTargetInfluences.push(0);
for (var i = 0; i < morphPositions.length; i++) this._morphTargetInfluences.push(0);
}
}
......@@ -123,7 +124,17 @@ export class Mesh3D extends Object3D {
}
}
};
copy(source: Mesh3D, recursive: boolean = true) {
super.copy(source, recursive);
if (source.morphTargetInfluences) {//变形的数据
this._morphTargetInfluences = source.morphTargetInfluences.slice();
}
//暂时不用
// if ( source.morphTargetDictionary !== undefined ) {
// this.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary );
// }
return this
}
/**
*
*/
......
......@@ -152,7 +152,7 @@ export class VertexArrayObject {
* @param start {Number}
* @param name {string} 名字,用于移除,否则不需要传
*/
public addAttribute(buffer, attribute, type?, normalized?, stride?, start?, name?: number) {
public addAttribute(buffer, attribute, type?, normalized?, stride?, start?, name?: string) {
this.attributes.push({
buffer: buffer,
attribute: attribute,
......
......@@ -45,7 +45,7 @@
<canvas id="canvas" style="width: 100%;height: 100%"></canvas>
</div>
<!-- 帧率检测 -->
<!-- <script src="js/stats.js"></script> -->
<script src="//yun.duiba.com.cn/db_games/libs0924/stats.js"></script>
</body>
<script>
window.addEventListener("load", async function () {
......@@ -155,13 +155,28 @@
//立方体几何
var geo = new FYGE.BoxGeometry(4, 4, 4)
geo._morphPositions = []
for (let i = 0; i < 1; i++) {
let v = geo._vertices.slice();
// console.log(v)
for (var j = 0; j < v.length; j++) {
// v[j] += 2
v[j] *= 2
}
geo._morphPositions.push(v)
}
console.log()
// console.log( new Float32Array(v))
//光照材质
var matL = new FYGE.LightMaterial();
matL.map = texture;//加个贴图
matL.side = 2
// matL.color=0xff0000
// matL.alpha=0.5
// matL.wireframe=true
var m = scene.addChild(new FYGE.Mesh3D(geo, matL))
matL.morphTargets = true
// m.morphTargetInfluences = [0]
m.position.set(0, 0, 0)
// m.scale.set(1.3, 1.3, 1.3)
// m.rotation.set(0,Math.PI/12,0)
......@@ -171,6 +186,16 @@
// m.visible = false;
m.position.y = 0
m.addEventListener(FYGE.MouseEvent.CLICK, () => { console.log(123123) }, this)
let mm = m;
m.addEventListener(FYGE.Event.ENTER_FRAME, () => {
var morph = Math.abs(Math.sin(mm.rotation.y)) * 1
mm.morphTargetInfluences[0] = morph
// mm.morphTargetInfluences[1] = morph
// mm.morphTargetInfluences[2] = morph
// mm.morphTargetInfluences[3] = morph
})
//不带光找的材质
var mat1 = new FYGE.BaseMaterial();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment