Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (799)
Games in Android Showcase (237)
games submitted by our members
Games in WIP (865)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Cube-Map Shadow Mapping  (Read 4625 times)
0 Members and 1 Guest are viewing this topic.
Offline Ecumene

JGO Kernel


Medals: 200
Projects: 4
Exp: 8 years


I did not hit her! I did not!


« Posted 2015-01-09 16:24:09 »

I'm slowly making progress with my game engine, but I can't seem to get omni-directional shadow maps to work.

The shading for each point light is done in two passes:
It renders the depth component 6 times in each direction (for the cube that is). One framebuffer is used to draw to a cube map. Then it passes the scene again with the light's calculation, sampling the cube-map texture.

Here's what I understand & have so far,

To initialize the OpenGL cubemap, there's 6 enums for 6 textures with one binding:
1  
2  
3  
4  
5  
6  
7  
GL13.GL_TEXTURE_CUBE_MAP
GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_X​
GL13.GL_TEXTURE_CUBE_MAP_NEGATIVE_X​
GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_Y​
GL13.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y​
GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_Z​
GL13.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z​


And the per-cubemap-face constants:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
private final static int[] GL_CUBEMAP_ENUM = {
   GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_X,
   GL13.GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
   GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
   GL13.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
   GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
   GL13.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
};

private final static Vector3f[] DIRECTIONS = new Vector3f[] {
   new Vector3f( 1.0f, 0.0f, 0.0f),
   new Vector3f(-1.0f, 0.0f, 0.0f),
   new Vector3f( 0.0f, 1.0f, 0.0f),
   new Vector3f( 0.0f,-1.0f, 0.0f),
   new Vector3f( 0.0f, 0.0f, 1.0f),
   new Vector3f( 0.0f, 0.0f,-1.0f),
};

private final static Vector3f[] DIRECTIONS_UP = new Vector3f[]{
   new Vector3f(0.0f,-1.0f, 0.0f),
   new Vector3f(0.0f,-1.0f, 0.0f),
   new Vector3f(0.0f, 0.0f,-1.0f),
   new Vector3f(0.0f, 0.0f, 1.0f),
   new Vector3f(0.0f,-1.0f, 0.0f),
   new Vector3f(0.0f,-1.0f, 0.0f),
};


And were I loop through the cubemap to initialize it:
1  
2  
3  
4  
5  
6  
depthCubeMap = new Texture(GL13.GL_TEXTURE_CUBE_MAP, WorldLightBatchObject.SHADOW_MAP_TMUNIT, GL11.GL_NEAREST, GL11.GL_REPEAT);
depthCubeMap.bind();
for(int i = 0; i < 6; i++){
   GL13.glActiveTexture(GL13.GL_TEXTURE0 + WorldLightBatchObject.SHADOW_MAP_TMUNIT);
   GL11.glTexImage2D(GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL14.GL_DEPTH_COMPONENT24, (int) (WorldGameContext.SHADOW_MAP_MUL * 1024), (int) (WorldGameContext.SHADOW_MAP_MUL * 1024), 0, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, (ByteBuffer) null);
}


Initializing the framebuffer & the perspecive matrix
1  
2  
3  
4  
depthFrame = new Frame(GL30.GL_FRAMEBUFFER);
depthFrame.bind();

depthProjection = Projection.createPerspective(90f, 1.f, 0.01f, 100f);


And to render to the depth-map:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
GL11.glPushAttrib(GL11.GL_VIEWPORT_BIT | GL11.GL_ENABLE_BIT);
GL11.glViewport(0, 0, (int) (WorldGameContext.SHADOW_MAP_MUL * 1024), (int) (WorldGameContext.SHADOW_MAP_MUL * 1024));
   for(int i = 0; i < 6; i++){
      GL11.glColorMask(false, false, false, false);
      GL11.glEnable(GL11.GL_DEPTH_TEST);
     
      GL11.glClearColor(Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE);
      depthFrame.bind();
      GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL_CUBEMAP_ENUM[i], depthCubeMap.getID(), 0);
      GL11.glDrawBuffer(GL11.GL_NONE);
      GL11.glReadBuffer(GL11.GL_NONE);
      GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
     
      Matrix4f depthTransform = getLightMatrix(i);
      depthProgram.use();
      depthProgram.setUniformM4("u_tLight", false, depthTransform);
      depthProgram.setUniformf("u_lPosition", position.x, position.y, position.z);
      rootObject.render(null, depthProgram);
      GL11.glColorMask(true, true, true, true);
   }
GL11.glPopAttrib();
GL11.glClearDepth(1.0d);


