c++ - 我的 godRays 片段着色器哪里出错了?
问题描述
我正在尝试实现上帝之光,但我不明白哪里出了问题。神光的来源是立方体的中心。
顶点着色器:
#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoords;
out vec2 TexCoords;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
TexCoords = aTexCoords;
}
这是一个简单的片段着色器,只是为了向您展示当我没有在片段着色器中添加上帝光线代码时场景的样子:
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D screenTexture;
void main()
{
FragColor = texture2D(screenTexture, TexCoords);
}
没有神光的场景:
添加上帝射线代码时的片段着色器:
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform vec2 lightPositionOnScreen;
uniform sampler2D screenTexture;
const float exposure = 0.3f;
const float decay = 0.96815;
const float density = 0.926;
const float weight = 0.587;
const int NUM_SAMPLES = 80;
void main()
{
// Calculate vector from pixel to light source in screen space.
vec2 deltaTexCoord = (TexCoords - lightPositionOnScreen.xy);
vec2 texCoord = TexCoords;
// Divide by number of samples and scale by control factor.
deltaTexCoord *= 1.0f / NUM_SAMPLES * density;
// Store initial sample.
vec3 color = texture2D(screenTexture, TexCoords);
// Set up illumination decay factor.
float illuminationDecay = 1.0f;
// Evaluate summation from Equation 3 NUM_SAMPLES iterations.
for (int i = 0; i < NUM_SAMPLES; i++)
{
// Step sample location along ray.
texCoord -= deltaTexCoord;
// Retrieve sample at new location.
vec3 sample = texture2D(screenTexture, texCoord);
// Apply sample attenuation scale/decay factors.
sample *= illuminationDecay * weight;
// Accumulate combined color.
color += sample;
// Update exponential decay factor.
illuminationDecay *= decay;
}
FragColor = vec4(color * exposure, 1.0);
}
场景如何处理 godRays 代码:
此代码用于将立方体中心的坐标从世界转换到窗口空间位置:
glm::vec4 clipSpacePos = projection * (view * glm::vec4(m_cubeCenter, 1.0));
glm::vec3 ndcSpacePos = glm::vec3(clipSpacePos.x / clipSpacePos.w, clipSpacePos.y / clipSpacePos.w, clipSpacePos.z / clipSpacePos.w);
glm::vec2 windowSpacePos;
windowSpacePos.x = (ndcSpacePos.x + 1.0) / 2.0;
windowSpacePos.y = 1.0f - (ndcSpacePos.y + 1.0) / 2.0;
wxMessageOutputDebug().Printf("test %f x position", windowSpacePos.x);
wxMessageOutputDebug().Printf("test %f y position", windowSpacePos.y);
shaderProgram.loadShaders("Shaders/godRays.vert", "Shaders/godRays.frag");
shaderProgram.use();
shaderProgram.setUniform("lightPositionOnScreen", windowSpacePos);
这就是我设置纹理的方式:
GLfloat vertices[] = {
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
1.0f, -1.0f, 0.0f, 1.0f, 0.0f, // bottom right
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom left
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom left
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // top left
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
};
GLuint testBuffer;
glGenBuffers(1, &testBuffer);
glBindBuffer(GL_ARRAY_BUFFER, testBuffer);
glBufferData(GL_ARRAY_BUFFER, 30 * sizeof(GLfloat), &vertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), NULL);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(3 * sizeof(float)));
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, screenTexture);
glDrawArrays(GL_TRIANGLES, 0, 6);
shaderProgram.deleteProgram();
glDeleteBuffers(1, &testBuffer);
解决方案
这是解决方案。问题出在线路上vec3 color = texture2D(screenTexture, TexCoords);
, vec3 sample = texture2D(screenTexture, texCoord);
我分别替换了它们 vec3 color = texture(screenTexture, TexCoords).rgb;
vec3 sample = texture(screenTexture, texCoord).rgb;
。
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform vec2 lightPositionOnScreen;
uniform sampler2D screenTexture;
const float exposure = 0.3f;
const float decay = 0.96815;
const float density = 0.926;
const float weight = 0.587;
const int NUM_SAMPLES = 100;
void main()
{
vec2 deltaTexCoord = vec2(TexCoords.xy - lightPositionOnScreen.xy);
vec2 texCoord = TexCoords;
deltaTexCoord *= 1.0f / NUM_SAMPLES * density;
vec3 color = texture(screenTexture, TexCoords).rgb;
float illuminationDecay = 1.0f;
for (int i = 0; i < NUM_SAMPLES; i++)
{
texCoord -= deltaTexCoord;
vec3 sample = texture(screenTexture, texCoord).rgb;
sample *= illuminationDecay * weight;
color += sample;
illuminationDecay *= decay;
}
FragColor = vec4(color * exposure, 1.0);
}
推荐阅读
- jquery - JSON 中的意外令牌 < 在 asp.net Web 表单中的位置
- arrays - 在 ReactJS 中的对象内设置嵌套数组
- eclipse-cdt - 修改 ast 节点时出现 AbortFormatting 异常
- react-native - 在 React Native 的服务对象中使用 axios 失败
- c# - 检查字符串中的字母或空格 C#
- reactjs - redux:更新减速器时摆脱样板
- javascript - 使用 JavaScript 附加 HTML+RDFa
- php - Json 解码返回 null。怎么了?
- javascript - “严格模式不支持 const 声明”语法错误
- python-3.x - Keras 在每个 epoch 中占用无限增加的内存量