Bump mapping for Animated meshes

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
CuteAlien
Admin
Posts: 9718
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Bump mapping for Animated meshes

Post by CuteAlien »

All not my speciality. But afaik it's like this:

As Kojack already wrote endings don't matter and can be anything. Irrlicht for example has .frag and .vert for glsl, but the shaders would also work with any other names. Endings just help you as programmer to see faster which one it is - the compiler does not care.

You can distinguish shaders in low-level shaders and high-level shaders. Low-level shaders are basically assembler. But they are different for OpenGL and D3D. In Irrlicht those have been hardcoded into strings (see for example COpenGLNormalMapRender.cpp or C3D9NormapMapRender.cpp). But could also just as well be in text files (that was just a design decision).

HLSL, GLSL and CG are all high-level languages which are all based on the c-language (with a few changes, but still looking similar to c). HLSL compiles to D3D shaders, GLSL compiles to OpenGL shaders and CG compiles to both of them. The HLSL compiler is inside the DLL's delivered by microsoft, so it's one step above the hardware-drivers from vendors. So it's compiled before it's send to the drivers. The GLSL compiler on the other hand is inside the drivers, so each card vendor delivers it's own. I think there are also some external GLSL compilers by now (for debugging etc). CG was simply a third solution by Nvidia which can compile to both - OpenGL and D3D. And as you noticed it's looking similar to HLSL. Just with the added feature it also can compile to OpenGL low-level shaders. Nice idea really as that way we could write shaders just once and they would run on OpenGL and D3D. But while CG as language was open to my knowledge (so it was legal to write competing compilers), they have never open-sourced their own compiler. So when they stopped developing it 3 years ago and even stopped supporting it the tech was basically at it's end. I wish it were not the case at it would have made things easier. Maybe we should write our own shader compiler in Irrlicht ;-) (just joking... for now).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

Thanks Alien! Now I know a little more! I'm trying something with Specular highlights and ways to hide them when they should be hidden..
I'm experimenting with Blender baked Shadow maps for four different lights encoded into a single RGBA image.
If it works Ill post it! I also hope to convert some stuff from GLSL to HLSL.. Later!
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

Thanks for the much needed education Kojack.
Love your Ogre Cat!
Your help would be much appreciated in "Open Discussion / Cg.....".
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

- GLSL to HLSL -

O.K. So I thought, get hold of a very simple project that uses HLSL in a very simple way.
I found the "Cell Shader" example on the forum.
Nice. Now all I have to do is to create a project for it, change

Code: Select all

createDevice(EDT_DIRECT3D9, dimension2d(800, 600), 32);
to

Code: Select all

device = createDevice(EDT_DIRECT3D9, core::dimension2d<u32>(1024, 768));
(I understand that) and change a few file references like "torus.b3d" to "Data/torus.b3d" and
"cel.hlsl" to "Shaders/cel.hlsl" (I like it that way).
O.K. Compile in VC 71 IDE under Irrlicht 1.8.3.
Cool! Compiled fine and I have have a beautiful "Compiled.exe".
I've got the Irrlicht 1.8.3 DLL right there in the release directory.
Run it and..

With the "Irrlicht.dll" (1.8.3) in my release directory
the console shows a repettitive "Error setting float array for HLSL variable".

With some other "irrlicht.dll"s in my release directory the console message
is gone but the rendered "Torus" is "Black".

Now, the originally downloaded pre-compiled "*.exe" with the included
irrlicht.dll (2.818.048 bytes) runs fine.

I just need a basic working HLSL project so I can try to convert a GLSL shader to HLSL.

Please help!
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

Got it!
Header files..
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

The "Cell Shader" posted by "BlindSide" through "ProjectIRR" looks like a good place to start.

Here is the original HLSL Shadercode pretty much as I found it..

