diff options
author | pathorn@chromium.org <pathorn@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-15 00:33:32 +0000 |
---|---|---|
committer | pathorn@chromium.org <pathorn@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-15 00:33:32 +0000 |
commit | 1f226797e6880b7885c8866a8d7309b1c3aa44fc (patch) | |
tree | abdce4c4772762854dede9deabe45c47d339e163 /o3d/samples | |
parent | 9b3fc53cf3e31fd61e24442fbdcadf8da99f56ed (diff) | |
download | chromium_src-1f226797e6880b7885c8866a8d7309b1c3aa44fc.zip chromium_src-1f226797e6880b7885c8866a8d7309b1c3aa44fc.tar.gz chromium_src-1f226797e6880b7885c8866a8d7309b1c3aa44fc.tar.bz2 |
o3djs: Recommit effect.js for skinning shader.
Also fixes skinning error in FF4 when getParameter(MAX_VERTEX_UNIFORM_VECTORS)
gives GL_INVALID_ENUM.
Review URL: http://codereview.chromium.org/3348006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@59469 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/samples')
-rw-r--r-- | o3d/samples/o3d-webgl/skin.js | 3 | ||||
-rw-r--r-- | o3d/samples/o3djs/effect.js | 92 |
2 files changed, 86 insertions, 9 deletions
diff --git a/o3d/samples/o3d-webgl/skin.js b/o3d/samples/o3d-webgl/skin.js index 1e9455c..abd77c6 100644 --- a/o3d/samples/o3d-webgl/skin.js +++ b/o3d/samples/o3d-webgl/skin.js @@ -412,6 +412,9 @@ o3d.SkinEval.getMaxNumBones = function(obj) { // The value must be at least 128. See glUniform. var gl = obj.gl; var maxVertexUniformVectors = gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS); + if (!maxVertexUniformVectors) { + maxVertexUniformVectors = 128; + } return Math.floor((maxVertexUniformVectors - 32) / 3); }; diff --git a/o3d/samples/o3djs/effect.js b/o3d/samples/o3djs/effect.js index 76867e8..221d781 100644 --- a/o3d/samples/o3djs/effect.js +++ b/o3d/samples/o3djs/effect.js @@ -409,10 +409,11 @@ o3djs.effect.getLanguage = function() { * @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 @@ o3djs.effect.buildAttributeDecls = 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,6 +845,21 @@ o3djs.effect.buildStandardShaderString = function(material, 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. @@ -906,6 +928,17 @@ o3djs.effect.buildStandardShaderString = function(material, }; /** + * 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 @@ o3djs.effect.buildStandardShaderString = function(material, var buildConstantShaderString = function(material, descriptions) { descriptions.push('constant'); return buildCommonVertexUniforms() + + buildSkinningUniforms() + buildVertexDecls(material, false, false) + p.beginVertexShaderMain() + positionVertexShaderCode() + @@ -994,6 +1028,7 @@ o3djs.effect.buildStandardShaderString = function(material, descriptions.push('lambert'); return buildCommonVertexUniforms() + buildLightingUniforms() + + buildSkinningUniforms() + buildVertexDecls(material, true, false) + p.beginVertexShaderMain() + p.buildUVPassthroughs(material) + @@ -1041,6 +1076,7 @@ o3djs.effect.buildStandardShaderString = function(material, descriptions.push('phong'); return buildCommonVertexUniforms() + buildLightingUniforms() + + buildSkinningUniforms() + buildVertexDecls(material, true, true) + p.beginVertexShaderMain() + p.buildUVPassthroughs(material) + @@ -1099,6 +1135,7 @@ o3djs.effect.buildStandardShaderString = function(material, descriptions.push('phong'); return buildCommonVertexUniforms() + buildLightingUniforms() + + buildSkinningUniforms() + buildVertexDecls(material, true, true) + p.beginVertexShaderMain() + p.buildUVPassthroughs(material) + @@ -1149,9 +1186,27 @@ o3djs.effect.buildStandardShaderString = function(material, * @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 @@ o3djs.effect.buildStandardShaderString = function(material, * @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 @@ o3djs.effect.buildStandardShaderString = function(material, */ var buildVertexDecls = function(material, diffuse, specular) { return p.buildAttributeDecls( - material, diffuse, specular, bumpSampler) + + material, diffuse, specular, bumpSampler, skinning) + p.buildVaryingDecls( material, diffuse, specular, bumpSampler); }; |