1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Two Factor Authentication is now available on BeyondUnreal Forums. To configure it, visit your Profile and look for the "Two Step Verification" option on the left side. We can send codes via email (may be slower) or you can set up any TOTP Authenticator app on your phone (Authy, Google Authenticator, etc) to deliver codes. It is highly recommended that you configure this to keep your account safe.

Taking the Skin off a mesh and modifying it through Shaders.

Discussion in 'Programming' started by JonAzz, Feb 28, 2005.

  1. JonAzz

    JonAzz UA Mapper

    Joined:
    Aug 1, 2003
    Messages:
    1,180
    Likes Received:
    0
    Ok I have just about worked out everything with this, the last problem that I am having is taking the original skin off of the Mesh and being able to run it through shaders.

    My problem is that I have no Idea how to get the skin off of the mesh. I have searched all through wiki and the only thing I found that was close to what I was looking for what GetNextSkin() or something like that, from what I read about it its slow and I think that is more for outside packages...

    I have everything done I just have no idea how to find the skin (yeah I've said it bout 50 times :B)

    Code:
    function InitializeSkin()
    {
        local int i;
    
        ShaderGood.Diffuse = CombinerGood;
        ShaderGood.Opacity = ShaderColor;
    
        CombinerGood.Material1 = <<< The Skin of the Mesh >>>
        CombinerGood.Material2 = ShaderColor;
    
        ShaderBad.Diffuse = CombinerBad;
        ShaderBad.Opacity = ShaderColor;
    
        CombinerBad.Material1 = <<< The Skin of the Mesh >>>
        CombinerBad.Material2 = ShaderColor;
    
        if (TeamID == 0)
           {
               for (i = 0; i < BuildStructureClass.default.NumSkins; i++)
               {
                   Skins[i] = BuildStructureClass.default.BlueSkins[i];
    
                       if (!ValidPlacement)
                          {
                               Skins[i] = ShaderBad;
                          }
                          else
                          {
                               Skins[i] = ShaderGood;
                          }
               }
        }
        else if (TeamID == 1)
        {
               for (i = 0; i < BuildStructureClass.default.NumSkins; i++)
               {
                   Skins[i] = BuildStructureClass.default.RedSkins[i];
    
                       if (!ValidPlacement)
                          {
                               Skins[i] = ShaderBad;
                          }
                          else
                          {
                               Skins[i] = ShaderGood;
                          }
               }
        }
    }
    
    Most of that is pseudocode, but very similar to what I have.

    What that does so far...
    • ShaderGood and ShaderBad take the Combiners and add an alpha to them to make them translucent.
    • The Combiners take <<< The Skin of the Mesh >>> and add it with a color.
    • TeamID distinguishes between which texture gets applied to the mesh depending on the Team that wants to place this mesh. Through Skins I am setting the new texture to the Mesh



    If anyone can point me into the right direction on how to get the Skin off of the mesh and in a way that I can put it through a shader, that would be great.

    I'm looking for more of an explanation on how to do this than a copy-paste job as I have been working on this for the past week (reading through unreal wiki, seraching google, etc.) and I am not bout ready to take the easy way out.


    Any help would be greatly appreicated :)

    Thanks in advance
    -Jon
     
  2. Shambler[sixpack]

    Shambler[sixpack] New Member

    Joined:
    May 3, 2001
    Messages:
    564
    Likes Received:
    0
    Your in luck I seem to have everything you want :)
    That was a very difficult problem that I had (for the most part) solved, I was drawing miniature transparent renders of the weapons on the HUD and the transparency part was the problem...
    This code which I created did the trick for me but I have absoloutly NO idea if this will run off of shaders that do other effects. (credit is appreciated btw ;) this code was pretty hard to do)

    The way I got the materials from the mesh's was by using the GetPropertyText function on those mesh's...The material's array for mesh's isn't accessible in UScript (but I noticed it WAS in UnrealEd) and that function was a handy workaround for accessing it without direct reference.
    For further explanation read the comments in the code, they might not be that detailed but you will understand more by looking at the code than by me trying to explain it.

    EDIT: Some of the below code obviously has references to my HUD code (which relevant parts I've included), for your own purposes you will need to edit some of it out...Which is not hard.

    Code:
    struct WSkins
    {
    	var Array<Material> MatArray;
    };
    
    var WSkins TranslucencyMaterials[16];
    
    var class sClassPlaceholder;
    
    // Use by FindStaticMeshSkins to create a new Shader class for the dynamic array. (only for meshes with MULTIPLE skins)
    simulated function Shader CreateNewTShader()
    {
    	local Shader ShaderObj;
    
    	ShaderObj = New Class'Engine.Shader';
    
    	ShaderObj.Opacity = New Class'Engine.ConstantColor';
    
    	ConstantColor(ShaderObj.Opacity).Color.A = 128.0 * FadeTimer;
    
    	Return ShaderObj;
    }
    
    // This function finds the textures used on a mesh and uses them with Shaders to create transparency...A substitute for the lack of working DrawType=DT_Alpha on meshes
    // It's VERY fast atm but I don't think it's a good idea to use each tick
    // Feel free to use this in your code but as always a little credit is appreciated ;)
    // NOTE: This has problems with parts of the ShockRifle textures and Avril reticle.
    simulated function Array<Material> FindStaticMeshSkins(string MaterialsPropText, int WeapGroup)
    {
    	local int iPointer, i, iCutOff;
    	local string sParseString, sTextureClass;
    	local array<Material> SkinArray;
    	local Material DiffuseTemp;
    
    	// This is the max number of iterations currently allowed for this loop. (to avoid an unlikely infinite recursion)
    	iCutOff = 128;
    
    	for (i=0; i<TranslucencyMaterials[WeapGroup].MatArray.Length; i++)
    		TranslucencyMaterials[WeapGroup].MatArray[i] = None;
    
    	TranslucencyMaterials[WeapGroup].MatArray.Length = 0;
    
    	i = 0;
    
    	// This is my own funny way of iterating complicated stuff, you might be better of using UTPT if you want to understand this codes workings...
    	for (iPointer = InStr(MaterialsPropText, ",Material="); iPointer != -1 && i < iCutOff; iPointer = InStr(MaterialsPropText, ",Material="))
    	{
    		sParseString = Mid(MaterialsPropText, iPointer + 10);
    
    		iPointer = InStr(sParseString, "'");
    
    		sTextureClass = Left(sParseString, iPointer);
    
    		SetPropertyText("sClassPlaceholder", sTextureClass);
    
    		sParseString = Mid(MaterialsPropText, iPointer + 1);
    
    		iPointer = InStr(sParseString, "'");
    
    		sParseString = Mid(sParseString, iPointer + 1);
    
    		iPointer = InStr(sParseString, "'");
    
    		// Cut off the parsed section of MaterialsPropText so that it will go onto the next section during the next iteration. (otherwise infinite recursion)
    		MaterialsPropText = Mid(sParseString, iPointer + 1);
    
    		sParseString = Left(sParseString, iPointer);
    
    		TranslucencyMaterials[WeapGroup].MatArray.Length = i + 1;
    		TranslucencyMaterials[WeapGroup].MatArray[i] = CreateNewTShader();
    
    		if (ClassIsChildOf(sClassPlaceholder, Class'Shader'))
    		{
    			SkinArray[i] = Shader(DynamicLoadObject(sParseString, Class'Shader'));
    
    			// Here is where the fun begins, if the SelfIllumination is set there is trouble! (stupid Link Gun textures)
    			if (Shader(SkinArray[i]).SelfIllumination != None)
    			{
    				// If these requirements are right then you can use the fallback texture (phew, you can do this with Link)
    				if (SkinArray[i].FallbackMaterial != None && (Shader(SkinArray[i].FallbackMaterial) == none || Shader(SkinArray[i].FallbackMaterial).SelfIllumination == none))
    				{
    					if (Shader(SkinArray[i].FallbackMaterial) != None)
    						SkinArray[i] = Shader(SkinArray[i].FallbackMaterial);
    					else
    					{
    						DiffuseTemp = SkinArray[i].FallbackMaterial;
    
    						SkinArray[i] = CreateNewTShader();
    						Shader(SkinArray[i]).Diffuse = DiffuseTemp;
    					}
    				}
    				else if (SkinArray[i].FallbackMaterial == None)
    					Shader(SkinArray[i]).SelfIllumination = None;
    			}
    
    			Shader(SkinArray[i]).Opacity = New Class'Engine.ConstantColor';
    
    			TranslucencyMaterials[WeapGroup].MatArray[i] = SkinArray[i];
    
    			ConstantColor(Shader(SkinArray[i]).Opacity).Color.A = 128 * FadeTimer;
    		}
    		else
    		{
    			Shader(TranslucencyMaterials[WeapGroup].MatArray[i]).Diffuse = None;
    			ConstantColor(Shader(TranslucencyMaterials[WeapGroup].MatArray[i]).Opacity).Color.A = 128 * FadeTimer;
    
    			Shader(TranslucencyMaterials[WeapGroup].MatArray[i]).Diffuse = Material(DynamicLoadObject(sParseString, sClassPlaceholder));
    
    			SkinArray[i] = TranslucencyMaterials[WeapGroup].MatArray[i];
    		}
    
    		i++;
    	}
    
    	Return SkinArray;
    }
    
    Usage of that function:
    Code:
    var WSkins WeapSkins[16];
    
    var actor MenuWeapons[16];
    
    function YourFunction()
    {
    	local string StructInfo;
    
    	if (bChangedMesh)
    	{
    		MenuWeapons[i].OverlayMaterial = None;
    
    		// I dunno why but if you call GetPropertyText on the mesh INSIDE of the function call then it will return nothing
    		if (MenuWeapons[i].DrawType == DT_StaticMesh && MenuWeapons[i].StaticMesh != None)
    		{
    			StructInfo = "";
    			StructInfo = MenuWeapons[i].StaticMesh.GetPropertyText("Materials");
    
    			// Transferring of dynamic arrays here works seamlessly
    			WeapSkins[i].MatArray = FindStaticMeshSkins(StructInfo, i);
    		}
    
    		// Works for normal meshes but not static meshes
    		if (MenuWeapons[i].DrawType == DT_Mesh && MenuWeapons[i].Mesh != None)
    			MenuWeapons[i].OverlayMaterial = TranslucencyMaterial;
    
    		bChangedMesh = False;
    
    		MenuWeapons[i].Skins = WeapSkins[i].MatArray;
    	}
    }
    
    ~ SA|Shambler
     
    Last edited by a moderator: Feb 28, 2005
  3. JonAzz

    JonAzz UA Mapper

    Joined:
    Aug 1, 2003
    Messages:
    1,180
    Likes Received:
    0
    Wow! Thank you, that is just what I was looking for :) I will mess with implementing it into my class in a little bit then get back to you.

    heh, glad to know I wasn't the only one that was having some trouble with this :p

    -Jon
     
  4. JonAzz

    JonAzz UA Mapper

    Joined:
    Aug 1, 2003
    Messages:
    1,180
    Likes Received:
    0
    Ok well after playing with this for the past hour I've released that I am going to need a little more explaining as to what is going on. I can just about figure out what your code does, but implementing it into my code I've run into problems.

    Shambler, if it is ok with you, I would like to go through this later tonight to try to get this working. Thank you for all you help so far :)

    -Jon
     
  5. Shambler[sixpack]

    Shambler[sixpack] New Member

    Joined:
    May 3, 2001
    Messages:
    564
    Likes Received:
    0
    Ok :) Added you to my ICQ.
     

Share This Page