Code: Select all

 
 
 // Original post by "Blindside" via "ProjectIRR"..
 //-------------------------------------- ----- ---- --- -- - 
 // To reproduce some GLSL functionality in this HLSL shader a few things should be done..
 // The first thing to do is to get the Source GLSL code as simple as possible but yet working..
 
 // I dont know how long this is going to take but we do have a basis to work from..
 
 // This is all in Irrlicht 1.8.3..
 
 float4x4 mWorldViewProj;
 float3   mLightPos;
 float3   mCamPos;
 
 //-------------------------------------- ----- ---- --- -- - 
 struct VS_OUTPUT
  {float4 Position: POSITION0;
   float2 TexCoord: TEXCOORD0;
   float3 Normal:   TEXCOORD1;
   float3 LightDir: TEXCOORD2;
   float3 EyeDir: TEXCOORD3;
  };
 //-------------------------------------- ----- ---- --- -- - 
 VS_OUTPUT vertexMain(float4 Position:  POSITION0,
                      float2 TexCoord:  TEXCOORD0,
                      float2 diffuse:   TEXCOORD1,
                      float3 Normal:    NORMAL0)
  {VS_OUTPUT Output;
   Output.Position = mul(Position, mWorldViewProj);
   Output.Normal   = normalize(Normal);
   Output.LightDir = normalize(mLightPos - Position.xyz);
   Output.EyeDir   = normalize(mCamPos - Position.xyz);
   Output.TexCoord = TexCoord;
   return(Output);
  }
 //-------------------------------------- ----- ---- --- -- - 
 sampler2D tex0 : register(s0);
 sampler1D diffuseRamp : register(s1);
 //-------------------------------------- ----- ---- --- -- - 
 float4 pixelMain
  (float2 TexCoord:     TEXCOORD0,
   float3 Normal:       TEXCOORD1,
   float3 LightDir:     TEXCOORD2,
   float3 EyeDir:       TEXCOORD3
  ) : COLOR0
  {float4 texCol = tex2D(tex0, TexCoord);
   float diffuse = clamp(dot(Normal, LightDir), 0.0, 1.0);
   float4 lightColor = tex1D(diffuseRamp, diffuse);
   float fresnal = dot(Normal, EyeDir);
   fresnal = clamp((fresnal - 0.2) * 1000.0, 0.0, 1.0);
   lightColor *= fresnal;
   float3 reflect = (2.0 * diffuse * Normal) - LightDir;
   float specular = pow(clamp(dot(reflect, EyeDir), 0.0, 1.0), 8.0);
   specular = clamp((specular - 0.5) * 1000.0, 0.0, 1.0);
   float4 specular4 = specular * float4(1.0, 1.0, 1.0, 1.0);
   return(saturate(lightColor * texCol + specular4));
  }
 //-------------------------------------- ----- ---- --- -- -   
  
 
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

Deadlocked..
I got "Cell Shader" and "Example 10" working just fine under the Shipped Irrlicht 1.8.3 "Irrlicht.dll" & "Irrlicht.lib".
Very nice! But..
Before I dive in I want to make sure that I have more than 4 textures available as was the case in GLSL (very cool).
No problem.. Recompile Irrlicht 1.8.3 with "#define _IRR_MATERIAL_MAX_TEXTURES_ 8" in "IrrCompileConfig.h".
Generate a brand new "Irrlicht.dll" and "Irrlicht.lib". Cool!
Recompile the "Cell Shader" and / or "Example 10" with my new "Irrlicht.dll" & "Irrlicht.lib" and what happens?
Error..
(probably a CompileConfig.h issue)

