Jump to content
• Advertisement  # SingularOne

Member

11

100 Neutral

## About SingularOne

• Rank
Member
1. The problem was i'm using 3-component vectors for all my lighting calculation, so vertex w-component was modified by rotation matrix correctly, but wasn't affecting lighting. so i should do it manually.
2. yes, i've noticed before, it works ok if bone1 weight = 1.0 and bone2 is ineffective, but i do normalize resulting normal and tangent vec3 T = normalize(gl_NormalMatrix * normalize(t2)); vec3 N = normalize(gl_NormalMatrix * normalize(n2)); vec3 B = cross(N, T); and even if i remove normal rotation, problem doesn't go away. also i modified code so second bone weight = 1.0 - FirstBoneWeight (because outside shader my program actually calculates weights for all affecting bones, but in examples i use to test it's always <= 2 bones affecting vertex); and to avoid wasting your time with snippets: full code of stuff that actually affects that problem, [spoiler] #version 110 attribute vec4 Bones; attribute vec3 Tangent; uniform mat4 BonesMat; varying vec3 ld; varying vec3 eye; varying vec4 V; void main() { V = gl_Vertex; vec3 n2 = gl_Normal; vec3 t2 = Tangent; if(Bones.x >= 0.0) { mat4 tmat = BonesMat[int(Bones.x)]; mat3 nmat = mat3(tmat.xyz, tmat.xyz, tmat.xyz); V = tmat * gl_Vertex * Bones.z; n2 = nmat * gl_Normal * Bones.z; t2 = nmat * Tangent * Bones.z; if(Bones.y >= 0.0) { tmat = BonesMat[int(Bones.y)]; nmat = mat3(tmat.xyz, tmat.xyz, tmat.xyz); V += tmat * gl_Vertex * (1.0-Bones.z); n2 += nmat * gl_Normal * (1.0-Bones.z); t2 += nmat * Tangent * (1.0-Bones.z); } } gl_TexCoord = gl_MultiTexCoord0; V = gl_ModelViewMatrix * V; vec3 T = -normalize(gl_NormalMatrix * normalize(t2)); vec3 N = normalize(gl_NormalMatrix * normalize(n2)); vec3 B = cross(N, T); vec3 lv = (gl_LightSource.position - V).xyz; ld.x = dot(lv, B); ld.y = dot(lv, T); ld.z = dot(lv, N); vec3 vt = -V.xyz; eye.x = dot(vt, B); eye.y = dot(vt, T); eye.z = dot(vt, N); gl_Position = gl_ProjectionMatrix * V; } [/spoiler]
3. yes it looks like problem is in my shader. here shader that i found in nvidia example of hardware skinning: attribute vec4 position; attribute vec3 normal; attribute vec4 weight; attribute vec4 index; attribute float numBones; uniform mat4 boneMatrices; uniform vec4 color; uniform vec4 lightPos; void main() { vec4 transformedPosition = vec4(0.0); vec3 transformedNormal = vec3(0.0); vec4 curIndex = index; vec4 curWeight = weight; for (int i = 0; i < int(numBones); i++) { mat4 m44 = boneMatrices[int(curIndex.x)]; // transform the offset by bone i transformedPosition += m44 * position * curWeight.x; mat3 m33 = mat3(m44.xyz, m44.xyz, m44.xyz); // transform normal by bone i transformedNormal += m33 * normal * curWeight.x; // shift over the index/weight variables, this moves the index and // weight for the current bone into the .x component of the index // and weight variables curIndex = curIndex.yzwx; curWeight = curWeight.yzwx; } gl_Position = gl_ModelViewProjectionMatrix * transformedPosition; transformedNormal = normalize(transformedNormal); gl_FrontColor = dot(transformedNormal, lightPos.xyz) * color; } and significant part of my adoption(maximum 2 bones affecting vertex, 1st one is always most effective, so 2nd affecting bone might exist only if 1st one is): V = gl_Vertex; vec3 n2 = gl_Normal; vec3 t2 = Tangent; if(Bones.x >= 0.0)//Bone1 ID { mat4 tmat = BonesMat[int(Bones.x)]; //Bone matrix mat3 nmat = mat3(tmat.xyz, tmat.xyz, tmat.xyz); V = tmat * gl_Vertex * Bones.z; //Bones.z - Bone 1 weight n2 = nmat * gl_Normal * Bones.z; t2 = nmat * Tangent * Bones.z; if(Bones.y >= 0.0)//Bone2 ID { tmat = BonesMat[int(Bones.y)]; nmat = mat3(tmat.xyz, tmat.xyz, tmat.xyz); V += tmat * gl_Vertex * Bones.w; //Bones.w - Bone2 weight n2 += nmat * gl_Normal * Bones.w; t2 += nmat * Tangent * Bones.w; } } Further - using V,N,T as regular; result: rotation\translation is alright. problem: lighting glitches. then i move camera away from object - vertices that affected by 2 bones become dark with the distance(lambert decreasing).
4. [color="#1C2837"] haegarr, i don't know how to thank you for your effort, your method works fine and it's much more efficient [color="#1c2837"] SillyCow, thank you too for pointing out the part i misunderstood. [color="#1c2837"]and yeah, i've alredy noticed, that it's not really good to rotate normals.
5. Ok, fixed by bMat *= oMat; oMat2 *= bMat; bMat = oMat2;//(or just pass oMat2 to shader) (equialent of -T * R * T) but i'm not sure if it's ok to use such a matrix for tangent and normal? looks ok, but just want to know.
6. Thanks for your replies. Well i've tried to do it like haegarr described: //Origins oMat.make_identity(); oMat2.make_identity(); oMat.element(0, 3) = -ox; oMat.element(1, 3) = -oy; oMat.element(2, 3) = -oz; oMat2.element(0, 3) = ox; oMat2.element(1, 3) = oy; oMat2.element(2, 3) = oz; //Rotation(tested) bMat.make_identity(); bMat.element(0, 0) = cos(rx) * cos(ry); bMat.element(1, 0) = -cos(rz) * sin(rx) - cos(rx)*sin(ry)*sin(rz); bMat.element(2, 0) = cos(rx) * cos(rz) * sin(ry) + sin(rx) * sin(rz);; bMat.element(0, 1) = cos(ry) * sin(rx); bMat.element(1, 1) = cos(rx) * cos(rz) - sin(rx)*sin(ry)*sin(rz); bMat.element(2, 1) = cos(rz) * sin(rx) * sin(ry) - cos(rx) * sin(rz); bMat.element(0, 2) = -sin(ry); bMat.element(1, 2) = cos(ry) * sin(rz); bMat.element(2, 2) = cos(ry) * cos(rz); //Bone translation bMat.element(0, 3) = translation.x; bMat.element(1, 3) = translation.y; bMat.element(2, 3) = translation.z; //M := R * T(-c) + T© ?? bMat *= oMat; bMat += oMat2; and rotation\translation is now rigth, but for some reason i[color="#8b0000"]t's about 2x weaker than it should be and it looks like it scales vertices a bit then rotating
7. Hey, would you help me a bit? I'm struggling with making matrices to rotate about point. My rotation part of the matrix construction looks like that: boneMatrices[offs + 0] = cos(rx) * cos(ry); boneMatrices[offs + 1] = -cos(rz) * sin(rx) - cos(rx)*sin(ry)*sin(rz); boneMatrices[offs + 2] = cos(rx) * cos(rz) * sin(ry) + sin(rx) * sin(rz); boneMatrices[offs + 4] = cos(ry) * sin(rx); boneMatrices[offs + 5] = cos(rx) * cos(rz) - sin(rx)*sin(ry)*sin(rz); boneMatrices[offs + 6] = cos(rz) * sin(rx) * sin(ry) - cos(rx) * sin(rz); boneMatrices[offs + 8] = -sin(ry); boneMatrices[offs + 9] = cos(ry) * sin(rz); boneMatrices[offs + 10] = cos(ry) * cos(rz); I pass origin for rotation instead of scaling part of the matrix, and then, in vertex shader i do: 1) subtract origin from vertex 2) rotate vertex 3) add origin to vertex It works, but it sucks. too much operations, ugly code; I want to pass to my shader matrices that already do rotation about specific point. but really i need someone's help here. how can i make above matrix to rotate about specific point? i couldn't find any descriprion adoptable in my case. i use opengl, if it matters.
8. http://trueimages.ru...7d72e241752.png Screenshot of how it looks on random bunch of geometry i use to test.
9. Thanks for helpful reply, i fixed that problem, but there's one more(i thought it will go away with first one). So lighting with this algorithm is not correct. Diffuse and Specular seems ok on flat horizontal(or close to flat) surfaces, but on more complex geometry it's obviously wrong, like: specular and diffuse light on the side opposite to light, camera movement affects affects specular too much et cetera... What could be wrong? It look like shader is ok(i tried different examples and faced simillar issues), it looks the same even if i pass light position using glLightfv(GL_LIGHT0, GL_POSITION, LigthData);. So light now stays still, but acts weird. Any idea why?
10. Hey, can i ask you for a little help finding mistake? The problem is then i'm passing my light's world coordinates to fragment shader - light is moving with camera, but wait... if i multiply it's position with gl_ModelViewMatrix or gl_ModelViewMatrixInverse, it doesn't help it just acting really weird(with gl_ModelViewMatrix it increases fragment color then i'm rotating camera down) , here are simplified examples: Vertex: varying vec4 V; varying vec4 N; void main() { gl_TexCoord = gl_MultiTexCoord0; V = gl_ModelViewMatrix * gl_Vertex; N = vec4(normalize(gl_NormalMatrix * gl_Normal), 1.0); gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex; } Fragment: uniform sampler2D colorMap; uniform vec4 Ambient, Specular, lightPos, camPos; varying vec4 V; varying vec4 N; void main (void) { vec4 lightDir = lightPos - V; vec4 camDir = normalize(camPos - V); lightDir = normalize(lightDir); vec4 halfVec = normalize(camDir + lightDir); vec4 Final; float Lambert = dot(N, lightDir); float Nhalf = 0.0; if(Lambert > 0.0) { Nhalf = pow(max( dot( halfVec, N), 0.0 ), 64.0); } Final = Ambient + Nhalf * Specular; gl_FragColor = texture2D( colorMap, gl_TexCoord.st)*Lambert + Final; }
11. Hello. I'm trying to recreate LightWave Bone animation in my program, but i have some trouble calculating bone weights for vertices affected by multiple bones without weight maps. I did some research, i know about that topic: http://www.gamedev.n...nesweight-maps/ and i'm a member of LWP on yahoo. But it didn't help much. Because modern LightWave(i'm using 9.6) animation system is weird as hell. Here's abstract representaion of how i'm trying to calculate bone weights: void NormalizeArray(float* &_Array, unsigned int _Count) { float WSum = 0.0f; for(unsigned int f = 0; f < _Count; f++) WSum += abs(_Array[f]); for(unsigned int f = 0; f < _Count; f++) _Array[f] /= WSum; } unsigned int ACount = 0; float temp_weight[Num_Bones]; for(int b = 0; b < Num_Bones; b++) { Bone.distance = Dist_PtS(bone, vertex); if(Bone.distance < Bone.Min_Range) temp_weigth[ACount] = 1.0 - Bone.distance/Bone.Min_Range; else temp_weigth[ACount] = 0; //Add faloff later ACount++; } NormalizeArray(temp_weight, ACount); //So now Array should store multiplier for every bone affecting current vertice; Rest Length multiplication is off. Min and Max range are 42. No weight maps. All Bones strength is 100%. I'm not sure if it's correct(i mean correct for general weight calculation, not lightwave specific), but sometimes it looks close to what i see in LightWave Layout, but most of the time it's not. So i can't figure out even basic lightwave weight calculation. Look at comparsion, maybe that will help tou to help me . [attachment=2264:ComparsionA.jpg]
• Advertisement
×

## Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!