Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Unified Diff: o3djs/effect.js

Issue 3348006: o3djs: Recommit effect.js for skinning shader.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/o3d/samples/
Patch Set: '' Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « o3d-webgl/skin.js ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: o3djs/effect.js
===================================================================
--- o3djs/effect.js (revision 59332)
+++ o3djs/effect.js (working copy)
@@ -409,10 +409,11 @@
* @param {boolean} specular Whether to include stuff for diffuse
* calculations.
* @param {boolean} bumpSampler Whether there is a bump sampler.
+ * @param {boolean} skinning Whether this mesh has a skin.
* @return {string} The code for the declarations.
*/
o3djs.effect.buildAttributeDecls =
- function(material, diffuse, specular, bumpSampler) {
+ function(material, diffuse, specular, bumpSampler, skinning) {
var str = o3djs.effect.BEGIN_IN_STRUCT +
o3djs.effect.ATTRIBUTE + o3djs.effect.FLOAT4 + ' ' + 'position' +
o3djs.effect.semanticSuffix('POSITION') + ';\n';
@@ -420,6 +421,12 @@
str += o3djs.effect.ATTRIBUTE + o3djs.effect.FLOAT3 + ' ' + 'normal' +
o3djs.effect.semanticSuffix('NORMAL') + ';\n';
}
+ if (skinning) {
+ str += o3djs.effect.ATTRIBUTE + o3djs.effect.FLOAT4 + ' influenceWeights' +
+ o3djs.effect.semanticSuffix('BLENDWEIGHT') + ';\n';
+ str += o3djs.effect.ATTRIBUTE + o3djs.effect.FLOAT4 + ' influenceIndices' +
+ o3djs.effect.semanticSuffix('BLENDINDICES') + ';\n';
+ }
str += o3djs.effect.buildTexCoords(material, false) +
o3djs.effect.buildBumpInputCoords(bumpSampler) +
o3djs.effect.END_STRUCT;
@@ -838,7 +845,22 @@
var p = o3djs.effect;
var bumpSampler = material.getParam('bumpSampler');
var bumpUVInterpolant;
+ var skinning;
+ var maxSkinInfluences = 4;
+
+ // Hardcode reasonable maximum for number of skinning uniforms.
+ // glsl: Table 6.19: minimum MAX_VERTEX_UNIFORM_VECTORS is 128.
+ // (DX9 requires a minimum of 256, so not a problem in o3d).
+ var maxSkinUniforms = 36 * 3;
+ if (o3djs.base.o3d && o3djs.base.o3d.SkinEval &&
+ o3djs.base.o3d.SkinEval.getMaxNumBones) {
+ maxSkinUniforms = o3d.SkinEval.getMaxNumBones(material) * 3;
+ skinning = true;
+ } else {
+ skinning = false;
+ }
+
/**
* Extracts the texture type from a texture param.
* @param {!o3d.ParamTexture} textureParam The texture parameter to
@@ -906,6 +928,17 @@
};
/**
+ * If skinning is enabled, builds the bone matrix uniform variables needed
+ * for skinning. Otherwise, returns the empty string.
+ * @return {string} The effect code for skinning uniforms.
+ */
+ var buildSkinningUniforms = function() {
+ return skinning ? 'uniform ' + p.FLOAT4 + ' boneToWorld3x4' +
+ '[' + maxSkinUniforms + '];\n' +
+ 'uniform float usingSkinShader;\n' : '';
+ };
+
+ /**
* Builds uniform parameters for a given color input. If the material
* has a sampler parameter, a sampler uniform is created, otherwise a
* float4 color value is created.
@@ -967,6 +1000,7 @@
var buildConstantShaderString = function(material, descriptions) {
descriptions.push('constant');
return buildCommonVertexUniforms() +
+ buildSkinningUniforms() +
buildVertexDecls(material, false, false) +
p.beginVertexShaderMain() +
positionVertexShaderCode() +
@@ -994,6 +1028,7 @@
descriptions.push('lambert');
return buildCommonVertexUniforms() +
buildLightingUniforms() +
+ buildSkinningUniforms() +
buildVertexDecls(material, true, false) +
p.beginVertexShaderMain() +
p.buildUVPassthroughs(material) +
@@ -1041,6 +1076,7 @@
descriptions.push('phong');
return buildCommonVertexUniforms() +
buildLightingUniforms() +
+ buildSkinningUniforms() +
buildVertexDecls(material, true, true) +
p.beginVertexShaderMain() +
p.buildUVPassthroughs(material) +
@@ -1099,6 +1135,7 @@
descriptions.push('phong');
return buildCommonVertexUniforms() +
buildLightingUniforms() +
+ buildSkinningUniforms() +
buildVertexDecls(material, true, true) +
p.beginVertexShaderMain() +
p.buildUVPassthroughs(material) +
@@ -1149,9 +1186,27 @@
* @return {string} The code for the vertex shader.
*/
var positionVertexShaderCode = function() {
- return ' ' + p.VERTEX_VARYING_PREFIX + 'position = ' +
- p.mul(p.ATTRIBUTE_PREFIX +
- 'position', 'worldViewProjection') + ';\n';
+ var attribute_position = p.ATTRIBUTE_PREFIX + 'position';
+ if (skinning) {
+ return ' ' + p.FLOAT4 + ' weightedpos = ' + attribute_position + ';\n' +
+ ' for (int i = 0; i < ' + maxSkinInfluences + '; i++) {\n' +
+ ' ' + p.FLOAT4 + ' temp = ' + p.FLOAT4 + '(' +
+ 'dot(boneToWorld3x4[int(influenceIndices[i] * 3.0)], ' +
+ attribute_position + '),\n' +
+ ' dot(boneToWorld3x4[int(influenceIndices[i] * 3.0 + 1.0)], ' +
+ attribute_position + '),\n' +
+ ' dot(boneToWorld3x4[int(influenceIndices[i] * 3.0 + 2.0)], ' +
+ attribute_position + '),\n' +
+ ' 1.0);\n' +
+ ' weightedpos += usingSkinShader * influenceWeights[i] * ' +
+ '(temp - ' + attribute_position + ');\n' +
+ ' }\n' +
+ ' ' + p.VERTEX_VARYING_PREFIX + 'position = ' +
+ p.mul('weightedpos', 'worldViewProjection') + ';\n';
+ } else {
+ return ' ' + p.VERTEX_VARYING_PREFIX + 'position = ' +
+ p.mul(attribute_position, 'worldViewProjection') + ';\n';
+ }
};
/**
@@ -1159,10 +1214,29 @@
* @return {string} The code for the vertex shader.
*/
var normalVertexShaderCode = function() {
- return ' ' + p.VERTEX_VARYING_PREFIX + 'normal = ' +
- p.mul(p.FLOAT4 + '(' +
- p.ATTRIBUTE_PREFIX +
- 'normal, 0)', 'worldInverseTranspose') + '.xyz;\n';
+ var attribute_normal = p.ATTRIBUTE_PREFIX + 'normal';
+ if (skinning) {
+ return ' ' + p.FLOAT3 + ' weightednorm = ' + attribute_normal + ';\n' +
+ ' for (int i = 0; i < ' + maxSkinInfluences + '; i++) {\n' +
+ ' ' + p.FLOAT3 + ' temp = ' + p.FLOAT3 + '(' +
+ 'dot(boneToWorld3x4[int(influenceIndices[i] * 3.0)].xyz, ' +
+ attribute_normal + '),\n' +
+ ' dot(boneToWorld3x4[int(influenceIndices[i] * 3.0 + 1.0)].xyz, ' +
+ attribute_normal + '),\n' +
+ ' dot(boneToWorld3x4[int(influenceIndices[i] * 3.0 + 2.0)].xyz, ' +
+ attribute_normal + '));\n' +
+ ' weightednorm += usingSkinShader * influenceWeights[i] * ' +
+ '(temp - ' + attribute_normal + ');\n' +
+ ' }\n' +
+ ' ' + p.VERTEX_VARYING_PREFIX + 'normal = ' +
+ p.mul(p.FLOAT4 + '(' + 'weightednorm' + ', 0)',
+ 'worldInverseTranspose') + '.xyz;\n';
+ } else {
+ return ' ' + p.VERTEX_VARYING_PREFIX + 'normal = ' +
+ p.mul(p.FLOAT4 + '(' +
+ attribute_normal + ', 0)', 'worldInverseTranspose') +
+ '.xyz;\n';
+ }
};
/**
@@ -1238,7 +1312,7 @@
*/
var buildVertexDecls = function(material, diffuse, specular) {
return p.buildAttributeDecls(
- material, diffuse, specular, bumpSampler) +
+ material, diffuse, specular, bumpSampler, skinning) +
p.buildVaryingDecls(
material, diffuse, specular, bumpSampler);
};
« no previous file with comments | « o3d-webgl/skin.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698