And to find the light projection/view matrix per-face, (I'm certain this one's right, worked with the spotlight...)
1  
2  
3  
4  
5  
6  
7  
8  
private Matrix4f getLightMatrix(int index){
   Vector3f direction = DIRECTIONS[index];      
   Vector3f up        = DIRECTIONS_UP[index];
   
   Matrix4f out = ViewTransformComponent.lookat(position, direction, up);
   out.mul(depthProjection);
   return out;
}


Here's what I use in the light pass, to multiply with the light fragment
v_position is in world space (object matrix * vertex) and l_position is traditionally in world space
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
uniform samplerCube u_sDepthMap;

float shadowVisibility(vec3 l_position, vec3 v_position){
   vec3 l_direction = l_position - v_position;
   
   float depth  = length(l_direction);
   float sample = textureCube(u_sDepthMap, normalize(l_direction)).z;
   
   if(sample <= depth + 0.00005) return 1;
   else                          return 0;
};


And the fragment shader for the 'depth' pass, same world space calculation as before just with the light's matrix.
1  
2  
3  
4  
5  
6  
7  
8  
9  
#include "./asset/shader/global.fsh"

varying vec3 v_lPosition_ws;
varying vec3 v_vPosition_ws;

vec4 calcPixel()
{
   return vec4(length(v_vPosition_ws - v_lPosition_ws));
}


Vertex shader for the 'depth' pass
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
#include "./asset/shader/global.vsh"

uniform mat4 u_tLight;
uniform vec3 u_lPosition;

varying vec3 v_lPosition_ws;
varying vec3 v_vPosition_ws;

void main(void)
{
   v_lPosition_ws = u_lPosition;
   v_vPosition_ws = vec3(u_tObject * gl_Vertex);
   gl_Position = u_tLight * vec4(v_vPosition_ws, gl_Vertex.w);
}


Stack overflow doesn't know what's up, but here's the output:


As you can see in the small circle is an error I noticed happening. But in the large circle the shadows not projecting. More code will be provided on request. Thanks in advance!

Offline pitbuller
« Reply #1 - Posted 2015-01-09 19:22:48 »

For shadow mapping you don't need any pixel shader. You just render to hardware depth buffer and use that as depth texture. You do not want distance to camera but the unmodified depth.
Offline Ecumene

JGO Kernel


Medals: 200
Projects: 4
Exp: 8 years


I did not hit her! I did not!


« Reply #2 - Posted 2015-01-10 00:08:36 »

For shadow mapping you don't need any pixel shader. You just render to hardware depth buffer and use that as depth texture. You do not want distance to camera but the unmodified depth.

But what about the cube maps? I still barely understand this, but doesn't cubemaps sample using a direction? In another tutorial they said to use a fragment shader with the length of the light in world space to the position in world space. Do you know any good tutorials / books that talk about cubemap shadow mapping? Also, how would I render the hardware depth buffer?

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline KudoDEV

JGO Ninja


Medals: 79
Exp: 6 years


Game Dev Hobbyist


« Reply #3 - Posted 2015-01-10 01:23:43 »

Yes for point lights you need a cubemap. That's how I would do it. There's another method but I don;t remember what it's called

Offline KaiHH

JGO Kernel


Medals: 764



« Reply #4 - Posted 2015-01-10 01:53:25 »

Quote
There's another method but I don;t remember what it's called
You likely mean Dual Paraboloid Mapping and it being applied to shadow mapping?
Pages: [1]
  ignore  |  Print  
 
 

 
Riven (189 views)
2019-09-04 15:33:17

hadezbladez (4875 views)
2018-11-16 13:46:03

hadezbladez (1790 views)
2018-11-16 13:41:33

hadezbladez (5147 views)
2018-11-16 13:35:35

hadezbladez (1018 views)
2018-11-16 13:32:03

EgonOlsen (4377 views)
2018-06-10 19:43:48

EgonOlsen (5220 views)
2018-06-10 19:43:44

EgonOlsen (2949 views)
2018-06-10 19:43:20

DesertCoockie (3868 views)
2018-05-13 18:23:11

nelsongames (4294 views)
2018-04-24 18:15:36
Java Gaming Resources
by philfrei
2019-05-14 16:15:13

Deployment and Packaging
by philfrei
2019-05-08 15:15:36

Deployment and Packaging
by philfrei
2019-05-08 15:13:34

Deployment and Packaging
by philfrei
2019-02-17 20:25:53

Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08

Deployment and Packaging
by gouessej
2018-08-22 08:03:45
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!