예제 #1
0
        private void Update(Scene scene, Camera camera)
        {
            // set GL state for depth map
		    GL.ClearColor( 1, 1, 1, 1 );
		    GL.Disable( EnableCap.Blend);
            renderer.DepthTest = true;

		// update scene
		if ( scene.AutoUpdate) scene.UpdateMatrixWorld();

		// update camera matrices and frustum
		camera.matrixWorldInverse = Matrix4.GetInverse(camera.matrixWorld);
            projectionScreenMatrix.MultiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
		frustum = Frustum.FromMatrix( projectionScreenMatrix );

		// render depth map
            renderer.SetRenderTarget(renderTarget );
		renderer.Clear();

		// set object matrices & frustum culling
		renderList.Clear();
		ProjectObject(scene,scene,camera);

		// render regular objects
            foreach(var glObject in renderList) 
            {
			var o = glObject.Object;
			var buffer = glObject.Buffer;

			// TODO: create proper depth material for particles
			if(o is PointCloud /*&& !o.customDepthMaterial*/) continue;

           // var useMorphing = o.geometry.MorphTargets != null && o.geometry.MorphTargets.Count > 0; /* TODO IAN, need this for skinning? && object.Material.morphTargets */
           //     var useSkinning = o is SkinnedMesh; /* TODO IAN, need this for skinning? && object.Material.skinning */

                Material material;
			if (o.customDepthMaterial != null) material = o.customDepthMaterial;
			//else if ( useSkinning ) material = useMorphing ? depthMaterialMorphSkin : depthMaterialSkin;
            //else if ( useMorphing ) material = depthMaterialMorph;
            else material = depthMaterial;
                
			renderer.RenderBuffer( camera, scene.lights, null, material, buffer, o );
		}

		// restore GL state
		var clearColor = renderer.ClearColor;
            GL.ClearColor(clearColor.R, clearColor.G, clearColor.B, 1 );
            GL.Enable( EnableCap.Blend);
        }
예제 #2
0
        public static Frustum  FromMatrix(Matrix4 projectionScreen)
        {
            var me = projectionScreen.elements;
            float me0 = me[0], me1 = me[1], me2 = me[2], me3 = me[3];
            float me4 = me[4], me5 = me[5], me6 = me[6], me7 = me[7];
            float me8 = me[8], me9 = me[9], me10 = me[10], me11 = me[11];
            float me12 = me[12], me13 = me[13], me14 = me[14], me15 = me[15];

            var f = new Frustum(
                new Plane(me3 - me0, me7 - me4, me11 - me8, me15 - me12),
                new Plane(me3 + me0, me7 + me4, me11 + me8, me15 + me12),
                new Plane(me3 + me1, me7 + me5, me11 + me9, me15 + me13),
                new Plane(me3 - me1, me7 - me5, me11 - me9, me15 - me13),
                new Plane(me3 - me2, me7 - me6, me11 - me10, me15 - me14),
                new Plane(me3 + me2, me7 + me6, me11 + me10, me15 + me14));
            foreach(var p in f.planes) p.Normalize();            
            return f;
        }
