Java 阴影贴图的灯光过程不适用于细分?
我目前正在实施阴影映射,在我的程序中我遇到了一部分奇怪的逻辑,我使用以下程序:Java 阴影贴图的灯光过程不适用于细分?,java,opengl,shader,shadow-mapping,tesselation,Java,Opengl,Shader,Shadow Mapping,Tesselation,我目前正在实施阴影映射,在我的程序中我遇到了一部分奇怪的逻辑,我使用以下程序: light.vs.glsl #version 440 core layout(location = 4) uniform mat4 light_mvp; layout(location = 0) in vec4 position; void main(void) { gl_Position = light_mvp * position; } #version 440 core layout(loca
light.vs.glsl
#version 440 core
layout(location = 4) uniform mat4 light_mvp;
layout(location = 0) in vec4 position;
void main(void) {
gl_Position = light_mvp * position;
}
#version 440 core
layout(location = 0) out vec4 color;
void main(void) {
color = vec4(gl_FragCoord.z);
}
light.fs.glsl
#version 440 core
layout(location = 4) uniform mat4 light_mvp;
layout(location = 0) in vec4 position;
void main(void) {
gl_Position = light_mvp * position;
}
#version 440 core
layout(location = 0) out vec4 color;
void main(void) {
color = vec4(gl_FragCoord.z);
}
然而,我得出的结论是,我实际上在做Tesselation,所以我对现在发生的事情一无所知,在Terrain.java
:
public class Terrain implements Drawable {
//<editor-fold defaultstate="collapsed" desc="keep-imports">
static {
int KEEP_LWJGL_IMPORTS = GL_2_BYTES | GL_ALIASED_LINE_WIDTH_RANGE | GL_ACTIVE_TEXTURE | GL_BLEND_COLOR | GL_ARRAY_BUFFER | GL_ACTIVE_ATTRIBUTE_MAX_LENGTH | GL_COMPRESSED_SLUMINANCE | GL_ALPHA_INTEGER | GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH | GL_ALREADY_SIGNALED | GL_ANY_SAMPLES_PASSED | GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH | GL_ACTIVE_PROGRAM | GL_ACTIVE_ATOMIC_COUNTER_BUFFERS | GL_ACTIVE_RESOURCES | GL_BUFFER_IMMUTABLE_STORAGE;
int KEEP_OWN_IMPORTS = UNIFORM_PROJECTION_MATRIX.getLocation() | VS_POSITION.getLocation();
}
//</editor-fold>
private static final float EPSILON = 0.0001f;
private FloatBuffer data;
private Program program;
private final int width;
private final int depth;
private final Random random = new Random();
private final float maxHeight = 8f;
private final int maxDecayFactor = 5;
private final float factor = 4f;
public Terrain(final int width, final int depth) {
this.width = width;
this.depth = depth;
data = generateRandomTerrain();
data.clear();
}
@Override
public void compileProgram() {
program = new Program(
new VertexShader("data/shaders/terrain.vs.glsl").compile(),
new TessellationControlShader("data/shaders/terrain.tcs.glsl").compile(),
new TessellationEvaluationShader("data/shaders/terrain.tes.glsl").compile(),
new FragmentShader("data/shaders/terrain.fs.glsl").compile()
).compile().setUniforms(
UNIFORM_MODEL_MATRIX,
UNIFORM_VIEW_MATRIX,
UNIFORM_PROJECTION_MATRIX,
UNIFORM_SHADOW_MATRIX
);
}
@Override
public Program getProgram() {
return program;
}
@Override
public int getDataSize() {
return width * depth * 16;
}
@Override
public FloatBuffer putData(final FloatBuffer dataBuffer) {
return dataBuffer.put(data);
}
@Override
public int getDataMode() {
return GL_PATCHES;
}
@Override
public void drawLightPass(final int offset, final Program lightProgram) {
lightProgram.drawArrays(getDataMode(), offset, getDataSize());
}
@Override
public void draw(final int offset) {
program.use();
program.drawArrays(getDataMode(), offset, getDataSize());
}
@Override
public void delete() {
program.delete();
}
public void refresh() {
data.clear();
data = generateRandomTerrain();
}
//...
}
public类地形工具可绘制{
//
静止的{
英国政府工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的工作人员的纹理,工作人员的工作人员的工作人员的纹理,工作人员的工作人员的工作人员的工作人员的纹理,混合颜色,混合颜色,混合颜色,颜色,混合颜色,颜色,德国军队军队的混合颜色,军队军队的颜色,军队的军队军队军队的军队的颜色,男男男男男色,数组,数组,数组,数组,数组,数组,数组,数组,数组,数组,数组,数组,数组,数组,缓冲,数组,缓冲,数组,数组,数组,数组,缓冲,数组,数组,数组,数组,数组U计划| GL_活动|原子|计数器| GL_活动|资源| GL_缓冲|不可变|存储;
int KEEP_OWN_IMPORTS=UNIFORM_PROJECTION_MATRIX.getLocation()| VS_POSITION.getLocation();
}
//
专用静态最终浮动ε=0.0001f;
私有缓冲区数据;
私人项目;
私有最终整数宽度;
私有最终整数深度;
私有最终随机=新随机();
专用最终浮子最大高度=8f;
专用最终整数maxDecayFactor=5;
私人最终浮动系数=4f;
公共地形(最终整型宽度、最终整型深度){
这个。宽度=宽度;
这个。深度=深度;
数据=GeneratorDomainTerrain();
data.clear();
}
@凌驾
公共无效编译器程序(){
程序=新程序(
新的VertexShader(“数据/着色器/terrain.vs.glsl”).compile(),
新的TessellationControlShader(“data/shaders/terrain.tcs.glsl”).compile(),
新的TessellationEvaluationShader(“data/shaders/terrain.tes.glsl”).compile(),
新的FragmentShader(“data/shaders/terrain.fs.glsl”).compile()
).compile().setUniforms(
一致_模型_矩阵,
统一视图矩阵,
均匀投影矩阵,
均匀阴影矩阵
);
}
@凌驾
公共程序getProgram(){
返回程序;
}
@凌驾
public int getDataSize(){
返回宽度*深度*16;
}
@凌驾
公共浮动缓冲区putData(最终浮动缓冲区数据缓冲区){
返回dataBuffer.put(数据);
}
@凌驾
public int getDataMode(){
返回glu补丁;
}
@凌驾
公共无效drawLightPass(最终整数偏移,最终程序lightProgram){
drawArrays(getDataMode(),offset,getDataSize());
}
@凌驾
公共空白绘制(最终整数偏移){
program.use();
program.drawArrays(getDataMode(),offset,getDataSize());
}
@凌驾
公共作废删除(){
program.delete();
}
公共无效刷新(){
data.clear();
数据=GeneratorDomainTerrain();
}
//...
}
另外,对于传递到drawLightPass
的lightProgram
,已确保在此之前调用了lightProgram.use()
,这可能从代码中看不明显
正如您所看到的,我在drawLightPass
中调用drawrayaries
,使用As参数GL\u PATCHES
,现在这确实应该出错了,因为在我的整个程序中,我发现每个部分都被认为处于阴影中,所以我有以下问题:
1) 我当前的设置是否存在问题?(我个人认为是这样的。)
2) 当附加的着色器没有启用镶嵌时,如果我传入GL\u补丁
,OpenGL怎么能不给出错误
3) 我如何修复它,使它也与Tesselation一起工作
如果需要更多的代码,那么我将发布它,我只是不想用不必要的代码把文章弄得太乱。Unrelated:是否有理由将窗口空间Z坐标写入4分量颜色输出?这对于阴影映射来说是非常浪费的,因为这实际上是已经自动写入深度缓冲区的完全相同的值。如果您不向颜色缓冲区写入/附加任何内容,而是使用深度纹理附件,则可以节省大量内存带宽/存储。@AndonM.Coleman在教程(OpenGL Superbible第六版)中就是这样做的,我实际上使用了
GL_depth_附件和GL_depth_组件32f
。哇,这对我来说是个惊喜。这似乎不是像那样一本有名望的书应该做的事情。无论如何,您是说细分几何体没有出现在阴影贴图中,还是说无法将阴影贴图应用于细分几何体?换句话说,在这种情况下,镶嵌几何体是否应该投射或接收阴影?@AndonM.Coleman我得到了它,现在它出现了,在修复了一个bug之后(标准化零向量导致NaN
被传递到着色器),但是它仍然有大量的瑕疵。我将首先集中在一个简单的XZ平面上,但是我对逻辑的关注仍然有效。我认为镶嵌几何体应该同时投射和接收阴影。