我想计算GLSL中的切线空间。
以下是我的代码中的重要部分:
// variables passed from vertex to fragment program //
in vec3 vertexNormal;
in vec2 textureCoord;
in vec3 lightPosition;
in vec3 vertexPos;
in mat4 modelView;
in mat4 viewMatrix;
// TODO: textures for color and normals //
uniform sampler2D normal;
uniform sampler2D texture;
// this defines the fragment output //
out vec4 color;
void main() {
// ###### TANGENT SPACE STUFF ############
vec4 position_eye = modelView * vec4(vertexPos,1.0);
vec3 q0 = dFdx(position_eye.xyz);
vec3 q1 = dFdy(position_eye.xyz);
vec2 st0 = dFdx(textureCoord.st);
vec2 st1 = dFdy(textureCoord.st);
float Sx = ( q0.x * st1.t - q1.x * st0.t) / (st1.t * st0.s - st0.t * st1.s);
float Tx = (-q0.x * st1.s + q1.x * st0.s) / (st1.t * st0.s - st0.t * st1.s);
q0.x = st0.s * Sx + st0.t * Tx;
q1.x = st1.s * Sx + st1.t * Tx;
vec3 S = normalize( q0 * st1.t - q1 * st0.t);
vec3 T = normalize(-q0 * st1.s + q1 * st0.s);
vec3 n = texture2D(normal,textureCoord).xyz;
n = smoothstep(-1,1,n);
mat3 tbn = (mat3(S,T,n));
// #######################################
n = tbn * n; // transfer the read normal to worldSpace;
vec3 eyeDir = - (modelView * vec4(vertexPos,1.0)).xyz;
vec3 lightDir = (modelView * vec4(lightPosition.xyz, 1.0)).xyz;
在此代码之后有一个phong着色,它将与纹理混合。将着色器应用于普通纹理而不使用normalMapping一切正常。 我需要在着色器中为稍后的其他动态部分计算它。
有人能告诉我出了什么问题吗?
目前的情况如下:
答案 0 :(得分:3)
有人可以告诉我出了什么问题吗?
您正在尝试在着色器中计算切线空间基础矩阵;那是错的。你实际上不能这样做。
dFdx/y
计算基本表面上屏幕空间中给定值的变化率。换句话说,它计算给定值相对于原语的导数。您的输入值是线性插值的。
线的导数是常数。并且线 ar插值产生线 ar结果。因此,每个基元的每个片段都将获得输入/输出的相同的导数。因此,每个片段都会计算相同的 S和T值,因为它们完全基于衍生物。
这就是为什么你得到一个刻面:三个矩阵组件中的两个在三角形表面上是相同的。
您的计算不起作用,因为它无法工作。您将不得不做其他人所做的事情:离线计算NBT矩阵并将其作为每顶点属性传递。或者使用网格的某些已知属性来计算它们。但是这个?它不会起作用。