Android LibGDX-自定义阴影映射

Android LibGDX-自定义阴影映射,android,libgdx,opengl-es-2.0,shader,glsles,Android,Libgdx,Opengl Es 2.0,Shader,Glsles,我需要在场景中创建阴影。我不想将Environment与DirectionalShadowLight一起使用,因为它已被弃用,DefaultShader是冗余的。因此,我需要实现我自己的支持阴影的着色器。基于,我创建了2个着色器。其中一个是ShadowGenshader: 顶点: attribute vec4 a_position; uniform mat4 u_m4LightMVP; uniform mat4 u_worldTrans; varying vec4 v_v4TexCoord;

我需要在场景中创建阴影。我不想将
Environment
DirectionalShadowLight
一起使用,因为它已被弃用,
DefaultShader
是冗余的。因此,我需要实现我自己的支持阴影的着色器。基于,我创建了2个着色器。其中一个是
ShadowGen
shader:

顶点:

attribute vec4 a_position;
uniform mat4 u_m4LightMVP;
uniform mat4 u_worldTrans;

varying vec4 v_v4TexCoord;

void main()
{
  v_v4TexCoord = u_m4LightMVP * u_worldTrans * a_position;
  gl_Position = v_v4TexCoord;
}
#ifdef GL_ES
precision highp float; 
#endif

attribute vec4 a_position;

uniform mat4 u_worldTrans;
uniform mat4 u_projTrans;
uniform mat4 u_m4Light;

varying vec4 v_v4TexCoord;

void main()
{
   const mat4 biasMat = mat4(0.5, 0.0, 0.0, 0.0,
                             0.0, 0.5, 0.0, 0.0,
                             0.0, 0.0, 1.0, 0.0,
                             0.5, 0.5, 0.0, 1.0);

   v_v4TexCoord = u_m4Light * u_worldTrans * a_position;     
   v_v4TexCoord = biasMat * v_v4TexCoord;    
   gl_Position = u_projTrans * u_worldTrans * a_position;
}
片段:

#ifdef GL_ES
precision mediump float; 
#endif

varying vec4 v_v4TexCoord;

void main(void)
{
   /* Generate shadow map - write fragment depth. */
   float value = 10.0 - v_v4TexCoord.z;
   float v = floor(value);
   float f = value - v;
   float vn = v * 0.1;
   gl_FragColor = vec4(vn, f, 0.0, 1.0);
}
#ifdef GL_ES
precision highp float; 
#endif

uniform sampler2D u_s2dShadowMap;
varying vec4 v_v4TexCoord;

void main()
{   
  vec2 vfDepth = texture2DProj(u_s2dShadowMap, v_v4TexCoord).xy;
  float fDepth = (vfDepth.x * 10.0 + vfDepth.y);
  /* Unpack the light distance. See how it is packed in the shadow.frag file. */
  float fLDepth = (10.0 - v_v4TexCoord.z) + 0.1 - fDepth ;
  float fLight = 1.0;
  if(fDepth > 0.0 && fLDepth < 0.0)
  {
    fLight = 0.2;       
  } 

  vec4 FinalColor = vec4(1.0,1.0,1.0,1.0);
  gl_FragColor = vec4(FinalColor.rgb * fLight, FinalColor.a);
}
另一个是使用此阴影贴图的基本着色器:

顶点:

attribute vec4 a_position;
uniform mat4 u_m4LightMVP;
uniform mat4 u_worldTrans;

varying vec4 v_v4TexCoord;

void main()
{
  v_v4TexCoord = u_m4LightMVP * u_worldTrans * a_position;
  gl_Position = v_v4TexCoord;
}
#ifdef GL_ES
precision highp float; 
#endif

attribute vec4 a_position;

uniform mat4 u_worldTrans;
uniform mat4 u_projTrans;
uniform mat4 u_m4Light;

varying vec4 v_v4TexCoord;

void main()
{
   const mat4 biasMat = mat4(0.5, 0.0, 0.0, 0.0,
                             0.0, 0.5, 0.0, 0.0,
                             0.0, 0.0, 1.0, 0.0,
                             0.5, 0.5, 0.0, 1.0);

   v_v4TexCoord = u_m4Light * u_worldTrans * a_position;     
   v_v4TexCoord = biasMat * v_v4TexCoord;    
   gl_Position = u_projTrans * u_worldTrans * a_position;
}
片段:

#ifdef GL_ES
precision mediump float; 
#endif

varying vec4 v_v4TexCoord;

void main(void)
{
   /* Generate shadow map - write fragment depth. */
   float value = 10.0 - v_v4TexCoord.z;
   float v = floor(value);
   float f = value - v;
   float vn = v * 0.1;
   gl_FragColor = vec4(vn, f, 0.0, 1.0);
}
#ifdef GL_ES
precision highp float; 
#endif

uniform sampler2D u_s2dShadowMap;
varying vec4 v_v4TexCoord;

void main()
{   
  vec2 vfDepth = texture2DProj(u_s2dShadowMap, v_v4TexCoord).xy;
  float fDepth = (vfDepth.x * 10.0 + vfDepth.y);
  /* Unpack the light distance. See how it is packed in the shadow.frag file. */
  float fLDepth = (10.0 - v_v4TexCoord.z) + 0.1 - fDepth ;
  float fLight = 1.0;
  if(fDepth > 0.0 && fLDepth < 0.0)
  {
    fLight = 0.2;       
  } 

  vec4 FinalColor = vec4(1.0,1.0,1.0,1.0);
  gl_FragColor = vec4(FinalColor.rgb * fLight, FinalColor.a);
}
shadowMapShader的代码为:

ShaderProgram program;  
int u_projTrans;    
int u_worldTrans;
int s_shadowMap;    

public Texture shadowTexture;   
public Matrix4 u_m4Light;

@Override
public void init() {
    String vert = Gdx.files.internal("shaders/shadowmap_mali_vs.glsl").readString();
    String frag = Gdx.files.internal("shaders/shadowmap_mali_ps.glsl").readString();
    program = new ShaderProgram(vert, frag);
    if (!program.isCompiled())
        throw new GdxRuntimeException(program.getLog());
    else Gdx.app.log("ShadowMapMaliShader", "shader compiled successfully!");
    u_projTrans = program.getUniformLocation("u_projTrans");
    u_worldTrans = program.getUniformLocation("u_worldTrans");
    s_shadowMap = program.getUniformLocation("u_s2dShadowMap");         
}

@Override
public void begin(Camera camera, RenderContext context) {       
    program.begin();
    program.setUniformMatrix(u_projTrans, camera.combined);
    program.setUniformMatrix("u_m4Light", u_m4Light);
}

@Override
public void render(Renderable renderable) {
    program.setUniformMatrix(u_worldTrans, renderable.worldTransform);      

    shadowTexture.bind(0);
    program.setUniformi(s_shadowMap, 0);

    renderable.mesh.render(program, renderable.primitiveType, renderable.meshPartOffset, renderable.meshPartSize);
}    
因此,实际结果是:
如果将
DefaultShader
Environment
一起使用,结果与预期一致:
这有什么问题?任何帮助都将不胜感激

很遗憾,没有人能帮助解决这个问题。我在寻找同样的解决办法-(这可能无法解决您的问题,但一个区别是,
方向阴影灯
使用的是
正交摄影机
而不是
透视摄影机
。您没有应用任何真实灯光(例如漫反射或镜面反射)在着色器中,这是视觉差异与DSL的第一个原因。其次,我有一种预感,您在渲染中实际看到0.2灰色,因为
if(fDepth>0.0&&fLDepth<0.0)fLight=0.2;
为所有片段激活。