[TOOL] DAEnerys - DAE Ship Editor


(Nathanius) #482

I really like the new icon! Nice work :smiley:

//EDIT:
Don’t know if this is a new thing, but the modified shipAnim shader from @cmdbob isn’t showing up in the editor, not affecting anything but it should recognise that the shader is there at least?


(Christoph Timmermann) #483

It’s @Alekfix789’s work. :smile:

I just tried loading a custom shader (which I surprisingly never have done before with DAEnerys).
The shader manifest is looping through all the paths and chooses the last one to load it’s shaders from, ignoring all the others. I am trying to make it load all of them, but I have never really touched this part of DAEnerys, as it’s entirely @radar3301’s work.


(Christoph Timmermann) #484

Okay, I just changed some things and it seems to work now:

There are still some issues when the same shader is present in multiple data paths, but that’s going to be a thing for the future (or when radar does this legit).


(ajlsunrise) #485

This was intentional, at least originally. When BitVenom mentioned that shaders don’t necessarily have to be in the manifest, I began rewriting the shader loading code.


(Christoph Timmermann) #486

Just pushing out a little bugfix release with some new features.
Download: DAEnerys_b6800.zip

Added features

  • Implemented algorithm to combine meshes with the same material on OBJ import.
  • Added the option to add joint templates. (Weapons, Hardpoints, Capture points, etc…)
  • Added Remove all button for joints, which removes the selected joint and all of it’s descendants at once.

Bugfixes

  • Fixed that there was no scrolling bar for the markers tab.
  • Zooming in orthographic mode is now also smoothed.
  • Fixed death-flickering on navlights after too much elapsed time between frames.
  • Fixed that the exporter put in UNCOMPRESSED instead of 8888.
  • Increased maximum material count to 64.
  • Shaders are now hopefully loaded from all data paths.
  • Only DIFF textures are getting put in library_images now.
  • Joints, markers etc. are no longer case sensitive.


Have fun. :slight_smile:


(Nathanius) #487

Huh-uh… :confused:


(Christoph Timmermann) #488

Uhh…
Could you send me the DAE + shader please? :sweat_smile:


(ajlsunrise) #489

@Nathanius, @PayDay

Can you please post the contents of manifest.log?


(Nathanius) #490

Here are the log contents, I will have to supply DAE and shader folders after work sorry :sweat_smile:

[details=Log.txt]OpenTK initialized.
WARNING: The texture “G:\Games\Homeworld 2\Modding Tools\Reference\HWR 2.0\background/ez10\ez10_hq_posx.dds” is not in TGA-Format.
WARNING: The texture “G:\Games\Homeworld 2\Modding Tools\Reference\HWR 2.0\background/ez10\ez10_hq_negx.dds” is not in TGA-Format.
WARNING: The texture “G:\Games\Homeworld 2\Modding Tools\Reference\HWR 2.0\background/ez10\ez10_hq_posy.dds” is not in TGA-Format.
WARNING: The texture “G:\Games\Homeworld 2\Modding Tools\Reference\HWR 2.0\background/ez10\ez10_hq_negy.dds” is not in TGA-Format.
WARNING: The texture “G:\Games\Homeworld 2\Modding Tools\Reference\HWR 2.0\background/ez10\ez10_hq_posz.dds” is not in TGA-Format.
WARNING: The texture “G:\Games\Homeworld 2\Modding Tools\Reference\HWR 2.0\background/ez10\ez10_hq_negz.dds” is not in TGA-Format.
WARNING: The texture “G:\Games\Homeworld 2\Modding Tools\Reference\HWR 2.0\background/m01\m01_hq_posx.dds” is not in TGA-Format.
WARNING: The texture “G:\Games\Homeworld 2\Modding Tools\Reference\HWR 2.0\background/m01\m01_hq_negx.dds” is not in TGA-Format.
WARNING: The texture “G:\Games\Homeworld 2\Modding Tools\Reference\HWR 2.0\background/m01\m01_hq_posy.dds” is not in TGA-Format.
WARNING: The texture “G:\Games\Homeworld 2\Modding Tools\Reference\HWR 2.0\background/m01\m01_hq_negy.dds” is not in TGA-Format.
WARNING: The texture “G:\Games\Homeworld 2\Modding Tools\Reference\HWR 2.0\background/m01\m01_hq_posz.dds” is not in TGA-Format.
WARNING: The texture “G:\Games\Homeworld 2\Modding Tools\Reference\HWR 2.0\background/m01\m01_hq_negz.dds” is not in TGA-Format.
Info, T13432: Load colladaBlenderFix.dae

Info, T13432: Found a matching importer for this file format

Info, T13432: Import root directory is ‘.’

Warn, T13432: Collada: No material specified for subgroup <> in geometry <NAVL[NavLightR2]_Type[default]_Sect[0]_Sz[1]_Ph[0]_Fr[1]_Col[1,0,0]_Dist[0]_Flags[Sprite]-lib>.

Warn, T13432: Collada: No material specified for subgroup <> in geometry <NAVL[NavLightW1]_Type[default]_Sect[0]_Sz[1]_Ph[0]_Fr[1]_Col[1,1,1]_Dist[0]_Flags[Sprite]-lib>.

Warn, T13432: Collada: No material specified for subgroup <> in geometry <NAVL[NavLightW2]_Type[default]_Sect[0]_Sz[1]_Ph[0]_Fr[1]_Col[1,1,1]_Dist[0]_Flags[Sprite]-lib>.

Warn, T13432: Collada: No material specified for subgroup <> in geometry <NAVL[NavLightG1]_Type[default]_Sect[0]_Sz[1]_Ph[0]_Fr[1]_Col[0,1,0]_Dist[0]_Flags[Sprite]-lib>.

Warn, T13432: Collada: No material specified for subgroup <> in geometry <NAVL[NavLightG2]_Type[default]_Sect[0]_Sz[1]_Ph[0]_Fr[1]_Col[0,1,0]_Dist[0]_Flags[Sprite]-lib>.

Warn, T13432: Collada: No material specified for subgroup <> in geometry <NAVL[NavLightR1]_Type[default]_Sect[0]_Sz[1]_Ph[0]_Fr[1]_Col[1,0,0]_Dist[0]_Flags[Sprite]-lib>.

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Warn, T13432: Collada: No material specified for subgroup <> in geometry .

Info, T13432: Entering post processing pipeline

Info, T13432: JoinVerticesProcess finished | Verts in: 126012 out: 78940 | ~37.4%

Info, T13432: Leaving post processing pipeline

Trying to parse texture “IMG[fed_TNG_sov_thruster_DIFF]_FMT[8888]”.
Trying to parse texture “IMG[fed_TNG_flaghull2_DIFF]_FMT[8888]”.
Trying to parse texture “IMG[fed_TNG_flaghull1_DIFF]_FMT[8888]”.
Trying to parse texture “IMG[bussard_TNG_DIFF]_FMT[8888]”.
Trying to parse material “MAT[bussard]_SHD[shipAnim]”.
WARNING: Unknown shader “shipAnim” of material “MAT[bussard]_SHD[shipAnim]”.
Trying to parse material “MAT[hull0]_SHD[ship]”.
Trying to parse material “MAT[hull1]_SHD[ship]”.
Trying to parse material “MAT[thruster]_SHD[thruster]”.
Trying to parse material “_collision_meshdefault”.
Trying to parse material “_shieldDefault”.
[/details]

[details=Manifest.log]Vendor: NVIDIA Corporation
Renderer: GeForce GTX 960/PCIe/SSE2
PartID: 960
Could not locate program sob_opqaue_s
Duplicate program detected: sob_salvage
Could not locate program fx_right_basic
Could not locate program re_me_rings
Duplicate surface detected: sob_salvage
Failed to compile shader:
0(832) : error C1038: declaration of “outUV0” conflicts with previous declaration at 0(119)
0(833) : error C1038: declaration of “outNorm” conflicts with previous declaration at 0(120)
0(834) : error C1038: declaration of “outTan” conflicts with previous declaration at 0(121)
0(835) : error C1038: declaration of “outBiNorm” conflicts with previous declaration at 0(122)
0(836) : error C1038: declaration of “outPos_W” conflicts with previous declaration at 0(123)
0(837) : error C1038: declaration of “outEye_W” conflicts with previous declaration at 0(124)
0(840) : error C1038: declaration of “outPos_KL” conflicts with previous declaration at 0(127)
0(841) : error C1038: declaration of “inTexShadow” conflicts with previous declaration at 0(128)
0(842) : error C1038: declaration of “inShadowTrans” conflicts with previous declaration at 0(129)
0(848) : error C1038: declaration of “inTime” conflicts with previous declaration at 0(135)
0(856) : error C1038: declaration of “inTexDiffOn” conflicts with previous declaration at 0(143)
0(857) : error C1038: declaration of “inTexGlowOn” conflicts with previous declaration at 0(144)
0(858) : error C1038: declaration of “inTexDiffOff” conflicts with previous declaration at 0(145)
0(859) : error C1038: declaration of “inTexGlowOff” conflicts with previous declaration at 0(146)
0(860) : error C1038: declaration of “inColEngine” conflicts with previous declaration at 0(147)
0(899) : error C1038: declaration of “inTexTeam” conflicts with previous declaration at 0(186)
0(902) : error C1038: declaration of “inTexNorm” conflicts with previous declaration at 0(189)
0(903) : error C1038: declaration of “inTexEnv0” conflicts with previous declaration at 0(190)
0(904) : error C1038: declaration of “inTexEnv1” conflicts with previous declaration at 0(191)
0(907) : error C1038: declaration of “inClipPlane” conflicts with previous declaration at 0(194)
0(914) : error C1038: declaration of “inSOBParams” conflicts with previous declaration at 0(201)
0(915) : error C1038: declaration of “inLifeParams” conflicts with previous declaration at 0(202)
0(917) : error C1038: declaration of “inFogColor” conflicts with previous declaration at 0(204)
0(918) : error C1038: declaration of “inFogWindow” conflicts with previous declaration at 0(205)
0(920) : error C1038: declaration of “inMatM” conflicts with previous declaration at 0(207)
0(923) : error C1038: declaration of “inColTeam” conflicts with previous declaration at 0(210)
0(924) : error C1038: declaration of “inColStripe” conflicts with previous declaration at 0(211)
0(928) : error C1038: declaration of “inColEffect” conflicts with previous declaration at 0(215)
0(931) : error C1038: declaration of “inSurfDiff” conflicts with previous declaration at 0(218)
0(932) : error C1038: declaration of “inSurfGlow” conflicts with previous declaration at 0(219)
0(933) : error C1038: declaration of “inSurfSpec” conflicts with previous declaration at 0(220)
0(934) : error C1038: declaration of “inSurfGloss” conflicts with previous declaration at 0(221)
0(935) : error C1038: declaration of “inSurfRefl” conflicts with previous declaration at 0(222)
0(936) : error C1038: declaration of “inSurfFren” conflicts with previous declaration at 0(223)
0(937) : error C1038: declaration of “inSurfPaint” conflicts with previous declaration at 0(224)
0(938) : error C1038: declaration of “inSurfPeak” conflicts with previous declaration at 0(225)
0(940) : error C1038: declaration of “inPaintStyle” conflicts with previous declaration at 0(227)
0(942) : error C1038: declaration of “inGammaScale” conflicts with previous declaration at 0(229)
0(943) : error C1038: declaration of “inBGAddLight” conflicts with previous declaration at 0(230)
0(944) : error C1038: declaration of “inBGEnvParams” conflicts with previous declaration at 0(231)
0(967) : error C1038: declaration of “inLightCounts” conflicts with previous declaration at 0(254)
0(968) : error C1038: declaration of “inLightShip” conflicts with previous declaration at 0(255)
0(969) : error C1038: declaration of “inLightCore” conflicts with previous declaration at 0(256)
0(971) : error C1038: declaration of “finalCol0” conflicts with previous declaration at 0(258)
0(975) : error C1038: declaration of “shadWH” conflicts with previous declaration at 0(262)
0(976) : error C1038: declaration of “invShad” conflicts with previous declaration at 0(263)
0(978) : error C1013: function “CALC_ShadowMask” is already defined at 0(265)
0(1057) : error C1013: function “CALC_ShadowMask_K” is already defined at 0(344)
0(1070) : error C1013: function “CALC_ShadowMask_F” is already defined at 0(357)
0(1073) : error C1013: function “main” is already defined at 0(360)

Failed to compile shader:
0(831) : error C1038: declaration of “outUV0” conflicts with previous declaration at 0(118)
0(832) : error C1038: declaration of “outNorm” conflicts with previous declaration at 0(119)
0(833) : error C1038: declaration of “outTan” conflicts with previous declaration at 0(120)
0(834) : error C1038: declaration of “outBiNorm” conflicts with previous declaration at 0(121)
0(835) : error C1038: declaration of “outPos_W” conflicts with previous declaration at 0(122)
0(836) : error C1038: declaration of “outEye_W” conflicts with previous declaration at 0(123)
0(839) : error C1038: declaration of “outPos_KL” conflicts with previous declaration at 0(126)
0(840) : error C1038: declaration of “inTexShadow” conflicts with previous declaration at 0(127)
0(841) : error C1038: declaration of “inShadowTrans” conflicts with previous declaration at 0(128)
0(847) : error C1038: declaration of “inTime” conflicts with previous declaration at 0(134)
0(861) : error C1038: declaration of “inTexDiff” conflicts with previous declaration at 0(148)
0(862) : error C1038: declaration of “inTexGlow” conflicts with previous declaration at 0(149)
0(898) : error C1038: declaration of “inTexTeam” conflicts with previous declaration at 0(185)
0(901) : error C1038: declaration of “inTexNorm” conflicts with previous declaration at 0(188)
0(902) : error C1038: declaration of “inTexEnv0” conflicts with previous declaration at 0(189)
0(903) : error C1038: declaration of “inTexEnv1” conflicts with previous declaration at 0(190)
0(906) : error C1038: declaration of “inClipPlane” conflicts with previous declaration at 0(193)
0(913) : error C1038: declaration of “inSOBParams” conflicts with previous declaration at 0(200)
0(914) : error C1038: declaration of “inLifeParams” conflicts with previous declaration at 0(201)
0(916) : error C1038: declaration of “inFogColor” conflicts with previous declaration at 0(203)
0(917) : error C1038: declaration of “inFogWindow” conflicts with previous declaration at 0(204)
0(919) : error C1038: declaration of “inMatM” conflicts with previous declaration at 0(206)
0(922) : error C1038: declaration of “inColTeam” conflicts with previous declaration at 0(209)
0(923) : error C1038: declaration of “inColStripe” conflicts with previous declaration at 0(210)
0(927) : error C1038: declaration of “inColEffect” conflicts with previous declaration at 0(214)
0(930) : error C1038: declaration of “inSurfDiff” conflicts with previous declaration at 0(217)
0(931) : error C1038: declaration of “inSurfGlow” conflicts with previous declaration at 0(218)
0(932) : error C1038: declaration of “inSurfSpec” conflicts with previous declaration at 0(219)
0(933) : error C1038: declaration of “inSurfGloss” conflicts with previous declaration at 0(220)
0(934) : error C1038: declaration of “inSurfRefl” conflicts with previous declaration at 0(221)
0(935) : error C1038: declaration of “inSurfFren” conflicts with previous declaration at 0(222)
0(936) : error C1038: declaration of “inSurfPaint” conflicts with previous declaration at 0(223)
0(937) : error C1038: declaration of “inSurfPeak” conflicts with previous declaration at 0(224)
0(939) : error C1038: declaration of “inPaintStyle” conflicts with previous declaration at 0(226)
0(941) : error C1038: declaration of “inGammaScale” conflicts with previous declaration at 0(228)
0(942) : error C1038: declaration of “inBGAddLight” conflicts with prev[/details]


(ajlsunrise) #491

I’m not sure which shader(s) decided to fail at compiling…

Here’s a quick fix. Just drop these 3 files in, and it’ll tell you which shader failed.


(ajlsunrise) #492

So the warning is just that; a warning. Specifically the warning is about the shader manifest not containing an HOD alias named “shipAnim” that points to the more unified format of “sob_shipanim”. I’ll likely be removing this warning in the manifest re-write, as shaders will be loaded differently.


(D Kesserich) #493

Relevant to peoples’ interests: I’m a good way through the ground-up re-write of the Blender DAE exporter, and I think I’ve cracked getting the bezier curves for animation (which also means I may have a way to get the importer to preserve the curves as well).

Open3DModelViewer plays the dae back with the animations in tact, so that’s a good sign. Still have to add all the HWRM specific data parsing to node naming stuff, and hopefully HODOR doesn’t hate that some of my element ordering is a little weird.


(Nathanius) #494

Updated manifest.log for you!

Manifest.log

Vendor: NVIDIA Corporation
Renderer: GeForce GTX 960/PCIe/SSE2
PartID: 960
Could not locate program sob_opqaue_s
Duplicate program detected: sob_salvage
Could not locate program fx_right_basic
Could not locate program re_me_rings
Duplicate surface detected: sob_salvage
Failed to compile shader from “shaders\gl_prog\sob_thruster.prog”. Details:
0(832) : error C1038: declaration of “outUV0” conflicts with previous declaration at 0(119)
0(833) : error C1038: declaration of “outNorm” conflicts with previous declaration at 0(120)
0(834) : error C1038: declaration of “outTan” conflicts with previous declaration at 0(121)
0(835) : error C1038: declaration of “outBiNorm” conflicts with previous declaration at 0(122)
0(836) : error C1038: declaration of “outPos_W” conflicts with previous declaration at 0(123)
0(837) : error C1038: declaration of “outEye_W” conflicts with previous declaration at 0(124)
0(840) : error C1038: declaration of “outPos_KL” conflicts with previous declaration at 0(127)
0(841) : error C1038: declaration of “inTexShadow” conflicts with previous declaration at 0(128)
0(842) : error C1038: declaration of “inShadowTrans” conflicts with previous declaration at 0(129)
0(848) : error C1038: declaration of “inTime” conflicts with previous declaration at 0(135)
0(856) : error C1038: declaration of “inTexDiffOn” conflicts with previous declaration at 0(143)
0(857) : error C1038: declaration of “inTexGlowOn” conflicts with previous declaration at 0(144)
0(858) : error C1038: declaration of “inTexDiffOff” conflicts with previous declaration at 0(145)
0(859) : error C1038: declaration of “inTexGlowOff” conflicts with previous declaration at 0(146)
0(860) : error C1038: declaration of “inColEngine” conflicts with previous declaration at 0(147)
0(899) : error C1038: declaration of “inTexTeam” conflicts with previous declaration at 0(186)
0(902) : error C1038: declaration of “inTexNorm” conflicts with previous declaration at 0(189)
0(903) : error C1038: declaration of “inTexEnv0” conflicts with previous declaration at 0(190)
0(904) : error C1038: declaration of “inTexEnv1” conflicts with previous declaration at 0(191)
0(907) : error C1038: declaration of “inClipPlane” conflicts with previous declaration at 0(194)
0(914) : error C1038: declaration of “inSOBParams” conflicts with previous declaration at 0(201)
0(915) : error C1038: declaration of “inLifeParams” conflicts with previous declaration at 0(202)
0(917) : error C1038: declaration of “inFogColor” conflicts with previous declaration at 0(204)
0(918) : error C1038: declaration of “inFogWindow” conflicts with previous declaration at 0(205)
0(920) : error C1038: declaration of “inMatM” conflicts with previous declaration at 0(207)
0(923) : error C1038: declaration of “inColTeam” conflicts with previous declaration at 0(210)
0(924) : error C1038: declaration of “inColStripe” conflicts with previous declaration at 0(211)
0(928) : error C1038: declaration of “inColEffect” conflicts with previous declaration at 0(215)
0(931) : error C1038: declaration of “inSurfDiff” conflicts with previous declaration at 0(218)
0(932) : error C1038: declaration of “inSurfGlow” conflicts with previous declaration at 0(219)
0(933) : error C1038: declaration of “inSurfSpec” conflicts with previous declaration at 0(220)
0(934) : error C1038: declaration of “inSurfGloss” conflicts with previous declaration at 0(221)
0(935) : error C1038: declaration of “inSurfRefl” conflicts with previous declaration at 0(222)
0(936) : error C1038: declaration of “inSurfFren” conflicts with previous declaration at 0(223)
0(937) : error C1038: declaration of “inSurfPaint” conflicts with previous declaration at 0(224)
0(938) : error C1038: declaration of “inSurfPeak” conflicts with previous declaration at 0(225)
0(940) : error C1038: declaration of “inPaintStyle” conflicts with previous declaration at 0(227)
0(942) : error C1038: declaration of “inGammaScale” conflicts with previous declaration at 0(229)
0(943) : error C1038: declaration of “inBGAddLight” conflicts with previous declaration at 0(230)
0(944) : error C1038: declaration of “inBGEnvParams” conflicts with previous declaration at 0(231)
0(967) : error C1038: declaration of “inLightCounts” conflicts with previous declaration at 0(254)
0(968) : error C1038: declaration of “inLightShip” conflicts with previous declaration at 0(255)
0(969) : error C1038: declaration of “inLightCore” conflicts with previous declaration at 0(256)
0(971) : error C1038: declaration of “finalCol0” conflicts with previous declaration at 0(258)
0(975) : error C1038: declaration of “shadWH” conflicts with previous declaration at 0(262)
0(976) : error C1038: declaration of “invShad” conflicts with previous declaration at 0(263)
0(978) : error C1013: function “CALC_ShadowMask” is already defined at 0(265)
0(1057) : error C1013: function “CALC_ShadowMask_K” is already defined at 0(344)
0(1070) : error C1013: function “CALC_ShadowMask_F” is already defined at 0(357)
0(1073) : error C1013: function “main” is already defined at 0(360)

