[2.2] Area Light bugs Topic is solved

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


Post Reply
rujialiu
Goblin
Posts: 296
Joined: Mon May 09, 2016 8:21 am
x 35

[2.2] Area Light bugs

Post by rujialiu »

Hi!

First of all, the new UpdatingDecalsAndAreaLightTex sample doesn't compile with D3D11 and Metal because of a small bug:

Code: Select all

@property( hlms_lights_area_tex_mask )
    @piece( DeclAreaApproxTextures )
        @property( syntax == glsl )
            uniform sampler2DArray areaLightMasks;
        @end

        @property( syntax == hlsl )
            Texture2DArray<float> areaLightMasks    : register(t@value(areaLightMasks));
            SamplerState areaLightMasksSampler        : register(s@value(areaLightMasks));
        @end

        @property( syntax == metal )
            , texture2d_array<float> areaLightMasks    [[texture(@value(areaLightMasks))]]
            , sampler areaLightMasksSampler            [[sampler(@value(areaLightMasks))]]
        @end
    @end
@end
the `<float>` part should be `<float3>` when hlms_property `hlms_lights_area_tex_colour` is true.

A much more weird problem is that... it looks like when OGRE_CONFIG_ENABLE_FINE_LIGHT_MASK_GRANULARITY is defined, only the highest 9 bits of the uint32 mask is working. This can be verified by modifying the UpdatingDecalsAndAreaLightTex sample:

Code: Select all

planeMesh->importV1( planeMeshV1.get(), true, true, true );

        {
            Ogre::Item *item = sceneManager->createItem( planeMesh, Ogre::SCENE_DYNAMIC );
            item->setDatablock( "MirrorLike" );
            Ogre::SceneNode *sceneNode = sceneManager->getRootSceneNode( Ogre::SCENE_DYNAMIC )->
                                                    createChildSceneNode( Ogre::SCENE_DYNAMIC );
            sceneNode->setPosition( 0, -1, 0 );
            sceneNode->attachObject( item );
            item->setLightMask(1u << 22); /////////////////////////// <-- add this line
        }
And also light->setLightMask(1u << 22) after creating the area light. Then the light doesn't show up. However, if we change 22 to 23, the light works again. I think Ogre 2.1 doesn't have such issue, but since I already upgraded all my projects to Ogre 2.2, I can't easily check it now.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5299
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1280
Contact:

Re: [2.2] Area Light bugs

Post by dark_sylinc »

rujialiu wrote: Sat Feb 02, 2019 10:46 am Hi!

First of all, the new UpdatingDecalsAndAreaLightTex sample doesn't compile with D3D11 and Metal because of a small bug:

Code: Select all

@property( hlms_lights_area_tex_mask )
    @piece( DeclAreaApproxTextures )
        @property( syntax == glsl )
            uniform sampler2DArray areaLightMasks;
        @end

        @property( syntax == hlsl )
            Texture2DArray<float> areaLightMasks    : register(t@value(areaLightMasks));
            SamplerState areaLightMasksSampler        : register(s@value(areaLightMasks));
        @end

        @property( syntax == metal )
            , texture2d_array<float> areaLightMasks    [[texture(@value(areaLightMasks))]]
            , sampler areaLightMasksSampler            [[sampler(@value(areaLightMasks))]]
        @end
    @end
@end
the `<float>` part should be `<float3>` when hlms_property `hlms_lights_area_tex_colour` is true.
Thanks!
Fixed.
A much more weird problem is that... it looks like when OGRE_CONFIG_ENABLE_FINE_LIGHT_MASK_GRANULARITY is defined, only the highest 9 bits of the uint32 mask is working. This can be verified by modifying the UpdatingDecalsAndAreaLightTex sample:
I'm afraid I'm unable to repro that bug.

When I tried this patch to toggle each light one by one:

Code: Select all

diff -r e19378346195 Samples/2.0/ApiUsage/UpdatingDecalsAndAreaLightTex/UpdatingDecalsAndAreaLightTexGameState.cpp
--- a/Samples/2.0/ApiUsage/UpdatingDecalsAndAreaLightTex/UpdatingDecalsAndAreaLightTexGameState.cpp	Sat Feb 02 19:57:33 2019 -0300
+++ b/Samples/2.0/ApiUsage/UpdatingDecalsAndAreaLightTex/UpdatingDecalsAndAreaLightTexGameState.cpp	Sat Feb 02 19:57:37 2019 -0300
@@ -269,6 +269,7 @@
         lightNode->setPosition( position );
         light->setDirection( Ogre::Vector3( 0, 0, 1 ).normalisedCopy() );
         light->setAttenuationBasedOnRadius( 10.0f, 0.01f );
+        light->setLightMask( 1u << (18 + idx) );
 
 //        //Control the diffuse mip (this is the default value)
 //        light->mTexLightMaskDiffuseMipStart = (Ogre::uint16)(0.95f * 65535);
@@ -400,6 +401,10 @@
                                                     createChildSceneNode( Ogre::SCENE_DYNAMIC );
             sceneNode->setPosition( 0, -1, 0 );
             sceneNode->attachObject( item );
+            item->setLightMask(1u << 18);
+//            item->setLightMask(1u << 19);
+//            item->setLightMask(1u << 20);
+//            item->setLightMask(1u << 21);
         }
 
         //Create the mesh template for all the lights (i.e. the billboard-like plane)
@@ -414,6 +419,7 @@
         light->setPowerScale( 1.0f );
         light->setType( Ogre::Light::LT_DIRECTIONAL );
         light->setDirection( Ogre::Vector3( -1, -1, -1 ).normalisedCopy() );
