c – 正常映射和翻译会破坏我的照明

c – 正常映射和翻译会破坏我的照明,第1张

概述我有一个正常的映射问题.我在通过ASSIMP库加载的每个模型上都有纹理和普通纹理.我在ASSIMP库的帮助下计算每个对象的切向量,所以这些应该没问题.这些对象与法线贴图完美配合,但是一旦我开始平移其中一个对象(从而影响具有平移的模型矩阵),灯光就会失败.正如你在图像上看到的那样,地板(沿着y轴向下平移)似乎失去了大部分漫射光,而且它的镜面光线方向错误(应该在灯泡和播放器位置之间) 它可能与普通矩阵 我有一个正常的映射问题.我在通过ASSIMP库加载的每个模型上都有纹理和普通纹理.我在ASSIMP库的帮助下计算每个对象的切向量,所以这些应该没问题.这些对象与法线贴图完美配合,但是一旦我开始平移其中一个对象(从而影响具有平移的模型矩阵),灯光就会失败.正如你在图像上看到的那样,地板(沿着y轴向下平移)似乎失去了大部分漫射光,而且它的镜面光线方向错误(应该在灯泡和播放器位置之间)

它可能与普通矩阵有关(尽管翻译应该丢失),也许在着色器中使用了错误的矩阵.我没有想法,希望你能对这个问题有所了解.

顶点着色器:

#version 330layout(location = 0) in vec3 position;layout(location = 1) in vec3 normal;layout(location = 2) in vec3 tangent;layout(location = 3) in vec3 color;layout(location = 4) in vec2 texCoord;// fragment pass throughout vec3 position;out vec3 normal;out vec3 Tangent;out vec3 color;out vec2 TexCoord;out vec3 TangentSurface2light;out vec3 TangentSurface2VIEw;uniform vec3 lightPos;uniform vec3 playerPos;// vertex transformationuniform mat4 model;uniform mat4 vIEw;uniform mat4 projection;voID main(){    mat3 normalMatrix = mat3(transpose(inverse(model)));     position = vec3(model * vec4(position,1.0));     normal = normalMatrix * normal;    Tangent = tangent;    color = color;    TexCoord = texCoord;    gl_position = projection * vIEw * model * vec4(position,1.0);    // Calculate tangent matrix and calculate fragment bump mapPing coord space.    vec3 light = lightPos;    vec3 n = normalize(normalMatrix * normal);    vec3 t = normalize(normalMatrix * tangent);    vec3 b = cross(n,t);    // create matrix for tangent (from vertex to tangent-space)    mat3 mat = mat3(t.x,b.x,n.x,t.y,b.y,n.y,t.z,b.z,n.z);    vec3 vector = normalize(light - position);    TangentSurface2light = mat * vector;    vector = normalize(playerPos - position);    TangentSurface2VIEw = mat * vector;}

片段着色器

#version 330in vec3 position;in vec3 normal;in vec3 Tangent;in vec3 color;in vec2 TexCoord;in vec3 TangentSurface2light;in vec3 TangentSurface2VIEw;out vec4 outcolor;uniform vec3 lightPos;uniform vec3 playerPos;uniform mat4 vIEw;uniform sampler2D texture0;uniform sampler2D texture_normal; // normaluniform float repeatFactor = 1;voID main(){       vec4 texcolor = texture(texture0,TexCoord * repeatFactor);    vec4 matcolor = vec4(color,1.0);    vec3 light = vec3(vec4(lightPos,1.0));    float dist = length(light - position);    // float att = 1.0 / (1.0 + 0.01 * dist + 0.001 * dist * dist);    float att = 1.0;    // AmbIEnt    vec4 ambIEnt = vec4(0.2);    // Diffuse    // vec3 surface2light = normalize(light - position);    vec3 surface2light = normalize(TangentSurface2light);    // vec3 norm = normalize(normal);     vec3 norm = normalize(texture(texture_normal,TexCoord * repeatFactor).xyz * 2.0 - 1.0);     float contribution = max(dot(norm,surface2light),0.0);    vec4 diffuse = contribution * vec4(0.6);    // specular    // vec3 surf2vIEw = normalize(-position); // Player is always at position 0    vec3 surf2vIEw = normalize(TangentSurface2VIEw);    vec3 reflection = reflect(-surface2light,norm); // reflection vector    float specContribution = pow(max(dot(surf2vIEw,reflection),0.0),32);    vec4 specular = vec4(1.0) * specContribution;    outcolor = (ambIEnt + (diffuse * att)+ (specular * pow(att,3))) * texcolor;    // outcolor = vec4(color,1.0) * texture(texture0,TexCoord);}