Failed to compile shader from “shaders\gl_prog\sob_ship.prog”. Details:
0(831) : error C1038: declaration of “outUV0” conflicts with previous declaration at 0(118)
0(832) : error C1038: declaration of “outNorm” conflicts with previous declaration at 0(119)
0(833) : error C1038: declaration of “outTan” conflicts with previous declaration at 0(120)
0(834) : error C1038: declaration of “outBiNorm” conflicts with previous declaration at 0(121)
0(835) : error C1038: declaration of “outPos_W” conflicts with previous declaration at 0(122)
0(836) : error C1038: declaration of “outEye_W” conflicts with previous declaration at 0(123)
0(839) : error C1038: declaration of “outPos_KL” conflicts with previous declaration at 0(126)
0(840) : error C1038: declaration of “inTexShadow” conflicts with previous declaration at 0(127)
0(841) : error C1038: declaration of “inShadowTrans” conflicts with previous declaration at 0(128)
0(847) : error C1038: declaration of “inTime” conflicts with previous declaration at 0(134)
0(861) : error C1038: declaration of “inTexDiff” conflicts with previous declaration at 0(148)
0(862) : error C1038: declaration of “inTexGlow” conflicts with previous declaration at 0(149)
0(898) : error C1038: declaration of “inTexTeam” conflicts with previous declaration at 0(185)
0(901) : error C1038: declaration of “inTexNorm” conflicts with previous declaration at 0(188)
0(902) : error C1038: declaration of “inTexEnv0” conflicts with previous declaration at 0(189)
0(903) : error C1038: declaration of “inTexEnv1” conflicts with previous declaration at 0(190)
0(906) : error C1038: declaration of “inClipPlane” conflicts with previous declaration at 0(193)
0(913) : error C1038: declaration of “inSOBParams” conflicts with previous declaration at 0(200)
0(914) : error C1038: declaration of “inLifeParams” conflicts with previous declaration at 0(201)
0(916) : error C1038: declaration of “inFogColor” conflicts with previous declaration at 0(203)
0(917) : error C1038: declaration of “inFogWindow” conflicts with previous declaration at 0(204)
0(919) : error C1038: declaration of “inMatM” conflicts with previous declaration at 0(206)
0(922) : error C1038: declaration of “inColTeam” conflicts with previous declaration at 0(209)
0(923) : error C1038: declaration of “inColStripe” conflicts with previous declaration at 0(210)
0(927) : error C1038: declaration of “inColEffect” conflicts with previous declaration at 0(214)
0(930) : error C1038: declaration of “inSurfDiff” conflicts with previous declaration at 0(217)
0(931) : error C1038: declaration of “inSurfGlow” conflicts with previous declaration at 0(218)
0(932) : error C1038: declaration of “inSurfSpec” conflicts with previous declaration at 0(219)
0(933) : error C1038: declaration of “inSurfGloss” conflicts with previous declaration at 0(220)
0(934) : error C1038: declaration of “inSurfRefl” conflicts with previous declaration at 0(221)
0(935) : error C1038: declaration of “inSurfFren” conflicts with previous declaration at 0(222)
0(936) : error C1038: declaration of “inSurfPaint” conflicts with previous declaration at 0(223)
0(937) : error C1038: declaration of “inSurfPeak” conflicts with previous declaration at 0(224)
0(939) : error C1038: declaration of “inPaintStyle” conflicts with previous declaration at 0(226)
0(941) : error C1038: declaration of “inGammaScale” conflicts with previous declaration at 0(228)
0(942) : error C1038: declaration of “inBGAddLight” conflicts with previous declaration at 0(229)
0(943) : error C1038: declaration of “inBGEnvParams” conflicts with previous declaration at 0(230)
0(966) : error C1038: declaration of “inLightCounts” conflicts with previous declaration at 0(253)
0(967) : error C1038: declaration of “inLightShip” conflicts with previous declaration at 0(254)
0(968) : error C1038: declaration of “inLightCore” conflicts with previous declaration at 0(255)
0(970) : error C1038: declaration of “finalCol0” conflicts with previous declaration at 0(257)
0(974) : error C1038: declaration of “shadWH” conflicts with previous declaration at 0(261)
0(975) : error C1038: declaration of “invShad” conflicts with previous declaration at 0(262)
0(977) : error C1013: function “CALC_ShadowMask” is already defined at 0(264)
0(1056) : error C1013: function “CALC_ShadowMask_K” is already defined at 0(343)
0(1069) : error C1013: function “CALC_ShadowMask_F” is already defined[/details]

[details=log.txt]OpenTK initialized.
WARNING: The texture “G:\Games\Homeworld 2\Modding Tools\Reference\HWR 2.0\background/m01\m01_hq_posx.dds” is not in TGA-Format.
WARNING: The texture “G:\Games\Homeworld 2\Modding Tools\Reference\HWR 2.0\background/m01\m01_hq_negx.dds” is not in TGA-Format.
WARNING: The texture “G:\Games\Homeworld 2\Modding Tools\Reference\HWR 2.0\background/m01\m01_hq_posy.dds” is not in TGA-Format.
WARNING: The texture “G:\Games\Homeworld 2\Modding Tools\Reference\HWR 2.0\background/m01\m01_hq_negy.dds” is not in TGA-Format.
WARNING: The texture “G:\Games\Homeworld 2\Modding Tools\Reference\HWR 2.0\background/m01\m01_hq_posz.dds” is not in TGA-Format.
WARNING: The texture “G:\Games\Homeworld 2\Modding Tools\Reference\HWR 2.0\background/m01\m01_hq_negz.dds” is not in TGA-Format.
Info, T12628: Load colladaBlenderFix.dae

Info, T12628: Found a matching importer for this file format

Info, T12628: Import root directory is ‘.’

Warn, T12628: Collada: No material specified for subgroup <> in geometry <NAVL[NavLightR2]_Type[default]_Sect[0]_Sz[1]_Ph[0]_Fr[1]_Col[1,0,0]_Dist[0]_Flags[Sprite]-lib>.

Warn, T12628: Collada: No material specified for subgroup <> in geometry <NAVL[NavLightW1]_Type[default]_Sect[0]_Sz[1]_Ph[0]_Fr[1]_Col[1,1,1]_Dist[0]_Flags[Sprite]-lib>.

Warn, T12628: Collada: No material specified for subgroup <> in geometry <NAVL[NavLightW2]_Type[default]_Sect[0]_Sz[1]_Ph[0]_Fr[1]_Col[1,1,1]_Dist[0]_Flags[Sprite]-lib>.

Warn, T12628: Collada: No material specified for subgroup <> in geometry <NAVL[NavLightG1]_Type[default]_Sect[0]_Sz[1]_Ph[0]_Fr[1]_Col[0,1,0]_Dist[0]_Flags[Sprite]-lib>.

Warn, T12628: Collada: No material specified for subgroup <> in geometry <NAVL[NavLightG2]_Type[default]_Sect[0]_Sz[1]_Ph[0]_Fr[1]_Col[0,1,0]_Dist[0]_Flags[Sprite]-lib>.

Warn, T12628: Collada: No material specified for subgroup <> in geometry <NAVL[NavLightR1]_Type[default]_Sect[0]_Sz[1]_Ph[0]_Fr[1]_Col[1,0,0]_Dist[0]_Flags[Sprite]-lib>.

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Warn, T12628: Collada: No material specified for subgroup <> in geometry .

Info, T12628: Entering post processing pipeline

Info, T12628: JoinVerticesProcess finished | Verts in: 126012 out: 78940 | ~37.4%

Info, T12628: Leaving post processing pipeline

Trying to parse texture “IMG[fed_TNG_sov_thruster_DIFF]_FMT[8888]”.
Trying to parse texture “IMG[fed_TNG_flaghull2_DIFF]_FMT[8888]”.
Trying to parse texture “IMG[fed_TNG_flaghull1_DIFF]_FMT[8888]”.
Trying to parse texture “IMG[bussard_TNG_DIFF]_FMT[8888]”.
Trying to parse material “MAT[bussard]_SHD[shipAnim]”.
WARNING: Unknown shader “shipAnim” of material “MAT[bussard]_SHD[shipAnim]”.
Trying to parse material “MAT[hull0]_SHD[ship]”.
Trying to parse material “MAT[hull1]_SHD[ship]”.
Trying to parse material “MAT[thruster]_SHD[thruster]”.
Trying to parse material “_collision_meshdefault”.
Trying to parse material “_shieldDefault”.

Looks like it’s sob_thruster.prog and sob_ship.prog having troubles, I have a copy of it here (I assume it was modified by @CMDBob for the shipAnim shader)

sob_ship.prog
smooth in vec2 outUV0;
smooth in vec3 outNorm;
smooth in vec3 outTan;
smooth in vec3 outBiNorm;
smooth in vec3 outPos_W;
smooth in vec3 outEye_W;

#ifdef SOB_SHADOWS_ON
	smooth in vec3 outPos_KL;
	uniform sampler2DShadow inTexShadow;
	uniform vec4 inShadowTrans[4];
	#ifdef SOB_SHADOWS_DUAL
		smooth in vec3 outPos_FL;
	#endif
#endif

uniform vec4 inTime;

#ifdef SOB_BADGE
smooth in vec2 outUV1;
uniform sampler2D inTexBadge;
#endif

#ifdef SOB_THRUSTERS
uniform sampler2D inTexDiffOn;
uniform sampler2D inTexGlowOn;
uniform sampler2D inTexDiffOff;
uniform sampler2D inTexGlowOff;
uniform vec4 inColEngine;
#else
uniform sampler2D inTexDiff;
uniform sampler2D inTexGlow;
#ifdef SOB_GLOWRGB
uniform sampler2D inTexSpec;
#endif
#endif

#ifdef SOB_RESOURCE
uniform sampler2D inTexProgress;
uniform vec2 inFadeInfo;
uniform vec3 inFadeWindow;
uniform vec4 inGlowStyle;

#ifdef SOB_DUALINPUT
uniform vec4 inMulDiff0;
uniform vec4 inMulDiff1;
uniform vec4 inMulGlow0;
uniform vec4 inMulGlow1;
uniform vec4 inMulSpec0;
uniform vec4 inMulSpec1;
smooth in vec2 outUV_Diff0;
smooth in vec2 outUV_Glow0;
smooth in vec2 outUV_Spec0;
smooth in vec2 outUV_Norm0;
smooth in vec2 outUV_Diff1;
smooth in vec2 outUV_Glow1;
smooth in vec2 outUV_Spec1;
smooth in vec2 outUV_Norm1;
#endif

#ifdef SOB_DEBRIS
uniform vec4 inFXInfo[2];
#endif

#endif

#ifdef SOB_TEAMTEX
uniform sampler2D inTexTeam;
#endif

uniform sampler2D inTexNorm;
uniform samplerCube inTexEnv0;
uniform samplerCube inTexEnv1;

#ifdef SOB_USECLIP
	uniform vec4 inClipPlane;

	#ifdef PATCH_ALTHYPER
		smooth in float outClipD;
	#endif
#endif

uniform vec4 inSOBParams;
uniform vec4 inLifeParams;

uniform vec4 inFogColor;
uniform vec4 inFogWindow;

uniform mat4 inMatM;

#ifdef SOB_TEAM
uniform vec4 inColTeam;
uniform vec4 inColStripe;
#endif

#ifndef SOB_DEBRIS
uniform vec4 inColEffect;
#endif

uniform vec4 inSurfDiff;
uniform vec4 inSurfGlow;
uniform vec4 inSurfSpec;
uniform	vec4 inSurfGloss;
uniform vec4 inSurfRefl;
uniform vec4 inSurfFren;
uniform vec4 inSurfPaint;
uniform vec4 inSurfPeak;

uniform vec4 inPaintStyle;

uniform vec4 inGammaScale;
uniform vec4 inBGAddLight;
uniform vec4 inBGEnvParams;

#ifdef SOB_BAYLIGHT

	uniform vec4 inBayExps;	//br, bR, Br, BR

	#ifdef SOB_POST_B0R0
	vec4 getBayExp(){ return vec4(inBayExps.x, inBayExps.x, inBayExps.x, 1.0f); }
	#endif

	#ifdef SOB_POST_B0R1
	vec4 getBayExp(){ return vec4(inBayExps.y, inBayExps.y, inBayExps.y, 1.0f); }
	#endif

	#ifdef SOB_POST_B1R0
	vec4 getBayExp(){ return vec4(inBayExps.z, inBayExps.z, inBayExps.z, 1.0f); }
	#endif

	#ifdef SOB_POST_B1R1
	vec4 getBayExp(){ return vec4(inBayExps.w, inBayExps.w, inBayExps.w, 1.0f); }
	#endif
#endif

uniform ivec2 inLightCounts;
uniform vec4 inLightShip[96];	// Pos/Diff/Spec (or just Pos/Diff) + attenuations in W
uniform vec4 inLightCore[7];

layout (location = 0) out vec4 finalCol0;

#ifdef SOB_SHADOWS_ON

ivec2 shadWH = textureSize(inTexShadow, 0);
vec2 invShad = vec2(1.0/shadWH.x, 1.0/shadWH.y);

float CALC_ShadowMask(float blend, vec3 baseUVW){
#ifdef SOB_SHADOWS_HQ
	if (blend > 0.0)
	{
		vec2 texelUV = baseUVW.xy*shadWH;
		vec2 baseUV = vec2(floor(texelUV.x+0.5), floor(texelUV.y+0.5));
		float s = texelUV.x+0.5-baseUV.x;
		float t = texelUV.y+0.5-baseUV.y;
		baseUV -= vec2(0.5);
		baseUV *= invShad;
		
#define SOB_SHADOWS_3X3 1
#ifdef SOB_SHADOWS_3X3
		float uw0 = (3 - 2 * s);
		float uw1 = (1 + 2 * s);

		float u0 = ((2 - s) / uw0 - 1)*invShad.x;
		float u1 = (s / uw1 + 1)*invShad.x;

		float vw0 = (3 - 2 * t);
		float vw1 = (1 + 2 * t);

		float v0 = ((2 - t) / vw0 - 1)*invShad.y;
		float v1 = (t / vw1 + 1)*invShad.y;
			
		float total = 0.0;
		
		total += uw0*vw0*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v0, baseUVW.z));
		total += uw1*vw0*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v0, baseUVW.z));
		total += uw0*vw1*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v1, baseUVW.z));
		total += uw1*vw1*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v1, baseUVW.z));
		
		total /= 16.0;
#else
		float uw0 = (4 - 3 * s);
		float uw1 = 7;
		float uw2 = (1 + 3 * s);

		float u0 = ((3 - 2 * s) / uw0 - 2)*invShad.x;
		float u1 = ((3 + s) / uw1)*invShad.x;
		float u2 = (s / uw2 + 2)*invShad.x;

		float vw0 = (4 - 3 * t);
		float vw1 = 7;
		float vw2 = (1 + 3 * t);

		float v0 = ((3 - 2 * t) / vw0 - 2)*invShad.y;
		float v1 = ((3 + t) / vw1)*invShad.y;
		float v2 = (t / vw2 + 2)*invShad.y;
		
		float total = 0.0;
		
		total += uw0*vw0*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v0, baseUVW.z));
		total += uw1*vw0*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v0, baseUVW.z));
		total += uw2*vw0*texture(inTexShadow, vec3(baseUV.x+u2, baseUV.y+v0, baseUVW.z));
		total += uw0*vw1*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v1, baseUVW.z));
		total += uw1*vw1*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v1, baseUVW.z));
		total += uw2*vw1*texture(inTexShadow, vec3(baseUV.x+u2, baseUV.y+v1, baseUVW.z));
		total += uw0*vw2*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v2, baseUVW.z));
		total += uw1*vw2*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v2, baseUVW.z));
		total += uw2*vw2*texture(inTexShadow, vec3(baseUV.x+u2, baseUV.y+v2, baseUVW.z));
		
		total /= 144.0;
#endif
		
		return 1.0-(blend*(1.0-total));
	}
	
	return 1.0;
#else
	if (blend > 0.0)	// So then -1.0 will disable
	{
		return 1.0-(blend*(1.0-texture(inTexShadow, baseUVW)));
	}
	
	return 1.0;
#endif
}

float CALC_ShadowMask_K(){
	return CALC_ShadowMask(inShadowTrans[1].w, outPos_KL);
}

#else
float CALC_ShadowMask_K(){ return 1.0; }
#endif

#ifdef SOB_SHADOWS_DUAL
float CALC_ShadowMask_F(){
	return CALC_ShadowMask(inShadowTrans[3].w, outPos_FL);
}
#else
float CALC_ShadowMask_F(){ return 1.0; }
#endif

