gpt4 book ai didi

c++ - 使用 pow() 时的 GLSL 问题

转载 作者:可可西里 更新时间:2023-11-01 18:37:48 24 4
gpt4 key购买 nike

我目前正在实现一个着色器来做一些定向光。我正在学习 Lighthouse 3d ( http://www.lighthouse3d.com/tutorials/glsl-core-tutorial/directional-lights-per-pixel/ ) 上的教程

我遇到的问题是以下几行:

vec3 h  = normalize(l_dir + e); 
float intSpec = max(dot(h, n), 0.0);
float specularPower = pow(intSpec, shininess);

如果我将“float specularPower”行留在 - 那么着色器不再“工作”....我在引号中说“工作”,因为我没有从着色器日志中得到任何输出或错误,但是,现在我的所有返回 -1 的统一位置,我无法设置我的纹理位置等。

如果我删除它,着色器的其余部分将按预期工作(但由于缺少镜面反射功率而产生不正确的结果)。

更奇怪的是,如果我连接了 nVidia Nsight 调试器,那么我会在屏幕上得到输出并且它似乎“工作”,但是如果我只是在 Debug模式下使用 VS2012,我在屏幕上什么也看不到,并且以下错误信息:

First-chance exception at 0x000000005EB066E6 (nvoglv64.dll) in application.exe: 0xC0000005: Access violation reading location 0x0000000000000008.
First-chance exception at 0x000000005EB066E6 (nvoglv64.dll) in application.exe: 0xC0000005: Access violation reading location 0x0000000000000008.

此行为已在运行 Windows 8 64 位的 PC 上的 GTX 480 和 GTX 560 上出现。

我知道作为统一位置返回的 -1 意味着名称错误,或者编译器已将其优化掉,但这对于在一行中添加没有任何意义,其结果根本不会被使用然后。当连接或不连接 NSight 调试器时,行为是不同的,这更没有意义

我可能做错了什么?

编辑:

下面是我可以创建的最简单的顶点/片段着色器,它复制了这个问题,同时仍然是一个“真实世界”着色器。

顶点着色器:

// Default Vertex Shader

#version 430 core

uniform mat4 projMatrix;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;

in vec4 in_Position;
in vec3 in_Normal;
in vec2 in_TexCoords;

out vec2 pass_TexCoords;

out vec3 v;

out Data {
vec3 normal;
vec4 eye;
} DataOut;

void main(void)
{
DataOut.normal = normalize(in_Normal);
DataOut.eye = (viewMatrix * modelMatrix) * in_Position;

pass_TexCoords = in_TexCoords;

v = vec3(in_Position);

gl_Position = projMatrix * viewMatrix * modelMatrix * in_Position;
}

片段着色器:

// Default Fragment Shader
#version 430 core

uniform sampler2D material[3];

in vec2 pass_TexCoords;


in Data {
vec3 normal;
vec4 eye;
} DataIn;

layout (location = 0) out vec4 out_Colour;

void main(void)
{
float shininess = 0.5;

vec3 l_dir = vec3(0.0, 0.0, 1.0);
vec3 n = normalize(DataIn.normal);
vec3 e = normalize(vec3(DataIn.eye));

float intensity = max(dot(n, l_dir), 0.0);
float specularPower;

if(intensity > 0.0) {
vec3 h = normalize(l_dir + e);

float dHN = dot(h, n);
float intSpec = max(dHN, 0.0);

float specularPower = pow(intSpec, shininess);
} else {
specularPower = 1.0;
}

vec4 diffuse_Colour = texture(material[0], pass_TexCoords);
out_Colour = diffuse_Colour * specularPower;
}

我还检查了程序信息日志,它没有返回任何错误。再一次,使用这些着色器,它在通过 VS2012 运行时失败(制服返回 -1),但在附加 nVidia Nsight 调试器时“有效”。

最佳答案

这个着色器中发生了一些有趣的事情,它们都与这一行有关:

float specularPower = pow(intSpec, shininess);

在最终编译的着色器中绝对不做任何事情。您在函数范围内隐藏了一个同名变量。

这是您的着色器实际执行的操作(如所写):

// Default Fragment Shader
#version 430 core

uniform sampler2D material[3];

in vec2 pass_TexCoords;

in Data {
vec3 normal;
vec4 eye;
} DataIn;

layout (location = 0) out vec4 out_Colour;

void main(void)
{
vec3 l_dir = vec3(0.0, 0.0, 1.0);
vec3 n = normalize(DataIn.normal);

float intensity = max(dot(n, l_dir), 0.0);
float specularPower;

if(intensity > 0.0) {
// This branch did not affect anything outside of this scope, so it is gone...

// specularPower is uninitialized if this branch is triggered
} else {
specularPower = 1.0;
}

vec4 diffuse_Colour = texture(material[0], pass_TexCoords);
out_Colour = diffuse_Colour * specularPower;
}

如果你用这个替换我提到的第一条语句:

specularPower = pow(intSpec, shininess);

您的着色器实际上会在 if (intensity > 0.0) { ... } 分支中执行某些操作。

因为光泽度在这个程序中是一个常量,你也可以像这样替换那个语句:

specularPower = sqrt (intSpec);

关于c++ - 使用 pow() 时的 GLSL 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21308377/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com