编辑

编辑着色器代码来计算世界空间中的所有内容,而不是在世界和相机空间之间进行乒乓球(更容易理解,更不容易出错).

解决方法 你正在用矩阵进行奇怪的 *** 作.在VS中,您通过逆视图世界转换法线(即模型空间).这没有任何意义.在世界空间中进行计算可能更容易.我有一些工作示例代码,但它使用了一些不同的命名.

顶点着色器:

voID main_vs(in A2V input,out V2P output) {    output.position = mul(input.position,_worldVIEwProjection);    output.normal = input.normal;    output.binormal = input.binormal;    output.tangent = input.tangent;    output.positionWorld = mul(input.position,_world);    output.tex = input.tex;}

在这里我们将位置转换为投影(屏幕) – 空间,TBN留在模型空间中,它们将在以后使用.我们也获得了照明评估的世界空间位置.

像素着色器:

voID main_ps(in V2P input,out float4 output : SV_Target){    float3x3 tbn = float3x3(input.tangent,-input.binormal,input.normal);    //extract & decode normal:    float3 texnormal = _normalTexture.Sample(_normalSampler,input.tex).xyz * 2 - 1;    //Now transform TBN-space texnormal to world space:    float3 normal = mul(texnormal,tbn);    normal = normalize(mul(normal,_world));    float3 lightDirection = -_lightposition.xyz;//directional    float3 vIEwDirection = normalize(input.positionWorld - _camera);    float3 reflectedlight = reflect(lightDirection,normal);    float diffuseIntensity = dot(normal,lightDirection);    float specularIntensity = max(0,dot(reflectedlight,vIEwDirection)*1.3);    output = ((_ambIEnt + diffuseIntensity * _diffuse) * _texture.Sample(_sampler,input.tex)         + pow(specularIntensity,7) * float4(1,1,1)) * _lightcolor;}

在这里我使用定向光,你应该做的事情

float3 lightDirection = normalize(input.positionWorld - _lightposition.xyz);//omni

这里我们首先从纹理中得到法线,即在TBN空间中.然后我们应用TBN矩阵将其转换为模型空间.然后应用世界矩阵将其转换为世界空间,我们已经有了轻型位置,眼睛等.

上面省略了一些其他着色器代码(DX11,但它很容易翻译):

cbuffer VIEwTranforms{    row_major matrix _worldVIEwProjection;    row_major matrix _world;    float3 _camera;};cbuffer BumpData{    float4 _ambIEnt;    float4 _diffuse;};cbuffer Textures{    texture2D _texture;    SamplerState _sampler;    texture2D _normalTexture;    SamplerState _normalSampler;};cbuffer light{    float4 _lightposition;    float4 _lightcolor;};//------------------------------------struct A2V{    float4 position : position;    float3 normal : norMAL;    float3 binormal : BInorMAL;    float3 tangent : TANGENT;    float2 tex : TEXCOORD;};struct V2P{    float4 position : SV_position;    float3 normal : norMAL;    float3 binormal : BInorMAL;    float3 tangent : TANGENT;    float3 positionWorld : norMAL1;    float2 tex : TEXCOORD;};

此外,这里我使用预先计算的binormal:你应该留下你的代码来计算它(通过交叉(正常,切线)).希望这可以帮助.

总结

以上是内存溢出为你收集整理的c – 正常映射和翻译会破坏我的照明全部内容,希望文章能够帮你解决c – 正常映射和翻译会破坏我的照明所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1238441.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存