void main()
{
#ifdef SOB_USECLIP
	#ifdef PATCH_ALTHYPER
		if (outClipD <= 0.0)
		{
			discard;
		}
	#endif
#endif

#ifdef SOB_TEAMTEX
	vec3 texTeam = texture(inTexTeam, outUV0).xyz;
	
	#ifdef SOB_SCISSOR
		if (texTeam.r < 0.5)
		{
			discard;
		}
	#endif

#else
	vec3 texTeam = vec3(0.0);
#endif

#ifdef SOB_RESOURCE

	//abs(0.5-fract(inTime.x*0.125))*2.0;	// Auto-cycle fade for testing
	
	#ifdef SOB_SALVAGE
	float resFade = clamp(1.0-inLifeParams.y, 0.0, 1.0);
	resFade *= resFade;		// Curve the burn rate
	
		#ifdef SOB_DEBRIS
		resFade = 1.0-inFXInfo[0].a;
		#endif
	#else
	float resFade = inFadeInfo.x;
	#endif
	
	float resDelta = inFadeInfo.y;
	
	float fadeWindow = inFadeWindow.x;
	float fadeLo = inFadeWindow.y;
	float fadeHi = inFadeWindow.z;
	
	#ifdef SOB_SALVAGE
	float fadeRange = (fadeHi-fadeLo)+(fadeWindow*2.0);
	#else
	float fadeRange = (fadeHi-fadeLo)+fadeWindow;
	#endif

	float fadeProgRaw = texture(inTexProgress, outUV0).r;
	float fadeProg = max(fadeProgRaw, fadeLo);
	float fadeRes = fadeLo-fadeWindow+(resFade*fadeRange);
	float fadeResLim = min(fadeRes, fadeHi);
	
	float texProgress = (fadeProg-fadeResLim)/fadeWindow;
	
	float burnScale = clamp(texProgress*1000.0, 0.0, 1.0);
	float texBurn = clamp((1.0-texProgress)*burnScale, 0.0, 1.0);
	texBurn *= clamp(1.0-((fadeRes-fadeResLim)/fadeWindow), 0.0, 1.0);
	texBurn = pow(texBurn, 0.25);
	
	texProgress = clamp(texProgress, 0.0, 1.0);
	
	#ifdef SOB_SALVAGE
		float fadeScissor = fadeProg-max(fadeLo, fadeResLim);
		if (fadeScissor <= 0.0)
		{
			discard;
		}
	#endif
	
	texBurn *= texProgress*4.0;	// 0.5*0.5 = 0.25
	
	#ifdef SOB_DUALINPUT
		vec3 texNorm = mix(texture(inTexNorm, outUV_Norm1).rgb, texture(inTexNorm, outUV_Norm0).rgb, texProgress);
		vec4 texDiff = mix(texture(inTexDiff, outUV_Diff1)*inMulDiff1, texture(inTexDiff, outUV_Diff0)*inMulDiff0, texProgress);
		vec4 texGlowRGB = mix(texture(inTexGlow, outUV_Glow1)*inMulGlow1, texture(inTexGlow, outUV_Glow0)*inMulGlow0, texProgress);
		vec4 texGlow = mix(texture(inTexSpec, outUV_Spec1)*inMulSpec1, texture(inTexSpec, outUV_Spec0)*inMulSpec0, texProgress);
	#else
		vec3 texNorm = texture(inTexNorm, outUV0).rgb;
		vec4 texDiff = texture(inTexDiff, outUV0);
		vec4 texGlowRGB = texture(inTexGlow, outUV0);
		vec4 texGlow = texture(inTexSpec, outUV0);
	#endif
	
	texNorm = normalize(texNorm*2.0-1.0);
	
	float isPaint = texGlow.g;
	texGlow.g = 1.0;
	
	#ifdef SOB_SALVAGE
		float styleDelta = 0.0;		// Deltas make no sense for Salvage
	#else
		float styleDelta = inGlowStyle.x;
	#endif
	
	float styleBurn = inGlowStyle.y;
	
	float glowDeltScale = mix(1.0, clamp((resDelta-0.25)*1.35, 0.0, 1.0), styleDelta);
	float glowBurnScale = mix(1.0, texBurn, styleBurn);
	texGlowRGB *= glowDeltScale*glowBurnScale;
#else
	#ifdef SOB_THRUSTERS
		float thrust = inColEngine.x;

		vec4 texDiffOn = texture(inTexDiffOn, outUV0);
		vec4 texGlowOn = texture(inTexGlowOn, outUV0);
		vec4 texDiffOff = texture(inTexDiffOff, outUV0);
		vec4 texGlowOff = texture(inTexGlowOff, outUV0);
		
		vec4 texDiff = mix(texDiffOff, texDiffOn, thrust);
		vec4 texGlow = mix(texGlowOff, texGlowOn, thrust);
	#else
		vec4 texDiff = texture(inTexDiff, outUV0);
		vec4 texGlow = texture(inTexGlow, outUV0);
		
		#ifdef SOB_GLOWRGB
			vec4 texGlowRGB = texGlow;
			texGlow = texture(inTexSpec, outUV0);
			texGlow.g = 1.0;
		#endif
	#endif
	
	vec3 texNorm = normalize(texture(inTexNorm, outUV0).rgb*2.0-1.0);
	
	#ifdef SOB_TEAM	
		float isPaint = texTeam.r*texTeam.g*(1.0-texTeam.b);
	#else
		float isPaint = 1.0-texTeam.b;
	#endif
#endif

	// Normal and Eye to Pos in World Space
#ifdef NO_NORMAL_MAP
	vec3 worldNorm = normalize(mat3(inMatM)*vec3(outNorm));
#else
	vec3 tempTW = mat3(outTan, outBiNorm, outNorm)*texNorm;
	vec3 worldNorm = normalize(mat3(inMatM)*tempTW);
#endif

	float shadowMask_K = CALC_ShadowMask_K();
	float shadowMask_F = CALC_ShadowMask_F();

#ifdef SOB_BADGE
	vec4 texBadge = texture(inTexBadge, outUV1);
	texGlow.b = mix(texGlow.b, 0.15, texBadge.a*0.35);
	texGlow.r = mix(texGlow.r, 0.1, texBadge.a*0.35);
	isPaint *= 1.0-texBadge.a;
#endif

	// Paint and Other map channels
	isPaint = 1.0-isPaint;
	float mapSpecSharp = texGlow.r;
	float mapGlowMask = texGlow.g;
	float mapSpecMask = max(0.0, texGlow.b-texGlow.g);

	vec3 worldEye = normalize(outEye_W);
	float worldDist = length(outEye_W);
	
#ifdef SOB_2SIDED
	if (false == gl_FrontFacing)
	{
		worldNorm = -worldNorm;
	}
#endif
	
	// Diffuse
	float extDiffFren = inSurfDiff.y;
	
	// Glow
	float extGlowPower = inSurfGlow.x;
	float extGlowFren = inSurfGlow.y;
	
	// Specular
	float extSpecPower = inSurfSpec.x;
	float extSpecFren = inSurfSpec.y;
	float extSpecCurve = inSurfSpec.z;
	
	// Paint Gloss
	float extPaintCurve = inSurfPaint.x;
	float extPaintScale = inSurfPaint.y;
	float extPaintBias = inSurfPaint.z;
	float extPaintDim = inSurfPaint.w;
	
	// Gloss
	float extGlossCurve = inSurfGloss.x+(extPaintCurve*isPaint);
	float extGlossScale = inSurfGloss.y+(extPaintScale*isPaint);
	float extGlossBias = inSurfGloss.z+(extPaintBias*isPaint);
	
	extSpecPower = mix(extSpecPower, extSpecPower*extPaintDim, isPaint);
	
	float specGloss = max(1.0, pow(mapSpecSharp, extGlossCurve)*extGlossScale)+extGlossBias;
	float pointGloss = max(1.0, specGloss*0.25);
	
	// Reflections
	float extReflPower = inSurfRefl.x;
	float extReflFren = inSurfRefl.y;
	float extReflAddMix = inSurfRefl.z;
	
	// Fresnel
	float extFrenPower = inSurfFren.x;
	float extFrenBias = inSurfFren.y;
	float extFrenCurve = inSurfFren.z;
	float frenDeg = clamp(pow(extFrenBias*(1.0-abs(dot(worldNorm, worldEye))), extFrenCurve)*extFrenPower, 0.0, 1.0);
	
	// Map Channel * Powers
	float peakStrength = 1.0+(mix(inSurfPeak.x, inSurfPeak.y, isPaint)*mix(1.0, inSurfPeak.z, frenDeg));
	float glowStrength = mapGlowMask*max(0.0, extGlowPower-(extGlowFren*frenDeg));
	float specRawStrength = mapSpecMask*extSpecPower;
	float specStrength = mix(specRawStrength, 1.0, frenDeg*mapSpecSharp*extSpecFren);
	float reflStrength = mix(mapSpecMask*extReflPower, 1.0, frenDeg*mapSpecSharp*extReflFren);
	
	// Time to get painted (paint + diffuse curves logic)
	float paintCurve = inPaintStyle.x;
	float paintDarkScale = inPaintStyle.y;
	float paintDarkOfs = inPaintStyle.z;
	vec4 paintBase = mix(vec4(0.5, 0.5, 0.5, 1.0), texDiff, paintCurve);
	
#ifdef SOB_TEAM
	// Base paint calc - paint, stripe, team, etc...
	vec4 paint = mix(inColTeam, paintBase, texTeam.r);
	paint = mix(inColStripe, paint, texTeam.g);
	
#ifdef SOB_BADGE
	vec4 lumMap = vec4(0.299, 0.587, 0.114, 0.0);
	vec4 diffLum = vec4(texDiff.r, texDiff.g, texDiff.b, dot(texDiff, lumMap));
	vec4 d_hi = clamp(((diffLum*2.0)-1.0), 0.0, 1.0);
	vec4 d_lo = clamp(((diffLum*paintDarkScale)-paintDarkOfs), 0.0, 1.0);	// Slight overdark for badge contouring
	paint = mix(d_lo*paint, vec4(1.0), d_hi);
	diffLum.rgb = d_lo.w*texBadge.rgb;
	d_lo = mix(diffLum, vec4(1.0), d_hi.w);
	paint = mix(paint, d_lo, texBadge.a);
#else
	vec4 d_hi = clamp(((texDiff*2.0)-1.0), 0.0, 1.0);
	vec4 d_lo = clamp(((texDiff*paintDarkScale)-paintDarkOfs), 0.0, 1.0);
	paint = mix(d_lo*paint, vec4(1.0), d_hi);
#endif

#else
	vec4 d_hi = clamp(((texDiff*2.0)-1.0), 0.0, 1.0);
	vec4 d_lo = clamp(((texDiff*paintDarkScale)-paintDarkOfs), 0.0, 1.0);
	vec4 paint = mix(d_lo*paintBase, vec4(1.0), d_hi);
#endif

	float diffStrength = max(0.0, 1.0-specRawStrength);
	diffStrength = pow(diffStrength, 1.0-(frenDeg*extDiffFren));
	
#ifdef SOB_GLOWRGB
	vec3 diffRGB = paint.rgb;
	vec3 glowRGB = texGlowRGB.rgb*0.8;
#else
	vec3 diffRGB = paint.rgb*((1.0-mapGlowMask)*diffStrength);
	vec3 glowRGB = paint.rgb*mapGlowMask;
#endif

	glowRGB *= glowStrength;
	
	// Seed lighting with Ambient+Black
	vec3 diffAll = inLightCore[0].rgb;
	vec3 specAll = vec3(0,0,0);
		
	// Key Light
	vec3 litNorm = normalize(inLightCore[1].rgb);
	vec3 holdLit_K = litNorm;
	
#ifndef SOB_BAYLIGHT
	float litDif = clamp(dot(litNorm, worldNorm), 0.0, 1.0);
	vec3 litRefl = reflect(-litNorm, worldNorm);
	float litSpec = clamp(dot(-worldEye, litRefl), 0.0, 1.0)*peakStrength;
	litSpec = pow(litSpec, specGloss)*min(litDif*1000, 1.0);
	diffAll += shadowMask_K*inLightCore[2].rgb*litDif;
	specAll += shadowMask_K*inLightCore[3].rgb*litSpec;
	
	// Fill Light
	litNorm = normalize(inLightCore[4].rgb);
	vec3 holdLit_F = litNorm;
	litDif = clamp(dot(litNorm, worldNorm), 0.0, 1.0);
	litRefl = reflect(-litNorm, worldNorm);
	litSpec = clamp(dot(-worldEye, litRefl), 0.0, 1.0)*peakStrength;
	litSpec = pow(litSpec, specGloss)*min(litDif*1000, 1.0);
	diffAll += shadowMask_F*inLightCore[5].rgb*litDif;
	specAll += shadowMask_F*inLightCore[6].rgb*litSpec;
	
	// Point lights...
	int inP = inLightCounts.x;	// Points?
	int inL = 0;
	for (; inL<inP; inL++)
	{
		int inS = inL*3;
		vec3 litVec = inLightShip[inS].rgb-outPos_W;
		vec3 atenVec = vec3(inLightShip[inS].w, inLightShip[inS+1].w, inLightShip[inS+2].w);
		float litLen = length(litVec);
		litVec = normalize(litVec);
		litDif = clamp(dot(litVec, worldNorm), 0.0, 1.0);
		float atenVal = 1.0/(atenVec.x+(atenVec.y*litLen)+(atenVec.z*litLen*litLen));
		diffAll.rgb += inLightShip[inS+1].rgb*litDif*atenVal*2.0;

		float subSpec = clamp(dot(-worldEye, reflect(-litVec, worldNorm)), 0.0, 1.0)*peakStrength;
		subSpec = pow(subSpec, pointGloss)*min(litDif*1000, 1.0);
		specAll.rgb += inLightShip[inS+2].rgb*subSpec*atenVal*2.0;
	}
#else
	diffAll = vec3(1.0, 1.0, 1.0);
#endif
	
#ifdef SOB_LIGHT_HQ
	vec3 beamDif = vec3(0.0f);
	vec3 beamSpec = vec3(0.0f);
	
	float beamGloss = max(1.0, specGloss*0.75);
	
	int inB = inLightCounts.x+inLightCounts.y;	// Beams?
	for (; inL<inB; inL++)
	{
		int inS = inL*3;
		
		vec3 beamHead = inLightShip[inS].xyz;
		float beamLen = inLightShip[inS].w;
		vec3 beamAxis = inLightShip[inS+1].xyz;
		float beamOORad = inLightShip[inS+1].w;
		vec3 beamRGB = inLightShip[inS+2].rgb;
		float beamCurve = inLightShip[inS+2].w;
		
		// Determine the closest on-beam point
		vec3 sepOfs = outPos_W-beamHead;
		float sepA = clamp(dot(sepOfs, beamAxis), 0.0, beamLen);
		vec3 litPos = beamHead+(beamAxis*sepA);
		
		// Gather angle/distance
		vec3 litVec = litPos-outPos_W;
		float litLen = length(litVec);
		litVec = normalize(litVec);
		
		// Attenuate for distance
		float atenVal = pow(1.0-min(litLen*beamOORad, 1.0), beamCurve)*2.0;	// *2 to adjust for HW old headroom
		
		// Bias diffuse angle due to co-incidence with beam 
		float litBias = abs(dot(worldNorm, beamAxis));
		litDif = clamp(dot(worldNorm, litVec), 0.0, 1.0);
		litDif = mix(litDif, 1.0, litBias);
		
		vec3 subRefl = reflect(-litVec, worldNorm);
		float subSpec = max(dot(-worldEye, subRefl), 0.0);
		float subBoost = abs(dot(inLightShip[inS+1].rgb, subRefl));	// Reflection along beam axis?
		subSpec = min(subSpec*(1.0+(subBoost*0.25)), 1.0)*peakStrength;
		subSpec = pow(subSpec, beamGloss)*min(litDif*1000, 1.0);
		
		beamDif += beamRGB*litDif*atenVal;
		beamSpec += inLightShip[inS+2].rgb*subSpec*atenVal;
	}
	
	diffAll += beamDif;
	specAll += beamSpec;
	
	//diffAll = beamDif;
	//specAll = beamSpec;
#endif
	 
	// Apply final lighting 
	paint.rgb = (diffRGB*diffAll)+glowRGB+(specAll*specStrength);

#ifndef SOB_BAYLIGHT
	// Add reflections
	vec3 envNorm = reflect(worldEye, worldNorm);
	vec4 texE0 = texture(inTexEnv0, envNorm);
	vec4 texE1 = texture(inTexEnv1, envNorm);
	vec4 reflTex = mix(texE0, texE1, mapSpecSharp);
	
	
#ifdef SOB_SHADOWS_ON
	float envMask = 1.0-(max((dot(envNorm,holdLit_K)*5.0)-4.0, 0.0)*(1.0-shadowMask_K));
	
	#ifdef SOB_SHADOWS_DUAL
		envMask *= 1.0-(max((dot(envNorm,holdLit_F)*5.0)-4.0, 0.0)*(1.0-shadowMask_F));
	#endif
#else
	float envMask = 1.0;
#endif

	float reflDeg = reflStrength*reflTex.a*inBGEnvParams.r*envMask;
	float reflAdd = extReflAddMix;
	float reflAlpha = 1.0-reflAdd;
	
	reflTex.rgb += inBGAddLight.rgb;
	
	paint.rgb += reflTex.rgb*reflDeg*reflAdd;
	paint.rgb = mix(paint.rgb, reflTex.rgb, reflDeg*reflAlpha);
#endif

	paint.a = inSOBParams.x;
	
#ifdef SOB_TEAM
	if (inSOBParams.y > 0.0)
	{
		float frenCloak = pow((1.0-abs(dot(worldNorm, worldEye)))*1.06, 2.0)*2.0-1.0;
		
		if (frenCloak > 0.0)
		{
			vec3 noisePos = outPos_W.xyz*0.05;
			vec3 timePos = holdLit_K*(inTime.z*2.0);
			float cloakNoise = HELP_Noise3(noisePos+timePos)*0.5+1.5;
			frenCloak = clamp(frenCloak*cloakNoise*0.5, 0.0, 1.0);
		}
		
		float cloakPaint = 1.0-(0.5*inSOBParams.y);
		paint.rgb = (paint.rgb*cloakPaint)+vec3(max(frenCloak, 0.0)*inSOBParams.y*1.5);
	}
#endif
	
#ifndef SOB_DEBRIS
	// UI Effect (glow, etc)
	paint.rgb += vec3(inColEffect)*inColEffect.a;
#endif
	
	paint.rgb = pow(paint.rgb, vec3(inGammaScale))*inGammaScale.a;
	
#ifdef SOB_USECLIP
	vec3 hyperSpace = vec3(inGammaScale.a);
	
	if (false == gl_FrontFacing)
	{
		paint.rgb = hyperSpace;
	}
	else
	{
#ifdef PATCH_ALTHYPER
		float hyperEdge = outClipD*0.02;
#else
		float hyperEdge = gl_ClipDistance[0]*0.02;
#endif
		if (hyperEdge < 1.0)
		{
			vec3 planeScales = vec3(1.5)+(abs(inClipPlane.xyz)*20.0);
			vec3 noisePos = outPos_W.xyz/planeScales;
			vec3 timePos = inClipPlane.xyz*(inTime.z*2.0);
			
			float hyperNoise = HELP_Noise3(noisePos+timePos)*0.5+1.5;
			hyperEdge = 1.0-clamp(hyperEdge*hyperNoise, 0.0, 1.0);
			hyperEdge = min(pow(hyperEdge*1.1, 5.0)/1.2, 1.0);
			
			paint.rgb = mix(paint.rgb, hyperSpace, hyperEdge*inSOBParams.z);
		}
	}
#endif
	
	float maxFog = inFogColor.a*inFogColor.w;
	if (maxFog > 0.0)
	{
		float useFog = clamp((worldDist-inFogWindow.x)/(inFogWindow.z-inFogWindow.x), inFogWindow.y, inFogWindow.w);
		paint.rgb = mix(paint.rgb, inFogColor.rgb, useFog*inFogColor.a);
	}
	
	paint *= getShipExp();
	
#ifdef SOB_BAYLIGHT
	paint *= getBayExp();
#endif

	// Enable to show 'bad UV' patches (as magenta)
	//vec2 delUV = vec2(dFdx(outUV0.x), dFdy(outUV0.y));
	//float delD = 1.0-min(1.0, length(delUV)*1000000.0);
	//paint.rgb = mix(paint.rgb, vec3(delD, 0.0, delD), delD);
	
#ifdef SOB_ALPHA
	paint.a *= texTeam.r;
#endif
	
	finalCol0 = paint;
}

I don’t have a modified sob_thruster.prog though…


(Taiidan Republic Mod) #495

Good work, let me know when you get to the importer!


(ajlsunrise) #496

Are you sure that’s not “sob_ship.frag”?

I may just need your whole shaders folder… Is it in STCR.big?


(ajlsunrise) #497

The sob_ship.frag that is in the STCR.big appears to be the the same as the original, and the rest of the shader logic seems sound.

If you could send the DAE, I’ll step through the code to see where the issue is at… Does it work in-game?


(Christoph Timmermann) #498

@radar3301 But be aware that I honked around in the shader manifest loading. I could have broken some things, and as I said, it seems to have problems with duplicate shaders in different data paths.


(ajlsunrise) #499

@Nathanius: I’ve updated the shader reporting to show the code that failed. Would you mind re-downloading (the link is the same) and posting the resulting manifest.log?

As I mentioned via PM, I’ve attempted a rewrite a few times and got frustrated with it, so I’ve been putting it off. I think enough time has passed to clear my mind, I’ll put this back on my immediate to-do list. I’ll try having the new version ready this weekend.


(Nathanius) #500

It is actually… I must have been cross eyed after attempting to pay attention at work after the New Year break :confounded:

[details=manifest.log - Part 1 (it’s too long to post)]Vendor: NVIDIA Corporation
Renderer: GeForce GTX 960/PCIe/SSE2
PartID: 960
Could not locate program sob_opqaue_s
Duplicate program detected: sob_salvage
Could not locate program fx_right_basic
Could not locate program re_me_rings
Duplicate surface detected: sob_salvage
Failed to compile FragmentShader shader from “shaders\gl_prog\sob_thruster.prog”
----- DETAILS -----
0(832) : error C1038: declaration of “outUV0” conflicts with previous declaration at 0(119)
0(833) : error C1038: declaration of “outNorm” conflicts with previous declaration at 0(120)
0(834) : error C1038: declaration of “outTan” conflicts with previous declaration at 0(121)
0(835) : error C1038: declaration of “outBiNorm” conflicts with previous declaration at 0(122)
0(836) : error C1038: declaration of “outPos_W” conflicts with previous declaration at 0(123)
0(837) : error C1038: declaration of “outEye_W” conflicts with previous declaration at 0(124)
0(840) : error C1038: declaration of “outPos_KL” conflicts with previous declaration at 0(127)
0(841) : error C1038: declaration of “inTexShadow” conflicts with previous declaration at 0(128)
0(842) : error C1038: declaration of “inShadowTrans” conflicts with previous declaration at 0(129)
0(848) : error C1038: declaration of “inTime” conflicts with previous declaration at 0(135)
0(856) : error C1038: declaration of “inTexDiffOn” conflicts with previous declaration at 0(143)
0(857) : error C1038: declaration of “inTexGlowOn” conflicts with previous declaration at 0(144)
0(858) : error C1038: declaration of “inTexDiffOff” conflicts with previous declaration at 0(145)
0(859) : error C1038: declaration of “inTexGlowOff” conflicts with previous declaration at 0(146)
0(860) : error C1038: declaration of “inColEngine” conflicts with previous declaration at 0(147)
0(899) : error C1038: declaration of “inTexTeam” conflicts with previous declaration at 0(186)
0(902) : error C1038: declaration of “inTexNorm” conflicts with previous declaration at 0(189)
0(903) : error C1038: declaration of “inTexEnv0” conflicts with previous declaration at 0(190)
0(904) : error C1038: declaration of “inTexEnv1” conflicts with previous declaration at 0(191)
0(907) : error C1038: declaration of “inClipPlane” conflicts with previous declaration at 0(194)
0(914) : error C1038: declaration of “inSOBParams” conflicts with previous declaration at 0(201)
0(915) : error C1038: declaration of “inLifeParams” conflicts with previous declaration at 0(202)
0(917) : error C1038: declaration of “inFogColor” conflicts with previous declaration at 0(204)
0(918) : error C1038: declaration of “inFogWindow” conflicts with previous declaration at 0(205)
0(920) : error C1038: declaration of “inMatM” conflicts with previous declaration at 0(207)
0(923) : error C1038: declaration of “inColTeam” conflicts with previous declaration at 0(210)
0(924) : error C1038: declaration of “inColStripe” conflicts with previous declaration at 0(211)
0(928) : error C1038: declaration of “inColEffect” conflicts with previous declaration at 0(215)
0(931) : error C1038: declaration of “inSurfDiff” conflicts with previous declaration at 0(218)
0(932) : error C1038: declaration of “inSurfGlow” conflicts with previous declaration at 0(219)
0(933) : error C1038: declaration of “inSurfSpec” conflicts with previous declaration at 0(220)
0(934) : error C1038: declaration of “inSurfGloss” conflicts with previous declaration at 0(221)
0(935) : error C1038: declaration of “inSurfRefl” conflicts with previous declaration at 0(222)
0(936) : error C1038: declaration of “inSurfFren” conflicts with previous declaration at 0(223)
0(937) : error C1038: declaration of “inSurfPaint” conflicts with previous declaration at 0(224)
0(938) : error C1038: declaration of “inSurfPeak” conflicts with previous declaration at 0(225)
0(940) : error C1038: declaration of “inPaintStyle” conflicts with previous declaration at 0(227)
0(942) : error C1038: declaration of “inGammaScale” conflicts with previous declaration at 0(229)
0(943) : error C1038: declaration of “inBGAddLight” conflicts with previous declaration at 0(230)
0(944) : error C1038: declaration of “inBGEnvParams” conflicts with previous declaration at 0(231)
0(967) : error C1038: declaration of “inLightCounts” conflicts with previous declaration at 0(254)
0(968) : error C1038: declaration of “inLightShip” conflicts with previous declaration at 0(255)
0(969) : error C1038: declaration of “inLightCore” conflicts with previous declaration at 0(256)
0(971) : error C1038: declaration of “finalCol0” conflicts with previous declaration at 0(258)
0(975) : error C1038: declaration of “shadWH” conflicts with previous declaration at 0(262)
0(976) : error C1038: declaration of “invShad” conflicts with previous declaration at 0(263)
0(978) : error C1013: function “CALC_ShadowMask” is already defined at 0(265)
0(1057) : error C1013: function “CALC_ShadowMask_K” is already defined at 0(344)
0(1070) : error C1013: function “CALC_ShadowMask_F” is already defined at 0(357)
0(1073) : error C1013: function “main” is already defined at 0(360)

----- CODE -----
#version 330
#define SOB_TEAM
#define SOB_TEAMTEX
#define SOB_THRUSTERS
#define SOB_SHADOWS_ON
#define SOB_SHADOWS_HQ
#define SOB_LIGHT_HQ
#define SOB_POST_B1R1
uniform vec4 inShipExps; //br, bR, Br, BR

#ifdef SOB_POST_B0R0
vec4 getShipExp(){ return vec4(inShipExps.x, inShipExps.x, inShipExps.x, 1.0f); }
#endif

#ifdef SOB_POST_B0R1
vec4 getShipExp(){ return vec4(inShipExps.y, inShipExps.y, inShipExps.y, 1.0f); }
#endif

#ifdef SOB_POST_B1R0
vec4 getShipExp(){ return vec4(inShipExps.z, inShipExps.z, inShipExps.z, 1.0f); }
#endif

#ifdef SOB_POST_B1R1
vec4 getShipExp(){ return vec4(inShipExps.w, inShipExps.w, inShipExps.w, 1.0f); }
#endif
#define SOB_USECLIP

vec3 mod289(vec3 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}

vec4 mod289(vec4 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}

vec4 permute(vec4 x) {
return mod289(((x*34.0)+1.0)*x);
}

vec4 taylorInvSqrt(vec4 r)
{
return 1.79284291400159 - 0.85373472095314 * r;
}

float HELP_Noise3(vec3 v)
{
const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);

// First corner
vec3 i = floor(v + dot(v, C.yyy) );
vec3 x0 = v - i + dot(i, C.xxx) ;

// Other corners
vec3 g = step(x0.yzx, x0.xyz);
vec3 l = 1.0 - g;
vec3 i1 = min( g.xyz, l.zxy );
vec3 i2 = max( g.xyz, l.zxy );

// x0 = x0 - 0.0 + 0.0 * C.xxx;
// x1 = x0 - i1 + 1.0 * C.xxx;
// x2 = x0 - i2 + 2.0 * C.xxx;
// x3 = x0 - 1.0 + 3.0 * C.xxx;
vec3 x1 = x0 - i1 + C.xxx;
vec3 x2 = x0 - i2 + C.yyy; // 2.0C.x = 1/3 = C.y
vec3 x3 = x0 - D.yyy; // -1.0+3.0
C.x = -0.5 = -D.y

// Permutations
i = mod289(i);
vec4 p = permute( permute( permute(
i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
+ i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
+ i.x + vec4(0.0, i1.x, i2.x, 1.0 ));

// Gradients: 7x7 points over a square, mapped onto an octahedron.
// The ring size 1717 = 289 is close to a multiple of 49 (496 = 294)
float n_ = 0.142857142857; // 1.0/7.0
vec3 ns = n_ * D.wyz - D.xzx;

vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)

vec4 x_ = floor(j * ns.z);
vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)

vec4 x = x_ *ns.x + ns.yyyy;
vec4 y = y_ *ns.x + ns.yyyy;
vec4 h = 1.0 - abs(x) - abs(y);

vec4 b0 = vec4( x.xy, y.xy );
vec4 b1 = vec4( x.zw, y.zw );

//vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
vec4 s0 = floor(b0)*2.0 + 1.0;
vec4 s1 = floor(b1)*2.0 + 1.0;
vec4 sh = -step(h, vec4(0.0));

vec4 a0 = b0.xzyw + s0.xzywsh.xxyy ;
vec4 a1 = b1.xzyw + s1.xzyw
sh.zzww ;

vec3 p0 = vec3(a0.xy,h.x);
vec3 p1 = vec3(a0.zw,h.y);
vec3 p2 = vec3(a1.xy,h.z);
vec3 p3 = vec3(a1.zw,h.w);

//Normalise gradients
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;

// Mix final noise value
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
m = m * m;
return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
dot(p2,x2), dot(p3,x3) ) );
}
smooth in vec2 outUV0;
smooth in vec3 outNorm;
smooth in vec3 outTan;
smooth in vec3 outBiNorm;
smooth in vec3 outPos_W;
smooth in vec3 outEye_W;

#ifdef SOB_SHADOWS_ON
smooth in vec3 outPos_KL;
uniform sampler2DShadow inTexShadow;
uniform vec4 inShadowTrans[4];
#ifdef SOB_SHADOWS_DUAL
smooth in vec3 outPos_FL;
#endif
#endif

uniform vec4 inTime;

#ifdef SOB_BADGE
smooth in vec2 outUV1;
uniform sampler2D inTexBadge;
#endif

#ifdef SOB_THRUSTERS
uniform sampler2D inTexDiffOn;
uniform sampler2D inTexGlowOn;
uniform sampler2D inTexDiffOff;
uniform sampler2D inTexGlowOff;
uniform vec4 inColEngine;
#else
uniform sampler2D inTexDiff;
uniform sampler2D inTexGlow;
#ifdef SOB_GLOWRGB
uniform sampler2D inTexSpec;
#endif
#endif

#ifdef SOB_RESOURCE
uniform sampler2D inTexProgress;
uniform vec2 inFadeInfo;
uniform vec3 inFadeWindow;
uniform vec4 inGlowStyle;

