Просмотр исходного кода

Fixed shadow mapping, which was broken by recent changes. Framebuffer binding in Renderer now keeps a stack, restores previous framebuffer binding on unbind, spotlight shadowmap fov now gets correctly set in SceneLight, shadow mapping now works in IDE entity editor

Ivan Safrin 11 лет назад
Родитель
Сommit
7fcf69c036

BIN
Assets/Default asset pack/default.pak


+ 6 - 5
Assets/Default asset pack/default/DefaultShaderShadows.frag

@@ -8,14 +8,13 @@ uniform sampler2D diffuse;
 uniform sampler2D shadowMap0;
 uniform sampler2D shadowMap1;
 
-uniform mat4 shadowMatrix0;
-uniform mat4 shadowMatrix1;
-
 uniform vec4 diffuse_color;
 uniform vec4 specular_color;
 uniform vec4 ambient_color;
 uniform float shininess;
 
+uniform float shadowAmount;
+
 
 float calculateAttenuation(in int i, in float dist)
 {
@@ -57,12 +56,14 @@ void pointLight(in int i, in vec3 normal, in vec4 pos, inout vec4 diffuse, inout
 void spotLight(in int i, in vec3 normal, in vec4 pos, inout vec4 diffuse, inout vec4 specular, sampler2D shadowMap, vec4 ShadowCoord) {
 	
 	vec4 shadowCoordinateWdivide = ShadowCoord / ShadowCoord.w;
-	shadowCoordinateWdivide.z -= 0.000005;
+	//shadowCoordinateWdivide.z -= 0.00005;
 	float distanceFromLight = texture2D(shadowMap,shadowCoordinateWdivide.st).z;
 	float shadow = 1.0;
-	if (shadowCoordinateWdivide.x > 0.01 && shadowCoordinateWdivide.y > 0.01 && shadowCoordinateWdivide.x < 0.99 && shadowCoordinateWdivide.y < 0.99)
+	if (shadowCoordinateWdivide.x > 0.001 && shadowCoordinateWdivide.y > 0.001 && shadowCoordinateWdivide.x < 0.999 && shadowCoordinateWdivide.y < 0.999)
 		shadow = distanceFromLight < shadowCoordinateWdivide.z ? 0.0 : 1.0 ;
 	
+	shadow = clamp(shadow+(1.0-shadowAmount), 0.0, 1.0);
+	
 	vec4 color = diffuse_color;
 	vec4 matspec = specular_color;
 	float shininess = shininess;

+ 1 - 1
Core/Contents/Include/PolyGLRenderer.h

@@ -1,4 +1,4 @@
-
+    
 /*
 Copyright (C) 2011 by Ivan Safrin
 

+ 6 - 3
Core/Contents/Include/PolyRenderer.h

@@ -103,9 +103,9 @@ namespace Polycode {
 		virtual void createRenderTextures(Texture **colorBuffer, Texture **depthBuffer, int width, int height, bool floatingPointBuffer) = 0;
 		
 		virtual Texture *createFramebufferTexture(unsigned int width, unsigned int height) = 0;
-		virtual void bindFrameBufferTexture(Texture *texture) = 0;
-		virtual void bindFrameBufferTextureDepth(Texture *texture) = 0;
-		virtual void unbindFramebuffers() = 0;
+		virtual void bindFrameBufferTexture(Texture *texture);
+		virtual void bindFrameBufferTextureDepth(Texture *texture);
+		virtual void unbindFramebuffers();
 
 		virtual Image *renderScreenToImage() = 0;
 		virtual Image *renderBufferToImage(Texture *texture) = 0;
@@ -315,6 +315,9 @@ namespace Polycode {
         std::stack<Color> vertexColorStack;
         Color currentVertexColor;
         
+        std::stack<Texture*> framebufferStackColor;
+        std::stack<Texture*> framebufferStackDepth;
+        
 		bool scissorEnabled;
 		
 		Polycode::Rectangle scissorBox;

+ 5 - 2
Core/Contents/Source/PolyGLRenderer.cpp

@@ -635,7 +635,8 @@ void OpenGLRenderer::bindFrameBufferTextureDepth(Texture *texture) {
 		return;
 	OpenGLTexture *glTexture = (OpenGLTexture*)texture;
 	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, glTexture->getFrameBufferID());
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
+    Renderer::bindFrameBufferTextureDepth(texture);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	        
 }
 
 
@@ -644,12 +645,14 @@ void OpenGLRenderer::bindFrameBufferTexture(Texture *texture) {
 		return;
 	OpenGLTexture *glTexture = (OpenGLTexture*)texture;
 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, glTexture->getFrameBufferID());
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
+    Renderer::bindFrameBufferTexture(texture);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 }
 
 void OpenGLRenderer::unbindFramebuffers() {
 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
 	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+    Renderer::unbindFramebuffers();
 }
 
 void OpenGLRenderer::createRenderTextures(Texture **colorBuffer, Texture **depthBuffer, int width, int height, bool floatingPointBuffer) {

+ 20 - 19
Core/Contents/Source/PolyGLSLShaderModule.cpp

@@ -375,6 +375,8 @@ bool GLSLShaderModule::applyShaderMaterial(Renderer *renderer, Material *materia
             glLightf (GL_LIGHT0+lightIndex, GL_LINEAR_ATTENUATION, light.linearAttenuation);				
             glLightf (GL_LIGHT0+lightIndex, GL_QUADRATIC_ATTENUATION, light.quadraticAttenuation);				
             
+            Number shadowAmount = 0.0;
+            
             if(light.shadowsEnabled) {
                 if(shadowMapTextureIndex < 4) {
                     switch(shadowMapTextureIndex) {
@@ -401,22 +403,22 @@ bool GLSLShaderModule::applyShaderMaterial(Renderer *renderer, Material *materia
                     glActiveTexture(GL_TEXTURE0 + textureIndex);		
                     glBindTexture(GL_TEXTURE_2D, ((OpenGLTexture*)light.shadowMapTexture)->getTextureID());	
                     textureIndex++;
+            
+                    LocalShaderParam *matParam = material->getShaderBinding(shaderIndex)->getLocalParamByName(matName);
+                    if(matParam) {
+                        matParam->setMatrix4(light.textureMatrix);
+                    }
                     
-                    int mloc = glGetUniformLocation(glslShader->shader_id, matName);
-                    light.textureMatrix = light.textureMatrix;
+                    shadowAmount = 1.0;
                     
-                
-                    GLfloat mat[16];
-                    for(int z=0; z < 16; z++) {
-                        mat[z] = light.textureMatrix.ml[z];
-                    }
-                    glUniformMatrix4fv(mloc, 1, false, mat);
-            
-                        
                 }
+                
                 shadowMapTextureIndex++;
-            } else {
-                light.shadowsEnabled = false;
+            }
+            
+            LocalShaderParam *amountParam = material->getShaderBinding(shaderIndex)->getLocalParamByName("shadowAmount");
+            if(amountParam) {
+                amountParam->setNumber(shadowAmount);
             }
             
             lightIndex++;
@@ -427,13 +429,12 @@ bool GLSLShaderModule::applyShaderMaterial(Renderer *renderer, Material *materia
 	glEnable(GL_TEXTURE_2D);
 
 	Matrix4 modelMatrix = renderer->getModelviewMatrix() * renderer->getCameraMatrix();
-	int mloc = glGetUniformLocation(glslShader->shader_id, "modelMatrix");				
-	GLfloat mat[16];
-	for(int z=0; z < 16; z++) {
-		mat[z] = modelMatrix.ml[z];
-	}
-	glUniformMatrix4fv(mloc, 1, false, mat);
-		
+    LocalShaderParam *modelMatrixParam = material->getShaderBinding(shaderIndex)->getLocalParamByName("modelMatrix");
+    
+    if(modelMatrixParam) {
+        modelMatrixParam->setMatrix4(modelMatrix);
+    }
+    
 	ShaderBinding *cgBinding = material->getShaderBinding(shaderIndex);
 	
 	for(int i=0; i < glslShader->expectedParams.size(); i++) {

+ 31 - 0
Core/Contents/Source/PolyRenderer.cpp

@@ -105,6 +105,37 @@ void Renderer::clearLights() {
 	spotLights.clear();
 }
 
+
+void Renderer::bindFrameBufferTexture(Texture *texture) {
+    framebufferStackColor.push(texture);
+}
+
+void Renderer::bindFrameBufferTextureDepth(Texture *texture) {
+    framebufferStackDepth.push(texture);
+}
+
+void Renderer::unbindFramebuffers() {
+    if(framebufferStackColor.size() > 0) {
+        framebufferStackColor.pop();
+    }
+    if(framebufferStackDepth.size() > 0) {
+        framebufferStackDepth.pop();
+    }
+
+    if(framebufferStackColor.size() > 0) {
+        Texture *rebindTexture = framebufferStackColor.top();
+        framebufferStackColor.pop();
+        bindFrameBufferTexture(rebindTexture);
+    }
+
+    if(framebufferStackDepth.size() > 0) {
+        Texture *rebindTexture = framebufferStackDepth.top();
+        framebufferStackDepth.pop();
+        bindFrameBufferTextureDepth(rebindTexture);
+    }
+    
+}
+
 void Renderer::setExposureLevel(Number level) {
 	exposureLevel = level;
 }

+ 4 - 5
Core/Contents/Source/PolyScene.cpp

@@ -245,13 +245,12 @@ void Scene::Render(Camera *targetCamera) {
 		Vector3 direction;
 		Vector3 position;
 		matrixPtr = NULL;				
-		direction.x = 0;		
-		direction.y = 0;
-		direction.z = -1;
-		
+		direction.x = 0;
+		direction.y = 0.0;
+		direction.z = -1.0;
+		direction.Normalize();
 		
 		direction = light->getConcatenatedMatrix().rotateVector(direction);
-		direction.Normalize();
 		
 		Texture *shadowMapTexture = NULL;
 		if(light->areShadowsEnabled()) {

+ 8 - 6
Core/Contents/Source/PolySceneLight.cpp

@@ -74,12 +74,16 @@ void SceneLight::enableShadows(bool val, unsigned int resolution) {
         if(zBufferTexture) {
             CoreServices::getInstance()->getMaterialManager()->deleteTexture(zBufferTexture);
         }
-        
         CoreServices::getInstance()->getRenderer()->createRenderTextures(NULL, &zBufferTexture, resolution, resolution, false);
 		if(!spotCamera) {
 			spotCamera = new Camera(parentScene);
+            /*
+            spotCamera->setProjectionMode(Camera::ORTHO_SIZE_MANUAL);
+            spotCamera->setOrthoSize(5.0, 5.0);
+             */
             spotCamera->editorOnly = true;
-//			spotCamera->setPitch(-45.0f);
+            spotCamera->setClippingPlanes(0.01, 100.0);
+//            spotCamera->setPitch(90.0);
 			addChild(spotCamera);	
 		}
 		shadowMapRes = resolution;
@@ -124,8 +128,8 @@ unsigned int SceneLight::getShadowMapResolution() const {
 }
 
 void SceneLight::renderDepthMap(Scene *scene) {
+    spotCamera->setFOV(shadowMapFOV);
 	Renderer* renderer = CoreServices::getInstance()->getRenderer();
-	renderer->clearScreen();
 	renderer->pushMatrix();
 	renderer->loadIdentity();
 
@@ -133,13 +137,11 @@ void SceneLight::renderDepthMap(Scene *scene) {
     Number vpH = renderer->getViewportHeight();
     
 	renderer->setViewportSize(shadowMapRes, shadowMapRes);
-	Camera* camera = scene->getActiveCamera();
-	renderer->setProjectionFromFoV(shadowMapFOV, camera->getNearClippingPlane(), camera->getFarClippingPlane());
 	renderer->bindFrameBufferTexture(zBufferTexture);
 
 	scene->RenderDepthOnly(spotCamera);
 		
-	lightViewMatrix = renderer->getModelviewMatrix() *  renderer->getProjectionMatrix();
+	lightViewMatrix = getConcatenatedMatrix().Inverse() *  renderer->getProjectionMatrix();
 	renderer->unbindFramebuffers();
 	renderer->popMatrix();
 	renderer->setViewportSize(vpW , vpH);

BIN
Examples/C++/Resources/default.pak


+ 1 - 0
IDE/Contents/Source/PolycodeEntityEditor.cpp

@@ -896,6 +896,7 @@ void EntityEditorMainView::addEntityFromMenu(String command) {
         mainScene->addLight(newLight);
         newLight->enabled = !lightsDisabled;        
         setEditorProps(newLight);
+        newLight->setLocalBoundingBox(Vector3());
         newLight->setPosition(cursorPosition);
         didPlaceEntity(newLight);
         selectEntity(newLight, false, false);