So, Either there is something wrong with the D3D Implementation somewhere or I (most likely) had missed something.
There could even be something amiss with these shader programs in that things in D3D had changed. (I don't think so)

To make matters worse, I tried recompiling Irrlicht1.8.3 without any changes so that I would theoretically have exactly the same
"Irrlicht.dll" and "Irrlicht.lib" as was "shipped" (downloaded).
They are not the same, causes the same errors.


See you around!
Last edited by Vectrotek on Mon Oct 05, 2015 7:22 pm, edited 1 time in total.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

This post moved to Everything 2D / 3D graphics
Last edited by Vectrotek on Sun Sep 27, 2015 11:22 pm, edited 1 time in total.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

- HLSL -
This Shouldn't really exite anyone yet but could be interesting.
It is also not complete but I thought I'd post it incase someone has some advice.

Don't mind the framerate, the machine was busy with other things.
Its runs on a system with Irrlicht 1.8.3 and "DXSDK_Jun10.exe 559,452,800 bytes" installed.
DirectX 9 Runtime (not sure of exact revision)
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

This shows the final render of a primitive HLSL shader.
It looks fine but there are underlying issues which will become apparent later.
Image
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

This is what happens when you understand that
"TEXCOORD1" and "TEXCOORD2" are the "Semantics" in the hardware
channels for Tangent and Binormal! (these are tangents)
The Appcode and Shader was edited too.
(were getting closer to a GLSL to HLSL conversion which I will be post when done)
Image
Last edited by Vectrotek on Tue Oct 06, 2015 11:20 am, edited 2 times in total.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

The UV Coords look fine.
Image
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

The Normals also look fine.
Image
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

This screengrab of Blender 2.75 just shows the model UV Coords.
Image
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

Here is the HLSL Shader:

Code: Select all

 
 
 // Irrlicht 1.8.3   (DXSDK_Jun10.exe) (559,452,800 bytes)
 // HLSL 00002
 // "An Adventureous Quest on the road to HLSL from GLSL".
 // This HLSL shader started of as the "Cell Shader" then de-evolved to this simple Diffuse and Specular shader.
 // Some things were removed like the texturing used for the cell shading..
 // Some variables were renamed and some calculations changed to make more "opticophysical sense". Huh? :)
 // Lights were added and are controlled inside this shader, for now.
 //-------------------------------------- ----- ---- --- -- - 
 
 // The first thing I noticed is that D3D is more strict than GLSL in terms of what you
 // have in the shader and what you attempt to feed the shader from your appcode..
 // Disabling the "LightPos001" in the shader by deleting the variable and the use of it
 // would not have caused much problems under GLSL.
 // In HLSL however the app indicates through the console window that it doesnt find the "HLSL variable to set"..
 // O.K. we disable the "services->setVertexShaderConstant("LightPos001", &lightPosOS.X, 3);" in the Apcode as well..
 // Compile and Run.. No Problem..
 
 // Another "strict" rule in HLSL is that everything must be "Properly Initialised", again unlike GLSL..
 
 // Remember! Variable Names changed here must also be changed in the Appcode calling functions like "CameraXYZPosition".
 
 // Note: FX Composer opens and plays animated "*.dae" exported from Blender 2.75.
 // It'l be quite a while before some of us have machines that would run things like Nvidia's "Gameworks" etc.
 // I posted this in the hope that someone could offer some advice..
 
 //========================================================================= ==== === == =
 //-------------------------------------- ----- ---- --- -- -  
 struct VS_OUTPUT
  {float4 Position:  POSITION0;
   float2 TexCoord:  TEXCOORD0;
   float3 Normal:    NORMAL;
   float3 EyeDir:    TEXCOORD1;
   float3 LightDir001: TEXCOORD2;
   float3 LightDir002: TEXCOORD3;  
    float3 WorldTangent : TANGENT;   // MUST COMPLETELY INTIALISE!!
    float3 WorldBinormal : BINORMAL;    // Note the SHADER PROFILES issue here!!  EPST_PS_3_0 and  EPST_VS_3_0
 
 
   // If we want many lights then using "TEXCOORD3" and "TEXCOORD4" etc, will probably have to change..
  };
 //-------------------------------------- ----- ---- --- -- - 
 // Fed from Appcode..(trying to change this in the Vertex program resulkts in errors.)
 
 // These comes straight from FX Composer (OpenGl Mode), so we can presume that HLSL suuports these..
 // This is how they would be sent from the Composer Apcode..
 // In Irrlicht we do it a bit different..
 // float4x4 WorldITXf : WorldInverseTranspose;
 // float4x4 WvpXf     : WorldViewProjection;  // This one seems to match with the existing "mWorldViewProj"..
 // float4x4 WorldXf   : World;
 // float4x4 ViewIXf   : ViewInverse;
 
 
 
 float4x4 mWorldViewProj; // in Composer this was "float4x4 WorldXf   : World;"
 
                                    // This was doine wirth it..    OUT.HPosition = mul(WvpXf,Po);\
                                    // where "OUT.HPosition" was VERTEX OUTPUT which in here is ..  Output.Position
                                    // which has applied to it.. mul(Position, mWorldViewProj)
                                    // which is comparable to OUT.HPosition = mul(WvpXf,Po) above,
                                    // but, what about the "Po" in mul(WvpXf,Po)..
                                    // O.K. theyve been swapped under multiplication which should be alright..
                                    // So.. if we changed "mul(Position, mWorldViewProj)" to "mul( mWorldViewProj , Position)" 
                                    // things should still look the same yes?
                                    // IT DOES NOT LOOK THE SAME!! How serious is this for us??
                                    // O.K. we are on the right track here..
                                    // YES!  in HLSL mode we have "float3 Pw = mul(Po,WorldXf).xyz;" which IS IN THE ORDER FOUND HERE!!
                                    // SO THERE IS DEFINITELY A "SWAPPED" ISSUE BETWEEN CG and HLSL..
                                    // "Position-Matrix" versus "Matrix-Position" where "Position Matrix" is what we want in HLSL..
 
 
 float3   CameraXYZPosition; // Identically named in Appcode..
 
 //-------------------------------------- ----- ---- --- -- - 
 VS_OUTPUT vertexMain
                     (float4 Position            : POSITION0,
                      float2 TexCoord            : TEXCOORD0,
                      float3 Normal              : NORMAL,
                      float3 TheTangent          : TANGENT,   // These looks right (just hope!!)
                      float3 TheBinormal         : BINORMAL   // Are these fed in here right..
)
  {                                                                       
 // Local Vertex Program Variables..
 float3   PositionL001;  // currently the camera positio..
 float3   PositionL002;  // Would it all have been tidier if lights existed in Fragment Shader exclusively??
                         // I suspect there is way too much activity in this Vertex Program..
                         // We'd like the appcode to talk to the Fragment Shader more than this Vertex Progam..
 
 
    PositionL001.x = 0.0; // Overriden by Camera Pos..
    PositionL001.y = 0.0;
    PositionL001.z = 0.0;
 
    PositionL002.x = 0.0; // We set this here (later from Appcode and in Fragment Shader)..
    PositionL002.y = -10000.0;
    PositionL002.z = 0.0;
 
 
 
    VS_OUTPUT Output;
   Output.Position = mul(Position, mWorldViewProj); //  "WvpXf" in the Composer Shader Code from Appcode..
 
    //                                                                              
 
    // A lot has to happen here.. With some experimentation I suppose well evetually get there..
 
    // Output.WorldTangent = mul(IN.Tangent,WorldITXf).xyz;
    // Output.WorldBinormal = mul(IN.Binormal,WorldITXf).xyz;
 
//    Output.WorldTangent  = mul(TheTangent, mWorldViewProj).xyz;  // MAKE SURE ABOUT "Position Matrix" ORDER!!!!
//    Output.WorldBinormal = mul(TheBinormal,mWorldViewProj).xyz;
 
    Output.WorldTangent  = mul( mWorldViewProj, TheTangent );  // MAKE SURE ABOUT "Position Matrix" ORDER!!!!
    Output.WorldBinormal = mul(TheBinormal, TheTangent);
 
 
 
    //                                                                              
 
   // This swapped items thing may be a GL vs D3D thing..
 
   // Output.Position = mul(mWorldViewProj , Position); // MOST DEFINITELY NOT GL versus D3D thing..
 
   Output.Normal   = normalize(Normal); // If your modelled normals are not already normalised?
                                        // I think in glsl something did happen to them..
 
   Output.LightDir001 = normalize(CameraXYZPosition - Position.xyz); // Get the light to move with the camera..
 
   Output.LightDir002 = normalize(CameraXYZPosition - Position.xyz);
 
   Output.EyeDir   = normalize(CameraXYZPosition - Position.xyz);
   Output.TexCoord = TexCoord;
   return(Output);
  }                                                                                  
 //========================================================================= ==== === == =
 // In GLSL more things seem to happen in the Fragment Shader,
 // and in HLSL more seems to happen in the Vertex Program.
 // Eventually we will have an HLSL shader that works very similar to the GLSL shader..
 // There are reasons for doing things in the Fragment Shader rather than in the Vertex Program..
 
 
 
 //========================================================================= ==== === == =
 // sampler2D tex0 :        register(s0); // Registers !?!?!
 // sampler1D diffuseRamp : register(s1);
 //-------------------------------------- ----- ---- --- -- - 
 float4 pixelMain 
                   (float2 TexCoord:     TEXCOORD0,
                    float3 Normal:       NORMAL,
                    float3 EyeDir:       TEXCOORD1,
                    float3 LightDir001:  TEXCOORD2, 
                    float3 LightDir002:  TEXCOORD3,  // Funny how mistake of 3 here also didnt cause warning..
 
                      float3 INTheWorldTangent          : TANGENT,   // These looks right (just hope!!)
                      float3 INTheWorldBinormal         : BINORMAL
 
 
                    ) : COLOR0
  {
   // We have nothing here from Appcode yet..
 
   // Variables used to define things like "Surface Attributes" and "Light Properties"..
   float4 SurfaceDiffuseRGBA;
   float  SurfaceSpecularity;       // 0.0 to 1.0 for "Reflective Intensity"..
   float  SurfaceGloss;             // Specular Power Phong based "Highlight Tightness"..
   float4 FinalRenderRGBA;          // Everything gets put in here and then rendered..
   float4 LightColor001; 
   float4 LightColor002;
   float  SpecSpotL001;             // The Specular Highlight caused by LIGHT 001..
   float  SpecSpotL002;
   float  RawDiffuseByL001;         // The raw "grey and colourless" shade caused by LIGHT 001..
   float  RawDiffuseByL002;
   float4 ColouredSpecSpotByL001;    // The Coloured Surface Shading caused by the Colour of the Light..
   float4 ColouredSpecSpotByL002;
   float4 ColouredDiffuseByL001;    // The Coloured Surface Shading caused by the Colour of the Light..
   float4 ColouredDiffuseByL002;    // These are separate because we don't want to do Diffuse Calculations
   float3 ReflectVecL001;
   float3 ReflectVecL002;            
 
 
   // Scene Description.
 
   SurfaceDiffuseRGBA.x =  0.25 ; SurfaceDiffuseRGBA.y =  0.5 ; SurfaceDiffuseRGBA.z =  0.25 ; SurfaceDiffuseRGBA.w =  1.0 ;
   SurfaceSpecularity = 1.0;  // Higher values would be visible because of the nature of the "Curve" in Phong Specular Shading..
   SurfaceGloss = 32.0;       // Assign this in Powers of Two. i.e. 2;4;8;16;32;64;128 etc (anything between is meaningless).
   LightColor001.x =  1.0 ; LightColor001.y =  1.0 ; LightColor001.z =  0.0 ;  LightColor001.w =  1.0 ;
   LightColor002.x =  1.0 ; LightColor002.y =  0.0 ; LightColor002.z =  0.0 ;  LightColor002.w =  1.0 ;
 
 
   // Diffuse.
   // Below comes from composer shader..
   // float4 litV_01 = lit(dot(Ln_01,Nn),dot(Hn_01,Nn),SpecExpon);
 
 
   RawDiffuseByL001 = clamp(dot(Normal, LightDir001), 0.0, 1.0);
   RawDiffuseByL002 = clamp(dot(Normal, LightDir002), 0.0, 1.0);
   ColouredDiffuseByL001 = RawDiffuseByL001 * LightColor001;
   ColouredDiffuseByL002 = RawDiffuseByL002 * LightColor002;
 
   // Specular Highlights.
   ReflectVecL001 = (2.0 * Normal) - LightDir001; // Im not too sure about these..
   ReflectVecL002 = (2.0 * Normal) - LightDir002; // 
   SpecSpotL001 = pow(clamp(dot(ReflectVecL001, EyeDir), 0.0, 1.0), SurfaceGloss);
   SpecSpotL002 = pow(clamp(dot(ReflectVecL002, EyeDir), 0.0, 1.0), SurfaceGloss);
   ColouredSpecSpotByL001 = SpecSpotL001 * LightColor001;
   ColouredSpecSpotByL002 = SpecSpotL002 * LightColor002;
 
 
   FinalRenderRGBA = 0; // Legal..(we do this so we can have multiple "FinalRenderRGBA +="'s to increment the final values..
 
   // Render looks cool but there are problems that will arise with Light positions and animation etc..
   // The matrix mulls have to be sorted out before proper normalmapping with Tangents and Binormals are used..
   FinalRenderRGBA += ((ColouredDiffuseByL001 * SurfaceDiffuseRGBA) + (ColouredSpecSpotByL001));
   FinalRenderRGBA += ((ColouredDiffuseByL002 * SurfaceDiffuseRGBA) + (ColouredSpecSpotByL002));
 
   // TAGENTS DONT LOOK RIGHT.. They definitely need a matrix mul!!
   FinalRenderRGBA.x = (INTheWorldTangent.x / 2.0) + 0.5;
   FinalRenderRGBA.y = (INTheWorldTangent.y / 2.0) + 0.5;
   FinalRenderRGBA.z = (INTheWorldTangent.z / 2.0) + 0.5;
 
   // TEXCOORDS LOOK COOL!!
   FinalRenderRGBA.x = TexCoord.x;
   FinalRenderRGBA.y = TexCoord.y ;
   FinalRenderRGBA.z = 0; // (TheWorldTangent.z / 2.0) + 0.5;
 
   // NORMALS LOOK COOL! (Well have to make sure they rotate and scale cool too!)
   FinalRenderRGBA.x = (Normal.x / 2.0) + 0.5;
   FinalRenderRGBA.y = (Normal.y / 2.0) + 0.5;
   FinalRenderRGBA.z = (Normal.z / 2.0) + 0.5;
   /* /// Move this line for selective commenting here..
   // Just for kicks.. (visualising otherwize invisibles can be useful)
   FinalRenderRGBA.x = (EyeDir.x / 2.0) + 0.5;
   FinalRenderRGBA.y = (EyeDir.y / 2.0) + 0.5;
   FinalRenderRGBA.x = (EyeDir.z / 2.0) + 0.5;
   //*/
   FinalRenderRGBA.w = 1.0; // Make sure if you want or have things clipped..
   return FinalRenderRGBA; 
  }
 //========================================================================= ==== === == = 
 
Post Reply