#ifdef SOB_DUALINPUT
uniform vec4 inMulDiff0;
uniform vec4 inMulDiff1;
uniform vec4 inMulGlow0;
uniform vec4 inMulGlow1;
uniform vec4 inMulSpec0;
uniform vec4 inMulSpec1;
smooth in vec2 outUV_Diff0;
smooth in vec2 outUV_Glow0;
smooth in vec2 outUV_Spec0;
smooth in vec2 outUV_Norm0;
smooth in vec2 outUV_Diff1;
smooth in vec2 outUV_Glow1;
smooth in vec2 outUV_Spec1;
smooth in vec2 outUV_Norm1;
#endif

#ifdef SOB_DEBRIS
uniform vec4 inFXInfo[2];
#endif

#endif

#ifdef SOB_TEAMTEX
uniform sampler2D inTexTeam;
#endif

uniform sampler2D inTexNorm;
uniform samplerCube inTexEnv0;
uniform samplerCube inTexEnv1;

#ifdef SOB_USECLIP
uniform vec4 inClipPlane;

#ifdef PATCH_ALTHYPER
	smooth in float outClipD;
#endif

#endif

uniform vec4 inSOBParams;
uniform vec4 inLifeParams;

uniform vec4 inFogColor;
uniform vec4 inFogWindow;

uniform mat4 inMatM;

#ifdef SOB_TEAM
uniform vec4 inColTeam;
uniform vec4 inColStripe;
#endif

#ifndef SOB_DEBRIS
uniform vec4 inColEffect;
#endif

uniform vec4 inSurfDiff;
uniform vec4 inSurfGlow;
uniform vec4 inSurfSpec;
uniform vec4 inSurfGloss;
uniform vec4 inSurfRefl;
uniform vec4 inSurfFren;
uniform vec4 inSurfPaint;
uniform vec4 inSurfPeak;

uniform vec4 inPaintStyle;

uniform vec4 inGammaScale;
uniform vec4 inBGAddLight;
uniform vec4 inBGEnvParams;

#ifdef SOB_BAYLIGHT

uniform vec4 inBayExps;	//br, bR, Br, BR

#ifdef SOB_POST_B0R0
vec4 getBayExp(){ return vec4(inBayExps.x, inBayExps.x, inBayExps.x, 1.0f); }
#endif

#ifdef SOB_POST_B0R1
vec4 getBayExp(){ return vec4(inBayExps.y, inBayExps.y, inBayExps.y, 1.0f); }
#endif

#ifdef SOB_POST_B1R0
vec4 getBayExp(){ return vec4(inBayExps.z, inBayExps.z, inBayExps.z, 1.0f); }
#endif

#ifdef SOB_POST_B1R1
vec4 getBayExp(){ return vec4(inBayExps.w, inBayExps.w, inBayExps.w, 1.0f); }
#endif

#endif

uniform ivec2 inLightCounts;
uniform vec4 inLightShip[96]; // Pos/Diff/Spec (or just Pos/Diff) + attenuations in W
uniform vec4 inLightCore[7];

layout (location = 0) out vec4 finalCol0;

#ifdef SOB_SHADOWS_ON

ivec2 shadWH = textureSize(inTexShadow, 0);
vec2 invShad = vec2(1.0/shadWH.x, 1.0/shadWH.y);

float CALC_ShadowMask(float blend, vec3 baseUVW){
#ifdef SOB_SHADOWS_HQ
if (blend > 0.0)
{
vec2 texelUV = baseUVW.xy*shadWH;
vec2 baseUV = vec2(floor(texelUV.x+0.5), floor(texelUV.y+0.5));
float s = texelUV.x+0.5-baseUV.x;
float t = texelUV.y+0.5-baseUV.y;
baseUV -= vec2(0.5);
baseUV *= invShad;

#define SOB_SHADOWS_3X3 1
#ifdef SOB_SHADOWS_3X3
float uw0 = (3 - 2 * s);
float uw1 = (1 + 2 * s);

	float u0 = ((2 - s) / uw0 - 1)*invShad.x;
	float u1 = (s / uw1 + 1)*invShad.x;

	float vw0 = (3 - 2 * t);
	float vw1 = (1 + 2 * t);

	float v0 = ((2 - t) / vw0 - 1)*invShad.y;
	float v1 = (t / vw1 + 1)*invShad.y;
		
	float total = 0.0;
	
	total += uw0*vw0*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v0, baseUVW.z));
	total += uw1*vw0*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v0, baseUVW.z));
	total += uw0*vw1*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v1, baseUVW.z));
	total += uw1*vw1*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v1, baseUVW.z));
	
	total /= 16.0;

#else
float uw0 = (4 - 3 * s);
float uw1 = 7;
float uw2 = (1 + 3 * s);

	float u0 = ((3 - 2 * s) / uw0 - 2)*invShad.x;
	float u1 = ((3 + s) / uw1)*invShad.x;
	float u2 = (s / uw2 + 2)*invShad.x;

	float vw0 = (4 - 3 * t);
	float vw1 = 7;
	float vw2 = (1 + 3 * t);

	float v0 = ((3 - 2 * t) / vw0 - 2)*invShad.y;
	float v1 = ((3 + t) / vw1)*invShad.y;
	float v2 = (t / vw2 + 2)*invShad.y;
	
	float total = 0.0;
	
	total += uw0*vw0*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v0, baseUVW.z));
	total += uw1*vw0*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v0, baseUVW.z));
	total += uw2*vw0*texture(inTexShadow, vec3(baseUV.x+u2, baseUV.y+v0, baseUVW.z));
	total += uw0*vw1*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v1, baseUVW.z));
	total += uw1*vw1*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v1, baseUVW.z));
	total += uw2*vw1*texture(inTexShadow, vec3(baseUV.x+u2, baseUV.y+v1, baseUVW.z));
	total += uw0*vw2*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v2, baseUVW.z));
	total += uw1*vw2*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v2, baseUVW.z));
	total += uw2*vw2*texture(inTexShadow, vec3(baseUV.x+u2, baseUV.y+v2, baseUVW.z));
	
	total /= 144.0;

#endif

	return 1.0-(blend*(1.0-total));
}

return 1.0;

#else
if (blend > 0.0) // So then -1.0 will disable
{
return 1.0-(blend*(1.0-texture(inTexShadow, baseUVW)));
}

return 1.0;

#endif
}

float CALC_ShadowMask_K(){
return CALC_ShadowMask(inShadowTrans[1].w, outPos_KL);
}

#else
float CALC_ShadowMask_K(){ return 1.0; }
#endif

#ifdef SOB_SHADOWS_DUAL
float CALC_ShadowMask_F(){
return CALC_ShadowMask(inShadowTrans[3].w, outPos_FL);
}
#else
float CALC_ShadowMask_F(){ return 1.0; }
#endif

void main()
{
#ifdef SOB_USECLIP
#ifdef PATCH_ALTHYPER
if (outClipD <= 0.0)
{
discard;
}
#endif
#endif

#ifdef SOB_TEAMTEX
vec3 texTeam = texture(inTexTeam, outUV0).xyz;

#ifdef SOB_SCISSOR
	if (texTeam.r < 0.5)
	{
		discard;
	}
#endif

#else
vec3 texTeam = vec3(0.0);
#endif

#ifdef SOB_RESOURCE

//abs(0.5-fract(inTime.x*0.125))*2.0;	// Auto-cycle fade for testing

#ifdef SOB_SALVAGE
float resFade = clamp(1.0-inLifeParams.y, 0.0, 1.0);
resFade *= resFade;		// Curve the burn rate

	#ifdef SOB_DEBRIS
	resFade = 1.0-inFXInfo[0].a;
	#endif
#else
float resFade = inFadeInfo.x;
#endif

float resDelta = inFadeInfo.y;

float fadeWindow = inFadeWindow.x;
float fadeLo = inFadeWindow.y;
float fadeHi = inFadeWindow.z;

#ifdef SOB_SALVAGE
float fadeRange = (fadeHi-fadeLo)+(fadeWindow*2.0);
#else
float fadeRange = (fadeHi-fadeLo)+fadeWindow;
#endif

float fadeProgRaw = texture(inTexProgress, outUV0).r;
float fadeProg = max(fadeProgRaw, fadeLo);
float fadeRes = fadeLo-fadeWindow+(resFade*fadeRange);
float fadeResLim = min(fadeRes, fadeHi);

float texProgress = (fadeProg-fadeResLim)/fadeWindow;

float burnScale = clamp(texProgress*1000.0, 0.0, 1.0);
float texBurn = clamp((1.0-texProgress)*burnScale, 0.0, 1.0);
texBurn *= clamp(1.0-((fadeRes-fadeResLim)/fadeWindow), 0.0, 1.0);
texBurn = pow(texBurn, 0.25);

texProgress = clamp(texProgress, 0.0, 1.0);

#ifdef SOB_SALVAGE
	float fadeScissor = fadeProg-max(fadeLo, fadeResLim);
	if (fadeScissor <= 0.0)
	{
		discard;
	}
#endif

texBurn *= texProgress*4.0;	// 0.5*0.5 = 0.25

#ifdef SOB_DUALINPUT
	vec3 texNorm = mix(texture(inTexNorm, outUV_Norm1).rgb, texture(inTexNorm, outUV_Norm0).rgb, texProgress);
	vec4 texDiff = mix(texture(inTexDiff, outUV_Diff1)*inMulDiff1, texture(inTexDiff, outUV_Diff0)*inMulDiff0, texProgress);
	vec4 texGlowRGB = mix(texture(inTexGlow, outUV_Glow1)*inMulGlow1, texture(inTexGlow, outUV_Glow0)*inMulGlow0, texProgress);
	vec4 texGlow = mix(texture(inTexSpec, outUV_Spec1)*inMulSpec1, texture(inTexSpec, outUV_Spec0)*inMulSpec0, texProgress);
#else
	vec3 texNorm = texture(inTexNorm, outUV0).rgb;
	vec4 texDiff = texture(inTexDiff, outUV0);
	vec4 texGlowRGB = texture(inTexGlow, outUV0);
	vec4 texGlow = texture(inTexSpec, outUV0);
#endif

texNorm = normalize(texNorm*2.0-1.0);

float isPaint = texGlow.g;
texGlow.g = 0.0;

#ifdef SOB_SALVAGE
	float styleDelta = 0.0;		// Deltas make no sense for Salvage
#else
	float styleDelta = inGlowStyle.x;
#endif

float styleBurn = inGlowStyle.y;

float glowDeltScale = mix(1.0, clamp((resDelta-0.25)*1.35, 0.0, 1.0), styleDelta);
float glowBurnScale = mix(1.0, texBurn, styleBurn);
texGlowRGB *= glowDeltScale*glowBurnScale;

#else
#ifdef SOB_THRUSTERS
float thrust = inColEngine.x;

	vec4 texDiffOn = texture(inTexDiffOn, outUV0);
	vec4 texGlowOn = texture(inTexGlowOn, outUV0);
	vec4 texDiffOff = texture(inTexDiffOff, outUV0);
	vec4 texGlowOff = texture(inTexGlowOff, outUV0);
	
	vec4 texDiff = mix(texDiffOff, texDiffOn, thrust);
	vec4 texGlow = mix(texGlowOff, texGlowOn, thrust);
#else
	vec4 texDiff = texture(inTexDiff, outUV0);
	vec4 texGlow = texture(inTexGlow, outUV0);
	
	#ifdef SOB_GLOWRGB
		vec4 texGlowRGB = texGlow;
		texGlow = texture(inTexSpec, outUV0);
		texGlow.g = 1.0;
	#endif
#endif

vec3 texNorm = normalize(texture(inTexNorm, outUV0).rgb*2.0-1.0);

#ifdef SOB_TEAM	
	float isPaint = texTeam.r*texTeam.g*(1.0-texTeam.b);
#else
	float isPaint = 1.0-texTeam.b;
#endif

#endif

// Normal and Eye to Pos in World Space

#ifdef NO_NORMAL_MAP
vec3 worldNorm = normalize(mat3(inMatM)*vec3(outNorm));
#else
vec3 tempTW = mat3(outTan, outBiNorm, outNorm)*texNorm;
vec3 worldNorm = normalize(mat3(inMatM)*tempTW);
#endif

float shadowMask_K = CALC_ShadowMask_K();
float shadowMask_F = CALC_ShadowMask_F();

#ifdef SOB_BADGE
vec4 texBadge = texture(inTexBadge, outUV1);
texGlow.b = mix(texGlow.b, 0.15, texBadge.a0.35);
texGlow.r = mix(texGlow.r, 0.1, texBadge.a
0.35);
isPaint *= 1.0-texBadge.a;
#endif

// Paint and Other map channels
isPaint = 1.0-isPaint;
float mapSpecSharp = texGlow.r;
float mapGlowMask = texGlow.g;
float mapSpecMask = max(0.0, texGlow.b-texGlow.g);

vec3 worldEye = normalize(outEye_W);
float worldDist = length(outEye_W);

#ifdef SOB_2SIDED
if (false == gl_FrontFacing)
{
worldNorm = -worldNorm;
}
#endif

// Diffuse
float extDiffFren = inSurfDiff.y;

// Glow
float extGlowPower = inSurfGlow.x;
float extGlowFren = inSurfGlow.y;

// Specular
float extSpecPower = inSurfSpec.x;
float extSpecFren = inSurfSpec.y;
float extSpecCurve = inSurfSpec.z;

// Paint Gloss
float extPaintCurve = inSurfPaint.x;
float extPaintScale = inSurfPaint.y;
float extPaintBias = inSurfPaint.z;
float extPaintDim = inSurfPaint.w;

// Gloss
float extGlossCurve = inSurfGloss.x+(extPaintCurve*isPaint);
float extGlossScale = inSurfGloss.y+(extPaintScale*isPaint);
float extGlossBias = inSurfGloss.z+(extPaintBias*isPaint);

extSpecPower = mix(extSpecPower, extSpecPower*extPaintDim, isPaint);

float specGloss = max(1.0, pow(mapSpecSharp, extGlossCurve)*extGlossScale)+extGlossBias;
float pointGloss = max(1.0, specGloss*0.25);

// Reflections
float extReflPower = inSurfRefl.x;
float extReflFren = inSurfRefl.y;
float extReflAddMix = inSurfRefl.z;

// Fresnel
float extFrenPower = inSurfFren.x;
float extFrenBias = inSurfFren.y;
float extFrenCurve = inSurfFren.z;
float frenDeg = clamp(pow(extFrenBias*(1.0-abs(dot(worldNorm, worldEye))), extFrenCurve)*extFrenPower, 0.0, 1.0);

// Map Channel * Powers
float peakStrength = 1.0+(mix(inSurfPeak.x, inSurfPeak.y, isPaint)*mix(1.0, inSurfPeak.z, frenDeg));
float glowStrength = mapGlowMask*max(0.0, extGlowPower-(extGlowFren*frenDeg));
float specRawStrength = mapSpecMask*extSpecPower;
float specStrength = mix(specRawStrength, 1.0, frenDeg*mapSpecSharp*extSpecFren);
float reflStrength = mix(mapSpecMask*extReflPower, 1.0, frenDeg*mapSpecSharp*extReflFren);

// Time to get painted (paint + diffuse curves logic)
float paintCurve = inPaintStyle.x;
float paintDarkScale = inPaintStyle.y;
float paintDarkOfs = inPaintStyle.z;
vec4 paintBase = mix(vec4(0.5, 0.5, 0.5, 1.0), texDiff, paintCurve);

#ifdef SOB_TEAM
// Base paint calc - paint, stripe, team, etc…
vec4 paint = mix(inColTeam, paintBase, texTeam.r);
paint = mix(inColStripe, paint, texTeam.g);

#ifdef SOB_BADGE
vec4 lumMap = vec4(0.299, 0.587, 0.114, 0.0);
vec4 diffLum = vec4(texDiff.r, texDiff.g, texDiff.b, dot(texDiff, lumMap));
vec4 d_hi = clamp(((diffLum2.0)-1.0), 0.0, 1.0);
vec4 d_lo = clamp(((diffLum
paintDarkScale)-paintDarkOfs), 0.0, 1.0); // Slight overdark for badge contouring
paint = mix(d_lopaint, vec4(1.0), d_hi);
diffLum.rgb = d_lo.w
texBadge.rgb;
d_lo = mix(diffLum, vec4(1.0), d_hi.w);
paint = mix(paint, d_lo, texBadge.a);
#else
vec4 d_hi = clamp(((texDiff2.0)-1.0), 0.0, 1.0);
vec4 d_lo = clamp(((texDiff
paintDarkScale)-paintDarkOfs), 0.0, 1.0);
paint = mix(d_lo*paint, vec4(1.0), d_hi);
#endif

#else
vec4 d_hi = clamp(((texDiff2.0)-1.0), 0.0, 1.0);
vec4 d_lo = clamp(((texDiff
paintDarkScale)-paintDarkOfs), 0.0, 1.0);
vec4 paint = mix(d_lo*paintBase, vec4(1.0), d_hi);
#endif

float diffStrength = max(0.0, 1.0-specRawStrength);
diffStrength = pow(diffStrength, 1.0-(frenDeg*extDiffFren));

#ifdef SOB_GLOWRGB
vec3 diffRGB = paint.rgb;
vec3 glowRGB = texGlowRGB.rgb0.8;
#else
vec3 diffRGB = paint.rgb
((1.0-mapGlowMask)diffStrength);
vec3 glowRGB = paint.rgb
mapGlowMask;
#endif

glowRGB *= glowStrength;

// Seed lighting with Ambient+Black
vec3 diffAll = inLightCore[0].rgb;
vec3 specAll = vec3(0,0,0);
	
// Key Light
vec3 litNorm = normalize(inLightCore[1].rgb);
vec3 holdLit_K = litNorm;

#ifndef SOB_BAYLIGHT
float litDif = clamp(dot(litNorm, worldNorm), 0.0, 1.0);
vec3 litRefl = reflect(-litNorm, worldNorm);
float litSpec = clamp(dot(-worldEye, litRefl), 0.0, 1.0)peakStrength;
litSpec = pow(litSpec, specGloss)min(litDif1000, 1.0);
diffAll += shadowMask_K
inLightCore[2].rgblitDif;
specAll += shadowMask_K
inLightCore[3].rgb*litSpec;

// Fill Light
litNorm = normalize(inLightCore[4].rgb);
vec3 holdLit_F = litNorm;
litDif = clamp(dot(litNorm, worldNorm), 0.0, 1.0);
litRefl = reflect(-litNorm, worldNorm);
litSpec = clamp(dot(-worldEye, litRefl), 0.0, 1.0)*peakStrength;
litSpec = pow(litSpec, specGloss)*min(litDif*1000, 1.0);
diffAll += shadowMask_F*inLightCore[5].rgb*litDif;
specAll += shadowMask_F*inLightCore[6].rgb*litSpec;

// Point lights...
int inP = inLightCounts.x;	// Points?
int inL = 0;
for (; inL<inP; inL++)
{
	int inS = inL*3;
	vec3 litVec = inLightShip[inS].rgb-outPos_W;
	vec3 atenVec = vec3(inLightShip[inS].w, inLightShip[inS+1].w, inLightShip[inS+2].w);
	float litLen = length(litVec);
	litVec = normalize(litVec);
	litDif = clamp(dot(litVec, worldNorm), 0.0, 1.0);
	float atenVal = 1.0/(atenVec.x+(atenVec.y*litLen)+(atenVec.z*litLen*litLen));
	diffAll.rgb += inLightShip[inS+1].rgb*litDif*atenVal*2.0;

	float subSpec = clamp(dot(-worldEye, reflect(-litVec, worldNorm)), 0.0, 1.0)*peakStrength;
	subSpec = pow(subSpec, pointGloss)*min(litDif*1000, 1.0);
	specAll.rgb += inLightShip[inS+2].rgb*subSpec*atenVal*2.0;
}

#else
diffAll = vec3(1.0, 1.0, 1.0);
#endif

#ifdef SOB_LIGHT_HQ
vec3 beamDif = vec3(0.0f);
vec3 beamSpec = vec3(0.0f);

float beamGloss = max(1.0, specGloss*0.75);

int inB = inLightCounts.x+inLightCounts.y;	// Beams?
for (; inL<inB; inL++)
{
	int inS = inL*3;
	
	vec3 beamHead = inLightShip[inS].xyz;
	float beamLen = inLightShip[inS].w;
	vec3 beamAxis = inLightShip[inS+1].xyz;
	float beamOORad = inLightShip[inS+1].w;
	vec3 beamRGB = inLightShip[inS+2].rgb;
	float beamCurve = inLightShip[inS+2].w;
	
	// Determine the closest on-beam point
	vec3 sepOfs = outPos_W-beamHead;
	float sepA = clamp(dot(sepOfs, beamAxis), 0.0, beamLen);
	vec3 litPos = beamHead+(beamAxis*sepA);
	
	// Gather angle/distance
	vec3 litVec = litPos-outPos_W;
	float litLen = length(litVec);
	litVec = normalize(litVec);
	
	// Attenuate for distance
	float atenVal = pow(1.0-min(litLen*beamOORad, 1.0), beamCurve)*2.0;	// *2 to adjust for HW old headroom
	
	// Bias diffuse angle due to co-incidence with beam 
	float litBias = abs(dot(worldNorm, beamAxis));
	litDif = clamp(dot(worldNorm, litVec), 0.0, 1.0);
	litDif = mix(litDif, 1.0, litBias);
	
	vec3 subRefl = reflect(-litVec, worldNorm);
	float subSpec = max(dot(-worldEye, subRefl), 0.0);
	float subBoost = abs(dot(inLightShip[inS+1].rgb, subRefl));	// Reflection along beam axis?
	subSpec = min(subSpec*(1.0+(subBoost*0.25)), 1.0)*peakStrength;
	subSpec = pow(subSpec, beamGloss)*min(litDif*1000, 1.0);
	
	beamDif += beamRGB*litDif*atenVal;
	beamSpec += inLightShip[inS+2].rgb*subSpec*atenVal;
}

diffAll += beamDif;
specAll += beamSpec;

//diffAll = beamDif;
//specAll = beamSpec;

#endif

// Apply final lighting 
paint.rgb = (diffRGB*diffAll)+glowRGB+(specAll*specStrength);

#ifndef SOB_BAYLIGHT
// Add reflections
vec3 envNorm = reflect(worldEye, worldNorm);
vec4 texE0 = texture(inTexEnv0, envNorm);
vec4 texE1 = texture(inTexEnv1, envNorm);
vec4 reflTex = mix(texE0, texE1, mapSpecSharp);

#ifdef SOB_SHADOWS_ON
float envMask = 1.0-(max((dot(envNorm,holdLit_K)5.0)-4.0, 0.0)(1.0-shadowMask_K));

#ifdef SOB_SHADOWS_DUAL
	envMask *= 1.0-(max((dot(envNorm,holdLit_F)*5.0)-4.0, 0.0)*(1.0-shadowMask_F));
#endif

#else
float envMask = 1.0;
#endif

float reflDeg = reflStrength*reflTex.a*inBGEnvParams.r*envMask;
float reflAdd = extReflAddMix;
float reflAlpha = 1.0-reflAdd;

reflTex.rgb += inBGAddLight.rgb;

paint.rgb += reflTex.rgb*reflDeg*reflAdd;
paint.rgb = mix(paint.rgb, reflTex.rgb, reflDeg*reflAlpha);

#endif

paint.a = inSOBParams.x;

#ifdef SOB_TEAM
if (inSOBParams.y > 0.0)
{
float frenCloak = pow((1.0-abs(dot(worldNorm, worldEye)))*1.06, 2.0)*2.0-1.0;

	if (frenCloak > 0.0)
	{
		vec3 noisePos = outPos_W.xyz*0.05;
		vec3 timePos = holdLit_K*(inTime.z*2.0);
		float cloakNoise = HELP_Noise3(noisePos+timePos)*0.5+1.5;
		frenCloak = clamp(frenCloak*cloakNoise*0.5, 0.0, 1.0);
	}
	
	float cloakPaint = 1.0-(0.5*inSOBParams.y);
	paint.rgb = (paint.rgb*cloakPaint)+vec3(max(frenCloak, 0.0)*inSOBParams.y*1.5);
}

#endif

#ifndef SOB_DEBRIS
// UI Effect (glow, etc)
paint.rgb += vec3(inColEffect)*inColEffect.a;
#endif

paint.rgb = pow(paint.rgb, vec3(inGammaScale))*inGammaScale.a;

#ifdef SOB_USECLIP
vec3 hyperSpace = vec3(inGammaScale.a);

if (false == gl_FrontFacing)
{
	paint.rgb = hyperSpace;
}
else
{

#ifdef PATCH_ALTHYPER
float hyperEdge = outClipD*0.02;
#else
float hyperEdge = gl_ClipDistance[0]0.02;
#endif
if (hyperEdge < 1.0)
{
vec3 planeScales = vec3(1.5)+(abs(inClipPlane.xyz)20.0);
vec3 noisePos = outPos_W.xyz/planeScales;
vec3 timePos = inClipPlane.xyz
(inTime.z
2.0);

		float hyperNoise = HELP_Noise3(noisePos+timePos)*0.5+1.5;
		hyperEdge = 1.0-clamp(hyperEdge*hyperNoise, 0.0, 1.0);
		hyperEdge = min(pow(hyperEdge*1.1, 5.0)/1.2, 1.0);
		
		paint.rgb = mix(paint.rgb, hyperSpace, hyperEdge*inSOBParams.z);
	}
}

#endif

float maxFog = inFogColor.a*inFogColor.w;
if (maxFog > 0.0)
{
	float useFog = clamp((worldDist-inFogWindow.x)/(inFogWindow.z-inFogWindow.x), inFogWindow.y, inFogWindow.w);
	paint.rgb = mix(paint.rgb, inFogColor.rgb, useFog*inFogColor.a);
}

paint *= getShipExp();

#ifdef SOB_BAYLIGHT
paint *= getBayExp();
#endif

// Enable to show 'bad UV' patches (as magenta)
//vec2 delUV = vec2(dFdx(outUV0.x), dFdy(outUV0.y));
//float delD = 1.0-min(1.0, length(delUV)*1000000.0);
//paint.rgb = mix(paint.rgb, vec3(delD, 0.0, delD), delD);

#ifdef SOB_ALPHA
paint.a *= texTeam.r;
#endif

finalCol0 = paint;

}
smooth in vec2 outUV0;
smooth in vec3 outNorm;
smooth in vec3 outTan;
smooth in vec3 outBiNorm;
smooth in vec3 outPos_W;
smooth in vec3 outEye_W;

