我正在尝试使用 opengl 纹理数组来存储大量阴影贴图。不幸的是,我总是在检查帧缓冲区时收到“不完整的附件”错误。我尝试像在 nvidia 的级联阴影映射示例中一样设置我的纹理数组(请参阅 NVIDIA 的级联阴影映射示例)。
所以这里有一些代码:
创建纹理:
glGenTextures(1, &shadowMapArray_);
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowMapArray_);
//maxArrayDepth_ = GL_MAX_ARRAY_TEXTURE_LAYERS
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT, size_, size_, maxArrayDepth_, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
Run Code Online (Sandbox Code Playgroud)创建 FBO:
glGenFramebuffers(1, &fbo_);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
glDrawBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Run Code Online (Sandbox Code Playgroud)将阴影贴图绘制到图层中:
glUseProgram(programID_);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowMapArray_, 0, currArraySize_);
GLView::checkGLFramebuffer("ShadowMapGenerator::createShadowMap()"); //here i get the incomplete attachment
[...]
currArraySize_++;
Run Code Online (Sandbox Code Playgroud)系统规格:
带有 Nvidia 驱动程序 304.60 和 GTX 560 Ti …
我有一个像这样实现阴影贴图的着色器:
#version 430 core
out vec4 color;
in VS_OUT {
vec3 N;
vec3 L;
vec3 V;
vec4 shadow_coord;
} fs_in;
layout(binding = 0) uniform sampler2DShadow shadow_tex;
uniform vec3 light_ambient_albedo = vec3(1.0);
uniform vec3 light_diffuse_albedo = vec3(1.0);
uniform vec3 light_specular_albedo = vec3(1.0);
uniform vec3 ambient_albedo = vec3(0.1, 0.1, 0.2);
uniform vec3 diffuse_albedo = vec3(0.4, 0.4, 0.8);
uniform vec3 specular_albedo = vec3(0.0, 0.0, 0.0);
uniform float specular_power = 128.0;
void main(void) {
//color = vec4(0.4, 0.4, 0.8, 1.0);
//normalize
vec3 N = …Run Code Online (Sandbox Code Playgroud) 我正在编写一个glsl片段着色器,其中我使用阴影贴图.按照本教程http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-16-shadow-mapping/,我写了这一行来评估shaodw偏见以避免阴影痤疮
float bias = 0.005 * tan( acos ( N_L_dot ) );
Run Code Online (Sandbox Code Playgroud)
但我从数学上知道
tan ( acos ( x ) = sqrt ( 1 - x^2 ) / x
Run Code Online (Sandbox Code Playgroud)
使用这种身份而不是棕褐色和acos会更快吗?在实践中,要使用这行代码
float bias = 0.005 * sqrt ( 1.f - N_L_dot * N_L_dot ) / N_L_dot ;
Run Code Online (Sandbox Code Playgroud)
我认为我的问题类似于"在执行sqrt和划分或tan和acos时,gpu更快吗?" ......或者我错过了什么?
我对阴影贴图中的偏差矩阵感到困惑.根据这个问题:阴影映射中的偏置矩阵,偏置矩阵用于缩小并转换为[0..1] x和[0..1] y.所以我认为如果我们不使用偏置矩阵,纹理只会被1/4场景大小填充?真的吗?或者这里有一些魔力吗?
我正在尝试实现阴影贴图技术,但在使其发挥作用时遇到一些问题。
我在灯光位置有一个相机,这是我得到的阴影贴图。所有顶点均已乘以每个modelViewProjectionMatrix。

我还有一个带有顶点世界位置的纹理。它是一个GL_RGBA32F纹理,因为所有点都已被每个点相乘ModelMatrix以获得世界空间中的点。

和着色器:
layout(binding=5) uniform sampler2D shadowMap;
layout(binding=6) uniform sampler2D positionMap;
in vec2 texcoord;
uniform mat uViewProjectionMatrix;
out vec4 color;
void main() {
vec4 pos = texture(positionMap, texcoord);
vec4 ShadowCoord = uViewProjectionMatrix * pos;
ShadowCoord.xy = ShadowCoord.xy * vec2(0.5,0.5) + vec2(0.5,0.5);
float a = texture(shadowMap, ShadowCoord.xy).z;
color = vec4(a, a, a, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
输出(相机几乎处于光线的相同位置):

我只是想看看每个顶点的投影是否与相机的位置垂直,但看起来并非如此。所有这一切的目的是比较:
if ( texture(shadowMap, ShadowCoord.xy).z < ( ShadowCoord.z-bias ) )
Run Code Online (Sandbox Code Playgroud)
但它也不起作用。
我将不胜感激任何帮助。谢谢。
我试图了解阴影映射是如何独立工作的,并描述了这个 Python 程序来测试阴影映射,这是尽可能的。
我搜索了阴影贴图问题,但我还没有发现这样的事情已经发生了什么,那么我如何为灯光前面的正常旋转立方体着色以及如何校正阴影的位置以使其出现并将其准确地放在表面上?我只是在修改着色器。
import pyglet, math, pyrr, ctypes
import numpy as np
from OpenGL.GL import *
from OpenGL.GL.shaders import *
app = pyglet.window.Window()
v = """
in layout(location=0) vec3 posicao;
uniform mat4 view;
uniform vec3 translate;
uniform float rot;
uniform float rot2;
uniform vec3 t2;
out vec3 outpos;
void main(){
vec3 p = posicao;
p = vec3(sin(rot)*p.x+cos(rot)*p.z,p.y,-sin(rot)*p.z+cos(rot)*p.x);
p = translate+p+t2;
p = vec3(p.x,sin(rot2)*p.z+cos(rot2)*p.y,-sin(rot2)*p.y+cos(rot2)*p.z);
outpos = p;
gl_Position = view*vec4(p,1);
}
"""
f = """
uniform vec3 cor;
uniform int …Run Code Online (Sandbox Code Playgroud) 在我的灯光视图之外采样点时,我遇到了问题,因此我的阴影贴图.这是我在使用GL_TEXTURE_WRAP设置为GL_CLAMP或GL_CLAMP_TO_EDGE的纹理参数创建阴影贴图时得到的:

我已经确定在这里发生的是,地图一侧阴影贴图之外的每个点都有阴影,而地图外侧的每个点都没有阴影被认为是没有阴影的.我认为这是GL_CLAMP和GL_CLAMP_TO_EDGE的预期行为,但我没有在网上找到的各种阴影映射示例中看到这个问题.通过使用GL_CLAMP_TO_BORDER并设置边框颜色来删除其中一些问题,但这也不是我在我看过的任何示例中看到的修复.在遮蔽聚光灯时这是一个预期的问题,如果是这样,通常的修复方法是什么?
如何在WebGLRenderer中动态打开和关闭抗锯齿和阴影?
简单地更改抗锯齿和shadowMapEnable的属性不起作用.我查看了源代码并找到了一个方法updateShadowMap()但它在第69版中被删除了.
更新:好的,我在这里找到问题后半部分的答案 https://github.com/mrdoob/three.js/issues/2466
因此,以下代码可以正常工作:
renderer.shadowMapEnabled = false;
for(var i in tiles.children)
tiles.children[i].material.needsUpdate=true;
renderer.clearTarget( sun.shadowMap );
Run Code Online (Sandbox Code Playgroud)