Announcement

Collapse
No announcement yet.

Multiple Objects Using One Shadow Map?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Multiple Objects Using One Shadow Map?

    Is it possible to have multiple objects such as InterpActors share a single shadow map?

    Here is an example, I have 4 InterpActors, each one with a shadow map as indicated by the shadow frustums:


    Is there any way to make all 4 use just one shadow map?

    #2
    No. Separate objects will have individual shadowmaps and lightmaps.

    The only way to get multiple objects to cast a single shadow would be to combine all of the objects into one.

    Similarly for lightmaps. One per object.
    The only way you could get around this is to create the lightmaps externally in a 3D rendering app, simulate the environment, create the lightmap, bake it into the texture, and then set the in-game Material to unlit so that it doesn't use any engine-based lightmaps.

    Comment


      #3
      I guess I am wondering then how does it appear that 2 different meshes in the case of a player and his weapon appear to use the same shadow map since they have only a single shadow frustum? Does this only apply to skeletal meshes. Or can InterpActors have shadow parents too?

      If this is not possible to share a shadow map used by dynamic objects. Is there any way to change the resolution of shadow maps?

      Comment


        #4
        Multiple meshes can have a single "shadow parent", which causes the engine to use one shadow for all of them. This is easy to do in UScript, but as far as I can see, the only way to do it in the editor is to attach an actor to a skeletal mesh and then set bShadowParented to true, as the comment in the code says:
        Code:
        /** If TRUE, BaseSkelComponent is used as the shadow parent for this actor. */
        var(Attachment) bool bShadowParented;

        Comment


          #5
          So if I was to create a simple "base skeletal mesh" to attach all 4 InterpActors to it could work?

          Comment


            #6
            Originally posted by SynaGl0w View Post
            So if I was to create a simple "base skeletal mesh" to attach all 4 InterpActors to it could work?
            Only one way to find out. The skeletal mesh would have to be set up to cast a shadow itself of course.

            Comment


              #7
              I just rigged up a simple set of rotating InterpActors and attached them to a skeletal mesh. Checked bShadowParented. At this point they do not share the shadow map. Once I specify a BaseBoneName of the skeletal mesh then they share shadow maps, but at the same time the InterpActors can no longer rotate independently of the bone. It's as though bHardAttach is implied even though none of the InterpActors have bHardAttach checked.

              Comment


                #8
                I was about to mention that Player+Weapon uses Attach which is why it has only one shadow, I see it has already been covered.

                My question is are all of the InterpActors moving independantly?
                If so, then they should all have individual shadows to look correct.
                If they are all moving in unison with no independant difference then why are they separate and not one mesh?

                Comment


                  #9
                  Yes they are all rotating independently from each other and are attached to the thing in the middle. The only light source that provides shadows is a directional light, in this case moonlight. This would not really be any different from a character's arm moving independently from his foot or head.

                  When I attached them in the editor to the skeletal mesh so they shared the shadow map, I could still move them around and the shadow map looks correct no matter how I move them, or rotate them. I can see it being a problem for a point light, or spot light though.

                  Basically when all of them share a shadow map, less memory is being used, and also the shadow edges have a slightly softer appearance. So if there is a way to lower the resolution of the shadow maps, that would work too, but I assume that those settings are inaccessible.

                  It looks like I may have to build a mesh with bones for each InterpActor and then manipulate the bones instead of the InterpActors.

                  On a side note, what is the purpose of the Dynamic Shadow Stats tab in the Generic browser? Whatever kind of dynamic shadows I have in a map, nothing ever appears in the Dynamic Shadow Stats tab.

                  Comment


                    #10
                    Originally posted by SynaGl0w View Post
                    On a side note, what is the purpose of the Dynamic Shadow Stats tab in the Generic browser? Whatever kind of dynamic shadows I have in a map, nothing ever appears in the Dynamic Shadow Stats tab.
                    You have to play the map and type DumpDynamicShadowStats into the console. Then the tab will be filled with the stats for your map. If you make changes, you will have to perform the process again to update the stats.

                    Comment


                      #11
                      Originally posted by ffejnosliw View Post
                      You have to play the map and type DumpDynamicShadowStats into the console. Then the tab will be filled with the stats for your map. If you make changes, you will have to perform the process again to update the stats.
                      Okay thanks for the info! Always wondered why it was blank...

                      Comment


                        #12
                        Originally posted by SynaGl0w View Post
                        Yes they are all rotating independently from each other ...

                        When I attached them in the editor to the skeletal mesh so they shared the shadow map, I could still move them around and the shadow map looks correct no matter how I move them, or rotate them.

                        Basically when all of them share a shadow map, less memory is being used ...

                        It looks like I may have to build a mesh with bones for each InterpActor and then manipulate the bones instead of the InterpActors.

                        On a side note, what is the purpose of the Dynamic Shadow Stats tab ...
                        OK, I wasn't sure if they were moving relative to each other, or away and back, etc.

                        Since I am still in the dark (pun intended) about the object's intended use and other map settings, I doubt that memory would be an issue unless this object is massive above the play field.
                        However, if you are using ShadowVolumes you will have sharper edges (dynamic lights on dynamic geometry), whereas ShadowBuffer will give softer edges (static lights on dynamic geometry).

                        Unless this object has a very important role in the map, creating mesh actors and bones seems like a lot of extra work. That's your call though.

                        As ffej already mentioned, you have to dump the dynamic light info from in the PIE. The results will then show the various light actors, shadow parents, shadow types (volume or buffer), etc.

                        Comment


                          #13
                          Well thanks for the help. I seem to have been able to figure most of it out. For right now I will not worry about it too much as I decided to move one of the "islands" that these were casting shadows on. Right now I have bigger things to worry about in my map.

                          Comment


                            #14
                            I have the same issue of overlaping shadows with the pawn and a custom weapon that I made. I tried using bParentedShadow with no effect.

                            Code:
                            class MyPawn extends UTPawn;
                            
                            simulated function PostBeginPlay()
                            {
                            	super.PostBeginPlay();
                            	SetThirdPersonCamera(true);
                            }
                            
                            function Hidden(bool hide)
                            {
                            	Mesh.SetHidden(hide);
                            
                            	if(Weapon!=none)
                            	{
                            		Weapon.SetHidden(hide);
                            	}
                            }
                            
                            simulated function FaceRotation(rotator NewRotation, float DeltaTime)
                            {    
                            	if (Normal(Acceleration)!=vect(0,0,0))
                                {
                            		if ( Physics == PHYS_Ladder )
                            		{
                            			NewRotation = OnLadder.Walldir;
                            		}
                            		else if ( (Physics == PHYS_Walking) || (Physics == PHYS_Falling) )
                            		{
                            			NewRotation.Pitch = 0;
                            		}
                            		NewRotation.Roll = Rotation.Roll;
                            
                            		if (NewRotation != Rotation)
                            		{
                            			//faz uma interpolação maluca que da oque possui, aonde quer chegar, o tempo e a velocidade. oque importa é que roda da maneira certa.
                                		NewRotation = RInterpTo(Rotation,NewRotation,DeltaTime,10);
                            		}
                            		SetRotation(NewRotation);
                            	}
                            	
                            	Owner.SetLocation(Location);
                            }
                            
                            DefaultProperties
                            {
                            	//relevante<
                            
                            	Begin Object Name=WPawnSkeletalMeshComponent
                            		SkeletalMesh=SkeletalMesh'CH_IronGuard_Male.Mesh.SK_CH_IronGuard_MaleA'
                            		AnimSets(0)=AnimSet'CH_AnimHuman.Anims.K_AnimHuman_BaseMale'
                            		AnimTreeTemplate=AnimTree'CH_AnimHuman_Tree.AT_CH_Human'
                            	bCastHiddenShadow=true
                            	End Object
                            
                            	bWeaponAttachmentVisible = FALSE
                            
                            	//relevante>
                            }
                            Code:
                             class MySword extends UTWeapon;
                            
                            simulated function SetPosition(UDKPawn Holder)
                            {
                            	local Vector socketPosition;
                            	local Rotator socketRotation;
                            	
                            	super.SetPosition(Holder);
                            
                            	 Holder.mesh.GetSocketWorldLocationAndRotation('WeaponPoint',socketPosition,socketRotation,0);
                            
                            
                            
                            	SetLocation(socketPosition);
                            	SetRotation(socketRotation);
                            }
                            
                            DefaultProperties
                            {
                            	Begin Object Class=AnimNodeSequence Name=MeshSequenceA
                                    
                                End Object
                            
                            	Begin Object name=FirstPersonMesh
                            		DepthPriorityGroup=SDPG_World
                            		bCastHiddenShadow=true
                            		SkeletalMesh=SkeletalMesh'MyWeapons.MySword'
                            		AnimSets(0)=AnimSet'MyWeapons.Mesh_006'
                            		Animations=MeshSequenceA
                            
                            		CollideActors=false
                            		AlwaysLoadOnClient=true
                            		AlwaysLoadOnServer=true
                            		
                            		bUpdateSkelWhenNotRendered=false
                            		bIgnoreControllersWhenNotRendered=true
                            		bOverrideAttachmentOwnerVisibility=true
                            		bAcceptsDynamicDecals=FALSE
                            		Rotation=(Pitch=5000,Yaw=0,Roll=4000)
                            		Translation=(x=0,y=10,z=10)
                            
                            	End Object
                            	bShadowParented=true;
                            	begin object name=PickupMesh
                            		SkeletalMesh=SkeletalMesh'MyWeapons.MySword'
                            		Translation=(x=0,y=0,z=20)
                            		Scale =1.5
                            	end object
                            
                            	AttachmentClass=class'MySwordAttachment'
                            	WeaponFireTypes(0)=EWFT_InstantHit
                            	WeaponFireTypes(1)=EWFT_None
                            
                            	InstantHitDamage(0)=50
                            
                            	ShotCost(0)=0
                            
                            	AmmoCount=1
                            	MaxAmmoCount=1
                            
                            	WeaponFireAnim(0)=sword
                            
                            	MuzzleFlashSocket=MF
                            
                            	WeaponRange=50
                            }
                            Code:
                             class MyController extends UDKPlayerController;
                            
                            
                            simulated function PostBeginPlay()
                            {
                            	super.PostBeginPlay();
                            	
                            	`log("post controller");
                            }
                            
                            exec function Use()
                            {
                            	local vector hitLoc, start, norm, end;
                            	local Rotator POVrot;
                            	local TraceHitInfo hitInfo;
                            	local Actor traceHit;
                            	
                            	GetPlayerViewPoint(start,POVrot);
                            
                            	end = start + vector(POVrot)* 600; 
                            	
                            	traceHit = trace(hitLoc, norm, end, start, true,, hitInfo,TRACEFLAG_Blocking);
                            	
                            	Spawn(class'PhysicsItem',,,end,,,);
                            
                            	
                            	if (traceHit != none) 
                            	{
                            		if(traceHit.Class == class 'PhysicsItem')
                            		{
                            			`log("meu item");
                            
                            			PhysicsItem(traceHit).Action();
                            		}
                            		else
                            		{
                            			`log("Hit: "$traceHit$"  class: "$traceHit.class.outer.name$"."$traceHit.class);
                             			`log("Location: "$hitLoc.X$","$hitLoc.Y$","$hitLoc.Z);
                             			`log("Material: "$hitInfo.Material$"  PhysMaterial: "$hitInfo.PhysMaterial);
                            			`log("Component: "$hitInfo.HitComponent);
                            		}
                            	}
                            }
                            
                            DefaultProperties
                            {
                            	CameraClass=class'MyCameraSetup'//relevante
                            }
                            Code:
                             class MySwordAttachment extends UTWeaponAttachment;
                            
                            DefaultProperties
                            {
                            	Begin Object Name=SkeletalMeshComponent0
                            		SkeletalMesh=SkeletalMesh'GDC_Materials.Meshes.SK_ExportSword2'
                            		
                            	end object
                            bShadowParented=true
                            	BaseBoneName=WeaponPoint
                            	WeaponClass=class'MySword'
                            	MuzzleFlashSocket=MF
                            }

                            Comment

                            Working...
                            X