#ifdef SOB_SHADOWS_ON
smooth in vec3 outPos_KL;
uniform sampler2DShadow inTexShadow;
uniform vec4 inShadowTrans[4];
#ifdef SOB_SHADOWS_DUAL
smooth in vec3 outPos_FL;
#endif
#endif

uniform vec4 inTime;

#ifdef SOB_BADGE
smooth in vec2 outUV1;
uniform sampler2D inTexBadge;
#endif

#ifdef SOB_THRUSTERS
uniform sampler2D inTexDiffOn;
uniform sampler2D inTexGlowOn;
uniform sampler2D inTexDiffOff;
uniform sampler2D inTexGlowOff;
uniform vec4 inColEngine;
#else
uniform sampler2D inTexDiff;
uniform sampler2D inTexGlow;
#ifdef SOB_GLOWRGB
uniform sampler2D inTexSpec;
#endif
#endif

#ifdef SOB_RESOURCE
uniform sampler2D inTexProgress;
uniform vec2 inFadeInfo;
uniform vec3 inFadeWindow;
uniform vec4 inGlowStyle;

#ifdef SOB_DUALINPUT
uniform vec4 inMulDiff0;
uniform vec4 inMulDiff1;
uniform vec4 inMulGlow0;
uniform vec4 inMulGlow1;
uniform vec4 inMulSpec0;
uniform vec4 inMulSpec1;
smooth in vec2 outUV_Diff0;
smooth in vec2 outUV_Glow0;
smooth in vec2 outUV_Spec0;
smooth in vec2 outUV_Norm0;
smooth in vec2 outUV_Diff1;
smooth in vec2 outUV_Glow1;
smooth in vec2 outUV_Spec1;
smooth in vec2 outUV_Norm1;
#endif

#ifdef SOB_DEBRIS
uniform vec4 inFXInfo[2];
#endif

#endif

#ifdef SOB_TEAMTEX
uniform sampler2D inTexTeam;
#endif

uniform sampler2D inTexNorm;
uniform samplerCube inTexEnv0;
uniform samplerCube inTexEnv1;

#ifdef SOB_USECLIP
uniform vec4 inClipPlane;

#ifdef PATCH_ALTHYPER
	smooth in float outClipD;
#endif

#endif

uniform vec4 inSOBParams;
uniform vec4 inLifeParams;

uniform vec4 inFogColor;
uniform vec4 inFogWindow;

uniform mat4 inMatM;

#ifdef SOB_TEAM
uniform vec4 inColTeam;
uniform vec4 inColStripe;
#endif

#ifndef SOB_DEBRIS
uniform vec4 inColEffect;
#endif

uniform vec4 inSurfDiff;
uniform vec4 inSurfGlow;
uniform vec4 inSurfSpec;
uniform vec4 inSurfGloss;
uniform vec4 inSurfRefl;
uniform vec4 inSurfFren;
uniform vec4 inSurfPaint;
uniform vec4 inSurfPeak;

uniform vec4 inPaintStyle;

uniform vec4 inGammaScale;
uniform vec4 inBGAddLight;
uniform vec4 inBGEnvParams;

#ifdef SOB_BAYLIGHT

uniform vec4 inBayExps;	//br, bR, Br, BR

#ifdef SOB_POST_B0R0
vec4 getBayExp(){ return vec4(inBayExps.x, inBayExps.x, inBayExps.x, 1.0f); }
#endif

#ifdef SOB_POST_B0R1
vec4 getBayExp(){ return vec4(inBayExps.y, inBayExps.y, inBayExps.y, 1.0f); }
#endif

#ifdef SOB_POST_B1R0
vec4 getBayExp(){ return vec4(inBayExps.z, inBayExps.z, inBayExps.z, 1.0f); }
#endif

#ifdef SOB_POST_B1R1
vec4 getBayExp(){ return vec4(inBayExps.w, inBayExps.w, inBayExps.w, 1.0f); }
#endif

#endif

uniform ivec2 inLightCounts;
uniform vec4 inLightShip[96]; // Pos/Diff/Spec (or just Pos/Diff) + attenuations in W
uniform vec4 inLightCore[7];

layout (location = 0) out vec4 finalCol0;

#ifdef SOB_SHADOWS_ON

ivec2 shadWH = textureSize(inTexShadow, 0);
vec2 invShad = vec2(1.0/shadWH.x, 1.0/shadWH.y);

float CALC_ShadowMask(float blend, vec3 baseUVW){
#ifdef SOB_SHADOWS_HQ
if (blend > 0.0)
{
vec2 texelUV = baseUVW.xy*shadWH;
vec2 baseUV = vec2(floor(texelUV.x+0.5), floor(texelUV.y+0.5));
float s = texelUV.x+0.5-baseUV.x;
float t = texelUV.y+0.5-baseUV.y;
baseUV -= vec2(0.5);
baseUV *= invShad;

#define SOB_SHADOWS_3X3 1
#ifdef SOB_SHADOWS_3X3
float uw0 = (3 - 2 * s);
float uw1 = (1 + 2 * s);

	float u0 = ((2 - s) / uw0 - 1)*invShad.x;
	float u1 = (s / uw1 + 1)*invShad.x;

	float vw0 = (3 - 2 * t);
	float vw1 = (1 + 2 * t);

	float v0 = ((2 - t) / vw0 - 1)*invShad.y;
	float v1 = (t / vw1 + 1)*invShad.y;
		
	float total = 0.0;
	
	total += uw0*vw0*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v0, baseUVW.z));
	total += uw1*vw0*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v0, baseUVW.z));
	total += uw0*vw1*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v1, baseUVW.z));
	total += uw1*vw1*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v1, baseUVW.z));
	
	total /= 16.0;

#else
float uw0 = (4 - 3 * s);
float uw1 = 7;
float uw2 = (1 + 3 * s);

	float u0 = ((3 - 2 * s) / uw0 - 2)*invShad.x;
	float u1 = ((3 + s) / uw1)*invShad.x;
	float u2 = (s / uw2 + 2)*invShad.x;

	float vw0 = (4 - 3 * t);
	float vw1 = 7;
	float vw2 = (1 + 3 * t);

	float v0 = ((3 - 2 * t) / vw0 - 2)*invShad.y;
	float v1 = ((3 + t) / vw1)*invShad.y;
	float v2 = (t / vw2 + 2)*invShad.y;
	
	float total = 0.0;
	
	total += uw0*vw0*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v0, baseUVW.z));
	total += uw1*vw0*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v0, baseUVW.z));
	total += uw2*vw0*texture(inTexShadow, vec3(baseUV.x+u2, baseUV.y+v0, baseUVW.z));
	total += uw0*vw1*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v1, baseUVW.z));
	total += uw1*vw1*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v1, baseUVW.z));
	total += uw2*vw1*texture(inTexShadow, vec3(baseUV.x+u2, baseUV.y+v1, baseUVW.z));
	total += uw0*vw2*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v2, baseUVW.z));
	total += uw1*vw2*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v2, baseUVW.z));
	total += uw2*vw2*texture(inTexShadow, vec3(baseUV.x+u2, baseUV.y+v2, baseUVW.z));
	
	total /= 144.0;

#endif

	return 1.0-(blend*(1.0-total));
}

return 1.0;

#else
if (blend > 0.0) // So then -1.0 will disable
{
return 1.0-(blend*(1.0-texture(inTexShadow, baseUVW)));
}

return 1.0;

#endif
}

float CALC_ShadowMask_K(){
return CALC_ShadowMask(inShadowTrans[1].w, outPos_KL);
}

#else
float CALC_ShadowMask_K(){ return 1.0; }
#endif

#ifdef SOB_SHADOWS_DUAL
float CALC_ShadowMask_F(){
return CALC_ShadowMask(inShadowTrans[3].w, outPos_FL);
}
#else
float CALC_ShadowMask_F(){ return 1.0; }
#endif

void main()
{
#ifdef SOB_USECLIP
#ifdef PATCH_ALTHYPER
if (outClipD <= 0.0)
{
discard;
}
#endif
#endif

#ifdef SOB_TEAMTEX
vec3 texTeam = texture(inTexTeam, outUV0).xyz;

#ifdef SOB_SCISSOR
	if (texTeam.r < 0.5)
	{
		discard;
	}
#endif

#else
vec3 texTeam = vec3(0.0);
#endif

#ifdef SOB_RESOURCE

//abs(0.5-fract(inTime.x*0.125))*2.0;	// Auto-cycle fade for testing

#ifdef SOB_SALVAGE
float resFade = clamp(1.0-inLifeParams.y, 0.0, 1.0);
resFade *= resFade;		// Curve the burn rate

	#ifdef SOB_DEBRIS
	resFade = 1.0-inFXInfo[0].a;
	#endif
#else
float resFade = inFadeInfo.x;
#endif

float resDelta = inFadeInfo.y;

float fadeWindow = inFadeWindow.x;
float fadeLo = inFadeWindow.y;
float fadeHi = inFadeWindow.z;

#ifdef SOB_SALVAGE
float fadeRange = (fadeHi-fadeLo)+(fadeWindow*2.0);
#else
float fadeRange = (fadeHi-fadeLo)+fadeWindow;
#endif

float fadeProgRaw = texture(inTexProgress, outUV0).r;
float fadeProg = max(fadeProgRaw, fadeLo);
float fadeRes = fadeLo-fadeWindow+(resFade*fadeRange);
float fadeResLim = min(fadeRes, fadeHi);

float texProgress = (fadeProg-fadeResLim)/fadeWindow;

float burnScale = clamp(texProgress*1000.0, 0.0, 1.0);
float texBurn = clamp((1.0-texProgress)*burnScale, 0.0, 1.0);
texBurn *= clamp(1.0-((fadeRes-fadeResLim)/fadeWindow), 0.0, 1.0);
texBurn = pow(texBurn, 0.25);

texProgress = clamp(texProgress, 0.0, 1.0);

#ifdef SOB_SALVAGE
	float fadeScissor = fadeProg-max(fadeLo, fadeResLim);
	if (fadeScissor <= 0.0)
	{
		discard;
	}
#endif

texBurn *= texProgress*4.0;	// 0.5*0.5 = 0.25

#ifdef SOB_DUALINPUT
	vec3 texNorm = mix(texture(inTexNorm, outUV_Norm1).rgb, texture(inTexNorm, outUV_Norm0).rgb, texProgress);
	vec4 texDiff = mix(texture(inTexDiff, outUV_Diff1)*inMulDiff1, texture(inTexDiff, outUV_Diff0)*inMulDiff0, texProgress);
	vec4 texGlowRGB = mix(texture(inTexGlow, outUV_Glow1)*inMulGlow1, texture(inTexGlow, outUV_Glow0)*inMulGlow0, texProgress);
	vec4 texGlow = mix(texture(inTexSpec, outUV_Spec1)*inMulSpec1, texture(inTexSpec, outUV_Spec0)*inMulSpec0, texProgress);
#else
	vec3 texNorm = texture(inTexNorm, outUV0).rgb;
	vec4 texDiff = texture(inTexDiff, outUV0);
	vec4 texGlowRGB = texture(inTexGlow, outUV0);
	vec4 texGlow = texture(inTexSpec, outUV0);
#endif

texNorm = normalize(texNorm*2.0-1.0);

float isPaint = texGlow.g;
texGlow.g = 1.0;

#ifdef SOB_SALVAGE
	float styleDelta = 0.0;		// Deltas make no sense for Salvage
#else
	float styleDelta = inGlowStyle.x;
#endif

float styleBurn = inGlowStyle.y;

float glowDeltScale = mix(1.0, clamp((resDelta-0.25)*1.35, 0.0, 1.0), styleDelta);
float glowBurnScale = mix(1.0, texBurn, styleBurn);
texGlowRGB *= glowDeltScale*glowBurnScale;

#else
#ifdef SOB_THRUSTERS
float thrust = inColEngine.x;

	vec4 texDiffOn = texture(inTexDiffOn, outUV0);
	vec4 texGlowOn = texture(inTexGlowOn, outUV0);
	vec4 texDiffOff = texture(inTexDiffOff, outUV0);
	vec4 texGlowOff = texture(inTexGlowOff, outUV0);
	
	vec4 texDiff = mix(texDiffOff, texDiffOn, thrust);
	vec4 texGlow = mix(texGlowOff, texGlowOn, thrust);
#else
	vec4 texDiff = texture(inTexDiff, outUV0);
	vec4 texGlow = texture(inTexGlow, outUV0);
	
	#ifdef SOB_GLOWRGB
		vec4 texGlowRGB = texGlow;
		texGlow = texture(inTexSpec, outUV0);
		texGlow.g = 1.0;
	#endif
#endif

vec3 texNorm = normalize(texture(inTexNorm, outUV0).rgb*2.0-1.0);

#ifdef SOB_TEAM	
	float isPaint = texTeam.r*texTeam.g*(1.0-texTeam.b);
#else
	float isPaint = 1.0-texTeam.b;
#endif

#endif

// Normal and Eye to Pos in World Space

#ifdef NO_NORMAL_MAP
vec3 worldNorm = normalize(mat3(inMatM)*vec3(outNorm));
#else
vec3 tempTW = mat3(outTan, outBiNorm, outNorm)*texNorm;
vec3 worldNorm = normalize(mat3(inMatM)*tempTW);
#endif

float shadowMask_K = CALC_ShadowMask_K();
float shadowMask_F = CALC_ShadowMask_F();

#ifdef SOB_BADGE
vec4 texBadge = texture(inTexBadge, outUV1);
texGlow.b = mix(texGlow.b, 0.15, texBadge.a0.35);
texGlow.r = mix(texGlow.r, 0.1, texBadge.a
0.35);
isPaint *= 1.0-texBadge.a;
#endif

// Paint and Other map channels
isPaint = 1.0-isPaint;
float mapSpecSharp = texGlow.r;
float mapGlowMask = texGlow.g;
float mapSpecMask = max(0.0, texGlow.b-texGlow.g);

vec3 worldEye = normalize(outEye_W);
float worldDist = length(outEye_W);

#ifdef SOB_2SIDED
if (false == gl_FrontFacing)
{
worldNorm = -worldNorm;
}
#endif

// Diffuse
float extDiffFren = inSurfDiff.y;

// Glow
float extGlowPower = inSurfGlow.x;
float extGlowFren = inSurfGlow.y;

// Specular
float extSpecPower = inSurfSpec.x;
float extSpecFren = inSurfSpec.y;
float extSpecCurve = inSurfSpec.z;

// Paint Gloss
float extPaintCurve = inSurfPaint.x;
float extPaintScale = inSurfPaint.y;
float extPaintBias = inSurfPaint.z;
float extPaintDim = inSurfPaint.w;

// Gloss
float extGlossCurve = inSurfGloss.x+(extPaintCurve*isPaint);
float extGlossScale = inSurfGloss.y+(extPaintScale*isPaint);
float extGlossBias = inSurfGloss.z+(extPaintBias*isPaint);

extSpecPower = mix(extSpecPower, extSpecPower*extPaintDim, isPaint);

float specGloss = max(1.0, pow(mapSpecSharp, extGlossCurve)*extGlossScale)+extGlossBias;
float pointGloss = max(1.0, specGloss*0.25);

// Reflections
float extReflPower = inSurfRefl.x;
float extReflFren = inSurfRefl.y;
float extReflAddMix = inSurfRefl.z;

// Fresnel
float extFrenPower = inSurfFren.x;
float extFrenBias = inSurfFren.y;
float extFrenCurve = inSurfFren.z;
float frenDeg = clamp(pow(extFrenBias*(1.0-abs(dot(worldNorm, worldEye))), extFrenCurve)*extFrenPower, 0.0, 1.0);

// Map Channel * Powers
float peakStrength = 1.0+(mix(inSurfPeak.x, inSurfPeak.y, isPaint)*mix(1.0, inSurfPeak.z, frenDeg));
float glowStrength = mapGlowMask*max(0.0, extGlowPower-(extGlowFren*frenDeg));
float specRawStrength = mapSpecMask*extSpecPower;
float specStrength = mix(specRawStrength, 1.0, frenDeg*mapSpecSharp*extSpecFren);
float reflStrength = mix(mapSpecMask*extReflPower, 1.0, frenDeg*mapSpecSharp*extReflFren);

// Time to get painted (paint + diffuse curves logic)
float paintCurve = inPaintStyle.x;
float paintDarkScale = inPaintStyle.y;
float paintDarkOfs = inPaintStyle.z;
vec4 paintBase = mix(vec4(0.5, 0.5, 0.5, 1.0), texDiff, paintCurve);

#ifdef SOB_TEAM
// Base paint calc - paint, stripe, team, etc…
vec4 paint = mix(inColTeam, paintBase, texTeam.r);
paint = mix(inColStripe, paint, texTeam.g);

#ifdef SOB_BADGE
vec4 lumMap = vec4(0.299, 0.587, 0.114, 0.0);
vec4 diffLum = vec4(texDiff.r, texDiff.g, texDiff.b, dot(texDiff, lumMap));
vec4 d_hi = clamp(((diffLum2.0)-1.0), 0.0, 1.0);
vec4 d_lo = clamp(((diffLum
paintDarkScale)-paintDarkOfs), 0.0, 1.0); // Slight overdark for badge contouring
paint = mix(d_lopaint, vec4(1.0), d_hi);
diffLum.rgb = d_lo.w
texBadge.rgb;
d_lo = mix(diffLum, vec4(1.0), d_hi.w);
paint = mix(paint, d_lo, texBadge.a);
#else
vec4 d_hi = clamp(((texDiff2.0)-1.0), 0.0, 1.0);
vec4 d_lo = clamp(((texDiff
paintDarkScale)-paintDarkOfs), 0.0, 1.0);
paint = mix(d_lo*paint, vec4(1.0), d_hi);
#endif

#else
vec4 d_hi = clamp(((texDiff2.0)-1.0), 0.0, 1.0);
vec4 d_lo = clamp(((texDiff
paintDarkScale)-paintDarkOfs), 0.0, 1.0);
vec4 paint = mix(d_lo*paintBase, vec4(1.0), d_hi);
#endif

float diffStrength = max(0.0, 1.0-specRawStrength);
diffStrength = pow(diffStrength, 1.0-(frenDeg*extDiffFren));

#ifdef SOB_GLOWRGB
vec3 diffRGB = paint.rgb;
vec3 glowRGB = texGlowRGB.rgb0.8;
#else
vec3 diffRGB = paint.rgb
((1.0-mapGlowMask)diffStrength);
vec3 glowRGB = paint.rgb
mapGlowMask;
#endif

glowRGB *= glowStrength;

// Seed lighting with Ambient+Black
vec3 diffAll = inLightCore[0].rgb;
vec3 specAll = vec3(0,0,0);
	
// Key Light
vec3 litNorm = normalize(inLightCore[1].rgb);
vec3 holdLit_K = litNorm;

#ifndef SOB_BAYLIGHT
float litDif = clamp(dot(litNorm, worldNorm), 0.0, 1.0);
vec3 litRefl = reflect(-litNorm, worldNorm);
float litSpec = clamp(dot(-worldEye, litRefl), 0.0, 1.0)peakStrength;
litSpec = pow(litSpec, specGloss)min(litDif1000, 1.0);
diffAll += shadowMask_K
inLightCore[2].rgblitDif;
specAll += shadowMask_K
inLightCore[3].rgb*litSpec;

// Fill Light
litNorm = normalize(inLightCore[4].rgb);
vec3 holdLit_F = litNorm;
litDif = clamp(dot(litNorm, worldNorm), 0.0, 1.0);
litRefl = reflect(-litNorm, worldNorm);
litSpec = clamp(dot(-worldEye, litRefl), 0.0, 1.0)*peakStrength;
litSpec = pow(litSpec, specGloss)*min(litDif*1000, 1.0);
diffAll += shadowMask_F*inLightCore[5].rgb*litDif;
specAll += shadowMask_F*inLightCore[6].rgb*litSpec;

// Point lights...
int inP = inLightCounts.x;	// Points?
int inL = 0;
for (; inL<inP; inL++)
{
	int inS = inL*3;
	vec3 litVec = inLightShip[inS].rgb-outPos_W;
	vec3 atenVec = vec3(inLightShip[inS].w, inLightShip[inS+1].w, inLightShip[inS+2].w);
	float litLen = length(litVec);
	litVec = normalize(litVec);
	litDif = clamp(dot(litVec, worldNorm), 0.0, 1.0);
	float atenVal = 1.0/(atenVec.x+(atenVec.y*litLen)+(atenVec.z*litLen*litLen));
	diffAll.rgb += inLightShip[inS+1].rgb*litDif*atenVal*2.0;

	float subSpec = clamp(dot(-worldEye, reflect(-litVec, worldNorm)), 0.0, 1.0)*peakStrength;
	subSpec = pow(subSpec, pointGloss)*min(litDif*1000, 1.0);
	specAll.rgb += inLightShip[inS+2].rgb*subSpec*atenVal*2.0;
}

#else
diffAll = vec3(1.0, 1.0, 1.0);
#endif

#ifdef SOB_LIGHT_HQ
vec3 beamDif = vec3(0.0f);
vec3 beamSpec = vec3(0.0f);

float beamGloss = max(1.0, specGloss*0.75);

int inB = inLightCounts.x+inLightCounts.y;	// Beams?
for (; inL<inB; inL++)
{
	int inS = inL*3;
	
	vec3 beamHead = inLightShip[inS].xyz;
	float beamLen = inLightShip[inS].w;
	vec3 beamAxis = inLightShip[inS+1].xyz;
	float beamOORad = inLightShip[inS+1].w;
	vec3 beamRGB = inLightShip[inS+2].rgb;
	float beamCurve = inLightShip[inS+2].w;
	
	// Determine the closest on-beam point
	vec3 sepOfs = outPos_W-beamHead;
	float sepA = clamp(dot(sepOfs, beamAxis), 0.0, beamLen);
	vec3 litPos = beamHead+(beamAxis*sepA);
	
	// Gather angle/distance
	vec3 litVec = litPos-outPos_W;
	float litLen = length(litVec);
	litVec = normalize(litVec);
	
	// Attenuate for distance
	float atenVal = pow(1.0-min(litLen*beamOORad, 1.0), beamCurve)*2.0;	// *2 to adjust for HW old headroom
	
	// Bias diffuse angle due to co-incidence with beam 
	float litBias = abs(dot(worldNorm, beamAxis));
	litDif = clamp(dot(worldNorm, litVec), 0.0, 1.0);
	litDif = mix(litDif, 1.0, litBias);
	
	vec3 subRefl = reflect(-litVec, worldNorm);
	float subSpec = max(dot(-worldEye, subRefl), 0.0);
	float subBoost = abs(dot(inLightShip[inS+1].rgb, subRefl));	// Reflection along beam axis?
	subSpec = min(subSpec*(1.0+(subBoost*0.25)), 1.0)*peakStrength;
	subSpec = pow(subSpec, beamGloss)*min(litDif*1000, 1.0);
	
	beamDif += beamRGB*litDif*atenVal;
	beamSpec += inLightShip[inS+2].rgb*subSpec*atenVal;
}

diffAll += beamDif;
specAll += beamSpec;

//diffAll = beamDif;
//specAll = beamSpec;

#endif

// Apply final lighting 
paint.rgb = (diffRGB*diffAll)+glowRGB+(specAll*specStrength);

#ifndef SOB_BAYLIGHT
// Add reflections
vec3 envNorm = reflect(worldEye, worldNorm);
vec4 texE0 = texture(inTexEnv0, envNorm);
vec4 texE1 = texture(inTexEnv1, envNorm);
vec4 reflTex = mix(texE0, texE1, mapSpecSharp);

#ifdef SOB_SHADOWS_ON
float envMask = 1.0-(max((dot(envNorm,holdLit_K)5.0)-4.0, 0.0)(1.0-shadowMask_K));

#ifdef SOB_SHADOWS_DUAL
	envMask *= 1.0-(max((dot(envNorm,holdLit_F)*5.0)-4.0, 0.0)*(1.0-shadowMask_F));
#endif

#else
float envMask = 1.0;
#endif

float reflDeg = reflStrength*reflTex.a*inBGEnvParams.r*envMask;
float reflAdd = extReflAddMix;
float reflAlpha = 1.0-reflAdd;

reflTex.rgb += inBGAddLight.rgb;

paint.rgb += reflTex.rgb*reflDeg*reflAdd;
paint.rgb = mix(paint.rgb, reflTex.rgb, reflDeg*reflAlpha);

#endif

paint.a = inSOBParams.x;

#ifdef SOB_TEAM
if (inSOBParams.y > 0.0)
{
float frenCloak = pow((1.0-abs(dot(worldNorm, worldEye)))*1.06, 2.0)*2.0-1.0;

	if (frenCloak > 0.0)
	{
		vec3 noisePos = outPos_W.xyz*0.05;
		vec3 timePos = holdLit_K*(inTime.z*2.0);
		float cloakNoise = HELP_Noise3(noisePos+timePos)*0.5+1.5;
		frenCloak = clamp(frenCloak*cloakNoise*0.5, 0.0, 1.0);
	}
	
	float cloakPaint = 1.0-(0.5*inSOBParams.y);
	paint.rgb = (paint.rgb*cloakPaint)+vec3(max(frenCloak, 0.0)*inSOBParams.y*1.5);
}

#endif

#ifndef SOB_DEBRIS
// UI Effect (glow, etc)
paint.rgb += vec3(inColEffect)*inColEffect.a;
#endif

paint.rgb = pow(paint.rgb, vec3(inGammaScale))*inGammaScale.a;

#ifdef SOB_USECLIP
vec3 hyperSpace = vec3(inGammaScale.a);

if (false == gl_FrontFacing)
{
	paint.rgb = hyperSpace;
}
else
{

#ifdef PATCH_ALTHYPER
float hyperEdge = outClipD*0.02;
#else
float hyperEdge = gl_ClipDistance[0]0.02;
#endif
if (hyperEdge < 1.0)
{
vec3 planeScales = vec3(1.5)+(abs(inClipPlane.xyz)20.0);
vec3 noisePos = outPos_W.xyz/planeScales;
vec3 timePos = inClipPlane.xyz
(inTime.z
2.0);

		float hyperNoise = HELP_Noise3(noisePos+timePos)*0.5+1.5;
		hyperEdge = 1.0-clamp(hyperEdge*hyperNoise, 0.0, 1.0);
		hyperEdge = min(pow(hyperEdge*1.1, 5.0)/1.2, 1.0);
		
		paint.rgb = mix(paint.rgb, hyperSpace, hyperEdge*inSOBParams.z);
	}
}

#endif

float maxFog = inFogColor.a*inFogColor.w;
if (maxFog > 0.0)
{
	float useFog = clamp((worldDist-inFogWindow.x)/(inFogWindow.z-inFogWindow.x), inFogWindow.y, inFogWindow.w);
	paint.rgb = mix(paint.rgb, inFogColor.rgb, useFog*inFogColor.a);
}

paint *= getShipExp();

#ifdef SOB_BAYLIGHT
paint *= getBayExp();
#endif

// Enable to show 'bad UV' patches (as magenta)
//vec2 delUV = vec2(dFdx(outUV0.x), dFdy(outUV0.y));
//float delD = 1.0-min(1.0, length(delUV)*1000000.0);
//paint.rgb = mix(paint.rgb, vec3(delD, 0.0, delD), delD);

#ifdef SOB_ALPHA
paint.a *= texTeam.r;
#endif

finalCol0 = paint;

}

----- END ERROR LOG -----
[/details]

I have popped the DAE I was using to test into my Public OneDrive folder for you


(Nathanius) #501

[details=manifest.log - Part 2]Failed to compile FragmentShader shader from “shaders\gl_prog\sob_ship.prog”
----- DETAILS -----
0(831) : error C1038: declaration of “outUV0” conflicts with previous declaration at 0(118)
0(832) : error C1038: declaration of “outNorm” conflicts with previous declaration at 0(119)
0(833) : error C1038: declaration of “outTan” conflicts with previous declaration at 0(120)
0(834) : error C1038: declaration of “outBiNorm” conflicts with previous declaration at 0(121)
0(835) : error C1038: declaration of “outPos_W” conflicts with previous declaration at 0(122)
0(836) : error C1038: declaration of “outEye_W” conflicts with previous declaration at 0(123)
0(839) : error C1038: declaration of “outPos_KL” conflicts with previous declaration at 0(126)
0(840) : error C1038: declaration of “inTexShadow” conflicts with previous declaration at 0(127)
0(841) : error C1038: declaration of “inShadowTrans” conflicts with previous declaration at 0(128)
0(847) : error C1038: declaration of “inTime” conflicts with previous declaration at 0(134)
0(861) : error C1038: declaration of “inTexDiff” conflicts with previous declaration at 0(148)
0(862) : error C1038: declaration of “inTexGlow” conflicts with previous declaration at 0(149)
0(898) : error C1038: declaration of “inTexTeam” conflicts with previous declaration at 0(185)
0(901) : error C1038: declaration of “inTexNorm” conflicts with previous declaration at 0(188)
0(902) : error C1038: declaration of “inTexEnv0” conflicts with previous declaration at 0(189)
0(903) : error C1038: declaration of “inTexEnv1” conflicts with previous declaration at 0(190)
0(906) : error C1038: declaration of “inClipPlane” conflicts with previous declaration at 0(193)
0(913) : error C1038: declaration of “inSOBParams” conflicts with previous declaration at 0(200)
0(914) : error C1038: declaration of “inLifeParams” conflicts with previous declaration at 0(201)
0(916) : error C1038: declaration of “inFogColor” conflicts with previous declaration at 0(203)
0(917) : error C1038: declaration of “inFogWindow” conflicts with previous declaration at 0(204)
0(919) : error C1038: declaration of “inMatM” conflicts with previous declaration at 0(206)
0(922) : error C1038: declaration of “inColTeam” conflicts with previous declaration at 0(209)
0(923) : error C1038: declaration of “inColStripe” conflicts with previous declaration at 0(210)
0(927) : error C1038: declaration of “inColEffect” conflicts with previous declaration at 0(214)
0(930) : error C1038: declaration of “inSurfDiff” conflicts with previous declaration at 0(217)
0(931) : error C1038: declaration of “inSurfGlow” conflicts with previous declaration at 0(218)
0(932) : error C1038: declaration of “inSurfSpec” conflicts with previous declaration at 0(219)
0(933) : error C1038: declaration of “inSurfGloss” conflicts with previous declaration at 0(220)
0(934) : error C1038: declaration of “inSurfRefl” conflicts with previous declaration at 0(221)
0(935) : error C1038: declaration of “inSurfFren” conflicts with previous declaration at 0(222)
0(936) : error C1038: declaration of “inSurfPaint” conflicts with previous declaration at 0(223)
0(937) : error C1038: declaration of “inSurfPeak” conflicts with previous declaration at 0(224)
0(939) : error C1038: declaration of “inPaintStyle” conflicts with previous declaration at 0(226)
0(941) : error C1038: declaration of “inGammaScale” conflicts with previous declaration at 0(228)
0(942) : error C1038: declaration of “inBGAddLight” conflicts with previous declaration at 0(229)
0(943) : error C1038: declaration of “inBGEnvParams” conflicts with previous declaration at 0(230)
0(966) : error C1038: declaration of “inLightCounts” conflicts with previous declaration at 0(253)
0(967) : error C1038: declaration of “inLightShip” conflicts with previous declaration at 0(254)
0(968) : error C1038: declaration of “inLightCore” conflicts with previous declaration at 0(255)
0(970) : error C1038: declaration of “finalCol0” conflicts with previous declaration at 0(257)
0(974) : error C1038: declaration of “shadWH” conflicts with previous declaration at 0(261)
0(975) : error C1038: declaration of “invShad” conflicts with previous declaration at 0(262)
0(977) : error C1013: function “CALC_ShadowMask” is already defined at 0(264)
0(1056) : error C1013: function “CALC_ShadowMask_K” is already defined at 0(343)
0(1069) : error C1013: function “CALC_ShadowMask_F” is already defined at 0(356)
0(1072) : error C1013: function “main” is already defined at 0(359)

----- CODE -----
#version 330
#define SOB_TEAM
#define SOB_TEAMTEX
#define SOB_SHADOWS_ON
#define SOB_SHADOWS_HQ
#define SOB_LIGHT_HQ
#define SOB_POST_B1R1
uniform vec4 inShipExps; //br, bR, Br, BR

#ifdef SOB_POST_B0R0
vec4 getShipExp(){ return vec4(inShipExps.x, inShipExps.x, inShipExps.x, 1.0f); }
#endif

#ifdef SOB_POST_B0R1
vec4 getShipExp(){ return vec4(inShipExps.y, inShipExps.y, inShipExps.y, 1.0f); }
#endif

#ifdef SOB_POST_B1R0
vec4 getShipExp(){ return vec4(inShipExps.z, inShipExps.z, inShipExps.z, 1.0f); }
#endif

#ifdef SOB_POST_B1R1
vec4 getShipExp(){ return vec4(inShipExps.w, inShipExps.w, inShipExps.w, 1.0f); }
#endif
#define SOB_USECLIP

vec3 mod289(vec3 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}

vec4 mod289(vec4 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}

vec4 permute(vec4 x) {
return mod289(((x*34.0)+1.0)*x);
}

vec4 taylorInvSqrt(vec4 r)
{
return 1.79284291400159 - 0.85373472095314 * r;
}

float HELP_Noise3(vec3 v)
{
const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);

// First corner
vec3 i = floor(v + dot(v, C.yyy) );
vec3 x0 = v - i + dot(i, C.xxx) ;

// Other corners
vec3 g = step(x0.yzx, x0.xyz);
vec3 l = 1.0 - g;
vec3 i1 = min( g.xyz, l.zxy );
vec3 i2 = max( g.xyz, l.zxy );

// x0 = x0 - 0.0 + 0.0 * C.xxx;
// x1 = x0 - i1 + 1.0 * C.xxx;
// x2 = x0 - i2 + 2.0 * C.xxx;
// x3 = x0 - 1.0 + 3.0 * C.xxx;
vec3 x1 = x0 - i1 + C.xxx;
vec3 x2 = x0 - i2 + C.yyy; // 2.0C.x = 1/3 = C.y
vec3 x3 = x0 - D.yyy; // -1.0+3.0
C.x = -0.5 = -D.y

// Permutations
i = mod289(i);
vec4 p = permute( permute( permute(
i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
+ i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
+ i.x + vec4(0.0, i1.x, i2.x, 1.0 ));

// Gradients: 7x7 points over a square, mapped onto an octahedron.
// The ring size 1717 = 289 is close to a multiple of 49 (496 = 294)
float n_ = 0.142857142857; // 1.0/7.0
vec3 ns = n_ * D.wyz - D.xzx;

vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)

vec4 x_ = floor(j * ns.z);
vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)

vec4 x = x_ *ns.x + ns.yyyy;
vec4 y = y_ *ns.x + ns.yyyy;
vec4 h = 1.0 - abs(x) - abs(y);

vec4 b0 = vec4( x.xy, y.xy );
vec4 b1 = vec4( x.zw, y.zw );

//vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
vec4 s0 = floor(b0)*2.0 + 1.0;
vec4 s1 = floor(b1)*2.0 + 1.0;
vec4 sh = -step(h, vec4(0.0));

vec4 a0 = b0.xzyw + s0.xzywsh.xxyy ;
vec4 a1 = b1.xzyw + s1.xzyw
sh.zzww ;

vec3 p0 = vec3(a0.xy,h.x);
vec3 p1 = vec3(a0.zw,h.y);
vec3 p2 = vec3(a1.xy,h.z);
vec3 p3 = vec3(a1.zw,h.w);

//Normalise gradients
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;

// Mix final noise value
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
m = m * m;
return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
dot(p2,x2), dot(p3,x3) ) );
}
smooth in vec2 outUV0;
smooth in vec3 outNorm;
smooth in vec3 outTan;
smooth in vec3 outBiNorm;
smooth in vec3 outPos_W;
smooth in vec3 outEye_W;

#ifdef SOB_SHADOWS_ON
smooth in vec3 outPos_KL;
uniform sampler2DShadow inTexShadow;
uniform vec4 inShadowTrans[4];
#ifdef SOB_SHADOWS_DUAL
smooth in vec3 outPos_FL;
#endif
#endif

uniform vec4 inTime;

#ifdef SOB_BADGE
smooth in vec2 outUV1;
uniform sampler2D inTexBadge;
#endif

#ifdef SOB_THRUSTERS
uniform sampler2D inTexDiffOn;
uniform sampler2D inTexGlowOn;
uniform sampler2D inTexDiffOff;
uniform sampler2D inTexGlowOff;
uniform vec4 inColEngine;
#else
uniform sampler2D inTexDiff;
uniform sampler2D inTexGlow;
#ifdef SOB_GLOWRGB
uniform sampler2D inTexSpec;
#endif
#endif

#ifdef SOB_RESOURCE
uniform sampler2D inTexProgress;
uniform vec2 inFadeInfo;
uniform vec3 inFadeWindow;
uniform vec4 inGlowStyle;

#ifdef SOB_DUALINPUT
uniform vec4 inMulDiff0;
uniform vec4 inMulDiff1;
uniform vec4 inMulGlow0;
uniform vec4 inMulGlow1;
uniform vec4 inMulSpec0;
uniform vec4 inMulSpec1;
smooth in vec2 outUV_Diff0;
smooth in vec2 outUV_Glow0;
smooth in vec2 outUV_Spec0;
smooth in vec2 outUV_Norm0;
smooth in vec2 outUV_Diff1;
smooth in vec2 outUV_Glow1;
smooth in vec2 outUV_Spec1;
smooth in vec2 outUV_Norm1;
#endif

#ifdef SOB_DEBRIS
uniform vec4 inFXInfo[2];
#endif

#endif

#ifdef SOB_TEAMTEX
uniform sampler2D inTexTeam;
#endif

uniform sampler2D inTexNorm;
uniform samplerCube inTexEnv0;
uniform samplerCube inTexEnv1;

#ifdef SOB_USECLIP
uniform vec4 inClipPlane;

#ifdef PATCH_ALTHYPER
	smooth in float outClipD;
#endif

#endif

uniform vec4 inSOBParams;
uniform vec4 inLifeParams;

uniform vec4 inFogColor;
uniform vec4 inFogWindow;

uniform mat4 inMatM;

#ifdef SOB_TEAM
uniform vec4 inColTeam;
uniform vec4 inColStripe;
#endif

#ifndef SOB_DEBRIS
uniform vec4 inColEffect;
#endif

uniform vec4 inSurfDiff;
uniform vec4 inSurfGlow;
uniform vec4 inSurfSpec;
uniform vec4 inSurfGloss;
uniform vec4 inSurfRefl;
uniform vec4 inSurfFren;
uniform vec4 inSurfPaint;
uniform vec4 inSurfPeak;

uniform vec4 inPaintStyle;

uniform vec4 inGammaScale;
uniform vec4 inBGAddLight;
uniform vec4 inBGEnvParams;

#ifdef SOB_BAYLIGHT

uniform vec4 inBayExps;	//br, bR, Br, BR

#ifdef SOB_POST_B0R0
vec4 getBayExp(){ return vec4(inBayExps.x, inBayExps.x, inBayExps.x, 1.0f); }
#endif

#ifdef SOB_POST_B0R1
vec4 getBayExp(){ return vec4(inBayExps.y, inBayExps.y, inBayExps.y, 1.0f); }
#endif

#ifdef SOB_POST_B1R0
vec4 getBayExp(){ return vec4(inBayExps.z, inBayExps.z, inBayExps.z, 1.0f); }
#endif

#ifdef SOB_POST_B1R1
vec4 getBayExp(){ return vec4(inBayExps.w, inBayExps.w, inBayExps.w, 1.0f); }
#endif

#endif

uniform ivec2 inLightCounts;
uniform vec4 inLightShip[96]; // Pos/Diff/Spec (or just Pos/Diff) + attenuations in W
uniform vec4 inLightCore[7];

layout (location = 0) out vec4 finalCol0;

#ifdef SOB_SHADOWS_ON

ivec2 shadWH = textureSize(inTexShadow, 0);
vec2 invShad = vec2(1.0/shadWH.x, 1.0/shadWH.y);

float CALC_ShadowMask(float blend, vec3 baseUVW){
#ifdef SOB_SHADOWS_HQ
if (blend > 0.0)
{
vec2 texelUV = baseUVW.xy*shadWH;
vec2 baseUV = vec2(floor(texelUV.x+0.5), floor(texelUV.y+0.5));
float s = texelUV.x+0.5-baseUV.x;
float t = texelUV.y+0.5-baseUV.y;
baseUV -= vec2(0.5);
baseUV *= invShad;

#define SOB_SHADOWS_3X3 1
#ifdef SOB_SHADOWS_3X3
float uw0 = (3 - 2 * s);
float uw1 = (1 + 2 * s);

	float u0 = ((2 - s) / uw0 - 1)*invShad.x;
	float u1 = (s / uw1 + 1)*invShad.x;

	float vw0 = (3 - 2 * t);
	float vw1 = (1 + 2 * t);

	float v0 = ((2 - t) / vw0 - 1)*invShad.y;
	float v1 = (t / vw1 + 1)*invShad.y;
		
	float total = 0.0;
	
	total += uw0*vw0*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v0, baseUVW.z));
	total += uw1*vw0*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v0, baseUVW.z));
	total += uw0*vw1*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v1, baseUVW.z));
	total += uw1*vw1*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v1, baseUVW.z));
	
	total /= 16.0;

#else
float uw0 = (4 - 3 * s);
float uw1 = 7;
float uw2 = (1 + 3 * s);

	float u0 = ((3 - 2 * s) / uw0 - 2)*invShad.x;
	float u1 = ((3 + s) / uw1)*invShad.x;
	float u2 = (s / uw2 + 2)*invShad.x;

	float vw0 = (4 - 3 * t);
	float vw1 = 7;
	float vw2 = (1 + 3 * t);

	float v0 = ((3 - 2 * t) / vw0 - 2)*invShad.y;
	float v1 = ((3 + t) / vw1)*invShad.y;
	float v2 = (t / vw2 + 2)*invShad.y;
	
	float total = 0.0;
	
	total += uw0*vw0*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v0, baseUVW.z));
	total += uw1*vw0*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v0, baseUVW.z));
	total += uw2*vw0*texture(inTexShadow, vec3(baseUV.x+u2, baseUV.y+v0, baseUVW.z));
	total += uw0*vw1*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v1, baseUVW.z));
	total += uw1*vw1*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v1, baseUVW.z));
	total += uw2*vw1*texture(inTexShadow, vec3(baseUV.x+u2, baseUV.y+v1, baseUVW.z));
	total += uw0*vw2*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v2, baseUVW.z));
	total += uw1*vw2*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v2, baseUVW.z));
	total += uw2*vw2*texture(inTexShadow, vec3(baseUV.x+u2, baseUV.y+v2, baseUVW.z));
	
	total /= 144.0;

#endif

	return 1.0-(blend*(1.0-total));
}

return 1.0;

#else
if (blend > 0.0) // So then -1.0 will disable
{
return 1.0-(blend*(1.0-texture(inTexShadow, baseUVW)));
}

return 1.0;

#endif
}

float CALC_ShadowMask_K(){
return CALC_ShadowMask(inShadowTrans[1].w, outPos_KL);
}

#else
float CALC_ShadowMask_K(){ return 1.0; }
#endif

#ifdef SOB_SHADOWS_DUAL
float CALC_ShadowMask_F(){
return CALC_ShadowMask(inShadowTrans[3].w, outPos_FL);
}
#else
float CALC_ShadowMask_F(){ return 1.0; }
#endif