예제 #3
0
        private void Update(Scene scene, Camera camera)
        {
            // set GL state for depth map
            GL.ClearColor(1, 1, 1, 1);
            GL.Disable(EnableCap.Blend);
            GL.Enable(EnableCap.CullFace);
            GL.FrontFace(FrontFaceDirection.Ccw);

            GL.CullFace(renderer.shadowMapCullFace);

            renderer.DepthTest = true;
            var lights = new List<Light>();

            // preprocess lights
            // 	- skip lights that are not casting shadows
            //	- create virtual lights for cascaded shadow maps
            foreach (var light in scene.lights)
            {
                if (!light.DoesCastShadow) continue;

                var shadowLight = light as HasShadow;
                if (shadowLight != null && shadowLight.ShadowCascade)
                {
                    for (var n = 0; n < shadowLight.ShadowCascadeCount; n++)
                    {
                        VirtualLight virtualLight;

                        if (shadowLight.ShadowCascadeArray[n] == null)
                        {
                            virtualLight = CreateVirtualLight(light, n);
                            virtualLight.OriginalCamera = camera;

                            var gyro = new Gyroscope();
                            gyro.Position = shadowLight.ShadowCascadeOffset;

                            gyro.Add(virtualLight);
                            //gyro.Add(virtualLight.Target);
                            camera.Add(gyro);

                            shadowLight.ShadowCascadeArray[n] = virtualLight;
                            Debug.WriteLine("Created virtualLight {0}", virtualLight);
                        }
                        else
                        {
                            virtualLight = shadowLight.ShadowCascadeArray[n];
                        }

                        UpdateVirtualLight(light, n);
                        lights.Add(virtualLight);
                    }
                }
                else
                {
                    lights.Add(light);
                }

            }

            // render depth map
            foreach (var light in lights)
            {
                var hasShadow = light as HasShadow;
                if (hasShadow.shadowMap == null)
                {
                    var isSoftShadow = renderer.shadowMapType == ShadowType.PCFSoftShadowMap;
                    hasShadow.shadowMap = new RenderTarget(hasShadow.ShadowMapWidth, hasShadow.ShadowMapHeight);
                    hasShadow.shadowMap.MinFilter = isSoftShadow ? TextureMinFilter.Nearest : TextureMinFilter.Linear;
                    hasShadow.shadowMap.MagFilter = isSoftShadow ? TextureMagFilter.Nearest : TextureMagFilter.Linear; ;
                    hasShadow.shadowMap.Format = Three.Net.Renderers.PixelFormat.RGBA;

                    hasShadow.ShadowMapSize = new Vector2(hasShadow.ShadowMapWidth, hasShadow.ShadowMapHeight);
                    hasShadow.ShadowMatrix = Matrix4.Identity;
                }

                if (hasShadow.ShadowCamera == null)
                {

                    if (hasShadow is SpotLight) hasShadow.ShadowCamera = new PerspectiveCamera(renderer, hasShadow.ShadowCameraFov, hasShadow.ShadowCameraNear, hasShadow.ShadowCameraFar);
                    else if (hasShadow is DirectionalLight) hasShadow.ShadowCamera = new OrthographicCamera(hasShadow.ShadowCameraLeft, hasShadow.ShadowCameraRight, hasShadow.ShadowCameraTop, hasShadow.ShadowCameraBottom, hasShadow.ShadowCameraNear, hasShadow.ShadowCameraFar);
                    else throw new Exception("Unsupported light type for shadow");

                    scene.Add(hasShadow.ShadowCamera);
                    if (scene.AutoUpdate) scene.UpdateMatrixWorld();

                }

                if (hasShadow.ShadowCameraVisible /* && light.CameraHelper == null*/)
                {
                    throw new NotImplementedException();
                    //light.CameraHelper = new CameraHelper( hasShadow.ShadowCamera );
                    //hasShadow.ShadowCamera.Add( light.CameraHelper );
                }

                var virtualLight = light as VirtualLight;
                if (virtualLight != null && virtualLight.OriginalCamera == camera)
                {
                    UpdateShadowCamera(camera, light);
                }

                var shadowMap = hasShadow.shadowMap;
                var shadowMatrix = hasShadow.ShadowMatrix;
                var shadowCamera = hasShadow.ShadowCamera;

                shadowCamera.Position = Vector3.FromPosition(light.matrixWorld);
                matrixPosition = (light as HasTarget).Target;
                shadowCamera.LookAt(matrixPosition);
                shadowCamera.UpdateMatrixWorld();

                shadowCamera.matrixWorldInverse = Matrix4.GetInverse(shadowCamera.matrixWorld);

                //TODO : Creating helpers if ( light.cameraHelper ) light.cameraHelper.visible = light.shadowCameraVisible;
                //if (hasShadow.ShadowCameraVisible) light.cameraHelper.update();

                // compute shadow matrix

                shadowMatrix = new Matrix4(0.5f, 0.0f, 0.0f, 0.5f,
                                            0.0f, 0.5f, 0.0f, 0.5f,
                                            0.0f, 0.0f, 0.5f, 0.5f,
                                            0.0f, 0.0f, 0.0f, 1.0f);

                shadowMatrix.Multiply(shadowCamera.projectionMatrix);
                shadowMatrix.Multiply(shadowCamera.matrixWorldInverse);

                // update camera matrices and frustum
                projectionScreenMatrix.MultiplyMatrices(shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse);
                frustum = Frustum.FromMatrix(projectionScreenMatrix);

                // render shadow map
                renderer.SetRenderTarget(shadowMap);
                renderer.Clear();

                // set object matrices & frustum culling

                renderList.Clear();
                ProjectObject(scene, scene, shadowCamera);

                // render regular objects
                foreach (var glObject in renderList)
                {
                    var o = glObject.Object;
                    var buffer = glObject.Buffer;

                    throw new NotImplementedException();
                }
            }

            // restore GL state
            var clearColor = renderer.ClearColor;
            GL.ClearColor(clearColor.R, clearColor.G, clearColor.B, 1);
            GL.Enable(EnableCap.Blend);

            if (renderer.shadowMapCullFace == CullFaceMode.Front) GL.CullFace(CullFaceMode.Back);

        }