+        //light->setLightMask(1u << 23);
 
         for( size_t i=0; i<c_numAreaLights; ++i )
         {
All variations (1u << 18 and co.) worked as expected. And having them all "1u << 22" also works.
I tried Linux (GL) and Windows (D3D11)

I remember you were having vestiges of Metal files in your Hlms data folder. Perhaps the same is happening to your HLSL files? An old template from pre-refactor stage would definitely explain the bug.

Another simple possibility is that your samples need a full clean rebuild.
al2950
OGRE Expert User
OGRE Expert User
Posts: 1227
Joined: Thu Dec 11, 2008 7:56 pm
Location: Bristol, UK
x 157

Re: [2.2] Area Light bugs

Post by al2950 »

Just been testing samples, and I noticed that LTC lights on Dx only dont work. Have had a quick look at shaders, but nothing obvious especially as it is works in OpenGL
rujialiu
Goblin
Posts: 296
Joined: Mon May 09, 2016 8:21 am
x 35

Re: [2.2] Area Light bugs

Post by rujialiu »

al2950 wrote: Mon Feb 04, 2019 11:27 am Just been testing samples, and I noticed that LTC lights on Dx only dont work. Have had a quick look at shaders, but nothing obvious especially as it is works in OpenGL
What about UpdatingDecalsAndAreaLightTex sample with my proposed modification? Just add two lines: light->setLightMask(1u << 22) for the area lights and item->setLightMask(1u << 22) for the plane item, and the lighting on the plane disappeared (of course the "light" objects with unlit datablock can still be seen). I've clean everything but it still doesn't work for me on DX11.
al2950
OGRE Expert User
OGRE Expert User
Posts: 1227
Joined: Thu Dec 11, 2008 7:56 pm
Location: Bristol, UK
x 157

Re: [2.2] Area Light bugs

Post by al2950 »

I do not have OGRE_CONFIG_ENABLE_FINE_LIGHT_MASK_GRANULARITY defined, but I seem to get the opposite problem! The lights are always visible on the plane no matter what mask is set, except if I set the mask to 0 on the light (The mask on the plane seems to have no affect).
al2950
OGRE Expert User
OGRE Expert User
Posts: 1227
Joined: Thu Dec 11, 2008 7:56 pm
Location: Bristol, UK
x 157

Re: [2.2] Area Light bugs

Post by al2950 »

Ah the LTC bug is very obvious. Line 254 of AreaLights_LTC_piece_ps.any, Dx complains about variable not being initialised, GL just ignores this issue.
So to fix just add

Code: Select all

L[4] = float3(0,0,0);
to line 215
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5299
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1280
Contact:

Re: [2.2] Area Light bugs

Post by dark_sylinc »

al2950 wrote: Mon Feb 04, 2019 1:04 pm Ah the LTC bug is very obvious. Line 254 of AreaLights_LTC_piece_ps.any, Dx complains about variable not being initialised, GL just ignores this issue.
So to fix just add

Code: Select all

L[4] = float3(0,0,0);
to line 215
**Sigh**
What's the actual error? (Ogre.log? Just renders incorrectly?)
It works on my machine (both WARP and AMD). The result of L[4] is never used if n < 4, and it is properly initialized otherwise. My guess this is a NVIDIA driver bug. But if that simple fix does it, then we'll do it.
al2950
OGRE Expert User
OGRE Expert User
Posts: 1227
Joined: Thu Dec 11, 2008 7:56 pm
Location: Bristol, UK
x 157

Re: [2.2] Area Light bugs

Post by al2950 »

Interesting... Went home as I have an AMD Vega 64 there and I still get the same issue.
There is an obvious compile error 'variable not completely initialised' type error, see below

Code: Select all

17:24:48: Creating resource group General
17:24:48: Creating resource group Internal
17:24:48: Creating resource group Autodetect
17:24:48: SceneManagerFactory for type 'DefaultSceneManager' registered.
17:24:48: Registering ResourceManager for type Material
17:24:48: Registering ResourceManager for type Mesh
17:24:48: Registering ResourceManager for type Mesh2
17:24:48: Registering ResourceManager for type OldSkeleton
17:24:48: MovableObjectFactory for type 'ParticleSystem' registered.
17:24:48: ArchiveFactory for archive type FileSystem registered.
17:24:48: ArchiveFactory for archive type Zip registered.
17:24:48: ArchiveFactory for archive type EmbeddedZip registered.
17:24:48: DDS codec registering
17:24:48: FreeImage version: 3.15.3
17:24:48: This program uses FreeImage, a free, open source image library supporting all common bitmap formats. See http://freeimage.sourceforge.net for details
17:24:48: Supported formats: bmp,ico,jpg,jif,jpeg,jpe,jng,koa,iff,lbm,mng,pbm,pbm,pcd,pcx,pgm,pgm,png,ppm,ppm,ras,tga,targa,tif,tiff,wap,wbmp,wbm,psd,cut,xbm,xpm,gif,hdr,g3,sgi,exr,j2k,j2c,jp2,pfm,pct,pict,pic
17:24:48: ETC codec registering
17:24:48: OITD codec registering
17:24:48: Registering ResourceManager for type HighLevelGpuProgram
17:24:48: MovableObjectFactory for type 'Decal' registered.
17:24:48: MovableObjectFactory for type 'InternalCubemapProbe' registered.
17:24:48: MovableObjectFactory for type 'Entity' registered.
17:24:48: MovableObjectFactory for type 'Item' registered.
17:24:48: MovableObjectFactory for type 'Light' registered.
17:24:48: MovableObjectFactory for type 'BillboardSet' registered.
17:24:48: MovableObjectFactory for type 'ManualObject2' registered.
17:24:48: MovableObjectFactory for type 'BillboardChain' registered.
17:24:48: MovableObjectFactory for type 'RibbonTrail' registered.
17:24:48: MovableObjectFactory for type 'WireAabb' registered.
17:24:48: Loading library .\RenderSystem_Direct3D11
17:24:48: Installing plugin: D3D11 RenderSystem
17:24:48: D3D11 : Direct3D11 Rendering Subsystem created.
17:24:48: D3D11: Driver Detection Starts
17:24:48: D3D11: Driver Detection Ends
17:24:48: Plugin successfully installed
17:24:48: Loading library .\RenderSystem_GL3Plus
17:24:48: Installing plugin: GL 3+ RenderSystem
17:24:48: OpenGL 3+ Rendering Subsystem created.
17:24:48: Plugin successfully installed
17:24:48: Loading library .\Plugin_ParticleFX
17:24:48: Installing plugin: ParticleFX
17:24:48: Particle Emitter Type 'Point' registered
17:24:48: Particle Emitter Type 'Box' registered
17:24:48: Particle Emitter Type 'Ellipsoid' registered
17:24:48: Particle Emitter Type 'Cylinder' registered
17:24:48: Particle Emitter Type 'Ring' registered
17:24:48: Particle Emitter Type 'HollowEllipsoid' registered
17:24:48: Particle Affector Type 'LinearForce' registered
17:24:48: Particle Affector Type 'ColourFader' registered
17:24:48: Particle Affector Type 'ColourFader2' registered
17:24:48: Particle Affector Type 'ColourImage' registered
17:24:48: Particle Affector Type 'ColourInterpolator' registered
17:24:48: Particle Affector Type 'Scaler' registered
17:24:48: Particle Affector Type 'Rotator' registered
17:24:48: Particle Affector Type 'DirectionRandomiser' registered
17:24:48: Particle Affector Type 'DeflectorPlane' registered
17:24:48: Plugin successfully installed
17:24:48: *-*-* OGRE Initialising
17:24:48: *-*-* Version 2.2.0unstable (C)
17:24:48: OGRE EXCEPTION(6:FileNotFoundException): './ogre.cfg' file not found! in ConfigFile::load at D:/Projects/Ogre/al2950_Ogre/OgreMain/src/OgreConfigFile.cpp (line 88)
17:24:52: D3D11 : RenderSystem Option: Full Screen = No
17:24:53: D3D11 : RenderSystem Option: sRGB Gamma Conversion = Yes
17:24:53: CPU Identifier & Features
17:24:53: -------------------------
17:24:53:  *   CPU ID: GenuineIntel: Intel(R) Core(TM) i7-4770K CPU @ 3.50GHz
17:24:53:  *   Logical cores: 8
17:24:53:  *      SSE: yes
17:24:53:  *     SSE2: yes
17:24:53:  *     SSE3: yes
17:24:53:  *      MMX: yes
17:24:53:  *   MMXEXT: yes
17:24:53:  *    3DNOW: no
17:24:53:  * 3DNOWEXT: no
17:24:53:  *     CMOV: yes
17:24:53:  *      TSC: yes
17:24:53:  *      FPU: yes
17:24:53:  *      PRO: yes
17:24:53:  *       HT: no
17:24:53: -------------------------
17:24:53: D3D11 : Subsystem Initialising
17:24:53: ***************************************
17:24:53: *** D3D11 : Subsystem Initialized OK ***
17:24:53: ***************************************
17:24:53: D3D11RenderSystem::_createRenderWindow "Area Lights (Fake / Approximation & Realistic / LTC)", 800x600 windowed  miscParams: MSAA=1 externalWindowHandle=723678 gamma=true reverse_depth=Yes title=Area Lights (Fake / Approximation & Realistic / LTC) vsync=No 
17:24:53: Registering ResourceManager for type Texture
17:24:53: Registering ResourceManager for type GpuProgram
17:24:53: RenderSystem capabilities
17:24:53: -------------------------
17:24:53: RenderSystem Name: Direct3D11 Rendering Subsystem
17:24:53: GPU Vendor: amd
17:24:53: Device Name: Radeon RX Vega_0
17:24:53: Driver Version: 25.20.15002.58
17:24:53:  * Fixed function pipeline: no
17:24:53:  * Hardware generation of mipmaps: yes
17:24:53:  * Texture blending: yes
17:24:53:  * Anisotropic texture filtering: yes
17:24:53:  * Dot product texture operation: yes
17:24:53:  * Cube mapping: yes
17:24:53:  * Hardware stencil buffer: yes
17:24:53:    - Stencil depth: 8
17:24:53:    - Two sided stencil support: yes
17:24:53:    - Wrap stencil values: yes
17:24:53:  * Hardware vertex / index buffers: yes
17:24:53:  * 32-bit index buffers: yes
17:24:53:  * Vertex programs: yes
17:24:53:  * Number of floating-point constants for vertex programs: 512
17:24:53:  * Number of integer constants for vertex programs: 16
17:24:53:  * Number of boolean constants for vertex programs: 16
17:24:53:  * Fragment programs: yes
17:24:53:  * Number of floating-point constants for fragment programs: 512
17:24:53:  * Number of integer constants for fragment programs: 16
17:24:53:  * Number of boolean constants for fragment programs: 16
17:24:53:  * Geometry programs: yes
17:24:53:  * Number of floating-point constants for geometry programs: 512
17:24:53:  * Number of integer constants for geometry programs: 16
17:24:53:  * Number of boolean constants for geometry programs: 16
17:24:53:  * Tessellation Hull programs: yes
17:24:53:  * Number of floating-point constants for tessellation hull programs: 512
17:24:53:  * Number of integer constants for tessellation hull programs: 16
17:24:53:  * Number of boolean constants for tessellation hull programs: 16
17:24:53:  * Tessellation Domain programs: yes
17:24:53:  * Number of floating-point constants for tessellation domain programs: 512
17:24:53:  * Number of integer constants for tessellation domain programs: 16
17:24:53:  * Number of boolean constants for tessellation domain programs: 16
17:24:53:  * Compute programs: yes
17:24:53:  * Number of floating-point constants for compute programs: 512
17:24:53:  * Number of integer constants for compute programs: 16
17:24:53:  * Number of boolean constants for compute programs: 16
17:24:53:  * Supported Shader Profiles: cs_4_0 cs_4_1 cs_5_0 ds_5_0 gs_4_0 gs_4_1 gs_5_0 hlsl hs_5_0 ps_4_0 ps_4_0_level_9_1 ps_4_0_level_9_3 ps_4_1 ps_5_0 vs_4_0 vs_4_0_level_9_1 vs_4_0_level_9_3 vs_4_1 vs_5_0
17:24:53:  * Texture Compression: yes
17:24:53:    - DXT: yes
17:24:53:    - VTC: no
17:24:53:    - PVRTC: no
17:24:53:    - ATC: no
17:24:53:    - ETC1: no
17:24:53:    - ETC2: no
17:24:53:    - BC4/BC5: yes
17:24:53:    - BC6H/BC7: yes
17:24:53:    - ASTC: no
17:24:53:  * Hardware Occlusion Query: yes
17:24:53:  * User clip planes: yes
17:24:53:  * VET_UBYTE4 vertex element type: yes
17:24:53:  * Infinite far plane projection: yes
17:24:53:  * Hardware render-to-texture: yes
17:24:53:  * Floating point textures: yes
17:24:53:  * Non-power-of-two textures: yes
17:24:53:  * 1d textures: yes
17:24:53:  * Volume textures: yes
17:24:53:  * Max Texture resolution (2D) 16384
17:24:53:  * Max Texture resolution (3D) 2048
17:24:53:  * Max Texture resolution (Cubemaps) 16384
17:24:53:  * Multiple Render Targets: 8
17:24:53:    - With different bit depths: yes
17:24:53:  * Point Sprites: yes
17:24:53:  * Extended point parameters: yes
17:24:53:  * Max Point Size: 256
17:24:53:  * Vertex texture fetch: yes
17:24:53:  * Number of world matrices: 0
17:24:53:  * Number of texture units: 16
17:24:53:  * Stencil buffer depth: 8
17:24:53:  * Number of vertex blend matrices: 0
17:24:53:    - Max vertex textures: 4
17:24:53:    - Vertex textures shared: no
17:24:53:  * Render to Vertex Buffer : yes
17:24:53:  * Hardware Atomic Counters: no
17:24:53: DefaultWorkQueue('Root') initialising on thread main.
17:24:53: Particle Renderer Type 'billboard' registered
17:24:53: OverlayElementFactory for type Panel registered.
17:24:53: OverlayElementFactory for type BorderPanel registered.
17:24:53: OverlayElementFactory for type TextArea registered.
17:24:53: Registering ResourceManager for type Font
17:24:53: Creating resource group Essential
17:24:53: Added resource location 'D:/Projects/Ogre/al2950_Ogre/Samples/Media/packs/DebugPack.zip' of type 'Zip' to resource group 'Essential'
17:24:53: Added resource location 'D:/Projects/Ogre/al2950_Ogre/Samples/Media/packs/profiler.zip' of type 'Zip' to resource group 'Essential'
17:24:53: Added resource location 'D:/Projects/Ogre/al2950_Ogre/Samples/Media/2.0/scripts/materials/Common' of type 'FileSystem' to resource group 'General'
17:24:53: Added resource location 'D:/Projects/Ogre/al2950_Ogre/Samples/Media/2.0/scripts/materials/Common/GLSL' of type 'FileSystem' to resource group 'General'
17:24:53: Added resource location 'D:/Projects/Ogre/al2950_Ogre/Samples/Media/2.0/scripts/materials/Common/HLSL' of type 'FileSystem' to resource group 'General'
17:24:53: Added resource location 'D:/Projects/Ogre/al2950_Ogre/Samples/Media/2.0/scripts/materials/Common/Metal' of type 'FileSystem' to resource group 'General'
17:24:53: Creating resource group Popular
17:24:53: Added resource location 'D:/Projects/Ogre/al2950_Ogre/Samples/Media/2.0/scripts/Compositors' of type 'FileSystem' to resource group 'Popular'
17:24:53: Added resource location 'D:/Projects/Ogre/al2950_Ogre/Samples/Media/models' of type 'FileSystem' to resource group 'Popular'
17:24:53: Added resource location 'D:/Projects/Ogre/al2950_Ogre/Samples/Media/materials/textures' of type 'FileSystem' to resource group 'Popular'
17:24:53: Added resource location 'D:/Projects/Ogre/al2950_Ogre/Samples/Media/materials/textures/Cubemaps' of type 'FileSystem' to resource group 'Popular'
17:24:53: Added resource location 'D:/Projects/Ogre/al2950_Ogre/Samples/Media/2.0/scripts/materials/PbsMaterials' of type 'FileSystem' to resource group 'General'
17:24:53: [INFO] Texture cache not found at .//textureMetadataCache.json
17:24:53: Parsing scripts for resource group Autodetect
17:24:53: Finished parsing scripts for resource group Autodetect
17:24:53: Creating resources for group Autodetect
17:24:53: All done
17:24:53: Parsing scripts for resource group Essential
17:24:53: Parsing script Materials.material
17:24:53: Parsing script OgreProfiler.material
17:24:53: Parsing script DebugFont.fontdef
17:24:53: Finished parsing scripts for resource group Essential
17:24:53: Creating resources for group Essential
17:24:53: All done
17:24:53: Parsing scripts for resource group General
17:24:53: Parsing script Quad.program
17:24:53: Parsing script Copyback.material
17:24:53: Parsing script DepthUtils.material
17:24:53: Parsing script DPM.material
17:24:53: Parsing script DPSM.material
17:24:53: Parsing script EsmGaussianBlurLogFilter.material
17:24:53: Parsing script PbsMaterials.material
17:24:53: Parsing script EsmGaussianBlurLogFilter.material.json
17:24:53: Parsing script Mipmaps.material.json
17:24:53: Finished parsing scripts for resource group General
17:24:53: Creating resources for group General
17:24:53: All done
17:24:53: Parsing scripts for resource group Internal
17:24:53: Finished parsing scripts for resource group Internal
17:24:53: Creating resources for group Internal
17:24:53: All done
17:24:53: Parsing scripts for resource group Popular
17:24:53: Parsing script LocalCubemaps.compositor
17:24:53: Parsing script PbsMaterials.compositor
17:24:53: Parsing script PlanarReflections.compositor
17:24:53: Parsing script ScreenSpaceReflections.compositor
17:24:53: Parsing script ShadowMapDebugging.compositor
17:24:53: Parsing script StaticShadowMaps.compositor
17:24:53: Parsing script StencilTest.compositor
17:24:53: Parsing script StereoRendering.compositor
17:24:53: Parsing script TutorialSky_Postprocess.compositor
17:24:53: Parsing script TutorialUav01_Setup.compositor
17:24:53: Parsing script TutorialUav02_Setup.compositor
17:24:53: Parsing script Tutorial_DynamicCubemap.compositor
17:24:53: Parsing script Tutorial_ReconstructPosFromDepth.compositor
17:24:53: Parsing script Tutorial_Terrain.compositor
17:24:53: Finished parsing scripts for resource group Popular
17:24:53: Creating resources for group Popular
17:24:53: All done
17:24:53: Mesh: Loading Sphere1000.mesh.
17:24:53: WARNING: Sphere1000.mesh is an older format ([MeshSerializer_v2.1 R1]); you should upgrade it as soon as possible using the OgreMeshTool tool.
17:24:53: Mesh: Loading Cube_d.mesh.
17:24:53: WARNING: Cube_d.mesh is an older format ([MeshSerializer_v2.1 R1]); you should upgrade it as soon as possible using the OgreMeshTool tool.
17:24:53: Font DebugFont using texture size 512x512
17:24:53: Info: Freetype returned null for character 127 in font DebugFont
17:24:53: Info: Freetype returned null for character 128 in font DebugFont
17:24:53: Info: Freetype returned null for character 129 in font DebugFont
17:24:53: Info: Freetype returned null for character 130 in font DebugFont
17:24:53: Info: Freetype returned null for character 131 in font DebugFont
17:24:53: Info: Freetype returned null for character 132 in font DebugFont
17:24:53: Info: Freetype returned null for character 133 in font DebugFont
17:24:53: Info: Freetype returned null for character 134 in font DebugFont
17:24:53: Info: Freetype returned null for character 135 in font DebugFont
17:24:53: Info: Freetype returned null for character 136 in font DebugFont
17:24:53: Info: Freetype returned null for character 137 in font DebugFont
17:24:53: Info: Freetype returned null for character 138 in font DebugFont
17:24:53: Info: Freetype returned null for character 139 in font DebugFont
17:24:53: Info: Freetype returned null for character 140 in font DebugFont
17:24:53: Info: Freetype returned null for character 141 in font DebugFont
17:24:53: Info: Freetype returned null for character 142 in font DebugFont
17:24:53: Info: Freetype returned null for character 143 in font DebugFont
17:24:53: Info: Freetype returned null for character 144 in font DebugFont
17:24:53: Info: Freetype returned null for character 145 in font DebugFont
17:24:53: Info: Freetype returned null for character 146 in font DebugFont
17:24:53: Info: Freetype returned null for character 147 in font DebugFont
17:24:53: Info: Freetype returned null for character 148 in font DebugFont
17:24:53: Info: Freetype returned null for character 149 in font DebugFont
17:24:53: Info: Freetype returned null for character 150 in font DebugFont
17:24:53: Info: Freetype returned null for character 151 in font DebugFont
17:24:53: Info: Freetype returned null for character 152 in font DebugFont
17:24:53: Info: Freetype returned null for character 153 in font DebugFont
17:24:53: Info: Freetype returned null for character 154 in font DebugFont
17:24:53: Info: Freetype returned null for character 155 in font DebugFont
17:24:53: Info: Freetype returned null for character 156 in font DebugFont
17:24:53: Info: Freetype returned null for character 157 in font DebugFont
17:24:53: Info: Freetype returned null for character 158 in font DebugFont
17:24:53: Info: Freetype returned null for character 159 in font DebugFont
17:24:53: Info: Freetype returned null for character 160 in font DebugFont
17:25:02: OGRE EXCEPTION(-2147467259:RenderingAPIException): Cannot compile D3D11 high-level shader 100000006PixelShader_ps Errors:
D:\Projects\Ogre\al2950_Ogre\build_vc15\bin\release\100000006PixelShader_ps.hlsl(798,22): error X4000: variable 'L' used without having been completely initialized
D:\Projects\Ogre\al2950_Ogre\build_vc15\bin\release\100000006PixelShader_ps.hlsl(798,22): error X4000: variable 'L' used without having been completely initialized
 in D3D11HLSLProgram::compileMicrocode at D:/Projects/Ogre/al2950_Ogre/RenderSystems/Direct3D11/src/OgreD3D11HLSLProgram.cpp (line 558)
17:25:02: High-level program 100000006PixelShader_ps encountered an error during loading and is thus not supported.
OGRE EXCEPTION(-2147467259:RenderingAPIException): Cannot compile D3D11 high-level shader 100000006PixelShader_ps Errors:
D:\Projects\Ogre\al2950_Ogre\build_vc15\bin\release\100000006PixelShader_ps.hlsl(798,22): error X4000: variable 'L' used without having been completely initialized
D:\Projects\Ogre\al2950_Ogre\build_vc15\bin\release\100000006PixelShader_ps.hlsl(798,22): error X4000: variable 'L' used without having been completely initialized
 in D3D11HLSLProgram::compileMicrocode at D:/Projects/Ogre/al2950_Ogre/RenderSystems/Direct3D11/src/OgreD3D11HLSLProgram.cpp (line 558)
17:25:03: OGRE EXCEPTION(-2147467259:RenderingAPIException): Cannot compile D3D11 high-level shader 100000007PixelShader_ps Errors:
D:\Projects\Ogre\al2950_Ogre\build_vc15\bin\release\100000007PixelShader_ps.hlsl(812,22): error X4000: variable 'L' used without having been completely initialized
D:\Projects\Ogre\al2950_Ogre\build_vc15\bin\release\100000007PixelShader_ps.hlsl(812,22): error X4000: variable 'L' used without having been completely initialized
 in D3D11HLSLProgram::compileMicrocode at D:/Projects/Ogre/al2950_Ogre/RenderSystems/Direct3D11/src/OgreD3D11HLSLProgram.cpp (line 558)
17:25:03: High-level program 100000007PixelShader_ps encountered an error during loading and is thus not supported.
OGRE EXCEPTION(-2147467259:RenderingAPIException): Cannot compile D3D11 high-level shader 100000007PixelShader_ps Errors:
D:\Projects\Ogre\al2950_Ogre\build_vc15\bin\release\100000007PixelShader_ps.hlsl(812,22): error X4000: variable 'L' used without having been completely initialized
D:\Projects\Ogre\al2950_Ogre\build_vc15\bin\release\100000007PixelShader_ps.hlsl(812,22): error X4000: variable 'L' used without having been completely initialized
 in D3D11HLSLProgram::compileMicrocode at D:/Projects/Ogre/al2950_Ogre/RenderSystems/Direct3D11/src/OgreD3D11HLSLProgram.cpp (line 558)
17:25:03: OGRE EXCEPTION(-2147467259:RenderingAPIException): Cannot compile D3D11 high-level shader 100000008PixelShader_ps Errors:
D:\Projects\Ogre\al2950_Ogre\build_vc15\bin\release\100000008PixelShader_ps.hlsl(797,22): error X4000: variable 'L' used without having been completely initialized
D:\Projects\Ogre\al2950_Ogre\build_vc15\bin\release\100000008PixelShader_ps.hlsl(797,22): error X4000: variable 'L' used without having been completely initialized
 in D3D11HLSLProgram::compileMicrocode at D:/Projects/Ogre/al2950_Ogre/RenderSystems/Direct3D11/src/OgreD3D11HLSLProgram.cpp (line 558)
17:25:03: High-level program 100000008PixelShader_ps encountered an error during loading and is thus not supported.
OGRE EXCEPTION(-2147467259:RenderingAPIException): Cannot compile D3D11 high-level shader 100000008PixelShader_ps Errors:
D:\Projects\Ogre\al2950_Ogre\build_vc15\bin\release\100000008PixelShader_ps.hlsl(797,22): error X4000: variable 'L' used without having been completely initialized
D:\Projects\Ogre\al2950_Ogre\build_vc15\bin\release\100000008PixelShader_ps.hlsl(797,22): error X4000: variable 'L' used without having been completely initialized
 in D3D11HLSLProgram::compileMicrocode at D:/Projects/Ogre/al2950_Ogre/RenderSystems/Direct3D11/src/OgreD3D11HLSLProgram.cpp (line 558)

Here is one of the offensing shaders '100000006PixelShader_ps'

Code: Select all

#if 0
	***	[Hash 0x010d84dd]	2
	***	[Hash 0x06285893]	0
	***	[Hash 0x0790ba12]	4
	***	[Hash 0x086bb3a6]	0
	***	[Hash 0x0ac4ff20]	3
	***	[Hash 0x0b4678e4]	1
	***	[Hash 0x0c7e761b]	4
	***	[Hash 0x1185e86f]	0
	***	[Hash 0x123606a9]	0
	***	[Hash 0x15cb74a1]	0
	***	[Hash 0x16e62810]	3
	***	[Hash 0x1825f286]	3
	***	[Hash 0x19a61682]	1
	***	[Hash 0x1af900a2]	1
	***	[Hash 0x1b0c2b69]	0
	***	[Hash 0x1bab8cdd]	0
	***	[Hash 0x1bb5acac]	0
	***	[Hash 0x1e8b5671]	50000
	***	[Hash 0x1f2c6e82]	0
	***	[Hash 0x21515f80]	3
	***	[Hash 0x2337351f]	8
	***	[Hash 0x24d6fb8f]	1
	***	[Hash 0x25dc73c6]	635204550
	***	[Hash 0x26249384]	42857
	***	[Hash 0x2a892b58]	0
	***	[Hash 0x2cb6ab02]	0
	***	[Hash 0x2dd3a2cd]	0
	***	[Hash 0x354d66c0]	3
	***	[Hash 0x359e8062]	1
	***	[Hash 0x360c3db1]	0
	***	[Hash 0x38942648]	3
	***	[Hash 0x39384d5a]	28571
	***	[Hash 0x3b038020]	0
	***	[Hash 0x3d790219]	3
	***	[Hash 0x3dde9817]	1
	***	[Hash 0x3f315fff]	0
	***	[Hash 0x3fcb60f1]	1070293233
	***	[Hash 0x415a738b]	0
	***	[Hash 0x4508a85c]	1
	***	[Hash 0x45d6475f]	0
	***	[Hash 0x4614eb82]	3
	***	[Hash 0x46bba485]	0
	***	[Hash 0x491233c3]	0
	***	[Hash 0x4956ca9a]	1
	***	[Hash 0x4ec19020]	1
	***	[Hash 0x4feb7b6e]	1
	***	[Hash 0x51de8f13]	42857
	***	[Hash 0x549bb006]	0
	***	[Hash 0x55683ca9]	1
	***	[Hash 0x57643473]	3
	***	[Hash 0x5a23f9f0]	0
	***	[Hash 0x5ca459ef]	0
	***	[Hash 0x5cb4719a]	1
	***	[Hash 0x5dbe1dca]	1
	***	[Hash 0x62055e42]	3
	***	[Hash 0x66ac9d57]	0
	***	[Hash 0x675280f4]	0
	***	[Hash 0x6962e498]	1
	***	[Hash 0x6be92c72]	0
	***	[Hash 0x6caa2971]	2
	***	[Hash 0x6d28c426]	2
	***	[Hash 0x6f177a79]	0
	***	[Hash 0x717564b5]	0
	***	[Hash 0x71dd9ea9]	4
	***	[Hash 0x74824502]	1
	***	[Hash 0x74a9afe4]	1
	***	[Hash 0x76277703]	3
	***	[Hash 0x7633d79c]	3
	***	[Hash 0x790cdbbe]	0
	***	[Hash 0x7a148ebc]	0
	***	[Hash 0x7ae862a6]	0
	***	[Hash 0x7e8dec1c]	0
	***	[Hash 0x7e934f0e]	0
	***	[Hash 0x8040ea88]	28571
	***	[Hash 0x8045c1b4]	1
	***	[Hash 0x840f5b80]	0
	***	[Hash 0x8421366d]	2
	***	[Hash 0x86319b9f]	1
	***	[Hash 0x875516cf]	0
	***	[Hash 0x8857c26f]	0
	***	[Hash 0x899520b9]	2
	***	[Hash 0x91f755f3]	0
	***	[Hash 0x92baf270]	0
	***	[Hash 0x9313c759]	0
	***	[Hash 0x93f2327b]	-334286542
	***	[Hash 0x94b1117a]	-1
	***	[Hash 0x962aeb1a]	1
	***	[Hash 0x969b85a2]	3
	***	[Hash 0x96c12323]	1
	***	[Hash 0x9abd84b5]	-1698855755
	***	[Hash 0xa0b3d929]	3
	***	[Hash 0xa461daa9]	1
	***	[Hash 0xa62cee23]	0
	***	[Hash 0xa69f72d5]	2
	***	[Hash 0xa6ac776b]	0
	***	[Hash 0xa89ac41a]	1
	***	[Hash 0xa90324bb]	0
	***	[Hash 0xa9ef564e]	3
	***	[Hash 0xab18cda0]	1
	***	[Hash 0xb22f037a]	0
	***	[Hash 0xb7b857ae]	1
	***	[Hash 0xb9201184]	0
	***	[Hash 0xb967bb7b]	0
	***	[Hash 0xbb17ed32]	3
	***	[Hash 0xbc128c23]	0
	***	[Hash 0xc0a55ecd]	3
	***	[Hash 0xc16170c0]	0
	***	[Hash 0xc163417f]	3
	***	[Hash 0xc19750c1]	3
	***	[Hash 0xc377e795]	50000
	***	[Hash 0xc46d5eba]	1
	***	[Hash 0xc5a41055]	3
	***	[Hash 0xc5ed03e2]	1
	***	[Hash 0xc7cccc57]	0
	***	[Hash 0xcb33bcfe]	0
	***	[Hash 0xcef10401]	1
	***	[Hash 0xd17f1d1c]	1
	***	[Hash 0xd62dae30]	4
	***	[Hash 0xd7ec9987]	1
	***	[Hash 0xdc23368e]	0
	***	[Hash 0xde8359cf]	1
	***	[Hash 0xdf16de3a]	1
	***	[Hash 0xe40b2520]	1
	***	[Hash 0xe7bd0fde]	0
	***	[Hash 0xe91dc048]	2
	***	[Hash 0xe9b3b96d]	0
	***	[Hash 0xebb7ea44]	1
	***	[Hash 0xebfcdcac]	28571
	***	[Hash 0xec133132]	-334286542
	***	[Hash 0xec4e19ce]	0
	***	[Hash 0xf6eb512d]	0
	DONE DUMPING PROPERTIES
	***	[Hash 0xcbb75443]	@insertpiece( NormalNonPremul)
	DONE DUMPING PIECES
#endif

//#include "SyntaxHighlightingMisc.h"


#define ushort uint
#define ogre_float4x3 float4x3

//Short used for read operations. It's an int in GLSL & HLSL. An ushort in Metal
#define rshort2 int2
//Short used for write operations. It's an int in GLSL. An ushort in HLSL & Metal
#define wshort2 uint2

#define toFloat3x3( x ) ((float3x3)(x))
#define buildFloat3x3( row0, row1, row2 ) transpose( float3x3( row0, row1, row2 ) )

#define min3( a, b, c ) min( a, min( b, c ) )
#define max3( a, b, c ) max( a, max( b, c ) )

#define INLINE
#define NO_INTERPOLATION_PREFIX nointerpolation
#define NO_INTERPOLATION_SUFFIX

#define finalDrawId input.drawId
#define PARAMS_ARG_DECL
#define PARAMS_ARG

#define floatBitsToUint(x) asuint(x)
#define uintBitsToFloat(x) asfloat(x)
#define floatBitsToInt(x) asint(x)
#define fract frac
#define lessThan( a, b ) (a < b)

#define inVs_vertexId input.vertexId
#define inVs_vertex input.vertex
#define inVs_blendWeights input.blendWeights
#define inVs_blendIndices input.blendIndices
#define inVs_qtangent input.qtangent
#define inVs_drawId input.drawId

	#define inVs_uv0 input.uv0
#define outVs_Position outVs.gl_Position
#define outVs_clipDistance0 outVs.gl_ClipDistance0

#define gl_SampleMaskIn0 gl_SampleMask
#define interpolateAtSample( interp, subsample ) EvaluateAttributeAtSample( interp, subsample )
#define findLSB firstbitlow

#define outPs_colour0 outPs.colour0
#define OGRE_Sample( tex, sampler, uv ) tex.Sample( sampler, uv )
#define OGRE_SampleLevel( tex, sampler, uv, lod ) tex.SampleLevel( sampler, uv, lod )
#define OGRE_SampleArray2D( tex, sampler, uv, arrayIdx ) tex.Sample( sampler, float3( uv, arrayIdx ) )
#define OGRE_SampleArray2DLevel( tex, sampler, uv, arrayIdx, lod ) tex.SampleLevel( sampler, float3( uv, arrayIdx ), lod )
#define OGRE_SampleArrayCubeLevel( tex, sampler, uv, arrayIdx, lod ) tex.SampleLevel( sampler, float4( uv, arrayIdx ), lod )
#define OGRE_SampleGrad( tex, sampler, uv, ddx, ddy ) tex.SampleGrad( sampler, uv, ddx, ddy )
#define OGRE_SampleArray2DGrad( tex, sampler, uv, arrayIdx, ddx, ddy ) tex.SampleGrad( sampler, float3( uv, arrayIdx ), ddx, ddy )
#define OGRE_ddx( val ) ddx( val )
#define OGRE_ddy( val ) ddy( val )
#define OGRE_Load2D( tex, iuv, lod ) tex.Load( int3( iuv, lod ) )
#define OGRE_Load2DMS( tex, iuv, subsample ) tex.Load( iuv, subsample )

#define bufferFetch( buffer, idx ) buffer.Load( idx )
#define bufferFetch1( buffer, idx ) buffer.Load( idx ).x

#define CONST_BUFFER( bufferName, bindingPoint ) cbuffer bufferName : register(b##bindingPoint)
#define CONST_BUFFER_STRUCT_BEGIN( structName, bindingPoint ) cbuffer structName : register(b##bindingPoint) { struct _##structName
#define CONST_BUFFER_STRUCT_END( variableName ) variableName; }

#define FLAT_INTERPOLANT( decl, bindingPoint ) nointerpolation decl : TEXCOORD##bindingPoint
#define INTERPOLANT( decl, bindingPoint ) decl : TEXCOORD##bindingPoint


	#define UV_DIFFUSE(x) (x)
	#define UV_NORMAL(x) (x)
	#define UV_SPECULAR(x) (x)
	#define UV_ROUGHNESS(x) (x)
	#define UV_DETAIL_WEIGHT(x) (x)
	#define UV_DETAIL0(x) (x)
	#define UV_DETAIL1(x) (x)
	#define UV_DETAIL2(x) (x)
	#define UV_DETAIL3(x) (x)
	#define UV_DETAIL_NM0(x) (x)
	#define UV_DETAIL_NM1(x) (x)
	#define UV_DETAIL_NM2(x) (x)
	#define UV_DETAIL_NM3(x) (x)
	#define UV_EMISSIVE(x) (x)
	



	
		#define float_fresnel float
		#define make_float_fresnel( x ) x
	

	
			#define OGRE_DEPTH_CMP_GE( a, b ) (a) <= (b)
		#define OGRE_DEPTH_DEFAULT_CLEAR 0.0
	

	struct PixelData
	{
		
			float3 normal;
			
				#define geomNormal normal
			
			float4	diffuse;
			float3	specular;
			float	roughness;
			float_fresnel	F0;

			
				float3	viewDir;
				float	NdotV;
			

			
		
	};

	#define SampleDetailWeightMap( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2D( tex, sampler, uv, arrayIdx )
	
		#define SampleDetailCol0( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2D( tex, sampler, uv, arrayIdx )
	
		
	
		
	
		
	
	
	
	
		#define SampleRoughness( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2D( tex, sampler, uv, arrayIdx )
	
	
	

	

	

	
		
//Default BRDF
INLINE float3 BRDF( float3 lightDir, float3 lightDiffuse, float3 lightSpecular, PixelData pixelData )
{
    float3 halfWay = normalize( lightDir + pixelData.viewDir );
    float NdotL = saturate( dot( pixelData.normal, lightDir ) );
    float NdotH = saturate( dot( pixelData.normal, halfWay ) );
    float VdotH = saturate( dot( pixelData.viewDir, halfWay ) );

    float sqR = pixelData.roughness * pixelData.roughness;

	//Roughness/Distribution/NDF term (GGX)
	//Formula:
	//	Where alpha = roughness
	//	R = alpha^2 / [ PI * [ ( NdotH^2 * (alpha^2 - 1) ) + 1 ]^2 ]
	float f = ( NdotH * sqR - NdotH ) * NdotH + 1.0;
	float R = sqR / (f * f + 1e-6f);

	//Geometric/Visibility term (Smith GGX Height-Correlated)

    float Lambda_GGXV = NdotL * sqrt( (-pixelData.NdotV * sqR + pixelData.NdotV) * pixelData.NdotV + sqR );
    float Lambda_GGXL = pixelData.NdotV * sqrt( (-NdotL * sqR + NdotL) * NdotL + sqR );

	float G = 0.5 / (( Lambda_GGXV + Lambda_GGXL + 1e-6f ) * 3.141592654);


	//Formula:
	//	fresnelS = lerp( (1 - V*H)^5, 1, F0 )
    float_fresnel fresnelS = pixelData.F0 + pow( 1.0 - VdotH, 5.0 ) * (1.0 - pixelData.F0);

	//We should divide Rs by PI, but it was done inside G for performance
    float3 Rs = ( fresnelS * (R * G) ) * pixelData.specular.xyz * lightSpecular;

	//Diffuse BRDF (*Normalized* Disney, see course_notes_moving_frostbite_to_pbr.pdf
	//"Moving Frostbite to Physically Based Rendering" Sebastien Lagarde & Charles de Rousiers)
    float energyBias	= pixelData.roughness * 0.5;
    float energyFactor	= lerp( 1.0, 1.0 / 1.51, pixelData.roughness );
    float fd90			= energyBias + 2.0 * VdotH * VdotH * pixelData.roughness;
	float lightScatter	= 1.0 + (fd90 - 1.0) * pow( 1.0 - NdotL, 5.0 );
    float viewScatter	= 1.0 + (fd90 - 1.0) * pow( 1.0 - pixelData.NdotV, 5.0 );

    
        float fresnelD = 1.0f - fresnelS;
    

	//We should divide Rd by PI, but it is already included in kD
    float3 Rd = (lightScatter * viewScatter * energyFactor * fresnelD) * pixelData.diffuse.xyz * lightDiffuse;

	return NdotL * (Rs + Rd);
}

		
		
	


// START UNIFORM DECLARATION

	
		
struct ShadowReceiverData
{
	float4x4 texViewProj;
	float2 shadowDepthRange;
	float2 padding;
	float4 invShadowMapSize;
};

struct Light
{
	float4 position;	//.w contains the objLightMask
	float4 diffuse;		//.w contains numNonCasterDirectionalLights
	float3 specular;

	float3 attenuation;
	//Spotlights:
	//  spotDirection.xyz is direction
	//  spotParams.xyz contains falloff params
	float4 spotDirection;
	float4 spotParams;
};

#define numNonCasterDirectionalLights lights[0].diffuse.w

#define areaLightDiffuseMipmapStart areaApproxLights[0].diffuse.w
#define areaLightNumMipmapsSpecFactor areaApproxLights[0].specular.w

#define numAreaApproxLights areaApproxLights[0].doubleSided.y
#define numAreaApproxLightsWithMask areaApproxLights[0].doubleSided.z

#define numAreaLtcLights areaLtcLights[0].points[0].w

struct AreaLight
{
	float4 position;	//.w contains the objLightMask
	float4 diffuse;		//[0].w contains diffuse mipmap start
	float4 specular;	//[0].w contains mipmap scale
	float4 attenuation;	//.w contains texture array idx
	//Custom 2D Shape:
	//  direction.xyz direction
	//  direction.w invHalfRectSize.x
	//  tangent.xyz tangent
	//  tangent.w invHalfRectSize.y
	float4 direction;
	float4 tangent;
	float4 doubleSided;	//.y contains numAreaApproxLights
						//.z contains numAreaApproxLightsWithMask
};

struct AreaLtcLight
{
	float4 position;		//.w contains the objLightMask
	float4 diffuse;			//.w contains attenuation range
	float4 specular;		//.w contains doubleSided
	float4 points[4];		//.w contains numAreaLtcLights
};



//Uniforms that change per pass
CONST_BUFFER_STRUCT_BEGIN( PassBuffer, 0 )
{
	//Vertex shader (common to both receiver and casters)
	float4x4 viewProj;




	//Vertex shader
	float4x4 view;
	ShadowReceiverData shadowRcv[3];
	//-------------------------------------------------------------------------

	//Pixel shader
	float3x3 invViewMatCubemap;

	float padding; //Compatibility with GLSL





	float pssmSplitPoints0;
	float pssmSplitPoints1;
	float pssmSplitPoints2;
	float pssmBlendPoints0;
	float pssmBlendPoints1;
	float pssmFadePoint;	Light lights[1];		AreaLtcLight areaLtcLights[2];

	


	
}
CONST_BUFFER_STRUCT_END( passBuf );

	
	
//Uniforms that change per Item/Entity, but change very infrequently
struct Material
{
	/* kD is already divided by PI to make it energy conserving.
	  (formula is finalDiffuse = NdotL * surfaceDiffuse / PI)
	*/
	float4 bgDiffuse;
	float4 kD; //kD.w is alpha_test_threshold
	float4 kS; //kS.w is roughness
	//Fresnel coefficient, may be per colour component (float3) or scalar (float)
	//F0.w is transparency
	float4 F0;
	float4 normalWeights;
	float4 cDetailWeights;
	float4 detailOffsetScale[4];
	float4 emissive;		//emissive.w contains mNormalMapWeight.
	float4 userValue[3];

	
		uint4 indices0_3;
		uint4 indices4_7;
	
	
};

	
		CONST_BUFFER( MaterialBuf, 1 )
		{
			Material materialArray[2];
		};
	
	
		//Uniforms that change per Item/Entity
		CONST_BUFFER( InstanceBuffer, 2 )
		{
			//.x =
			//The lower 9 bits contain the material's start index.
			//The higher 23 bits contain the world matrix start index.
			//
			//.y =
			//shadowConstantBias. Send the bias directly to avoid an
			//unnecessary indirection during the shadow mapping pass.
			//Must be loaded with uintBitsToFloat
			//
			//.z =
			//lightMask. Ogre must have been compiled with OGRE_NO_FINE_LIGHT_MASK_GRANULARITY
			
				uint4 worldMaterialIdx[2];
					};
	
	


// END UNIFORM DECLARATION
struct PS_INPUT
{

	
					
				FLAT_INTERPOLANT( ushort drawId, 0 );
					
		
			INTERPOLANT( float3 pos, 1 );
			INTERPOLANT( float3 normal, 2 );
							
			INTERPOLANT( float2 uv0, 3 );
		
			
				INTERPOLANT( float4 posL0, 4 );
			
				INTERPOLANT( float4 posL1, 5 );
			
				INTERPOLANT( float4 posL2, 6 );		INTERPOLANT( float depth, 7 );				

};















	Texture2DArray textureMaps0 : register(t3);
	Texture2DArray textureMaps1 : register(t4);




	SamplerState samplerState3 : register(s3);







	#define hlms_shadowmap0 texShadowMap0
	#define hlms_shadowmap0_uv_min float2( 0.0, 0.0 )
	#define hlms_shadowmap0_uv_max float2( 1.0, 0.28571 )
	
		
			#define hlms_shadowmap0_uv_param , hlms_shadowmap0_uv_min, hlms_shadowmap0_uv_max
			
	#define hlms_shadowmap1 texShadowMap0
	#define hlms_shadowmap1_uv_min float2( 0.0, 0.28571 )
	#define hlms_shadowmap1_uv_max float2( 0.50000, 0.42857 )
	
		
			#define hlms_shadowmap1_uv_param , hlms_shadowmap1_uv_min, hlms_shadowmap1_uv_max
			
	#define hlms_shadowmap2 texShadowMap0
	#define hlms_shadowmap2_uv_min float2( 0.50000, 0.28571 )
	#define hlms_shadowmap2_uv_max float2( 1.0, 0.42857 )
	
		
			#define hlms_shadowmap2_uv_param , hlms_shadowmap2_uv_min, hlms_shadowmap2_uv_max
			


	#define OGRE_SAMPLE_SHADOW( tex, sampler, uv, depth ) (OGRE_DEPTH_CMP_GE( depth, OGRE_DEPTH_DEFAULT_CLEAR ) ? 1.0 : tex.SampleCmpLevelZero( sampler, uv.xy, depth ).x)
	#define OGRE_SAMPLE_SHADOW_ESM( tex, sampler, uv ) tex.SampleLevel( sampler, uv, 0 ).x
	#define PASSBUF_ARG_DECL
	#define PASSBUF_ARG



		SamplerComparisonState shadowSampler: register(s2);
		
			Texture2D<float> texShadowMap0				: register(t2);	


	
		INLINE float getShadow( Texture2D<float> shadowMap, SamplerComparisonState shadowSampler, 
								float4 psPosLN, float4 invShadowMapSize )
		{
	
		//Spot and directional lights
		
			float fDepth = psPosLN.z / psPosLN.w;
				float2 uv = float2( psPosLN.xy / psPosLN.w );
	
	
		float retVal = 0;

		
			float2 offsets[4] =
                        
            {
            			
				float2( 0, 0 ),	//0, 0
				float2( 1, 0 ),	//1, 0
				float2( 0, 1 ),	//1, 1
				float2(-1, 0 ) 	//0, 1
						                        
			};
            		
		
		
			
				uv += offsets[0] * invShadowMapSize.xy;				retVal += OGRE_SAMPLE_SHADOW( shadowMap, shadowSampler, uv, fDepth );
				uv += offsets[1] * invShadowMapSize.xy;				retVal += OGRE_SAMPLE_SHADOW( shadowMap, shadowSampler, uv, fDepth );
				uv += offsets[2] * invShadowMapSize.xy;				retVal += OGRE_SAMPLE_SHADOW( shadowMap, shadowSampler, uv, fDepth );
				uv += offsets[3] * invShadowMapSize.xy;				retVal += OGRE_SAMPLE_SHADOW( shadowMap, shadowSampler, uv, fDepth );		
		
			retVal *= 0.25;
			///! exponential_shadow_maps
	   ///! exponential_shadow_maps

	
	
		return retVal;
	}

	
		INLINE float getShadow( Texture2D<float> shadowMap, SamplerComparisonState shadowSampler, 
								float4 psPosLN, float4 invShadowMapSize, float2 minUV, float2 maxUV )
		{
	
		//Spot and directional lights
		
			float fDepth = psPosLN.z / psPosLN.w;
				float2 uv = float2( psPosLN.xy / psPosLN.w );
	
	
		float retVal = 0;

		
			float2 offsets[4] =
                        
            {
            			
				float2( 0, 0 ),	//0, 0
				float2( 1, 0 ),	//1, 0
				float2( 0, 1 ),	//1, 1
				float2(-1, 0 ) 	//0, 1
						                        
			};
            		
		
		
			
				uv += offsets[0] * invShadowMapSize.xy;				retVal += OGRE_SAMPLE_SHADOW( shadowMap, shadowSampler, uv, fDepth );
				uv += offsets[1] * invShadowMapSize.xy;				retVal += OGRE_SAMPLE_SHADOW( shadowMap, shadowSampler, uv, fDepth );
				uv += offsets[2] * invShadowMapSize.xy;				retVal += OGRE_SAMPLE_SHADOW( shadowMap, shadowSampler, uv, fDepth );
				uv += offsets[3] * invShadowMapSize.xy;				retVal += OGRE_SAMPLE_SHADOW( shadowMap, shadowSampler, uv, fDepth );		
		
			retVal *= 0.25;
			///! exponential_shadow_maps
	   ///! exponential_shadow_maps

	
	
		retVal = (uv.x <= minUV.x || uv.x >= maxUV.x ||
				  uv.y <= minUV.y || uv.y >= maxUV.y) ? 1.0 : retVal;
	
		return retVal;
	}

	
		INLINE float getShadowPoint( Texture2D<float> shadowMap, SamplerComparisonState shadowSampler, 
									 float3 posVS, float3 lightPos, float4 invShadowMapSize, float2 invDepthRange
									 PASSBUF_ARG_DECL )
		{
			//Point lights
		float3 cubemapDir = posVS.xyz - lightPos.xyz;
		float fDepth = length( cubemapDir );
		cubemapDir *= 1.0 / fDepth;
		cubemapDir = mul( cubemapDir.xyz, passBuf.invViewMatCubemap );
					fDepth = (invDepthRange.x - fDepth) * invDepthRange.y;
		
		float2 uv;
		uv.x = (cubemapDir.x / (1.0 + abs( cubemapDir.z ))) * 0.25 +
				(cubemapDir.z < 0.0 ? 0.75 : 0.25 );
		uv.y = (cubemapDir.y / (1.0 + abs( cubemapDir.z ))) * 0.5 + 0.5;

			
	
		float retVal = 0;

		
			float2 offsets[4] =
                        
            {
            			
				float2( 0, 0 ),	//0, 0
				float2( 1, 0 ),	//1, 0
				float2( 0, 1 ),	//1, 1
				float2(-1, 0 ) 	//0, 1
						                        
			};
            		
		
		
			
				uv += offsets[0] * invShadowMapSize.xy;				retVal += OGRE_SAMPLE_SHADOW( shadowMap, shadowSampler, uv, fDepth );
				uv += offsets[1] * invShadowMapSize.xy;				retVal += OGRE_SAMPLE_SHADOW( shadowMap, shadowSampler, uv, fDepth );
				uv += offsets[2] * invShadowMapSize.xy;				retVal += OGRE_SAMPLE_SHADOW( shadowMap, shadowSampler, uv, fDepth );
				uv += offsets[3] * invShadowMapSize.xy;				retVal += OGRE_SAMPLE_SHADOW( shadowMap, shadowSampler, uv, fDepth );		
		
			retVal *= 0.25;
			///! exponential_shadow_maps
	   ///! exponential_shadow_maps

	
	
		return retVal;
	}

	
		INLINE float getShadowPoint( Texture2D<float> shadowMap, SamplerComparisonState shadowSampler, 
									 float3 posVS, float3 lightPos, float4 invShadowMapSize, float2 invDepthRange,
									 float2 minUV, float2 maxUV, float2 lengthUV
									 PASSBUF_ARG_DECL )
		{
			//Point lights
		float3 cubemapDir = posVS.xyz - lightPos.xyz;
		float fDepth = length( cubemapDir );
		cubemapDir *= 1.0 / fDepth;
		cubemapDir = mul( cubemapDir.xyz, passBuf.invViewMatCubemap );
					fDepth = (invDepthRange.x - fDepth) * invDepthRange.y;
		
		float2 uv;
		uv.x = (cubemapDir.x / (1.0 + abs( cubemapDir.z ))) * 0.25 +
				(cubemapDir.z < 0.0 ? 0.75 : 0.25 );
		uv.y = (cubemapDir.y / (1.0 + abs( cubemapDir.z ))) * 0.5 + 0.5;

		uv.xy = uv.xy * lengthUV.xy + minUV.xy;	
	
		float retVal = 0;

		
			float2 offsets[4] =
                        
            {
            			
				float2( 0, 0 ),	//0, 0
				float2( 1, 0 ),	//1, 0
				float2( 0, 1 ),	//1, 1
				float2(-1, 0 ) 	//0, 1
						                        
			};
            		
		
		
			
				uv += offsets[0] * invShadowMapSize.xy;				retVal += OGRE_SAMPLE_SHADOW( shadowMap, shadowSampler, uv, fDepth );
				uv += offsets[1] * invShadowMapSize.xy;				retVal += OGRE_SAMPLE_SHADOW( shadowMap, shadowSampler, uv, fDepth );
				uv += offsets[2] * invShadowMapSize.xy;				retVal += OGRE_SAMPLE_SHADOW( shadowMap, shadowSampler, uv, fDepth );
				uv += offsets[3] * invShadowMapSize.xy;				retVal += OGRE_SAMPLE_SHADOW( shadowMap, shadowSampler, uv, fDepth );		
		
			retVal *= 0.25;
			///! exponential_shadow_maps
	   ///! exponential_shadow_maps

	
	
		retVal = (uv.x <= minUV.x || uv.x >= maxUV.x ||
				  uv.y <= minUV.y || uv.y >= maxUV.y) ? 1.0 : retVal;
	
		return retVal;
	}



				
			Texture2DArray<float4> ltcMatrix	: register(t1);
			SamplerState ltcSampler				: register(s1);
					

#define LUT_SIZE  64.0
#define LUT_SCALE ((LUT_SIZE - 1.0)/LUT_SIZE)
#define LUT_BIAS  (0.5/LUT_SIZE)

INLINE float3 IntegrateEdgeVec( float3 v1, float3 v2 )
{
	float x = dot(v1, v2);
	float y = abs(x);

	float a = 0.8543985 + (0.4965155 + 0.0145206*y)*y;
	float b = 3.4175940 + (4.1616724 + y)*y;
	float v = a / b;

	float theta_sintheta = (x > 0.0) ? v : 0.5*rsqrt(max(1.0 - x*x, 1e-7)) - v;

	return cross( v1, v2 ) * theta_sintheta;
}

INLINE float IntegrateEdge( float3 v1, float3 v2 )
{
	return IntegrateEdgeVec( v1, v2 ).z;
}


INLINE void ClipQuadToHorizon( inout float3 L[5], out int n )
{
	// detect clipping config
	int config = 0;
	if (L[0].z > 0.0) config += 1;
	if (L[1].z > 0.0) config += 2;
	if (L[2].z > 0.0) config += 4;
	if (L[3].z > 0.0) config += 8;

	// clip
	n = 0;

	if (config == 0)
	{
		// clip all
	}
	else if (config == 1) // V1 clip V2 V3 V4
	{
		n = 3;
		L[1] = -L[1].z * L[0] + L[0].z * L[1];
		L[2] = -L[3].z * L[0] + L[0].z * L[3];
	}
	else if (config == 2) // V2 clip V1 V3 V4
	{
		n = 3;
		L[0] = -L[0].z * L[1] + L[1].z * L[0];
		L[2] = -L[2].z * L[1] + L[1].z * L[2];
	}
	else if (config == 3) // V1 V2 clip V3 V4
	{
		n = 4;
		L[2] = -L[2].z * L[1] + L[1].z * L[2];
		L[3] = -L[3].z * L[0] + L[0].z * L[3];
	}
	else if (config == 4) // V3 clip V1 V2 V4
	{
		n = 3;
		L[0] = -L[3].z * L[2] + L[2].z * L[3];
		L[1] = -L[1].z * L[2] + L[2].z * L[1];
	}
	else if (config == 5) // V1 V3 clip V2 V4) impossible
	{
		n = 0;
	}
	else if (config == 6) // V2 V3 clip V1 V4
	{
		n = 4;
		L[0] = -L[0].z * L[1] + L[1].z * L[0];
		L[3] = -L[3].z * L[2] + L[2].z * L[3];
	}
	else if (config == 7) // V1 V2 V3 clip V4
	{
		n = 5;
		L[4] = -L[3].z * L[0] + L[0].z * L[3];
		L[3] = -L[3].z * L[2] + L[2].z * L[3];
	}
	else if (config == 8) // V4 clip V1 V2 V3
	{
		n = 3;
		L[0] = -L[0].z * L[3] + L[3].z * L[0];
		L[1] = -L[2].z * L[3] + L[3].z * L[2];
		L[2] =  L[3];
	}
	else if (config == 9) // V1 V4 clip V2 V3
	{
		n = 4;
		L[1] = -L[1].z * L[0] + L[0].z * L[1];
		L[2] = -L[2].z * L[3] + L[3].z * L[2];
	}
	else if (config == 10) // V2 V4 clip V1 V3) impossible
	{
		n = 0;
	}
	else if (config == 11) // V1 V2 V4 clip V3
	{
		n = 5;
		L[4] = L[3];
		L[3] = -L[2].z * L[3] + L[3].z * L[2];
		L[2] = -L[2].z * L[1] + L[1].z * L[2];
	}
	else if (config == 12) // V3 V4 clip V1 V2
	{
		n = 4;
		L[1] = -L[1].z * L[2] + L[2].z * L[1];
		L[0] = -L[0].z * L[3] + L[3].z * L[0];
	}
	else if (config == 13) // V1 V3 V4 clip V2
	{
		n = 5;
		L[4] = L[3];
		L[3] = L[2];
		L[2] = -L[1].z * L[2] + L[2].z * L[1];
		L[1] = -L[1].z * L[0] + L[0].z * L[1];
	}
	else if (config == 14) // V2 V3 V4 clip V1
	{
		n = 5;
		L[4] = -L[0].z * L[3] + L[3].z * L[0];
		L[0] = -L[0].z * L[1] + L[1].z * L[0];
	}
	else if (config == 15) // V1 V2 V3 V4
	{
		n = 4;
	}

	if (n == 3)
		L[3] = L[0];
	if (n == 4)
		L[4] = L[0];
}

INLINE float LTC_Evaluate( float3 N, float3 V, float3 P, float3x3 Minv,
							 float4 points[4],
							bool twoSided )
{
	// construct orthonormal basis around N
	float3 T1, T2;
	T1 = normalize( V - N*dot(V, N) );
	T2 = cross(N, T1);

	// rotate area light in (T1, T2, N) basis
	Minv = mul( Minv, transpose( buildFloat3x3( T1, T2, N ) ) );

	// polygon (allocate 5 vertices for clipping)
	float3 L[5];
	L[0] = mul( Minv, points[0].xyz - P );
	L[1] = mul( Minv, points[1].xyz - P );
	L[2] = mul( Minv, points[2].xyz - P );
	L[3] = mul( Minv, points[3].xyz - P );

	// integrate
	float sum = 0.0;

		
		int n;
		ClipQuadToHorizon( L, n );

		if( n == 0 )
			return 0;
		// project onto sphere
		L[0] = normalize( L[0] );
		L[1] = normalize( L[1] );
		L[2] = normalize( L[2] );
		L[3] = normalize( L[3] );
		L[4] = normalize( L[4] );

		// integrate
		sum += IntegrateEdge( L[0], L[1] );
		sum += IntegrateEdge( L[1], L[2] );
		sum += IntegrateEdge( L[2], L[3] );
		if( n >= 4 )
			sum += IntegrateEdge( L[3], L[4] );
		if( n == 5 )
			sum += IntegrateEdge( L[4], L[0] );

		sum = twoSided ? abs(sum) : max(0.0, sum);
	
	return sum;
}



	struct PS_OUTPUT
	{
		
			float4 colour0 : SV_Target0;
		
	};




PS_OUTPUT main
(
	PS_INPUT inPs
	
	
	
)
{
	PS_OUTPUT outPs;
	
	
	
		PixelData pixelData;

		
	
		
            ushort materialId	= worldMaterialIdx[inPs.drawId].x & 0x1FFu;
            #define material materialArray[materialId]
		
	

		
	
		
		
				ushort texIndex_detailMapIdx0		= material.indices0_3.z >> 16u;
		
		
		
	

		
	
		
		
				ushort texIndex_roughnessIdx		= material.indices0_3.y >> 16u;
		
		
		
		
		
		
	

		
		

		
	
		//Prepare weight map for the detail maps.
		
			
				float4 detailWeights = float4( 1.0, 1.0, 1.0, 1.0 );
			
		
	


		
	/// Sample detail maps and weight them against the weight map in the next foreach loop.
	
		
			float4 detailCol0 = SampleDetailCol0( textureMaps1,
													samplerState3,
                                                    UV_DETAIL0( inPs.uv0.xy * material.detailOffsetScale[0].zw + material.detailOffsetScale[0].xy ),
                                                    texIndex_detailMapIdx0 );
			detailWeights.x *= detailCol0.w;
			detailCol0.w = detailWeights.x;
		
	
		
	
		
	
		
	


		
			
	/// DIFFUSE MAP
	
		/// If there are no diffuse maps, we must initialize it to some value.
		pixelData.diffuse.xyzw = material.bgDiffuse.xyzw;
	

	/// Blend the detail diffuse maps with the main diffuse.
	
		
	//Normal Non Premultiplied 0
	pixelData.diffuse.xyz = lerp( pixelData.diffuse.xyz, detailCol0.xyz, detailCol0.a );
	pixelData.diffuse.w = lerp( pixelData.diffuse.w, 1.0, detailCol0.w );
  
		  
		  
		  

	/// Apply the material's diffuse over the textures
	pixelData.diffuse.xyz *= material.kD.xyz;
	

	

		

		
	/// SPECUlAR MAP
	pixelData.specular.xyz = material.kS.xyz;
	
		pixelData.F0 = material.F0.x;
		
		
	
	

		
	/// ROUGHNESS MAP
	pixelData.roughness = material.kS.w;
	
		pixelData.roughness *= SampleRoughness( textureMaps0,
												samplerState3,
												UV_ROUGHNESS( inPs.uv0.xy ),
												texIndex_roughnessIdx ).x;
		pixelData.roughness = max( pixelData.roughness, 0.001f );
	


		

		
			
	
		// Geometric normal
		pixelData.normal = normalize( inPs.normal ) ;
	

			
	/// If there is no normal map, the first iteration must
	/// initialize pixelData.normal instead of try to merge with it.
	
		
		
	

	
	

	

	/// Blend the detail normal maps with the main normal.
	
	


			

			

			

			

		float fShadow = 1.0;
	
		float fShadowBlend = 1.0;
		
		if( inPs.depth <= passBuf.pssmSplitPoints0 )
		{
			fShadow = getShadow( hlms_shadowmap0, shadowSampler, 
								 inPs.posL0,
								 passBuf.shadowRcv[0].invShadowMapSize
								 hlms_shadowmap0_uv_param );
			
				if( inPs.depth > passBuf.pssmBlendPoints0 )
				{
					fShadowBlend = getShadow( hlms_shadowmap1, shadowSampler, 
											  inPs.posL1,
											  passBuf.shadowRcv[1].invShadowMapSize
											  hlms_shadowmap1_uv_param );
					fShadow = lerp( fShadow, fShadowBlend,
									(inPs.depth - passBuf.pssmBlendPoints0) /
									(passBuf.pssmSplitPoints0 - passBuf.pssmBlendPoints0) );
				}
								}
		
		else if( inPs.depth <= passBuf.pssmSplitPoints1 )
		{
			fShadow = getShadow( hlms_shadowmap1, shadowSampler, 
								 inPs.posL1,
								 passBuf.shadowRcv[1].invShadowMapSize
								 hlms_shadowmap1_uv_param );
			
				if( inPs.depth > passBuf.pssmBlendPoints1 )
				{
					fShadowBlend = getShadow( hlms_shadowmap2, shadowSampler, 
											  inPs.posL2,
											  passBuf.shadowRcv[2].invShadowMapSize
											  hlms_shadowmap2_uv_param );
					fShadow = lerp( fShadow, fShadowBlend,
									(inPs.depth - passBuf.pssmBlendPoints1) /
									(passBuf.pssmSplitPoints1 - passBuf.pssmBlendPoints1) );
				}
								}
		else if( inPs.depth <= passBuf.pssmSplitPoints2 )
		{
			fShadow = getShadow( hlms_shadowmap2, shadowSampler, 
								 inPs.posL2,
								 passBuf.shadowRcv[2].invShadowMapSize
								 hlms_shadowmap2_uv_param );
			
				if( inPs.depth > passBuf.pssmFadePoint )
				{
					fShadow = lerp( fShadow, 1.0,
									(inPs.depth - passBuf.pssmFadePoint) /
									(passBuf.pssmSplitPoints2 - passBuf.pssmFadePoint) );
				}
								}	

		

		
			
	//Everything's in Camera space
	
		pixelData.viewDir	= normalize( -inPs.pos );
		pixelData.NdotV		= saturate( dot( pixelData.normal, pixelData.viewDir ) );
	

	
		float3 finalColour = float3(0, 0, 0);
	

	
		float3 lightDir;
		float fDistance;
		float3 tmpColour;
		float spotCosAngle;
	
	


			

			
				
	
		
			finalColour += BRDF( passBuf.lights[0].position.xyz, passBuf.lights[0].diffuse.xyz, passBuf.lights[0].specular, pixelData ) * fShadow;
	
	

	
		
	

			

			
	

			
	


			
			
for( int i=0; i<floatBitsToInt( passBuf.numAreaLtcLights ); ++i )
{
	lightDir = passBuf.areaLtcLights[i].position.xyz - inPs.pos;
	fDistance = length( lightDir );
	if( fDistance <= passBuf.areaLtcLights[i].diffuse.w  )
	{
		float2 ltcUV = float2( pixelData.roughness, sqrt(1.0 - pixelData.NdotV) );
		ltcUV = ltcUV * LUT_SCALE + LUT_BIAS;

		float4 ltc0 = OGRE_SampleArray2DLevel( ltcMatrix, ltcSampler, ltcUV, 0, 0 );
		float4 ltc1 = OGRE_SampleArray2DLevel( ltcMatrix, ltcSampler, ltcUV, 1, 0 );

		float3x3 Minv = buildFloat3x3(
			float3(ltc0.x, 0, ltc0.y),
			float3(  0,  1,    0),
			float3(ltc0.z, 0, ltc0.w)
		);

		bool doubleSidedLtc = passBuf.areaLtcLights[i].specular.w != 0.0f;

		
			float ltcSpecular = LTC_Evaluate( pixelData.normal.xyz, pixelData.viewDir.xyz, inPs.pos.xyz, Minv,
											  passBuf.areaLtcLights[i].points, doubleSidedLtc );
			// BRDF shadowing and Fresnel
			ltcSpecular *= pixelData.F0 * ltc1.x + (1.0 - pixelData.F0) * ltc1.y;
		
		float ltcDiffuse = LTC_Evaluate( pixelData.normal.xyz, pixelData.viewDir.xyz, inPs.pos.xyz,
										 buildFloat3x3( float3( 1, 0, 0 ), float3( 0, 1, 0 ), float3( 0, 0, 1 ) ),
										 passBuf.areaLtcLights[i].points, doubleSidedLtc );

		finalColour += passBuf.areaLtcLights[i].diffuse.xyz * ltcDiffuse * pixelData.diffuse.xyz;
		finalColour += passBuf.areaLtcLights[i].specular.xyz * ltcSpecular * pixelData.specular.xyz;
	}
}


			
			
			

			
	


			

			

			

			

            
		///!hlms_prepass

	///!hlms_normal || hlms_qtangent

	
		
			
				
					outPs_colour0.xyz	= finalColour;
				

				
					outPs_colour0.w		= 1.0;
				

				
			
		
	

	

	


	return outPs;

}

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5299
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1280
Contact:

Re: [2.2] Area Light bugs

Post by dark_sylinc »

Must be a DX SDK/DLL version thing then. Anyway pushed a fix.

@rujialiu: I was able to repro the Light Mask bug. It is a VERY, VERY weird one. It only reproduced on a 64-bit build for me, but not 32-bit one.
This is what I found:

Both versions returned exactly the same result while inside RenderDoc's HLSL debugger (which runs HLSL inside its own interpreter), but this did not coincide with the actual output as rendered by the GPU or by WARP.

The original code:

Code: Select all

for( int i=0; i<floatBitsToInt( passBuf.numAreaApproxLights ); ++i )
{
    lightDir = passBuf.areaApproxLights[i].position.xyz - inPs.pos;
    projectedPosInPlane.xyz = inPs.pos - dot( -lightDir.xyz, passBuf.areaApproxLights[i].direction.xyz ) *
                                         passBuf.areaApproxLights[i].direction.xyz;
    fDistance = length( lightDir );
    if( fDistance <= passBuf.areaApproxLights[i].attenuation.x &&
        && ((objLightMask & floatBitsToUint( passBuf.areaApproxLights[i].position.w )) != 0u) )
    {
Has trouble. However the following alternatives to the code work as intended:

Code: Select all

for( int i=0; i<4; ++i ) //Hardcoded the 4

Code: Select all

((objLightMask & floatBitsToUint( passBuf.areaApproxLights[0].position.w )) //Hardcoded the index (any value in valid range worked)
Disabling textured area lights (i.e. use non-textured) also fixed the problem ¯\_(ツ)_/¯

Further experimentation showed that D3D11 thinks "floatBitsToUint( passBuf.areaApproxLights[ i].position.w )" returns 0 but it does return the right value if 'i' is a hardcoded value.

Then I went to https://www.h-schmidt.net/FloatConverter/IEEE754.html, entered the mask manually and everything made sense: Leaving the bitmask range in [30; 23] as all 0s results in a denormal.

My guess is that the denormal is being flushed to 0 by HLSL, then reinterpreted to to uint, but it is too late; now all first 22 bits were lost.

Note that this only affects the light mask, not the object mask.

A simple workaround is to reserve the 29th bit of the light mask, to avoid having denormals:

Code: Select all

light->setLightMask( (1 << 29u) | (1 << 22u) );
item->setLightMask( (1 << 22u) );
I did not experiment what would happen if all bits in range [30; 23] are set at the same time (which would result in either Infinity, -Infinity or NaN). To be on the safe side, reserve both 29th & 28th bits, always set the 29th and never set the 28th.

I will have to rewrite this bit of code so that instead of doing floatBitsToUint() we always use a native uint on that value.

UPDATE: Definitely fxc borks here.
Writing floatBitsToUint( passBuf.areaApproxLights.position.w ); results in:

Code: Select all

 510:   mul r5.w, cb0[37].w, icb[r3 + 0].x
 511:   add r5.w, r5.w, l(0)
 512:   mul r6.w, cb0[44].w, icb[r3 + 0].y
 513:   add r5.w, r5.w, r6.w
 514:   mul r6.w, cb0[51].w, icb[r3 + 0].z
 515:   add r5.w, r5.w, r6.w
 516:   mul r6.w, cb0[58].w, icb[r3 + 0].w
 517:   add r5.w, r5.w, r6.w
The value is in cb0[37].w, however instead of directly reading from it, it performs lots of weird floating point calculations (which force the flush to 0) and mixes it with unrelated variables at cb[44], 51 & 58; storing the result of the mask in r5.w

The compiler should've been written instead (which is what it does with the workarounds):

Code: Select all

mov r5.w, cb0[[r3 + 37]].w
UPDATE 2: I think the reason my 32-bit version works ok is because it's using the compiler from June 2010 SDK (I build using Visual Studio 2008), while the 64-bit version is built using Visual Studio 2015 (which uses a much newer SDK)
rujialiu
Goblin
Posts: 296
Joined: Mon May 09, 2016 8:21 am
x 35

Re: [2.2] Area Light bugs

Post by rujialiu »

dark_sylinc wrote: Mon Feb 04, 2019 8:14 pm @rujialiu: I was able to repro the Light Mask bug. It is a VERY, VERY weird one. It only reproduced on a 64-bit build for me, but not 32-bit one.
This is what I found:
Ahh.... that was unexpected. Anyway, reserving 28th and 29th bit solves the problem for me. Thanks!!!
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5299
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1280
Contact:

Re: [2.2] Area Light bugs

Post by dark_sylinc »

Pushed a fix for the light masks.

There's no more need to reserve bits 28 & 29.

Update: Bitbucket link is dead, Github link
rujialiu
Goblin
Posts: 296
Joined: Mon May 09, 2016 8:21 am
x 35

Re: [2.2] Area Light bugs

Post by rujialiu »

dark_sylinc wrote: Sat Feb 09, 2019 11:07 pm Pushed a fix for the light masks.

There's no more need to reserve bits 28 & 29.
D3D11 works! However, according to Metal Shading Language Specification section 2.9 Packed Vector Data Types:
"Components of a packed vector data type can be accessed with an array index. However, components of a packed vector data type cannot be accessed with the .xyzw or .rgba selection syntax."

And indeed, it failes to compile in our iOS app. However, metal compile doesn't have this issue so I simply changed syntax == glsl to syntax != hlsl, then both D3D11 and Metal works 8-)
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5299
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1280
Contact:

Re: [2.2] Area Light bugs

Post by dark_sylinc »

rujialiu wrote: Sun Feb 10, 2019 10:41 am D3D11 works! However, according to Metal Shading Language Specification section 2.9 Packed Vector Data Types:
"Components of a packed vector data type can be accessed with an array index. However, components of a packed vector data type cannot be accessed with the .xyzw or .rgba selection syntax."
What the f---? I swear that wasn't there years ago. Maybe I'm mistaken.
rujialiu wrote: Sun Feb 10, 2019 10:41 am And indeed, it failes to compile in our iOS app. However, metal compile doesn't have this issue so I simply changed syntax == glsl to syntax != hlsl, then both D3D11 and Metal works 8-)
Yeah that's the proper fix.
Post Reply