void main()
{
#ifdef SOB_USECLIP
#ifdef PATCH_ALTHYPER
if (outClipD <= 0.0)
{
discard;
}
#endif
#endif

#ifdef SOB_TEAMTEX
vec3 texTeam = texture(inTexTeam, outUV0).xyz;

#ifdef SOB_SCISSOR
	if (texTeam.r < 0.5)
	{
		discard;
	}
#endif

#else
vec3 texTeam = vec3(0.0);
#endif

#ifdef SOB_RESOURCE

//abs(0.5-fract(inTime.x*0.125))*2.0;	// Auto-cycle fade for testing

#ifdef SOB_SALVAGE
float resFade = clamp(1.0-inLifeParams.y, 0.0, 1.0);
resFade *= resFade;		// Curve the burn rate

	#ifdef SOB_DEBRIS
	resFade = 1.0-inFXInfo[0].a;
	#endif
#else
float resFade = inFadeInfo.x;
#endif

float resDelta = inFadeInfo.y;

float fadeWindow = inFadeWindow.x;
float fadeLo = inFadeWindow.y;
float fadeHi = inFadeWindow.z;

#ifdef SOB_SALVAGE
float fadeRange = (fadeHi-fadeLo)+(fadeWindow*2.0);
#else
float fadeRange = (fadeHi-fadeLo)+fadeWindow;
#endif

float fadeProgRaw = texture(inTexProgress, outUV0).r;
float fadeProg = max(fadeProgRaw, fadeLo);
float fadeRes = fadeLo-fadeWindow+(resFade*fadeRange);
float fadeResLim = min(fadeRes, fadeHi);

float texProgress = (fadeProg-fadeResLim)/fadeWindow;

float burnScale = clamp(texProgress*1000.0, 0.0, 1.0);
float texBurn = clamp((1.0-texProgress)*burnScale, 0.0, 1.0);
texBurn *= clamp(1.0-((fadeRes-fadeResLim)/fadeWindow), 0.0, 1.0);
texBurn = pow(texBurn, 0.25);

texProgress = clamp(texProgress, 0.0, 1.0);

#ifdef SOB_SALVAGE
	float fadeScissor = fadeProg-max(fadeLo, fadeResLim);
	if (fadeScissor <= 0.0)
	{
		discard;
	}
#endif

texBurn *= texProgress*4.0;	// 0.5*0.5 = 0.25

#ifdef SOB_DUALINPUT
	vec3 texNorm = mix(texture(inTexNorm, outUV_Norm1).rgb, texture(inTexNorm, outUV_Norm0).rgb, texProgress);
	vec4 texDiff = mix(texture(inTexDiff, outUV_Diff1)*inMulDiff1, texture(inTexDiff, outUV_Diff0)*inMulDiff0, texProgress);
	vec4 texGlowRGB = mix(texture(inTexGlow, outUV_Glow1)*inMulGlow1, texture(inTexGlow, outUV_Glow0)*inMulGlow0, texProgress);
	vec4 texGlow = mix(texture(inTexSpec, outUV_Spec1)*inMulSpec1, texture(inTexSpec, outUV_Spec0)*inMulSpec0, texProgress);
#else
	vec3 texNorm = texture(inTexNorm, outUV0).rgb;
	vec4 texDiff = texture(inTexDiff, outUV0);
	vec4 texGlowRGB = texture(inTexGlow, outUV0);
	vec4 texGlow = texture(inTexSpec, outUV0);
#endif

texNorm = normalize(texNorm*2.0-1.0);

float isPaint = texGlow.g;
texGlow.g = 0.0;

#ifdef SOB_SALVAGE
	float styleDelta = 0.0;		// Deltas make no sense for Salvage
#else
	float styleDelta = inGlowStyle.x;
#endif

float styleBurn = inGlowStyle.y;

float glowDeltScale = mix(1.0, clamp((resDelta-0.25)*1.35, 0.0, 1.0), styleDelta);
float glowBurnScale = mix(1.0, texBurn, styleBurn);
texGlowRGB *= glowDeltScale*glowBurnScale;

#else
#ifdef SOB_THRUSTERS
float thrust = inColEngine.x;

	vec4 texDiffOn = texture(inTexDiffOn, outUV0);
	vec4 texGlowOn = texture(inTexGlowOn, outUV0);
	vec4 texDiffOff = texture(inTexDiffOff, outUV0);
	vec4 texGlowOff = texture(inTexGlowOff, outUV0);
	
	vec4 texDiff = mix(texDiffOff, texDiffOn, thrust);
	vec4 texGlow = mix(texGlowOff, texGlowOn, thrust);
#else
	vec4 texDiff = texture(inTexDiff, outUV0);
	vec4 texGlow = texture(inTexGlow, outUV0);
	
	#ifdef SOB_GLOWRGB
		vec4 texGlowRGB = texGlow;
		texGlow = texture(inTexSpec, outUV0);
		texGlow.g = 1.0;
	#endif
#endif

vec3 texNorm = normalize(texture(inTexNorm, outUV0).rgb*2.0-1.0);

#ifdef SOB_TEAM	
	float isPaint = texTeam.r*texTeam.g*(1.0-texTeam.b);
#else
	float isPaint = 1.0-texTeam.b;
#endif

#endif

// Normal and Eye to Pos in World Space

#ifdef NO_NORMAL_MAP
vec3 worldNorm = normalize(mat3(inMatM)*vec3(outNorm));
#else
vec3 tempTW = mat3(outTan, outBiNorm, outNorm)*texNorm;
vec3 worldNorm = normalize(mat3(inMatM)*tempTW);
#endif

float shadowMask_K = CALC_ShadowMask_K();
float shadowMask_F = CALC_ShadowMask_F();

#ifdef SOB_BADGE
vec4 texBadge = texture(inTexBadge, outUV1);
texGlow.b = mix(texGlow.b, 0.15, texBadge.a0.35);
texGlow.r = mix(texGlow.r, 0.1, texBadge.a
0.35);
isPaint *= 1.0-texBadge.a;
#endif

// Paint and Other map channels
isPaint = 1.0-isPaint;
float mapSpecSharp = texGlow.r;
float mapGlowMask = texGlow.g;
float mapSpecMask = max(0.0, texGlow.b-texGlow.g);

vec3 worldEye = normalize(outEye_W);
float worldDist = length(outEye_W);

#ifdef SOB_2SIDED
if (false == gl_FrontFacing)
{
worldNorm = -worldNorm;
}
#endif

// Diffuse
float extDiffFren = inSurfDiff.y;

// Glow
float extGlowPower = inSurfGlow.x;
float extGlowFren = inSurfGlow.y;

// Specular
float extSpecPower = inSurfSpec.x;
float extSpecFren = inSurfSpec.y;
float extSpecCurve = inSurfSpec.z;

// Paint Gloss
float extPaintCurve = inSurfPaint.x;
float extPaintScale = inSurfPaint.y;
float extPaintBias = inSurfPaint.z;
float extPaintDim = inSurfPaint.w;

// Gloss
float extGlossCurve = inSurfGloss.x+(extPaintCurve*isPaint);
float extGlossScale = inSurfGloss.y+(extPaintScale*isPaint);
float extGlossBias = inSurfGloss.z+(extPaintBias*isPaint);

extSpecPower = mix(extSpecPower, extSpecPower*extPaintDim, isPaint);

float specGloss = max(1.0, pow(mapSpecSharp, extGlossCurve)*extGlossScale)+extGlossBias;
float pointGloss = max(1.0, specGloss*0.25);

// Reflections
float extReflPower = inSurfRefl.x;
float extReflFren = inSurfRefl.y;
float extReflAddMix = inSurfRefl.z;

// Fresnel
float extFrenPower = inSurfFren.x;
float extFrenBias = inSurfFren.y;
float extFrenCurve = inSurfFren.z;
float frenDeg = clamp(pow(extFrenBias*(1.0-abs(dot(worldNorm, worldEye))), extFrenCurve)*extFrenPower, 0.0, 1.0);

// Map Channel * Powers
float peakStrength = 1.0+(mix(inSurfPeak.x, inSurfPeak.y, isPaint)*mix(1.0, inSurfPeak.z, frenDeg));
float glowStrength = mapGlowMask*max(0.0, extGlowPower-(extGlowFren*frenDeg));
float specRawStrength = mapSpecMask*extSpecPower;
float specStrength = mix(specRawStrength, 1.0, frenDeg*mapSpecSharp*extSpecFren);
float reflStrength = mix(mapSpecMask*extReflPower, 1.0, frenDeg*mapSpecSharp*extReflFren);

// Time to get painted (paint + diffuse curves logic)
float paintCurve = inPaintStyle.x;
float paintDarkScale = inPaintStyle.y;
float paintDarkOfs = inPaintStyle.z;
vec4 paintBase = mix(vec4(0.5, 0.5, 0.5, 1.0), texDiff, paintCurve);

#ifdef SOB_TEAM
// Base paint calc - paint, stripe, team, etc…
vec4 paint = mix(inColTeam, paintBase, texTeam.r);
paint = mix(inColStripe, paint, texTeam.g);

#ifdef SOB_BADGE
vec4 lumMap = vec4(0.299, 0.587, 0.114, 0.0);
vec4 diffLum = vec4(texDiff.r, texDiff.g, texDiff.b, dot(texDiff, lumMap));
vec4 d_hi = clamp(((diffLum2.0)-1.0), 0.0, 1.0);
vec4 d_lo = clamp(((diffLum
paintDarkScale)-paintDarkOfs), 0.0, 1.0); // Slight overdark for badge contouring
paint = mix(d_lopaint, vec4(1.0), d_hi);
diffLum.rgb = d_lo.w
texBadge.rgb;
d_lo = mix(diffLum, vec4(1.0), d_hi.w);
paint = mix(paint, d_lo, texBadge.a);
#else
vec4 d_hi = clamp(((texDiff2.0)-1.0), 0.0, 1.0);
vec4 d_lo = clamp(((texDiff
paintDarkScale)-paintDarkOfs), 0.0, 1.0);
paint = mix(d_lo*paint, vec4(1.0), d_hi);
#endif

#else
vec4 d_hi = clamp(((texDiff2.0)-1.0), 0.0, 1.0);
vec4 d_lo = clamp(((texDiff
paintDarkScale)-paintDarkOfs), 0.0, 1.0);
vec4 paint = mix(d_lo*paintBase, vec4(1.0), d_hi);
#endif

float diffStrength = max(0.0, 1.0-specRawStrength);
diffStrength = pow(diffStrength, 1.0-(frenDeg*extDiffFren));

#ifdef SOB_GLOWRGB
vec3 diffRGB = paint.rgb;
vec3 glowRGB = texGlowRGB.rgb0.8;
#else
vec3 diffRGB = paint.rgb
((1.0-mapGlowMask)diffStrength);
vec3 glowRGB = paint.rgb
mapGlowMask;
#endif

glowRGB *= glowStrength;

// Seed lighting with Ambient+Black
vec3 diffAll = inLightCore[0].rgb;
vec3 specAll = vec3(0,0,0);
	
// Key Light
vec3 litNorm = normalize(inLightCore[1].rgb);
vec3 holdLit_K = litNorm;

#ifndef SOB_BAYLIGHT
float litDif = clamp(dot(litNorm, worldNorm), 0.0, 1.0);
vec3 litRefl = reflect(-litNorm, worldNorm);
float litSpec = clamp(dot(-worldEye, litRefl), 0.0, 1.0)peakStrength;
litSpec = pow(litSpec, specGloss)min(litDif1000, 1.0);
diffAll += shadowMask_K
inLightCore[2].rgblitDif;
specAll += shadowMask_K
inLightCore[3].rgb*litSpec;

// Fill Light
litNorm = normalize(inLightCore[4].rgb);
vec3 holdLit_F = litNorm;
litDif = clamp(dot(litNorm, worldNorm), 0.0, 1.0);
litRefl = reflect(-litNorm, worldNorm);
litSpec = clamp(dot(-worldEye, litRefl), 0.0, 1.0)*peakStrength;
litSpec = pow(litSpec, specGloss)*min(litDif*1000, 1.0);
diffAll += shadowMask_F*inLightCore[5].rgb*litDif;
specAll += shadowMask_F*inLightCore[6].rgb*litSpec;

// Point lights...
int inP = inLightCounts.x;	// Points?
int inL = 0;
for (; inL<inP; inL++)
{
	int inS = inL*3;
	vec3 litVec = inLightShip[inS].rgb-outPos_W;
	vec3 atenVec = vec3(inLightShip[inS].w, inLightShip[inS+1].w, inLightShip[inS+2].w);
	float litLen = length(litVec);
	litVec = normalize(litVec);
	litDif = clamp(dot(litVec, worldNorm), 0.0, 1.0);
	float atenVal = 1.0/(atenVec.x+(atenVec.y*litLen)+(atenVec.z*litLen*litLen));
	diffAll.rgb += inLightShip[inS+1].rgb*litDif*atenVal*2.0;

	float subSpec = clamp(dot(-worldEye, reflect(-litVec, worldNorm)), 0.0, 1.0)*peakStrength;
	subSpec = pow(subSpec, pointGloss)*min(litDif*1000, 1.0);
	specAll.rgb += inLightShip[inS+2].rgb*subSpec*atenVal*2.0;
}

#else
diffAll = vec3(1.0, 1.0, 1.0);
#endif

#ifdef SOB_LIGHT_HQ
vec3 beamDif = vec3(0.0f);
vec3 beamSpec = vec3(0.0f);

float beamGloss = max(1.0, specGloss*0.75);

int inB = inLightCounts.x+inLightCounts.y;	// Beams?
for (; inL<inB; inL++)
{
	int inS = inL*3;
	
	vec3 beamHead = inLightShip[inS].xyz;
	float beamLen = inLightShip[inS].w;
	vec3 beamAxis = inLightShip[inS+1].xyz;
	float beamOORad = inLightShip[inS+1].w;
	vec3 beamRGB = inLightShip[inS+2].rgb;
	float beamCurve = inLightShip[inS+2].w;
	
	// Determine the closest on-beam point
	vec3 sepOfs = outPos_W-beamHead;
	float sepA = clamp(dot(sepOfs, beamAxis), 0.0, beamLen);
	vec3 litPos = beamHead+(beamAxis*sepA);
	
	// Gather angle/distance
	vec3 litVec = litPos-outPos_W;
	float litLen = length(litVec);
	litVec = normalize(litVec);
	
	// Attenuate for distance
	float atenVal = pow(1.0-min(litLen*beamOORad, 1.0), beamCurve)*2.0;	// *2 to adjust for HW old headroom
	
	// Bias diffuse angle due to co-incidence with beam 
	float litBias = abs(dot(worldNorm, beamAxis));
	litDif = clamp(dot(worldNorm, litVec), 0.0, 1.0);
	litDif = mix(litDif, 1.0, litBias);
	
	vec3 subRefl = reflect(-litVec, worldNorm);
	float subSpec = max(dot(-worldEye, subRefl), 0.0);
	float subBoost = abs(dot(inLightShip[inS+1].rgb, subRefl));	// Reflection along beam axis?
	subSpec = min(subSpec*(1.0+(subBoost*0.25)), 1.0)*peakStrength;
	subSpec = pow(subSpec, beamGloss)*min(litDif*1000, 1.0);
	
	beamDif += beamRGB*litDif*atenVal;
	beamSpec += inLightShip[inS+2].rgb*subSpec*atenVal;
}

diffAll += beamDif;
specAll += beamSpec;

//diffAll = beamDif;
//specAll = beamSpec;

#endif

// Apply final lighting 
paint.rgb = (diffRGB*diffAll)+glowRGB+(specAll*specStrength);

#ifndef SOB_BAYLIGHT
// Add reflections
vec3 envNorm = reflect(worldEye, worldNorm);
vec4 texE0 = texture(inTexEnv0, envNorm);
vec4 texE1 = texture(inTexEnv1, envNorm);
vec4 reflTex = mix(texE0, texE1, mapSpecSharp);

#ifdef SOB_SHADOWS_ON
float envMask = 1.0-(max((dot(envNorm,holdLit_K)5.0)-4.0, 0.0)(1.0-shadowMask_K));

#ifdef SOB_SHADOWS_DUAL
	envMask *= 1.0-(max((dot(envNorm,holdLit_F)*5.0)-4.0, 0.0)*(1.0-shadowMask_F));
#endif

#else
float envMask = 1.0;
#endif

float reflDeg = reflStrength*reflTex.a*inBGEnvParams.r*envMask;
float reflAdd = extReflAddMix;
float reflAlpha = 1.0-reflAdd;

reflTex.rgb += inBGAddLight.rgb;

paint.rgb += reflTex.rgb*reflDeg*reflAdd;
paint.rgb = mix(paint.rgb, reflTex.rgb, reflDeg*reflAlpha);

#endif

paint.a = inSOBParams.x;

#ifdef SOB_TEAM
if (inSOBParams.y > 0.0)
{
float frenCloak = pow((1.0-abs(dot(worldNorm, worldEye)))*1.06, 2.0)*2.0-1.0;

	if (frenCloak > 0.0)
	{
		vec3 noisePos = outPos_W.xyz*0.05;
		vec3 timePos = holdLit_K*(inTime.z*2.0);
		float cloakNoise = HELP_Noise3(noisePos+timePos)*0.5+1.5;
		frenCloak = clamp(frenCloak*cloakNoise*0.5, 0.0, 1.0);
	}
	
	float cloakPaint = 1.0-(0.5*inSOBParams.y);
	paint.rgb = (paint.rgb*cloakPaint)+vec3(max(frenCloak, 0.0)*inSOBParams.y*1.5);
}

#endif

#ifndef SOB_DEBRIS
// UI Effect (glow, etc)
paint.rgb += vec3(inColEffect)*inColEffect.a;
#endif

paint.rgb = pow(paint.rgb, vec3(inGammaScale))*inGammaScale.a;

#ifdef SOB_USECLIP
vec3 hyperSpace = vec3(inGammaScale.a);

if (false == gl_FrontFacing)
{
	paint.rgb = hyperSpace;
}
else
{

#ifdef PATCH_ALTHYPER
float hyperEdge = outClipD*0.02;
#else
float hyperEdge = gl_ClipDistance[0]0.02;
#endif
if (hyperEdge < 1.0)
{
vec3 planeScales = vec3(1.5)+(abs(inClipPlane.xyz)20.0);
vec3 noisePos = outPos_W.xyz/planeScales;
vec3 timePos = inClipPlane.xyz
(inTime.z
2.0);

		float hyperNoise = HELP_Noise3(noisePos+timePos)*0.5+1.5;
		hyperEdge = 1.0-clamp(hyperEdge*hyperNoise, 0.0, 1.0);
		hyperEdge = min(pow(hyperEdge*1.1, 5.0)/1.2, 1.0);
		
		paint.rgb = mix(paint.rgb, hyperSpace, hyperEdge*inSOBParams.z);
	}
}

#endif

float maxFog = inFogColor.a*inFogColor.w;
if (maxFog > 0.0)
{
	float useFog = clamp((worldDist-inFogWindow.x)/(inFogWindow.z-inFogWindow.x), inFogWindow.y, inFogWindow.w);
	paint.rgb = mix(paint.rgb, inFogColor.rgb, useFog*inFogColor.a);
}

paint *= getShipExp();

#ifdef SOB_BAYLIGHT
paint *= getBayExp();
#endif

// Enable to show 'bad UV' patches (as magenta)
//vec2 delUV = vec2(dFdx(outUV0.x), dFdy(outUV0.y));
//float delD = 1.0-min(1.0, length(delUV)*1000000.0);
//paint.rgb = mix(paint.rgb, vec3(delD, 0.0, delD), delD);

#ifdef SOB_ALPHA
paint.a *= texTeam.r;
#endif

finalCol0 = paint;

}
smooth in vec2 outUV0;
smooth in vec3 outNorm;
smooth in vec3 outTan;
smooth in vec3 outBiNorm;
smooth in vec3 outPos_W;
smooth in vec3 outEye_W;

#ifdef SOB_SHADOWS_ON
smooth in vec3 outPos_KL;
uniform sampler2DShadow inTexShadow;
uniform vec4 inShadowTrans[4];
#ifdef SOB_SHADOWS_DUAL
smooth in vec3 outPos_FL;
#endif
#endif

uniform vec4 inTime;

#ifdef SOB_BADGE
smooth in vec2 outUV1;
uniform sampler2D inTexBadge;
#endif

#ifdef SOB_THRUSTERS
uniform sampler2D inTexDiffOn;
uniform sampler2D inTexGlowOn;
uniform sampler2D inTexDiffOff;
uniform sampler2D inTexGlowOff;
uniform vec4 inColEngine;
#else
uniform sampler2D inTexDiff;
uniform sampler2D inTexGlow;
#ifdef SOB_GLOWRGB
uniform sampler2D inTexSpec;
#endif
#endif

#ifdef SOB_RESOURCE
uniform sampler2D inTexProgress;
uniform vec2 inFadeInfo;
uniform vec3 inFadeWindow;
uniform vec4 inGlowStyle;

#ifdef SOB_DUALINPUT
uniform vec4 inMulDiff0;
uniform vec4 inMulDiff1;
uniform vec4 inMulGlow0;
uniform vec4 inMulGlow1;
uniform vec4 inMulSpec0;
uniform vec4 inMulSpec1;
smooth in vec2 outUV_Diff0;
smooth in vec2 outUV_Glow0;
smooth in vec2 outUV_Spec0;
smooth in vec2 outUV_Norm0;
smooth in vec2 outUV_Diff1;
smooth in vec2 outUV_Glow1;
smooth in vec2 outUV_Spec1;
smooth in vec2 outUV_Norm1;
#endif

#ifdef SOB_DEBRIS
uniform vec4 inFXInfo[2];
#endif

#endif

#ifdef SOB_TEAMTEX
uniform sampler2D inTexTeam;
#endif

uniform sampler2D inTexNorm;
uniform samplerCube inTexEnv0;
uniform samplerCube inTexEnv1;

#ifdef SOB_USECLIP
uniform vec4 inClipPlane;

#ifdef PATCH_ALTHYPER
	smooth in float outClipD;
#endif

#endif

uniform vec4 inSOBParams;
uniform vec4 inLifeParams;

uniform vec4 inFogColor;
uniform vec4 inFogWindow;

uniform mat4 inMatM;

#ifdef SOB_TEAM
uniform vec4 inColTeam;
uniform vec4 inColStripe;
#endif

#ifndef SOB_DEBRIS
uniform vec4 inColEffect;
#endif

uniform vec4 inSurfDiff;
uniform vec4 inSurfGlow;
uniform vec4 inSurfSpec;
uniform vec4 inSurfGloss;
uniform vec4 inSurfRefl;
uniform vec4 inSurfFren;
uniform vec4 inSurfPaint;
uniform vec4 inSurfPeak;

uniform vec4 inPaintStyle;

uniform vec4 inGammaScale;
uniform vec4 inBGAddLight;
uniform vec4 inBGEnvParams;

#ifdef SOB_BAYLIGHT

uniform vec4 inBayExps;	//br, bR, Br, BR

#ifdef SOB_POST_B0R0
vec4 getBayExp(){ return vec4(inBayExps.x, inBayExps.x, inBayExps.x, 1.0f); }
#endif

#ifdef SOB_POST_B0R1
vec4 getBayExp(){ return vec4(inBayExps.y, inBayExps.y, inBayExps.y, 1.0f); }
#endif

#ifdef SOB_POST_B1R0
vec4 getBayExp(){ return vec4(inBayExps.z, inBayExps.z, inBayExps.z, 1.0f); }
#endif

#ifdef SOB_POST_B1R1
vec4 getBayExp(){ return vec4(inBayExps.w, inBayExps.w, inBayExps.w, 1.0f); }
#endif

#endif

uniform ivec2 inLightCounts;
uniform vec4 inLightShip[96]; // Pos/Diff/Spec (or just Pos/Diff) + attenuations in W
uniform vec4 inLightCore[7];

layout (location = 0) out vec4 finalCol0;

#ifdef SOB_SHADOWS_ON

