Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 10 of 10

Thread: using nvidia HW PCF

  1. #1
    Intern Contributor
    Join Date
    Jan 2007
    Location
    Sweden
    Posts
    50

    using nvidia HW PCF

    how would on use nvidia hw pcf?

    also im unsure how i would use a regular depthmap for shadowmaps.. right now i simply convert the depth to fit a rgba8 texture liek this...

    Code :
    //FBO
    			size = 2048.0;
                             GLint  type = GL_RGBA8;
     
    			glActiveTexture(GL_TEXTURE10);
     
    			// Setup our FBO
    			glGenFramebuffersEXT(1, &fbo);
    			glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
     
    			// Create the render buffer for depth	
    			glGenRenderbuffersEXT(1, &depthBuffer);
    			glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
    			glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size, size);
     
    			// Now setup a texture to render to
    			glGenTextures(1, &img);
    			glBindTexture(GL_TEXTURE_2D, img);
    				glTexImage2D(GL_TEXTURE_2D, 0, type,  size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    				glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    				glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    				glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    				glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     
     
     
    			// And attach it to the FBO so we can render to it
    			glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, img, 0);
     
    			// Attach the depth render buffer to the FBO as it's depth attachment
    			glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);
     
    			glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);	// Unbind the FBO for now
     
    			GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
     
    /// WRITE TO SHADOWMAP 
     
    // FRAGMENT
     
    varying float Depth;
     
    void main()
    {		 		
        const vec4 bitSh = vec4(	256*256*256, 256*256,	256,			1);
        const vec4 bitMsk = vec4(	0,		1.0/256.0, 	1.0/256.0, 1.0/256.0);
     
        float dist = Depth;
     
        vec4 comp;
    	comp=dist*bitSh;	
     
        comp=fract(comp);
        comp-=comp.xxyz*bitMsk;    
     
        gl_FragColor= vec4(comp);
     
    }
     
    // CALCULATE SHADOWS
     
    // FRAGMENT 
     
    varying vec4 ProjShadow;
    varying float Depth;
     
    uniform sampler2D Shadow;
     
     
    const vec4 bitShifts = vec4(1.0/(256.0*256.0*256.0),1.0/(256.0*256.0), 1.0/256.0, 1);
     
    float GetShadow(vec2 TexCoord)
    {
    	vec4 shadmap = texture2D(Shadow,TexCoord);
    	float shad = dot(shadmap , bitShifts);
    	return (shad < Depth+0.0065);
    }
    i dont think is the best way to do it... but as i said im unsure how to write to a 32bit depthmap and use HW pcf

  2. #2
    Junior Member Regular Contributor
    Join Date
    Mar 2007
    Location
    Latvia
    Posts
    225

    Re: using nvidia HW PCF

    I think nvidia hw pcf is ONLY available to textures with GL_DEPTH_COMPONENT internal format and GL_LINEAR min/mag filter.

  3. #3
    Intern Contributor
    Join Date
    Jan 2007
    Location
    Sweden
    Posts
    50

    Re: using nvidia HW PCF

    ok.. but my problem is taht i dont know how to use GL_DEPTH_COMPONENT... how do i send info to it in the fragment shader? does it work with glortho where near = 0.0 and far = 1.0... what settings should the FBO use?

  4. #4
    Member Regular Contributor
    Join Date
    Jul 2005
    Location
    Germany
    Posts
    311

    Re: using nvidia HW PCF

    for your fbo you should use perspective projection. when creating your depth texture set these parameters:

    Code :
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE );
    in your fragment shader you can then declare your texture as sampler2DShadow instead of the regular sampler2D. this will automatically perform the depth comparison for you.

  5. #5
    Intern Contributor
    Join Date
    Jan 2007
    Location
    Sweden
    Posts
    50

    Re: using nvidia HW PCF

    Originally posted by Vexator:
    for your fbo you should use perspective projection. when creating your depth texture set these parameters:

    Code :
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE );
    in your fragment shader you can then declare your texture as sampler2DShadow instead of the regular sampler2D. this will automatically perform the depth comparison for you.
    so basicly is et the FBO liek this..

    Code :
     			size = 2048.0;
                             GLint  type = GL_DEPTH_COMPONENT;
     
    			glActiveTexture(GL_TEXTURE10);
     
    			// Setup our FBO
    			glGenFramebuffersEXT(1, &amp;fbo);
    			glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
     
    			// Create the render buffer for depth	
    			glGenRenderbuffersEXT(1, &amp;depthBuffer);
    			glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
    			glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size, size);
     
    			// Now setup a texture to render to
    			glGenTextures(1, &amp;img);
    			glBindTexture(GL_TEXTURE_2D, img);
    				glTexImage2D(GL_TEXTURE_2D, 0, type,  size, size, 0, type, GL_UNSIGNED_BYTE, NULL);
    				glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    				glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    				glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    				glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE );
     
    			// And attach it to the FBO so we can render to it
    			glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, img, 0);
     
    			// Attach the depth render buffer to the FBO as it's depth attachment
    			glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);
     
    			glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);	// Unbind the FBO for now
     
    			GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    but how do i set up the shader when rendering to the FBO... is it just gl_FragColor = Depth... ?how are the values stored in the depth buffer.. are they 0.0-1.0 or realworld values?

    also i want to use ortho projection since my lightsource is parallel...

    when i call the shadow2Dproj function in the shader are they with pcf or only with bilinear filtering?

  6. #6
    Intern Contributor
    Join Date
    Jan 2007
    Location
    Sweden
    Posts
    50

    Re: using nvidia HW PCF

    just as a side note... how would i do bilinear filtering in the fragment shader.. i think ive got pcf right..

    Code :
    float shadow = GetPCF(ProjShadow.xy/ProjShadow.w);
    float GetShadow(vec2 TexCoord)
    {
    	vec4 shadmap = texture2D(Shadow,TexCoord);
    	float shad = dot(shadmap , bitShifts);
    	return (shad < Depth+0.0058);
    }	
     
    float GetPCF(vec2 TexCoord)
    {
    	float offset = 1.0/512.0;
    	float shadow1 = 0.0;
    	shadow1 += GetShadow(TexCoord+vec2(-offset	,offset));
    	shadow1 += GetShadow(TexCoord+vec2(0		,offset));
    	shadow1 += GetShadow(TexCoord+vec2(offset	,offset));
    	shadow1 += GetShadow(TexCoord+vec2(-offset	,0));
    	shadow1 += GetShadow(TexCoord+vec2(0		,0));
    	shadow1 += GetShadow(TexCoord+vec2(offset	,0));
    	shadow1 += GetShadow(TexCoord+vec2(-offset	,-offset));
    	shadow1 += GetShadow(TexCoord+vec2(0		,-offset));
    	shadow1 += GetShadow(TexCoord+vec2(offset	,-offset));
    	shadow1 /= 9.0;
     
    	return shadow1;
    }

  7. #7
    Senior Member OpenGL Guru
    Join Date
    Mar 2001
    Posts
    3,768

    Re: using nvidia HW PCF

    In PCF, you don't filter the color. You filter the results of the comparison.

    So if you're in the middle of a 2x2 texel quad, and 3 of them say "not shadow" and one of them says "shadow", the number you should use to multiply against the light color is "0.75".

    Further, you only need 4 accesses for bilinear, not 9. And the average should be weighted based on how close the offset is to each texel.

  8. #8
    Intern Contributor
    Join Date
    Jan 2007
    Location
    Sweden
    Posts
    50

    Re: using nvidia HW PCF

    i guess my code was a bit unclear.. the function GetShadow return either 1 or 0 depending on if the color is in shadow or not...which is correct pcf right?

    but i sitll dontknow how to do the bilnear filtering.. do i filter the depth values from the shadowmap? or the result from the pcf filtering? also i have no idea how to calculate the weigth or the offsets needed for bilinear filtering... ive tried simply using 1/shadowmap size as offset... which might be right,, but i still dont know how to get the weights... also isnt the offsets somehow related to the pcf filtering?

  9. #9
    Intern Contributor
    Join Date
    Jan 2007
    Location
    Sweden
    Posts
    50

    Re: using nvidia HW PCF

    ok.. ive converted my shadowmap into the rgba16 format...and simply put the depth intto single colorchannel... which should support linear filtering.. and ive set the filtering mode to GL_LINEAR.. but it still doesnt look good.. what am i doin wrong?


  10. #10
    Super Moderator OpenGL Lord
    Join Date
    Dec 2003
    Location
    Grenoble - France
    Posts
    5,655

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •