Opengl 材料、纹理和光的相互作用

Opengl 材料、纹理和光的相互作用,opengl,glsl,textures,lighting,Opengl,Glsl,Textures,Lighting,我已经编写了一个简单的3D模型查看器(使用OpenGL3.2和GLSL),它可以加载和渲染U3D模型(可以是独立的,也可以是从PDF内部)。它基本上可以渲染所有不同的网格,通过顶点颜色、纹理或材质绘制网格,并相应地照亮网格 然而,我还没有完全弄清楚什么是组合材质和纹理的“预期方式”。我看过一些教程,其中灯光对象具有材质(具有漫反射/镜面反射/环境光组件以及不透明度和光泽度因子),还有一些教程使用纹理并对其进行照明,但我还没有找到任何关于组合时预期行为的好资源(即网格具有材质和一个或多个纹理层)

我已经编写了一个简单的3D模型查看器(使用OpenGL3.2和GLSL),它可以加载和渲染U3D模型(可以是独立的,也可以是从PDF内部)。它基本上可以渲染所有不同的网格,通过顶点颜色、纹理或材质绘制网格,并相应地照亮网格

然而,我还没有完全弄清楚什么是组合材质和纹理的“预期方式”。我看过一些教程,其中灯光对象具有材质(具有漫反射/镜面反射/环境光组件以及不透明度和光泽度因子),还有一些教程使用纹理并对其进行照明,但我还没有找到任何关于组合时预期行为的好资源(即网格具有材质和一个或多个纹理层)

此外,根据U3D文件格式在其“LitTextureShader”描述中的规范,我支持4种不同的混合函数,用于确定一个纹理层如何与先前纹理层的结果相结合:

// Multiply     
blended = current * previous;  
// Add  
blended = clamp(current + previous, 0.0, 1.0);  
// Replace  
blended = current;  
// Blend  
blended = mix( previous , current, current.a );
起初我以为这只是应用于纹理层之间,但当我在Adobe Reader中查看模型时,这些混合操作有时似乎也应用于纹理和材质之间,但结果从来不是我所期望的(并且看起来与我的结果非常不同),所以我假设有一些我没有完全理解的潜在部分

在测试中,我创建了一个由一个三角形、一个红色材质和两个棋盘纹理组成的网格:

我的片段着色器通常如下所示(缩短和简化,不考虑镜面反射或偏光):

这让我相信我走在了正确的轨道上,应该对材质和纹理进行操作以获得正确的结果,但是“添加”着色器:

结果是:

这让我觉得材质不应该影响它。因此我还尝试了两种纹理(棋盘格,没有透明度)的情况,它们应该相互添加:

// set up colors and opacity
currDiffuseColor = texture(texSampler0, vertTexCoord0) * vec4( vec3(texIntensity0), 1.0 );
vec4 texLayer1 = texture(texSampler1, vertTexCoord1) * vec4( vec3(texIntensity1), 1.0 );
currDiffuseColor = vec4( clamp(currDiffuseColor + texLayer1, 0.0, 1.0).rgb, texLayer1.a );

我的代码将其添加到一起,而Adobe Reader似乎只显示纹理层0

另外,例如,如果我将U3D设置为使纹理层透明(并使用混合常数),Adobe会给出以下信息:

但是Adobe似乎没有考虑混合常数的值,所以我得到了不同的结果

因此,所有这些结果让我感到困惑,因为“正常”纹理和材质应该如何相互影响。本质上,结果不一定与Adobe完全相同,但我希望得到可预测的结果,以便制作模型的人能够知道基于“典型行为”的预期结果用于建模或渲染软件

如果我有材质不透明度和纹理不透明度,它们会彼此相乘吗?只有纹理层应该相互混合/添加/相乘/替换,还是与材质交互?材质是照明的唯一因素?还是应该在纹理上计算灯光?对我来说,Adobe的结果似乎不一致,但可能是我缺乏理解

作为参考,我已将我创建的示例PDF上传到此zip:-它还包含从我的应用程序生成的屏幕截图,以及用于创建U3D的文本文件(IDTF)(以及PDF)

// add base color info
currDiffuseColor = texture(texSampler0, vertTexCoord0) * vec4( vec3(texIntensity0), 1.0 );

// modify color according to blend factors
currOpacity = matOpacity * currDiffuseColor.a;
currDiffuseColor = matDiffuse * currDiffuseColor;
// add base color info
currDiffuseColor = texture(texSampler0, vertTexCoord0) * vec4( vec3(texIntensity0), 1.0 );

// modify color according to blend factors
currOpacity = matOpacity;
currDiffuseColor = vec4( clamp(matDiffuse + currDiffuseColor, 0.0, 1.0).rgb, currDiffuseColor.a );
// set up colors and opacity
currDiffuseColor = texture(texSampler0, vertTexCoord0) * vec4( vec3(texIntensity0), 1.0 );
vec4 texLayer1 = texture(texSampler1, vertTexCoord1) * vec4( vec3(texIntensity1), 1.0 );
currDiffuseColor = vec4( clamp(currDiffuseColor + texLayer1, 0.0, 1.0).rgb, texLayer1.a );