ivec2 shadWH = textureSize(inTexShadow, 0);
vec2 invShad = vec2(1.0/shadWH.x, 1.0/shadWH.y);

float CALC_ShadowMask(float blend, vec3 baseUVW){
#ifdef SOB_SHADOWS_HQ
if (blend > 0.0)
{
vec2 texelUV = baseUVW.xy*shadWH;
vec2 baseUV = vec2(floor(texelUV.x+0.5), floor(texelUV.y+0.5));
float s = texelUV.x+0.5-baseUV.x;
float t = texelUV.y+0.5-baseUV.y;
baseUV -= vec2(0.5);
baseUV *= invShad;

#define SOB_SHADOWS_3X3 1
#ifdef SOB_SHADOWS_3X3
float uw0 = (3 - 2 * s);
float uw1 = (1 + 2 * s);

	float u0 = ((2 - s) / uw0 - 1)*invShad.x;
	float u1 = (s / uw1 + 1)*invShad.x;

	float vw0 = (3 - 2 * t);
	float vw1 = (1 + 2 * t);

	float v0 = ((2 - t) / vw0 - 1)*invShad.y;
	float v1 = (t / vw1 + 1)*invShad.y;
		
	float total = 0.0;
	
	total += uw0*vw0*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v0, baseUVW.z));
	total += uw1*vw0*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v0, baseUVW.z));
	total += uw0*vw1*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v1, baseUVW.z));
	total += uw1*vw1*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v1, baseUVW.z));
	
	total /= 16.0;

#else
float uw0 = (4 - 3 * s);
float uw1 = 7;
float uw2 = (1 + 3 * s);

	float u0 = ((3 - 2 * s) / uw0 - 2)*invShad.x;
	float u1 = ((3 + s) / uw1)*invShad.x;
	float u2 = (s / uw2 + 2)*invShad.x;

	float vw0 = (4 - 3 * t);
	float vw1 = 7;
	float vw2 = (1 + 3 * t);

	float v0 = ((3 - 2 * t) / vw0 - 2)*invShad.y;
	float v1 = ((3 + t) / vw1)*invShad.y;
	float v2 = (t / vw2 + 2)*invShad.y;
	
	float total = 0.0;
	
	total += uw0*vw0*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v0, baseUVW.z));
	total += uw1*vw0*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v0, baseUVW.z));
	total += uw2*vw0*texture(inTexShadow, vec3(baseUV.x+u2, baseUV.y+v0, baseUVW.z));
	total += uw0*vw1*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v1, baseUVW.z));
	total += uw1*vw1*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v1, baseUVW.z));
	total += uw2*vw1*texture(inTexShadow, vec3(baseUV.x+u2, baseUV.y+v1, baseUVW.z));
	total += uw0*vw2*texture(inTexShadow, vec3(baseUV.x+u0, baseUV.y+v2, baseUVW.z));
	total += uw1*vw2*texture(inTexShadow, vec3(baseUV.x+u1, baseUV.y+v2, baseUVW.z));
	total += uw2*vw2*texture(inTexShadow, vec3(baseUV.x+u2, baseUV.y+v2, baseUVW.z));
	
	total /= 144.0;

#endif

	return 1.0-(blend*(1.0-total));
}

return 1.0;

#else
if (blend > 0.0) // So then -1.0 will disable
{
return 1.0-(blend*(1.0-texture(inTexShadow, baseUVW)));
}

return 1.0;

#endif
}

float CALC_ShadowMask_K(){
return CALC_ShadowMask(inShadowTrans[1].w, outPos_KL);
}

#else
float CALC_ShadowMask_K(){ return 1.0; }
#endif

#ifdef SOB_SHADOWS_DUAL
float CALC_ShadowMask_F(){
return CALC_ShadowMask(inShadowTrans[3].w, outPos_FL);
}
#else
float CALC_ShadowMask_F(){ return 1.0; }
#endif

void main()
{
#ifdef SOB_USECLIP
#ifdef PATCH_ALTHYPER
if (outClipD <= 0.0)
{
discard;
}
#endif
#endif

#ifdef SOB_TEAMTEX
vec3 texTeam = texture(inTexTeam, outUV0).xyz;

#ifdef SOB_SCISSOR
	if (texTeam.r < 0.5)
	{
		discard;
	}
#endif

#else
vec3 texTeam = vec3(0.0);
#endif

#ifdef SOB_RESOURCE

//abs(0.5-fract(inTime.x*0.125))*2.0;	// Auto-cycle fade for testing

#ifdef SOB_SALVAGE
float resFade = clamp(1.0-inLifeParams.y, 0.0, 1.0);
resFade *= resFade;		// Curve the burn rate

	#ifdef SOB_DEBRIS
	resFade = 1.0-inFXInfo[0].a;
	#endif
#else
float resFade = inFadeInfo.x;
#endif

float resDelta = inFadeInfo.y;

float fadeWindow = inFadeWindow.x;
float fadeLo = inFadeWindow.y;
float fadeHi = inFadeWindow.z;

#ifdef SOB_SALVAGE
float fadeRange = (fadeHi-fadeLo)+(fadeWindow*2.0);
#else
float fadeRange = (fadeHi-fadeLo)+fadeWindow;
#endif

float fadeProgRaw = texture(inTexProgress, outUV0).r;
float fadeProg = max(fadeProgRaw, fadeLo);
float fadeRes = fadeLo-fadeWindow+(resFade*fadeRange);
float fadeResLim = min(fadeRes, fadeHi);

float texProgress = (fadeProg-fadeResLim)/fadeWindow;

float burnScale = clamp(texProgress*1000.0, 0.0, 1.0);
float texBurn = clamp((1.0-texProgress)*burnScale, 0.0, 1.0);
texBurn *= clamp(1.0-((fadeRes-fadeResLim)/fadeWindow), 0.0, 1.0);
texBurn = pow(texBurn, 0.25);

texProgress = clamp(texProgress, 0.0, 1.0);

#ifdef SOB_SALVAGE
	float fadeScissor = fadeProg-max(fadeLo, fadeResLim);
	if (fadeScissor <= 0.0)
	{
		discard;
	}
#endif

texBurn *= texProgress*4.0;	// 0.5*0.5 = 0.25

#ifdef SOB_DUALINPUT
	vec3 texNorm = mix(texture(inTexNorm, outUV_Norm1).rgb, texture(inTexNorm, outUV_Norm0).rgb, texProgress);
	vec4 texDiff = mix(texture(inTexDiff, outUV_Diff1)*inMulDiff1, texture(inTexDiff, outUV_Diff0)*inMulDiff0, texProgress);
	vec4 texGlowRGB = mix(texture(inTexGlow, outUV_Glow1)*inMulGlow1, texture(inTexGlow, outUV_Glow0)*inMulGlow0, texProgress);
	vec4 texGlow = mix(texture(inTexSpec, outUV_Spec1)*inMulSpec1, texture(inTexSpec, outUV_Spec0)*inMulSpec0, texProgress);
#else
	vec3 texNorm = texture(inTexNorm, outUV0).rgb;
	vec4 texDiff = texture(inTexDiff, outUV0);
	vec4 texGlowRGB = texture(inTexGlow, outUV0);
	vec4 texGlow = texture(inTexSpec, outUV0);
#endif

texNorm = normalize(texNorm*2.0-1.0);

float isPaint = texGlow.g;
texGlow.g = 1.0;

#ifdef SOB_SALVAGE
	float styleDelta = 0.0;		// Deltas make no sense for Salvage
#else
	float styleDelta = inGlowStyle.x;
#endif

float styleBurn = inGlowStyle.y;

float glowDeltScale = mix(1.0, clamp((resDelta-0.25)*1.35, 0.0, 1.0), styleDelta);
float glowBurnScale = mix(1.0, texBurn, styleBurn);
texGlowRGB *= glowDeltScale*glowBurnScale;

#else
#ifdef SOB_THRUSTERS
float thrust = inColEngine.x;

	vec4 texDiffOn = texture(inTexDiffOn, outUV0);
	vec4 texGlowOn = texture(inTexGlowOn, outUV0);
	vec4 texDiffOff = texture(inTexDiffOff, outUV0);
	vec4 texGlowOff = texture(inTexGlowOff, outUV0);
	
	vec4 texDiff = mix(texDiffOff, texDiffOn, thrust);
	vec4 texGlow = mix(texGlowOff, texGlowOn, thrust);
#else
	vec4 texDiff = texture(inTexDiff, outUV0);
	vec4 texGlow = texture(inTexGlow, outUV0);
	
	#ifdef SOB_GLOWRGB
		vec4 texGlowRGB = texGlow;
		texGlow = texture(inTexSpec, outUV0);
		texGlow.g = 1.0;
	#endif
#endif

vec3 texNorm = normalize(texture(inTexNorm, outUV0).rgb*2.0-1.0);

#ifdef SOB_TEAM	
	float isPaint = texTeam.r*texTeam.g*(1.0-texTeam.b);
#else
	float isPaint = 1.0-texTeam.b;
#endif

#endif

// Normal and Eye to Pos in World Space

#ifdef NO_NORMAL_MAP
vec3 worldNorm = normalize(mat3(inMatM)*vec3(outNorm));
#else
vec3 tempTW = mat3(outTan, outBiNorm, outNorm)*texNorm;
vec3 worldNorm = normalize(mat3(inMatM)*tempTW);
#endif

float shadowMask_K = CALC_ShadowMask_K();
float shadowMask_F = CALC_ShadowMask_F();

#ifdef SOB_BADGE
vec4 texBadge = texture(inTexBadge, outUV1);
texGlow.b = mix(texGlow.b, 0.15, texBadge.a0.35);
texGlow.r = mix(texGlow.r, 0.1, texBadge.a
0.35);
isPaint *= 1.0-texBadge.a;
#endif

// Paint and Other map channels
isPaint = 1.0-isPaint;
float mapSpecSharp = texGlow.r;
float mapGlowMask = texGlow.g;
float mapSpecMask = max(0.0, texGlow.b-texGlow.g);

vec3 worldEye = normalize(outEye_W);
float worldDist = length(outEye_W);

#ifdef SOB_2SIDED
if (false == gl_FrontFacing)
{
worldNorm = -worldNorm;
}
#endif

// Diffuse
float extDiffFren = inSurfDiff.y;

// Glow
float extGlowPower = inSurfGlow.x;
float extGlowFren = inSurfGlow.y;

// Specular
float extSpecPower = inSurfSpec.x;
float extSpecFren = inSurfSpec.y;
float extSpecCurve = inSurfSpec.z;

// Paint Gloss
float extPaintCurve = inSurfPaint.x;
float extPaintScale = inSurfPaint.y;
float extPaintBias = inSurfPaint.z;
float extPaintDim = inSurfPaint.w;

// Gloss
float extGlossCurve = inSurfGloss.x+(extPaintCurve*isPaint);
float extGlossScale = inSurfGloss.y+(extPaintScale*isPaint);
float extGlossBias = inSurfGloss.z+(extPaintBias*isPaint);

extSpecPower = mix(extSpecPower, extSpecPower*extPaintDim, isPaint);

float specGloss = max(1.0, pow(mapSpecSharp, extGlossCurve)*extGlossScale)+extGlossBias;
float pointGloss = max(1.0, specGloss*0.25);

// Reflections
float extReflPower = inSurfRefl.x;
float extReflFren = inSurfRefl.y;
float extReflAddMix = inSurfRefl.z;

// Fresnel
float extFrenPower = inSurfFren.x;
float extFrenBias = inSurfFren.y;
float extFrenCurve = inSurfFren.z;
float frenDeg = clamp(pow(extFrenBias*(1.0-abs(dot(worldNorm, worldEye))), extFrenCurve)*extFrenPower, 0.0, 1.0);

// Map Channel * Powers
float peakStrength = 1.0+(mix(inSurfPeak.x, inSurfPeak.y, isPaint)*mix(1.0, inSurfPeak.z, frenDeg));
float glowStrength = mapGlowMask*max(0.0, extGlowPower-(extGlowFren*frenDeg));
float specRawStrength = mapSpecMask*extSpecPower;
float specStrength = mix(specRawStrength, 1.0, frenDeg*mapSpecSharp*extSpecFren);
float reflStrength = mix(mapSpecMask*extReflPower, 1.0, frenDeg*mapSpecSharp*extReflFren);

// Time to get painted (paint + diffuse curves logic)
float paintCurve = inPaintStyle.x;
float paintDarkScale = inPaintStyle.y;
float paintDarkOfs = inPaintStyle.z;
vec4 paintBase = mix(vec4(0.5, 0.5, 0.5, 1.0), texDiff, paintCurve);

#ifdef SOB_TEAM
// Base paint calc - paint, stripe, team, etc…
vec4 paint = mix(inColTeam, paintBase, texTeam.r);
paint = mix(inColStripe, paint, texTeam.g);

#ifdef SOB_BADGE
vec4 lumMap = vec4(0.299, 0.587, 0.114, 0.0);
vec4 diffLum = vec4(texDiff.r, texDiff.g, texDiff.b, dot(texDiff, lumMap));
vec4 d_hi = clamp(((diffLum2.0)-1.0), 0.0, 1.0);
vec4 d_lo = clamp(((diffLum
paintDarkScale)-paintDarkOfs), 0.0, 1.0); // Slight overdark for badge contouring
paint = mix(d_lopaint, vec4(1.0), d_hi);
diffLum.rgb = d_lo.w
texBadge.rgb;
d_lo = mix(diffLum, vec4(1.0), d_hi.w);
paint = mix(paint, d_lo, texBadge.a);
#else
vec4 d_hi = clamp(((texDiff2.0)-1.0), 0.0, 1.0);
vec4 d_lo = clamp(((texDiff
paintDarkScale)-paintDarkOfs), 0.0, 1.0);
paint = mix(d_lo*paint, vec4(1.0), d_hi);
#endif

#else
vec4 d_hi = clamp(((texDiff2.0)-1.0), 0.0, 1.0);
vec4 d_lo = clamp(((texDiff
paintDarkScale)-paintDarkOfs), 0.0, 1.0);
vec4 paint = mix(d_lo*paintBase, vec4(1.0), d_hi);
#endif

float diffStrength = max(0.0, 1.0-specRawStrength);
diffStrength = pow(diffStrength, 1.0-(frenDeg*extDiffFren));

#ifdef SOB_GLOWRGB
vec3 diffRGB = paint.rgb;
vec3 glowRGB = texGlowRGB.rgb0.8;
#else
vec3 diffRGB = paint.rgb
((1.0-mapGlowMask)diffStrength);
vec3 glowRGB = paint.rgb
mapGlowMask;
#endif

glowRGB *= glowStrength;

// Seed lighting with Ambient+Black
vec3 diffAll = inLightCore[0].rgb;
vec3 specAll = vec3(0,0,0);
	
// Key Light
vec3 litNorm = normalize(inLightCore[1].rgb);
vec3 holdLit_K = litNorm;

#ifndef SOB_BAYLIGHT
float litDif = clamp(dot(litNorm, worldNorm), 0.0, 1.0);
vec3 litRefl = reflect(-litNorm, worldNorm);
float litSpec = clamp(dot(-worldEye, litRefl), 0.0, 1.0)peakStrength;
litSpec = pow(litSpec, specGloss)min(litDif1000, 1.0);
diffAll += shadowMask_K
inLightCore[2].rgblitDif;
specAll += shadowMask_K
inLightCore[3].rgb*litSpec;

// Fill Light
litNorm = normalize(inLightCore[4].rgb);
vec3 holdLit_F = litNorm;
litDif = clamp(dot(litNorm, worldNorm), 0.0, 1.0);
litRefl = reflect(-litNorm, worldNorm);
litSpec = clamp(dot(-worldEye, litRefl), 0.0, 1.0)*peakStrength;
litSpec = pow(litSpec, specGloss)*min(litDif*1000, 1.0);
diffAll += shadowMask_F*inLightCore[5].rgb*litDif;
specAll += shadowMask_F*inLightCore[6].rgb*litSpec;

// Point lights...
int inP = inLightCounts.x;	// Points?
int inL = 0;
for (; inL<inP; inL++)
{
	int inS = inL*3;
	vec3 litVec = inLightShip[inS].rgb-outPos_W;
	vec3 atenVec = vec3(inLightShip[inS].w, inLightShip[inS+1].w, inLightShip[inS+2].w);
	float litLen = length(litVec);
	litVec = normalize(litVec);
	litDif = clamp(dot(litVec, worldNorm), 0.0, 1.0);
	float atenVal = 1.0/(atenVec.x+(atenVec.y*litLen)+(atenVec.z*litLen*litLen));
	diffAll.rgb += inLightShip[inS+1].rgb*litDif*atenVal*2.0;

	float subSpec = clamp(dot(-worldEye, reflect(-litVec, worldNorm)), 0.0, 1.0)*peakStrength;
	subSpec = pow(subSpec, pointGloss)*min(litDif*1000, 1.0);
	specAll.rgb += inLightShip[inS+2].rgb*subSpec*atenVal*2.0;
}

#else
diffAll = vec3(1.0, 1.0, 1.0);
#endif

#ifdef SOB_LIGHT_HQ
vec3 beamDif = vec3(0.0f);
vec3 beamSpec = vec3(0.0f);

float beamGloss = max(1.0, specGloss*0.75);

int inB = inLightCounts.x+inLightCounts.y;	// Beams?
for (; inL<inB; inL++)
{
	int inS = inL*3;
	
	vec3 beamHead = inLightShip[inS].xyz;
	float beamLen = inLightShip[inS].w;
	vec3 beamAxis = inLightShip[inS+1].xyz;
	float beamOORad = inLightShip[inS+1].w;
	vec3 beamRGB = inLightShip[inS+2].rgb;
	float beamCurve = inLightShip[inS+2].w;
	
	// Determine the closest on-beam point
	vec3 sepOfs = outPos_W-beamHead;
	float sepA = clamp(dot(sepOfs, beamAxis), 0.0, beamLen);
	vec3 litPos = beamHead+(beamAxis*sepA);
	
	// Gather angle/distance
	vec3 litVec = litPos-outPos_W;
	float litLen = length(litVec);
	litVec = normalize(litVec);
	
	// Attenuate for distance
	float atenVal = pow(1.0-min(litLen*beamOORad, 1.0), beamCurve)*2.0;	// *2 to adjust for HW old headroom
	
	// Bias diffuse angle due to co-incidence with beam 
	float litBias = abs(dot(worldNorm, beamAxis));
	litDif = clamp(dot(worldNorm, litVec), 0.0, 1.0);
	litDif = mix(litDif, 1.0, litBias);
	
	vec3 subRefl = reflect(-litVec, worldNorm);
	float subSpec = max(dot(-worldEye, subRefl), 0.0);
	float subBoost = abs(dot(inLightShip[inS+1].rgb, subRefl));	// Reflection along beam axis?
	subSpec = min(subSpec*(1.0+(subBoost*0.25)), 1.0)*peakStrength;
	subSpec = pow(subSpec, beamGloss)*min(litDif*1000, 1.0);
	
	beamDif += beamRGB*litDif*atenVal;
	beamSpec += inLightShip[inS+2].rgb*subSpec*atenVal;
}

diffAll += beamDif;
specAll += beamSpec;

//diffAll = beamDif;
//specAll = beamSpec;

#endif

// Apply final lighting 
paint.rgb = (diffRGB*diffAll)+glowRGB+(specAll*specStrength);

#ifndef SOB_BAYLIGHT
// Add reflections
vec3 envNorm = reflect(worldEye, worldNorm);
vec4 texE0 = texture(inTexEnv0, envNorm);
vec4 texE1 = texture(inTexEnv1, envNorm);
vec4 reflTex = mix(texE0, texE1, mapSpecSharp);

#ifdef SOB_SHADOWS_ON
float envMask = 1.0-(max((dot(envNorm,holdLit_K)5.0)-4.0, 0.0)(1.0-shadowMask_K));

#ifdef SOB_SHADOWS_DUAL
	envMask *= 1.0-(max((dot(envNorm,holdLit_F)*5.0)-4.0, 0.0)*(1.0-shadowMask_F));
#endif

#else
float envMask = 1.0;
#endif

float reflDeg = reflStrength*reflTex.a*inBGEnvParams.r*envMask;
float reflAdd = extReflAddMix;
float reflAlpha = 1.0-reflAdd;

reflTex.rgb += inBGAddLight.rgb;

paint.rgb += reflTex.rgb*reflDeg*reflAdd;
paint.rgb = mix(paint.rgb, reflTex.rgb, reflDeg*reflAlpha);

#endif

paint.a = inSOBParams.x;

#ifdef SOB_TEAM
if (inSOBParams.y > 0.0)
{
float frenCloak = pow((1.0-abs(dot(worldNorm, worldEye)))*1.06, 2.0)*2.0-1.0;

	if (frenCloak > 0.0)
	{
		vec3 noisePos = outPos_W.xyz*0.05;
		vec3 timePos = holdLit_K*(inTime.z*2.0);
		float cloakNoise = HELP_Noise3(noisePos+timePos)*0.5+1.5;
		frenCloak = clamp(frenCloak*cloakNoise*0.5, 0.0, 1.0);
	}
	
	float cloakPaint = 1.0-(0.5*inSOBParams.y);
	paint.rgb = (paint.rgb*cloakPaint)+vec3(max(frenCloak, 0.0)*inSOBParams.y*1.5);
}

#endif

#ifndef SOB_DEBRIS
// UI Effect (glow, etc)
paint.rgb += vec3(inColEffect)*inColEffect.a;
#endif

paint.rgb = pow(paint.rgb, vec3(inGammaScale))*inGammaScale.a;

#ifdef SOB_USECLIP
vec3 hyperSpace = vec3(inGammaScale.a);

if (false == gl_FrontFacing)
{
	paint.rgb = hyperSpace;
}
else
{

#ifdef PATCH_ALTHYPER
float hyperEdge = outClipD*0.02;
#else
float hyperEdge = gl_ClipDistance[0]0.02;
#endif
if (hyperEdge < 1.0)
{
vec3 planeScales = vec3(1.5)+(abs(inClipPlane.xyz)20.0);
vec3 noisePos = outPos_W.xyz/planeScales;
vec3 timePos = inClipPlane.xyz
(inTime.z
2.0);

		float hyperNoise = HELP_Noise3(noisePos+timePos)*0.5+1.5;
		hyperEdge = 1.0-clamp(hyperEdge*hyperNoise, 0.0, 1.0);
		hyperEdge = min(pow(hyperEdge*1.1, 5.0)/1.2, 1.0);
		
		paint.rgb = mix(paint.rgb, hyperSpace, hyperEdge*inSOBParams.z);
	}
}

#endif

float maxFog = inFogColor.a*inFogColor.w;
if (maxFog > 0.0)
{
	float useFog = clamp((worldDist-inFogWindow.x)/(inFogWindow.z-inFogWindow.x), inFogWindow.y, inFogWindow.w);
	paint.rgb = mix(paint.rgb, inFogColor.rgb, useFog*inFogColor.a);
}

paint *= getShipExp();

#ifdef SOB_BAYLIGHT
paint *= getBayExp();
#endif

// Enable to show 'bad UV' patches (as magenta)
//vec2 delUV = vec2(dFdx(outUV0.x), dFdy(outUV0.y));
//float delD = 1.0-min(1.0, length(delUV)*1000000.0);
//paint.rgb = mix(paint.rgb, vec3(delD, 0.0, delD), delD);

#ifdef SOB_ALPHA
paint.a *= texTeam.r;
#endif

finalCol0 = paint;

}

----- END ERROR LOG -----[/details]