?
Also der Treiber macht definitiv kein PCF, 100%ig.
Ich wollte mich nun erstmal an einem neuen Tutorial orietieren, da vorallem dort PCF gezeigt wird!
http://fabiensanglard.net/shadowmappingPCF/index.php
Die Sache ist, wenn ich mir die fertige exe downloade und ausführe, dann werden zwar die Objekte gerendert aber ein Schatten wird nicht angezeigt (zumindest alles andere als richtig). Habe daher das Projekt mal selber compiled mit dem selben Ergebnis! Hab schon das FBO gegen meins ausgetauscht und einiges mehr aber es will nicht funktionieren! Ich packe daher einfach mal den Code hier rein - vllt. fällt ja jemanden etwas auf! Code an sich sollte übersichtlich sein.
#include <iostream>
#include <cmath>
#include <cstdio>
#include "gl/glew.h"
#include "gl/freeglut.h"
using namespace std;
const int RENDER_WIDTH = 1024;
const int RENDER_HEIGHT = 768;
const int ShadowMapSize = 512;
float p_camera[3] = {35,25,5};
float l_camera[3] = {0,-7,-25};
float p_light[3] = {3,16,0};
float l_light[3] = {0,0,-5};
float light_mvnt = 30.0f;
GLuint fboId;
GLuint depthTextureId;
GLuint shadowShaderId;
GLuint shadowMapUniform;
GLuint shadowMapStepXUniform;
GLuint shadowMapStepYUniform;
char *textFileRead(char *fn)
{
FILE *fp;
char *content = NULL;
size_t count=0;
if (fn != NULL) {
fopen_s(&fp, fn,"rt");
if (fp != NULL) {
fseek(fp, 0, SEEK_END);
count = ftell(fp);
rewind(fp);
if (count > 0) {
content = (char *)malloc(sizeof(char) * (count+1));
count = fread(content,sizeof(char),count,fp);
content[count] = '\0';
}
fclose(fp);
}
}
return content;
}
void loadShadowShader()
{
GLuint v, f;
char *vs = NULL, *fs = NULL;
v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);
vs = textFileRead("VertexShader.c");
fs = textFileRead("FragmentShader.c");
const char * vv = vs;
const char * ff = fs;
glShaderSource(v, 1, &vv,NULL);
glShaderSource(f, 1, &ff,NULL);
delete vs;
delete fs;
glCompileShader(v);
glCompileShader(f);
shadowShaderId = glCreateProgram();
glAttachShader(shadowShaderId, v);
glAttachShader(shadowShaderId, f);
glLinkProgram(shadowShaderId);
glUseProgram(shadowShaderId);
shadowMapUniform = glGetUniformLocation(shadowShaderId, "ShadowMap");
shadowMapStepXUniform = glGetUniformLocation(shadowShaderId, "xPixelOffset");
shadowMapStepYUniform = glGetUniformLocation(shadowShaderId, "yPixelOffset");
}
void generateShadowFBO()
{
glGenTextures(1, &depthTextureId);
glBindTexture(GL_TEXTURE_2D, depthTextureId);
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, ShadowMapSize, ShadowMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
float cp[] = {1,1,1,1};
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, cp);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
glBindTexture(GL_TEXTURE_2D, 0);
glGenFramebuffers(1, &fboId);
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTextureId, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void setupMatrices(float position_x,float position_y,float position_z,float lookAt_x,float lookAt_y,float lookAt_z, bool mode)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (mode)
gluPerspective(45, 1.0, 1.0, 1000.0);
else
gluPerspective(45, (double)RENDER_WIDTH/RENDER_HEIGHT, 1.0, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(position_x,position_y,position_z,lookAt_x,lookAt_y,lookAt_z,0,1,0);
}
void update(void)
{
p_light[0] = light_mvnt * cos(glutGet(GLUT_ELAPSED_TIME)/1000.0f);
p_light[2] = light_mvnt * sin(glutGet(GLUT_ELAPSED_TIME)/1000.0f);
}
void setTextureMatrix(void)
{
static double modelView[16];
static double projection[16];
const GLdouble bias[16] = {
0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0};
// Grab modelview and transformation matrices
glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glMatrixMode(GL_TEXTURE);
glActiveTexture(GL_TEXTURE7);
glLoadIdentity();
glLoadMatrixd(bias);
// concatating all matrice into one.
glMultMatrixd (projection);
glMultMatrixd (modelView);
// Go back to normal matrix mode
glMatrixMode(GL_MODELVIEW);
}
void startTranslate(float x,float y,float z)
{
glPushMatrix();
glTranslatef(x,y,z);
glMatrixMode(GL_TEXTURE);
glActiveTexture(GL_TEXTURE7);
glPushMatrix();
glTranslatef(x,y,z);
}
void endTranslate()
{
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
void drawObjects(void)
{
// Ground
glColor4f(0.3f,0.3f,0.3f,1);
glBegin(GL_QUADS);
glVertex3f(-45,2,-45);
glVertex3f(-45,2, 55);
glVertex3f( 55,2, 55);
glVertex3f( 55,2,-45);
glEnd();
glColor4f(0.9f,0.9f,0.9f,1);
// Instead of calling glTranslatef, we need a custom function that also maintain the light matrix
startTranslate(0,4,-16);
glutSolidCube(4);
endTranslate();
startTranslate(0,4,-5);
glutSolidSphere(4,40,40);
endTranslate();
}
void renderScene(void)
{
update();
glUseProgram(0);
//Render Scene => FBO
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
glClear( GL_DEPTH_BUFFER_BIT);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glViewport(0, 0, ShadowMapSize, ShadowMapSize);
setupMatrices(p_light[0],p_light[1],p_light[2],l_light[0],l_light[1],l_light[2], true);
glCullFace(GL_FRONT);
drawObjects();
setTextureMatrix();
glBindFramebuffer(GL_FRAMEBUFFER,0);
glViewport(0,0, (int)RENDER_WIDTH, (int)RENDER_HEIGHT);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Using the shadow shader
glUseProgram(shadowShaderId);
glActiveTexture(GL_TEXTURE7);
glUniform1i(shadowMapUniform, 7);
glBindTexture(GL_TEXTURE_2D,depthTextureId);
glUniform1f(shadowMapStepXUniform, 1.0/ ShadowMapSize);
glUniform1f(shadowMapStepYUniform, 1.0/ ShadowMapSize);
setupMatrices(p_camera[0],p_camera[1],p_camera[2],l_camera[0],l_camera[1],l_camera[2], false);
glCullFace(GL_BACK);
drawObjects();
// DEBUG only. this piece of code draw the depth buffer onscreen
glUseProgram(0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-RENDER_WIDTH/2,RENDER_WIDTH/2,-RENDER_HEIGHT/2,RENDER_HEIGHT/2,1,20);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor4f(1,1,1,1);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,depthTextureId);
glEnable(GL_TEXTURE_2D);
glTranslated(0,0,-1);
glBegin(GL_QUADS);
glTexCoord2d(0,0);glVertex3f(0,0,0);
glTexCoord2d(1,0);glVertex3f(RENDER_WIDTH/2,0,0);
glTexCoord2d(1,1);glVertex3f(RENDER_WIDTH/2,RENDER_HEIGHT/2,0);
glTexCoord2d(0,1);glVertex3f(0,RENDER_HEIGHT/2,0);
glEnd();
glDisable(GL_TEXTURE_2D);
glUseProgram(shadowShaderId);
glutSwapBuffers();
glutPostRedisplay();
}
void processNormalKeys(unsigned char key, int x, int y) {
if (key == 27)
exit(0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
glutInitWindowPosition(100,100);
glutInitWindowSize((int)RENDER_WIDTH, (int)RENDER_HEIGHT);
glutCreateWindow("GLSL Shadow mapping");
glewInit();
generateShadowFBO();
loadShadowShader();
// This is important, if not here, FBO's depthbuffer won't be populated.
glEnable(GL_DEPTH_TEST);
glClearDepth(1.0);
glDepthFunc(GL_LEQUAL);
glClearColor(0,0,0,1.0f);
glEnable(GL_CULL_FACE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
glutDisplayFunc(renderScene);
glutKeyboardFunc(processNormalKeys);
glutMainLoop();
return 0;
}
VertexShader:
varying vec4 ShadowCoord;
void main()
{
ShadowCoord= gl_TextureMatrix[7] * gl_Vertex;
gl_Position = ftransform();
gl_FrontColor = gl_Color;
}
FragmentShader:
uniform sampler2DShadow ShadowMap;
varying vec4 ShadowCoord;
uniform float xPixelOffset ;
uniform float yPixelOffset ;
float lookup( vec2 offSet)
{
return shadow2DProj(ShadowMap, ShadowCoord + vec4(offSet.x * xPixelOffset * ShadowCoord.w, offSet.y * yPixelOffset * ShadowCoord.w, 0.05, 0.0) ).w;
}
void main()
{
float shadow ;
if (ShadowCoord.w > 1.0)
{
float x,y;
for (y = -3.5 ; y <=3.5 ; y+=1.0)
for (x = -3.5 ; x <=3.5 ; x+=1.0)
shadow += lookup(vec2(x,y));
shadow /= 64.0 ;
}
gl_FragColor = (shadow+0.2) * gl_Color;
}
Für mich sieht es so aus, als ob garkeine depth-texture ins FBO kommt, was mich aber wundert, da ich eben auch ein FBO von mir genommen habe was definitiv funktioniert - der Fehler muss also noch woanders liegen.
Ps. Ich hatte mir auch mal sein normales ShadowMapping angeschaut und muss sagen, dass es auch dort ein Fehler gibt.
Im Fragment Shader will er z.B. eine vec4 Variable an texture2D übergeben - läuft natürlich nicht. Als vec2 mit .st oder texture2DProj und dann vec4 läuft. Fehler sind wohl keine Seltenheit.