diff --git a/Content/OgreInternal/FFPLib_AlphaTest.glsl b/Content/OgreInternal/FFPLib_AlphaTest.glsl new file mode 100644 index 0000000..c28f059 --- /dev/null +++ b/Content/OgreInternal/FFPLib_AlphaTest.glsl @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------------- +// Program Name: FFPLib_AlphaTest +// Program Desc: Alpha test function. +// Program Type: Vertex/Pixel shader +// Language: GLSL +//----------------------------------------------------------------------------- + +#define CMPF_ALWAYS_FAIL 0 +#define CMPF_ALWAYS_PASS 1 +#define CMPF_LESS 2 +#define CMPF_LESS_EQUAL 3 +#define CMPF_EQUAL 4 +#define CMPF_NOT_EQUAL 5 +#define CMPF_GREATER_EQUAL 6 +#define CMPF_GREATER 7 + +bool Alpha_Func(in int func, in float alphaRef, in float alphaValue) +{ + // ES2 does not have switch + if(func == CMPF_ALWAYS_PASS) + return true; + else if(func == CMPF_LESS) + return alphaValue < alphaRef; + else if(func == CMPF_LESS_EQUAL) + return alphaValue <= alphaRef; + else if(func == CMPF_EQUAL) + return alphaValue == alphaRef; + else if(func == CMPF_NOT_EQUAL) + return alphaValue != alphaRef; + else if(func == CMPF_GREATER_EQUAL) + return alphaValue >= alphaRef; + else if(func == CMPF_GREATER) + return alphaValue > alphaRef; + + // CMPF_ALWAYS_FAIL and default + return false; +} + + +void FFP_Alpha_Test(in float func, in float alphaRef, in vec4 texel) +{ + bool pass_ = Alpha_Func(int(func), alphaRef, texel.a); + if (!pass_) + discard; +} diff --git a/Content/OgreInternal/FFPLib_Common.glsl b/Content/OgreInternal/FFPLib_Common.glsl new file mode 100644 index 0000000..7961c71 --- /dev/null +++ b/Content/OgreInternal/FFPLib_Common.glsl @@ -0,0 +1 @@ +// this file is going to dissapear with Ogre 14 \ No newline at end of file diff --git a/Content/OgreInternal/FFPLib_Fog.glsl b/Content/OgreInternal/FFPLib_Fog.glsl new file mode 100644 index 0000000..3741d40 --- /dev/null +++ b/Content/OgreInternal/FFPLib_Fog.glsl @@ -0,0 +1,134 @@ +/* +----------------------------------------------------------------------------- +This source file is part of OGRE +(Object-oriented Graphics Rendering Engine) +For the latest info, see http://www.ogre3d.org + +Copyright (c) 2000-2014 Torus Knot Software Ltd +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +----------------------------------------------------------------------------- +*/ + +//----------------------------------------------------------------------------- +// Program Name: FFPLib_Fog +// Program Desc: Fog functions of the FFP. +// Program Type: Vertex/Pixel shader +// Language: GLSL +// Notes: Implements core functions needed by FFPFog class. +// Based on fog engine. +// See http://msdn.microsoft.com/en-us/library/bb173398.aspx +// Vertex based fog: the w component of the out position is used +// as the distance parameter to fog formulas. This is basically the z coordinate +// in world space. See pixel fog under D3D docs. The fog factor is computed according +// to each formula, then clamped and output to the pixel shader. +// Pixel based fog: the w component of the out position is passed to pixel shader +// that computes the fog factor based on it. +// Both techniques use the fog factor in the end of the pixel shader to blend +// the output color with the fog color. +//----------------------------------------------------------------------------- + + + +//----------------------------------------------------------------------------- +void FFP_VertexFog_Linear(in vec4 vOutPos, + in vec4 fogParams, + out float oFogFactor) +{ + float distance = abs(vOutPos.w); + float fogFactor = (fogParams.z - distance) * fogParams.w; + + oFogFactor = clamp(fogFactor, 0.0, 1.0); +} + +//----------------------------------------------------------------------------- +void FFP_VertexFog_Exp(in vec4 vOutPos, + in vec4 fogParams, + out float oFogFactor) +{ + float distance = abs(vOutPos.w); + float x = distance*fogParams.x; + float fogFactor = 1.0 / exp(x); + + oFogFactor = clamp(fogFactor, 0.0, 1.0); +} + +//----------------------------------------------------------------------------- +void FFP_VertexFog_Exp2(in vec4 vOutPos, + in vec4 fogParams, + out float oFogFactor) +{ + float distance = abs(vOutPos.w); + float x = (distance*fogParams.x*distance*fogParams.x); + float fogFactor = 1.0 / exp(x); + + oFogFactor = clamp(fogFactor, 0.0, 1.0); +} + +//----------------------------------------------------------------------------- +void FFP_PixelFog_PositionDepth(in mat4 mWorld, + in vec3 cameraPos, + in vec4 pos, + out vec3 oPosView, + out float oDepth) +{ + vec4 vOutPos = mul(mWorld, pos); + oPosView = vOutPos.xyz - cameraPos; + oDepth = length(oPosView); +} + +//----------------------------------------------------------------------------- +void FFP_PixelFog_Linear(in float depth, + in vec4 fogParams, + in vec4 fogColor, + in vec4 baseColor, + out vec4 oColor) +{ + float distance = abs(depth); + float fogFactor = clamp((fogParams.z - distance) * fogParams.w, 0.0, 1.0); + + oColor = mix(fogColor, baseColor, fogFactor); +} + +//----------------------------------------------------------------------------- +void FFP_PixelFog_Exp(in float depth, + in vec4 fogParams, + in vec4 fogColor, + in vec4 baseColor, + out vec4 oColor) +{ + float distance = abs(depth); + float x = (distance*fogParams.x); + float fogFactor = clamp(1.0 / exp(x), 0.0, 1.0); + + oColor = mix(fogColor, baseColor, fogFactor); +} + +//----------------------------------------------------------------------------- +void FFP_PixelFog_Exp2(in float depth, + in vec4 fogParams, + in vec4 fogColor, + in vec4 baseColor, + out vec4 oColor) +{ + float distance = abs(depth); + float x = (distance*fogParams.x*distance*fogParams.x); + float fogFactor = clamp(1.0 / exp(x), 0.0, 1.0); + + oColor = mix(fogColor, baseColor, fogFactor); +} diff --git a/Content/OgreInternal/FFPLib_Texturing.glsl b/Content/OgreInternal/FFPLib_Texturing.glsl new file mode 100644 index 0000000..a77a270 --- /dev/null +++ b/Content/OgreInternal/FFPLib_Texturing.glsl @@ -0,0 +1,144 @@ +/* +----------------------------------------------------------------------------- +This source file is part of OGRE +(Object-oriented Graphics Rendering Engine) +For the latest info, see http://www.ogre3d.org + +Copyright (c) 2000-2014 Torus Knot Software Ltd +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +----------------------------------------------------------------------------- +*/ + +//----------------------------------------------------------------------------- +// Program Name: FFPLib_Texturing +// Program Desc: Texture functions of the FFP. +// Program Type: Vertex/Pixel shader +// Language: GLSL +// Notes: Implements core functions for FFPTexturing class. +// based on texturing operations needed by render system. +// Implements texture coordinate processing: +// see http://msdn.microsoft.com/en-us/library/bb206247.aspx +// Implements texture blending operation: +// see http://msdn.microsoft.com/en-us/library/bb206241.aspx +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +void FFP_TransformTexCoord(in mat4 m, in vec2 v, out vec2 vOut) +{ + vOut = mul(m, vec4(v, 0.0, 1.0)).xy; +} +//----------------------------------------------------------------------------- +void FFP_TransformTexCoord(in mat4 m, in vec4 v, out vec2 vOut) +{ + vOut = mul(m, v).xy; +} + +//----------------------------------------------------------------------------- +void FFP_TransformTexCoord(in mat4 m, in vec3 v, out vec3 vOut) +{ + vOut = mul(m, vec4(v, 1.0)).xyz; +} + +//----------------------------------------------------------------------------- +void FFP_GenerateTexCoord_EnvMap_Normal(in mat3 mWorldIT, + in vec3 vNormal, + out vec3 vOut) +{ + vOut = normalize(mul(mWorldIT, vNormal)); +} + +//----------------------------------------------------------------------------- +void FFP_GenerateTexCoord_EnvMap_Sphere(in mat4 mWorldView, + in mat3 mWorldIT, + in vec4 vPos, + in vec3 vNormal, + out vec2 vOut) +{ + vec3 normal = normalize( mul(mWorldIT, vNormal)); + vec3 eyedir = normalize(mul(mWorldView, vPos)).xyz; + vec3 r = reflect(eyedir, normal); + r.z += 1.0; + float two_p = 2.0 * length(r); + vOut = vec2(0.5 + r.x / two_p, 0.5 - r.y / two_p); +} + +//----------------------------------------------------------------------------- +void FFP_GenerateTexCoord_EnvMap_Reflect(in mat4 mWorld, + in mat4 mWorldIT, + in vec3 vCamPos, + in vec3 vNormal, + in vec4 vPos, + out vec3 vOut) +{ + vec3 vWorldNormal = normalize(mul(mWorldIT, vec4(vNormal, 0.0)).xyz); + vec3 vWorldPos = mul(mWorld, vPos).xyz; + vec3 vEyeDir = normalize(vWorldPos - vCamPos); + + vec3 vReflect = reflect(vEyeDir, vWorldNormal); + vReflect.z *= -1.0; + + vOut = vReflect; +} + +//----------------------------------------------------------------------------- +void FFP_AddSmooth(in float vIn0, in float vIn1, out float vOut) +{ + vOut = vIn0 + vIn1 - (vIn0 * vIn1); +} + +//----------------------------------------------------------------------------- +void FFP_AddSmooth(in vec2 vIn0, in vec2 vIn1, out vec2 vOut) +{ + vOut = vIn0 + vIn1 - (vIn0 * vIn1); +} + +//----------------------------------------------------------------------------- +void FFP_AddSmooth(in vec3 vIn0, in vec3 vIn1, out vec3 vOut) +{ + vOut = vIn0 + vIn1 - (vIn0 * vIn1); +} + +//----------------------------------------------------------------------------- +void FFP_AddSmooth(in vec4 vIn0, in vec4 vIn1, out vec4 vOut) +{ + vOut = vIn0 + vIn1 - (vIn0 * vIn1); +} +//----------------------------------------------------------------------------- +void FFP_DotProduct(in float vIn0, in float vIn1, out float vOut) +{ + vOut = dot(vIn0, vIn1); +} + +//----------------------------------------------------------------------------- +void FFP_DotProduct(in vec2 vIn0, in vec2 vIn1, out vec2 vOut) +{ + vOut = vec2_splat(dot(vIn0, vIn1)); +} + +//----------------------------------------------------------------------------- +void FFP_DotProduct(in vec3 vIn0, in vec3 vIn1, out vec3 vOut) +{ + vOut = vec3_splat(dot(vIn0, vIn1)); +} + +//----------------------------------------------------------------------------- +void FFP_DotProduct(in vec4 vIn0, in vec4 vIn1, out vec4 vOut) +{ + vOut = vec4_splat(dot(vIn0, vIn1)); +} \ No newline at end of file diff --git a/Content/OgreInternal/FFPLib_Transform.glsl b/Content/OgreInternal/FFPLib_Transform.glsl new file mode 100644 index 0000000..4102ff2 --- /dev/null +++ b/Content/OgreInternal/FFPLib_Transform.glsl @@ -0,0 +1,117 @@ +/* +----------------------------------------------------------------------------- +This source file is part of OGRE +(Object-oriented Graphics Rendering Engine) +For the latest info, see http://www.ogre3d.org + +Copyright (c) 2000-2014 Torus Knot Software Ltd +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +----------------------------------------------------------------------------- +*/ + +//----------------------------------------------------------------------------- +// Program Name: FFPLib_Transform +// Program Desc: Transform functions of the FFP. +// Program Type: Vertex shader +// Language: GLSL +// Notes: Implements core functions for FFPTransform class. +// based on transform engine. +// See http://msdn.microsoft.com/en-us/library/bb206269.aspx +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +void FFP_Transform(in mat3 m, + in vec3 v, + out vec3 vOut) +{ + vOut = mul(m, v); +} + +//----------------------------------------------------------------------------- +void FFP_Transform(in mat4 m, + in vec4 v, + out vec4 vOut) +{ + vOut = mul(m, v); +} + +//----------------------------------------------------------------------------- +void FFP_Transform(in mat4 m, + in vec4 v, + out vec3 vOut) +{ + vOut = mul(m, v).xyz; +} + +#ifdef OGRE_HLSL +void FFP_Transform(in float3x4 m, + in float4 v, + out float3 vOut) +{ + vOut = mul(m, v); +} + +//----------------------------------------------------------------------------- +void FFP_Transform(in float3x4 m, + in float3 v, + out float3 vOut) +{ + vOut = mul((float3x3)m, v); +} +#elif !defined(OGRE_GLSLES) || OGRE_GLSLES > 100 +//----------------------------------------------------------------------------- +void FFP_Transform(in mat3x4 m, + in vec4 v, + out vec3 vOut) +{ +/* transpose non-square uniform matrix for correct row-major > column-major mapping + * to keep the indexing inside the shader so mat[0] returns the same data in both GLSL and HLSL + * although it will be the first row in HLSL and the first column in GLSL + */ + vOut = v * m; +} + +void FFP_Transform(in mat3x4 m, + in vec3 v, + out vec3 vOut) +{ + vOut = v * mat3(m); +} +#endif + +//----------------------------------------------------------------------------- +void FFP_Transform(in mat4 m, + in vec3 v, + out vec3 vOut) +{ +#ifdef OGRE_HLSL + vOut = mul((float3x3)m, v); +#else + vOut = mat3(m) * v; +#endif +} + +//----------------------------------------------------------------------------- +void FFP_DerivePointSize(in vec4 params, + in float d, + out float sz) +{ + sz = params.x/sqrt(params.y + params.z*d + params.w*d*d); +} diff --git a/Content/OgreInternal/GLSL_GL3Support.glsl b/Content/OgreInternal/GLSL_GL3Support.glsl new file mode 100644 index 0000000..754e1d7 --- /dev/null +++ b/Content/OgreInternal/GLSL_GL3Support.glsl @@ -0,0 +1,86 @@ +// This file is part of the OGRE project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at https://www.ogre3d.org/licensing. + +// @public-api + +#if __VERSION__ == 100 +mat2 transpose(mat2 m) +{ + return mat2(m[0][0], m[1][0], + m[0][1], m[1][1]); +} + +mat3 transpose(mat3 m) +{ + return mat3(m[0][0], m[1][0], m[2][0], + m[0][1], m[1][1], m[2][1], + m[0][2], m[1][2], m[2][2]); +} + +mat4 transpose(mat4 m) +{ + return mat4(m[0][0], m[1][0], m[2][0], m[3][0], + m[0][1], m[1][1], m[2][1], m[3][1], + m[0][2], m[1][2], m[2][2], m[3][2], + m[0][3], m[1][3], m[2][3], m[3][3]); +} +#endif + +#if __VERSION__ > 120 || defined(OGRE_GLSLANG) +#define texture1D texture +#define texture2D texture +#define texture3D texture +#define texture2DArray texture +#define textureCube texture +#define shadow2D texture +#define shadow2DProj textureProj +#define texture2DProj textureProj +#define texture2DLod textureLod +#define textureCubeLod textureLod + +#if defined(OGRE_GLSLANG) || (__VERSION__ > 150 && defined(OGRE_VERTEX_SHADER)) || __VERSION__ >= 410 +#define IN(decl, loc) layout(location = loc) in decl; +#else +#define IN(decl, loc) in decl; +#endif + +#if defined(OGRE_GLSLANG) || (__VERSION__ > 150 && defined(OGRE_FRAGMENT_SHADER)) || __VERSION__ >= 410 +#define OUT(decl, loc) layout(location = loc) out decl; +#else +#define OUT(decl, loc) out decl; +#endif + +#else + +#ifdef OGRE_VERTEX_SHADER +#define IN(decl, loc) attribute decl; +#define OUT(decl, loc) varying decl; +#else +#define IN(decl, loc) varying decl; +#define OUT(decl, loc) out decl; +#endif + +#endif + +#if defined(OGRE_FRAGMENT_SHADER) && (defined(OGRE_GLSLANG) || (__VERSION__ > 130)) +#define gl_FragColor FragColor +OUT(vec4 FragColor, 0) +#endif + +#ifdef VULKAN + +#ifdef OGRE_VERTEX_SHADER +#define OGRE_UNIFORMS_BEGIN layout(binding = 0, row_major) uniform OgreUniforms { +#else +#define OGRE_UNIFORMS_BEGIN layout(binding = 1, row_major) uniform OgreUniforms { +#endif + +#define OGRE_UNIFORMS_END }; + +#else + +#define OGRE_UNIFORMS_BEGIN +#define OGRE_UNIFORMS_END + +#endif \ No newline at end of file diff --git a/Content/OgreInternal/HLSL_SM4Support.hlsl b/Content/OgreInternal/HLSL_SM4Support.hlsl new file mode 100644 index 0000000..2d2e3ea --- /dev/null +++ b/Content/OgreInternal/HLSL_SM4Support.hlsl @@ -0,0 +1,98 @@ +// This file is part of the OGRE project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at https://www.ogre3d.org/licensing. + +// @public-api + +#if OGRE_HLSL >= 4 + +// SM4 separates sampler into Texture and SamplerState + +#define sampler1D Sampler1D +#define sampler2D Sampler2D +#define sampler3D Sampler3D +#define samplerCUBE SamplerCube + +struct Sampler1D +{ + Texture1D t; + SamplerState s; +}; +struct Sampler2D +{ + Texture2D t; + SamplerState s; +}; +struct Sampler3D +{ + Texture3D t; + SamplerState s; +}; +struct SamplerCube +{ + TextureCube t; + SamplerState s; +}; + +float4 tex1D(Sampler1D s, float v) { return s.t.Sample(s.s, v); } +float4 tex2D(Sampler2D s, float2 v) { return s.t.Sample(s.s, v); } +float4 tex3D(Sampler3D s, float3 v) { return s.t.Sample(s.s, v); } +float4 texCUBE(SamplerCube s, float3 v) { return s.t.Sample(s.s, v); } +float4 texCUBElod(SamplerCube s, float4 v) { return s.t.SampleLevel(s.s, v.xyz, v.w); } + +float4 tex2D(Sampler2D s, float2 v, float2 ddx, float2 ddy) { return s.t.SampleGrad(s.s, v, ddx, ddy); } +float4 tex2Dproj(Sampler2D s, float4 v) { return s.t.Sample(s.s, v.xy/v.w); } +float4 tex2Dlod(Sampler2D s, float4 v) { return s.t.SampleLevel(s.s, v.xy, v.w); } + +#define SAMPLER1D(name, reg) \ + Texture1D name ## Tex : register(t ## reg);\ + SamplerState name ## State : register(s ## reg);\ + static Sampler1D name = {name ## Tex, name ## State} + +#define SAMPLER2D(name, reg) \ + Texture2D name ## Tex : register(t ## reg);\ + SamplerState name ## State : register(s ## reg);\ + static Sampler2D name = {name ## Tex, name ## State} + +#define SAMPLER3D(name, reg) \ + Texture3D name ## Tex : register(t ## reg);\ + SamplerState name ## State : register(s ## reg);\ + static Sampler3D name = {name ## Tex, name ## State} + +#define SAMPLERCUBE(name, reg) \ + TextureCube name ## Tex : register(t ## reg);\ + SamplerState name ## State : register(s ## reg);\ + static SamplerCube name = {name ## Tex, name ## State} + +// the following are not available in D3D9, but provided for convenience +struct Sampler2DShadow +{ + Texture2D t; + SamplerComparisonState s; +}; +struct Sampler2DArray +{ + Texture2DArray t; + SamplerState s; +}; + +#define SAMPLER2DSHADOW(name, reg) \ + Texture2D name ## Tex : register(t ## reg);\ + SamplerComparisonState name ## State : register(s ## reg);\ + static Sampler2DShadow name = {name ## Tex, name ## State} + +#define SAMPLER2DARRAY(name, reg) \ + Texture2DArray name ## Tex : register(t ## reg);\ + SamplerState name ## State : register(s ## reg);\ + static Sampler2DArray name = {name ## Tex, name ## State} + +float tex2Dcmp(Sampler2DShadow s, float3 v) { return s.t.SampleCmpLevelZero(s.s, v.xy, v.z); } +float4 tex2DARRAY(Sampler2DArray s, float3 v) { return s.t.Sample(s.s, v); } +#else + +#define SAMPLER1D(name, reg) sampler1D name : register(s ## reg) +#define SAMPLER2D(name, reg) sampler2D name : register(s ## reg) +#define SAMPLER3D(name, reg) sampler3D name : register(s ## reg) +#define SAMPLERCUBE(name, reg) samplerCUBE name : register(s ## reg) + +#endif \ No newline at end of file diff --git a/Content/OgreInternal/OgreUnifiedShader.h b/Content/OgreInternal/OgreUnifiedShader.h new file mode 100644 index 0000000..370b671 --- /dev/null +++ b/Content/OgreInternal/OgreUnifiedShader.h @@ -0,0 +1,184 @@ +// This file is part of the OGRE project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at https://www.ogre3d.org/licensing. + +// greatly inspired by +// - shiny: https://ogrecave.github.io/shiny/defining-materials-shaders.html +// - bgfx: https://github.com/bkaradzic/bgfx/blob/master/src/bgfx_shader.sh + +/// general usage: +// MAIN_PARAMETERS +// IN(vec4 vertex, POSITION) +// MAIN_DECLARATION +// { +// GLSL code here +// } + +/// configuration +// use macros that will be default with Ogre 14 +// #define USE_OGRE_FROM_FUTURE + +// @public-api + +#if defined(OGRE_HLSL) || defined(OGRE_CG) +// HLSL +#include "HLSL_SM4Support.hlsl" +#define vec2 float2 +#define vec3 float3 +#define vec4 float4 +#define mat3 float3x3 +#define mat4 float4x4 + +#define ivec2 int2 +#define ivec3 int3 +#define ivec4 int4 + +#define texture1D tex1D +#define texture2D tex2D +#define texture3D tex3D +#define texture2DArray tex2DARRAY +#define textureCube texCUBE +#define shadow2D tex2Dcmp +#define texture2DProj tex2Dproj +vec4 texture2DLod(sampler2D s, vec2 v, float lod) { return tex2Dlod(s, vec4(v.x, v.y, 0, lod)); } + +#define samplerCube samplerCUBE +vec4 textureCubeLod(samplerCube s, vec3 v, float lod) { return texCUBElod(s, vec4(v.x, v.y, v.z, lod)); } + +#define sampler2DShadow Sampler2DShadow + +#define mix lerp +#define fract frac + +float mod(float _a, float _b) { return _a - _b * floor(_a / _b); } +vec2 mod(vec2 _a, vec2 _b) { return _a - _b * floor(_a / _b); } +vec3 mod(vec3 _a, vec3 _b) { return _a - _b * floor(_a / _b); } +vec4 mod(vec4 _a, vec4 _b) { return _a - _b * floor(_a / _b); } + +vec2 vec2_splat(float x) { return vec2(x, x); } +vec3 vec3_splat(float x) { return vec3(x, x, x); } +vec4 vec4_splat(float x) { return vec4(x, x, x, x); } + +mat4 mtxFromRows(vec4 a, vec4 b, vec4 c, vec4 d) +{ + return mat4(a, b, c, d); +} + +mat3 mtxFromRows(vec3 a, vec3 b, vec3 c) +{ + return mat3(a, b, c); +} + +mat3 mtxFromCols(vec3 a, vec3 b, vec3 c) +{ + return transpose(mat3(a, b, c)); +} + +#define STATIC static + +#define OGRE_UNIFORMS_BEGIN +#define OGRE_UNIFORMS_END + +#define MAIN_PARAMETERS void main( + +#ifdef OGRE_VERTEX_SHADER +#define MAIN_DECLARATION out float4 gl_Position : POSITION) +#else +#define MAIN_DECLARATION in float4 gl_FragCoord : POSITION, out float4 gl_FragColor : COLOR) +#endif + +#define IN(decl, sem) in decl : sem, +#define OUT(decl, sem) out decl : sem, +#elif defined(OGRE_METAL) +#define vec2 float2 +#define vec3 float3 +#define vec4 float4 +#define mat3 metal::float3x3 +#define mat4 metal::float4x4 + +#define IN(decl, sem) decl [[ attribute(sem) ]]; +#else +// GLSL +#include "GLSL_GL3Support.glsl" + +#ifndef USE_OGRE_FROM_FUTURE +#define _UNIFORM_BINDING(b) +#elif defined(VULKAN) +#define _UNIFORM_BINDING(b) layout(binding = b + 2) uniform +#elif __VERSION__ >= 420 +#define _UNIFORM_BINDING(b) layout(binding = b) uniform +#else +#define _UNIFORM_BINDING(b) uniform +#endif + +#define SAMPLER1D(name, reg) _UNIFORM_BINDING(reg) sampler1D name +#define SAMPLER2D(name, reg) _UNIFORM_BINDING(reg) sampler2D name +#define SAMPLER3D(name, reg) _UNIFORM_BINDING(reg) sampler3D name +#define SAMPLER2DARRAY(name, reg) _UNIFORM_BINDING(reg) sampler2DArray name +#define SAMPLERCUBE(name, reg) _UNIFORM_BINDING(reg) samplerCube name +#define SAMPLER2DSHADOW(name, reg) _UNIFORM_BINDING(reg) sampler2DShadow name + +#define saturate(x) clamp(x, 0.0, 1.0) +#define mul(a, b) ((a) * (b)) + +#define vec2_splat vec2 +#define vec3_splat vec3 +#define vec4_splat vec4 + +mat4 mtxFromRows(vec4 a, vec4 b, vec4 c, vec4 d) +{ + return transpose(mat4(a, b, c, d)); +} + +mat3 mtxFromRows(vec3 a, vec3 b, vec3 c) +{ + return transpose(mat3(a, b, c)); +} + +mat3 mtxFromCols(vec3 a, vec3 b, vec3 c) +{ + return mat3(a, b, c); +} + +#define STATIC + +#define MAIN_PARAMETERS +#define MAIN_DECLARATION void main() + +#endif + +#if !defined(OGRE_HLSL) && !defined(OGRE_CG) +// semantics as aliases for attribute locations +#define POSITION 0 +#define BLENDWEIGHT 1 +#define NORMAL 2 +#define COLOR0 3 +#define COLOR1 4 +#define COLOR COLOR0 +#define FOG 5 +#define BLENDINDICES 7 +#define TEXCOORD0 8 +#define TEXCOORD1 9 +#define TEXCOORD2 10 +#define TEXCOORD3 11 +#define TEXCOORD4 12 +#define TEXCOORD5 13 +#define TEXCOORD6 14 +#define TEXCOORD7 15 +#define TANGENT 14 +#endif + +#define OGRE_UNIFORMS(params) OGRE_UNIFORMS_BEGIN params OGRE_UNIFORMS_END + +// GL_EXT_shader_explicit_arithmetic_types polyfill +#ifdef OGRE_GLSLES +#define float32_t highp float +#define f32vec2 highp vec2 +#define f32vec3 highp vec3 +#define f32vec4 highp vec4 +#else +#define float32_t float +#define f32vec2 vec2 +#define f32vec3 vec3 +#define f32vec4 vec4 +#endif diff --git a/Content/OgreInternal/RTSLib_IBL.glsl b/Content/OgreInternal/RTSLib_IBL.glsl new file mode 100644 index 0000000..f55372d --- /dev/null +++ b/Content/OgreInternal/RTSLib_IBL.glsl @@ -0,0 +1,88 @@ +// This file is part of the OGRE project. +// code adapted from Google Filament +// SPDX-License-Identifier: Apache-2.0 + +vec3 specularDFG(const PixelParams pixel) { + return mix(pixel.dfg.xxx, pixel.dfg.yyy, pixel.f0); +} + +vec3 decodeDataForIBL(const vec4 data) { + return data.rgb; +} + +vec3 Irradiance_RoughnessOne(samplerCube light_iblSpecular, const vec3 n, float iblRoughnessOneLevel) { + // note: lod used is always integer, hopefully the hardware skips tri-linear filtering + return decodeDataForIBL(textureCubeLod(light_iblSpecular, n, iblRoughnessOneLevel)); +} + +vec3 PrefilteredDFG_LUT(sampler2D light_iblDFG, float lod, float NoV) { + // coord = sqrt(linear_roughness), which is the mapping used by cmgen. + // OGRE Specific: y is flipped compared to Filament code + return texture2DLod(light_iblDFG, vec2(NoV, 1.0 - lod), 0.0).rgb; +} + +float perceptualRoughnessToLod(float iblRoughnessOneLevel, float perceptualRoughness) { + // The mapping below is a quadratic fit for log2(perceptualRoughness)+iblRoughnessOneLevel when + // iblRoughnessOneLevel is 4. We found empirically that this mapping works very well for + // a 256 cubemap with 5 levels used. But also scales well for other iblRoughnessOneLevel values. + return iblRoughnessOneLevel * perceptualRoughness * (2.0 - perceptualRoughness); +} + +vec3 prefilteredRadiance(samplerCube light_iblSpecular, const vec3 r, float perceptualRoughness, float iblRoughnessOneLevel) { + float lod = perceptualRoughnessToLod(iblRoughnessOneLevel, perceptualRoughness); + return decodeDataForIBL(textureCubeLod(light_iblSpecular, r, lod)); +} + +vec3 getSpecularDominantDirection(const vec3 n, const vec3 r, float roughness) { + return mix(r, n, roughness * roughness); +} + +void evaluateIBL(inout PixelParams pixel, + in vec3 vNormal, + in vec3 viewPos, + in mat4 invViewMat, + in sampler2D dfgTex, + in samplerCube iblEnvTex, + in float iblRoughnessOneLevel, + in float iblLuminance, + inout vec3 color) +{ + vec3 shading_normal = normalize(vNormal); + vec3 shading_view = -normalize(viewPos); + float shading_NoV = clampNoV(abs(dot(shading_normal, shading_view))); + + // the above is currently duplicated with CookTorrance + + vec3 shading_reflected = reflect(-shading_view, shading_normal); + + // Pre-filtered DFG term used for image-based lighting + pixel.dfg = PrefilteredDFG_LUT(dfgTex, pixel.perceptualRoughness, shading_NoV); + + vec3 E = specularDFG(pixel); + vec3 r = getSpecularDominantDirection(shading_normal, shading_reflected, pixel.roughness); + + // OGRE specific: convert r and n back to world space for texture sampling + r = normalize(mul(invViewMat, vec4(r, 0.0)).xyz); + r.z *= -1.0; + shading_normal = normalize(mul(invViewMat, vec4(shading_normal, 0.0)).xyz); + + // specular layer + vec3 Fr = E * prefilteredRadiance(iblEnvTex, r, pixel.perceptualRoughness, iblRoughnessOneLevel); + + vec3 diffuseIrradiance = Irradiance_RoughnessOne(iblEnvTex, shading_normal, iblRoughnessOneLevel); + vec3 Fd = pixel.diffuseColor * diffuseIrradiance * (1.0 - E); + + Fr *= iblLuminance; + Fd *= iblLuminance; + + // Combine all terms + // Note: iblLuminance is already premultiplied by the exposure + + color = pow(color, vec3_splat(2.2)); // gamma to linear + + color += Fr + Fd; + + // linear to gamma + color = pow(color, vec3_splat(1.0/2.2)); + color = saturate(color); +} \ No newline at end of file diff --git a/Content/OgreInternal/SGXLib_CookTorrance.glsl b/Content/OgreInternal/SGXLib_CookTorrance.glsl new file mode 100644 index 0000000..214c72c --- /dev/null +++ b/Content/OgreInternal/SGXLib_CookTorrance.glsl @@ -0,0 +1,241 @@ +// This file is part of the OGRE project. +// code adapted from Google Filament +// SPDX-License-Identifier: Apache-2.0 + +#define PI 3.14159265359 + +#ifdef OGRE_GLSLES + // min roughness such that (MIN_PERCEPTUAL_ROUGHNESS^4) > 0 in fp16 (i.e. 2^(-14/4), rounded up) + #define MIN_PERCEPTUAL_ROUGHNESS 0.089 +#else + #define MIN_PERCEPTUAL_ROUGHNESS 0.045 +#endif + +#define MEDIUMP_FLT_MAX 65504.0 +#define saturateMediump(x) min(x, MEDIUMP_FLT_MAX) + +#define MIN_N_DOT_V 1e-4 + +struct PixelParams +{ + vec3 baseColor; + vec3 diffuseColor; + float perceptualRoughness; + float roughness; + vec3 f0; + vec3 dfg; + vec3 energyCompensation; +}; + +float clampNoV(float NoV) { + // Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886" + return max(NoV, MIN_N_DOT_V); +} + +// Computes x^5 using only multiply operations. +float pow5(float x) { + float x2 = x * x; + return x2 * x2 * x; +} + +// https://google.github.io/filament/Filament.md.html#materialsystem/diffusebrdf +float Fd_Lambert() { + return 1.0 / PI; +} + +// https://google.github.io/filament/Filament.md.html#materialsystem/specularbrdf/fresnel(specularf) +vec3 F_Schlick(const vec3 f0, float f90, float VoH) { + // Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering" + return f0 + (f90 - f0) * pow5(1.0 - VoH); +} + +vec3 computeDiffuseColor(const vec3 baseColor, float metallic) { + return baseColor.rgb * (1.0 - metallic); +} + +vec3 computeF0(const vec3 baseColor, float metallic, float reflectance) { + return baseColor.rgb * metallic + (reflectance * (1.0 - metallic)); +} + +float perceptualRoughnessToRoughness(float perceptualRoughness) { + return perceptualRoughness * perceptualRoughness; +} + +// https://google.github.io/filament/Filament.md.html#materialsystem/specularbrdf/geometricshadowing(specularg) +float V_SmithGGXCorrelated(float roughness, float NoV, float NoL) { + // Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs" + float a2 = roughness * roughness; + // TODO: lambdaV can be pre-computed for all the lights, it should be moved out of this function + float lambdaV = NoL * sqrt((NoV - a2 * NoV) * NoV + a2); + float lambdaL = NoV * sqrt((NoL - a2 * NoL) * NoL + a2); + float v = 0.5 / (lambdaV + lambdaL); + // a2=0 => v = 1 / 4*NoL*NoV => min=1/4, max=+inf + // a2=1 => v = 1 / 2*(NoL+NoV) => min=1/4, max=+inf + // clamp to the maximum value representable in mediump + return saturateMediump(v); +} + +// https://google.github.io/filament/Filament.md.html#materialsystem/specularbrdf/normaldistributionfunction(speculard) +float D_GGX(float roughness, float NoH, const vec3 h, const vec3 n) { + // Walter et al. 2007, "Microfacet Models for Refraction through Rough Surfaces" + + // In mediump, there are two problems computing 1.0 - NoH^2 + // 1) 1.0 - NoH^2 suffers floating point cancellation when NoH^2 is close to 1 (highlights) + // 2) NoH doesn't have enough precision around 1.0 + // Both problem can be fixed by computing 1-NoH^2 in highp and providing NoH in highp as well + + // However, we can do better using Lagrange's identity: + // ||a x b||^2 = ||a||^2 ||b||^2 - (a . b)^2 + // since N and H are unit vectors: ||N x H||^2 = 1.0 - NoH^2 + // This computes 1.0 - NoH^2 directly (which is close to zero in the highlights and has + // enough precision). + // Overall this yields better performance, keeping all computations in mediump +#ifdef OGRE_GLSLES + vec3 NxH = cross(n, h); + float oneMinusNoHSquared = dot(NxH, NxH); +#else + float oneMinusNoHSquared = 1.0 - NoH * NoH; +#endif + + float a = NoH * roughness; + float k = roughness / (oneMinusNoHSquared + a * a); + float d = k * k * (1.0 / PI); + return saturateMediump(d); +} + +float getDistanceAttenuation(const vec3 params, float distance) +{ + return 1.0 / (params.x + params.y * distance + params.z * distance * distance); +} + +float getAngleAttenuation(const vec3 params, const vec3 lightDir, const vec3 toLight) +{ + float rho = dot(-lightDir, toLight); + float fSpotE = saturate((rho - params.y) / (params.x - params.y)); + return pow(fSpotE, params.z); +} + +void evaluateLight( + in vec3 vNormal, + in vec3 viewPos, + in vec4 lightPos, + in vec3 lightColor, + in vec4 pointParams, + in vec4 vLightDirView, + in vec4 spotParams, + in PixelParams pixel, + inout vec3 vOutColour) +{ + vec3 vLightView = lightPos.xyz; + float fLightD = 0.0; + + if (lightPos.w != 0.0) + { + vLightView -= viewPos; // to light + fLightD = length(vLightView); + + if(fLightD > pointParams.x) + return; + } + + vLightView = normalize(vLightView); + + vec3 vNormalView = normalize(vNormal); + float NoL = saturate(dot(vNormalView, vLightView)); + + if(NoL <= 0.0) + return; // not lit by this light + + // https://google.github.io/filament/Filament.md.html#toc5.6.2 + float f90 = saturate(dot(pixel.f0, vec3_splat(50.0 * 0.33))); + + vec3 vView = -normalize(viewPos); + + // https://google.github.io/filament/Filament.md.html#materialsystem/standardmodelsummary + vec3 h = normalize(vView + vLightView); + float NoH = saturate(dot(vNormalView, h)); + float NoV = clampNoV(abs(dot(vNormalView, vView))); + + float V = V_SmithGGXCorrelated(pixel.roughness, NoV, NoL); + vec3 F = F_Schlick(pixel.f0, f90, NoH); + float D = D_GGX(pixel.roughness, NoH, h, vNormalView); + + vec3 Fr = (D * V) * F; + vec3 Fd = pixel.diffuseColor * Fd_Lambert(); + + // https://google.github.io/filament/Filament.md.html#materialsystem/improvingthebrdfs/energylossinspecularreflectance + vec3 color = NoL * lightColor * (Fr * pixel.energyCompensation + Fd); + + color *= getDistanceAttenuation(pointParams.yzw, fLightD); + + if(spotParams.w != 0.0) + { + color *= getAngleAttenuation(spotParams.xyz, vLightDirView.xyz, vLightView); + } + + vOutColour += color; +} + +void PBR_MakeParams(in vec3 baseColor, in vec2 mrParam, inout PixelParams pixel) +{ +#ifdef DEBUG_PSSM + baseColor += pssm_lod_info; +#endif + baseColor = pow(baseColor, vec3_splat(2.2)); + pixel.baseColor = baseColor; + + float perceptualRoughness = mrParam.x; + // Clamp the roughness to a minimum value to avoid divisions by 0 during lighting + pixel.perceptualRoughness = clamp(perceptualRoughness, MIN_PERCEPTUAL_ROUGHNESS, 1.0); + // Remaps the roughness to a perceptually linear roughness (roughness^2) + pixel.roughness = perceptualRoughnessToRoughness(pixel.perceptualRoughness); + + float metallic = saturate(mrParam.y); + pixel.f0 = computeF0(baseColor, metallic, 0.04); + pixel.diffuseColor = computeDiffuseColor(baseColor, metallic); + + pixel.dfg = vec3_splat(0.5); // use full f0 for energy compensation + pixel.energyCompensation = vec3_splat(0.0); // will be set later +} + +#if LIGHT_COUNT > 0 +void PBR_Lights( +#ifdef HAVE_SHADOW_FACTOR + in float shadowFactor, +#endif + in vec3 vNormal, + in vec3 viewPos, + in vec4 ambient, + in vec4 lightPos[LIGHT_COUNT], + in vec4 lightColor[LIGHT_COUNT], + in vec4 pointParams[LIGHT_COUNT], + in vec4 vLightDirView[LIGHT_COUNT], + in vec4 spotParams[LIGHT_COUNT], + in PixelParams pixel, + inout vec3 vOutColour) +{ + vOutColour = pow(vOutColour, vec3_splat(2.2)); // gamma to linear + + // Energy compensation for multiple scattering in a microfacet model + // See "Multiple-Scattering Microfacet BSDFs with the Smith Model" + pixel.energyCompensation = 1.0 + pixel.f0 * (1.0 / pixel.dfg.y - 1.0); + + for(int i = 0; i < LIGHT_COUNT; i++) + { + evaluateLight(vNormal, viewPos, lightPos[i], lightColor[i].xyz, pointParams[i], vLightDirView[i], spotParams[i], + pixel, vOutColour); + +#ifdef HAVE_SHADOW_FACTOR + if(i == 0) // directional lights always come first + vOutColour *= shadowFactor; +#endif + } + + vOutColour += pixel.baseColor * pow(ambient.rgb, vec3_splat(2.2)); + + // linear to gamma + vOutColour = pow(vOutColour, vec3_splat(1.0/2.2)); + + vOutColour = saturate(vOutColour); +} +#endif \ No newline at end of file diff --git a/Content/OgreInternal/SGXLib_DualQuaternion.glsl b/Content/OgreInternal/SGXLib_DualQuaternion.glsl new file mode 100644 index 0000000..e9a64a3 --- /dev/null +++ b/Content/OgreInternal/SGXLib_DualQuaternion.glsl @@ -0,0 +1,172 @@ +/* +----------------------------------------------------------------------------- +This source file is part of OGRE +(Object-oriented Graphics Rendering Engine) +For the latest info, see http://www.ogre3d.org + +Copyright (c) 2000-2014 Torus Knot Software Ltd +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +----------------------------------------------------------------------------- +*/ + +//These functions are based on dqs.cg from http://isg.cs.tcd.ie/kavanl/dq/ +/* dqs.cg + + Dual quaternion skinning vertex shaders (no shading computations) + + Version 1.0.3, November 1st, 2007 + + Copyright (C) 2006-2007 University of Dublin, Trinity College, All Rights + Reserved + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author(s) be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Author: Ladislav Kavan, kavanl@cs.tcd.ie + +*/ + +//----------------------------------------------------------------------------- +// Program Name: SGXLib_DualQuaternion +// Program Desc: Dual quaternion skinning functions. +// Program Type: Vertex shader +// Language: GLSL +//----------------------------------------------------------------------------- + +#if defined(OGRE_HLSL) || defined(OGRE_CG) +// this is technically wrong, thats why we dont put it into OgreUnifiedShader.h +#define mat2x4 float2x4 +#define mat3x4 float3x4 +#endif + +//----------------------------------------------------------------------------- +void SGX_BlendWeight(in float blendWgt, in mat2x4 dualQuaternion, out mat2x4 vOut) +{ + vOut = blendWgt*dualQuaternion; +} + +//----------------------------------------------------------------------------- +void SGX_BlendWeight(in float blendWgt, in mat3x4 scaleShearMatrix, out mat3x4 vOut) +{ + vOut = blendWgt*scaleShearMatrix; +} + +//----------------------------------------------------------------------------- +// Adjusts the sign of a dual quaternion depending on its orientation to the root dual quaternion +void SGX_AntipodalityAdjustment(in mat2x4 dq0, in mat2x4 dq1,out mat2x4 dq2) +{ + //Accurate antipodality handling. For speed increase, remove the following line, + //though, the results will only be valid for rotations less than 180 degrees. + dq2 = (dot(dq0[0], dq1[0]) < 0.0) ? dq1 * -1.0 : dq1; +} + +//----------------------------------------------------------------------------- +void SGX_CalculateBlendPosition(in vec3 position, in mat2x4 blendDQ, out vec4 vOut) +{ + vec3 blendPosition = position + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, position) + blendDQ[0].x*position); + vec3 trans = 2.0*(blendDQ[0].x*blendDQ[1].yzw - blendDQ[1].x*blendDQ[0].yzw + cross(blendDQ[0].yzw, blendDQ[1].yzw)); + blendPosition += trans; + + vOut = vec4(blendPosition, 1.0); +} + +//----------------------------------------------------------------------------- +void SGX_CalculateBlendNormal(in vec3 normal, in mat2x4 blendDQ, out vec3 vOut) +{ + vOut = normal + 2.0*cross(blendDQ[0].yzw, cross(blendDQ[0].yzw, normal) + blendDQ[0].x*normal); +} + +//----------------------------------------------------------------------------- +void SGX_AdjointTransposeMatrix(in mat3x4 M, out mat3 vOut) +{ + mat3 atM; + atM[0][0] = M[2][2] * M[1][1] - M[1][2] * M[2][1]; + atM[0][1] = M[1][2] * M[2][0] - M[1][0] * M[2][2]; + atM[0][2] = M[1][0] * M[2][1] - M[2][0] * M[1][1]; + + atM[1][0] = M[0][2] * M[2][1] - M[2][2] * M[0][1]; + atM[1][1] = M[2][2] * M[0][0] - M[0][2] * M[2][0]; + atM[1][2] = M[2][0] * M[0][1] - M[0][0] * M[2][1]; + + atM[2][0] = M[1][2] * M[0][1] - M[0][2] * M[1][1]; + atM[2][1] = M[1][0] * M[0][2] - M[1][2] * M[0][0]; + atM[2][2] = M[0][0] * M[1][1] - M[1][0] * M[0][1]; + + vOut = atM; +} + +//----------------------------------------------------------------------------- +void blendBonesDQ(mat2x4 bones_dq[BONE_COUNT], vec4 indices, vec4 weights, out mat2x4 blendDQ) +{ + blendDQ = bones_dq[int(indices.x)] * weights.x; + mat2x4 dqi; +#ifdef CORRECT_ANTIPODALITY + mat2x4 dq0 = blendDQ; +#endif +#if WEIGHT_COUNT > 1 + dqi = bones_dq[int(indices.y)] * weights.y; +# ifdef CORRECT_ANTIPODALITY + SGX_AntipodalityAdjustment(dq0, dqi, dqi); +# endif + blendDQ += dqi; +#endif +#if WEIGHT_COUNT > 2 + dqi = bones_dq[int(indices.z)] * weights.z; +# ifdef CORRECT_ANTIPODALITY + SGX_AntipodalityAdjustment(dq0, dqi, dqi); +# endif + blendDQ += dqi; +#endif +#if WEIGHT_COUNT > 3 + dqi = bones_dq[int(indices.w)] * weights.w; +# ifdef CORRECT_ANTIPODALITY + SGX_AntipodalityAdjustment(dq0, dqi, dqi); +# endif + blendDQ += dqi; +#endif + + blendDQ /= length(blendDQ[0]); // normalise dual quaternion +} + +void blendBonesMat3x4(mat3x4 bones_mat[BONE_COUNT], vec4 indices, vec4 weights, out mat3x4 blendMat) +{ + blendMat = bones_mat[int(indices.x)] * weights.x; +#if WEIGHT_COUNT > 1 + blendMat += bones_mat[int(indices.y)] * weights.y; +#endif +#if WEIGHT_COUNT > 2 + blendMat += bones_mat[int(indices.z)] * weights.z; +#endif +#if WEIGHT_COUNT > 3 + blendMat += bones_mat[int(indices.w)] * weights.w; +#endif +} \ No newline at end of file diff --git a/Content/OgreInternal/SGXLib_IntegratedPSSM.glsl b/Content/OgreInternal/SGXLib_IntegratedPSSM.glsl new file mode 100644 index 0000000..a5ad1bc --- /dev/null +++ b/Content/OgreInternal/SGXLib_IntegratedPSSM.glsl @@ -0,0 +1,182 @@ +/* +----------------------------------------------------------------------------- +This source file is part of OGRE +(Object-oriented Graphics Rendering Engine) +For the latest info, see http://www.ogre3d.org + +Copyright (c) 2000-2014 Torus Knot Software Ltd +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +----------------------------------------------------------------------------- +*/ +//----------------------------------------------------------------------------- +// Program Name: SGXLib_IntegratedPSSM +// Program Desc: Integrated PSSM functions. +// Program Type: Vertex/Pixel shader +// Language: GLSL +//----------------------------------------------------------------------------- + +#ifdef PSSM_SAMPLE_CMP +#define SAMPLER_TYPE sampler2DShadow +#else +#define SAMPLER_TYPE sampler2D +#endif + +#ifdef DEBUG_PSSM +STATIC vec3 pssm_lod_info = vec3(0.0, 0.0, 0.0); +#endif + +// default to 2x2 PCF +#ifndef PCF_XSAMPLES +#define PCF_XSAMPLES 2.0 +#endif + +//----------------------------------------------------------------------------- +void SGX_ApplyShadowFactor_Diffuse(in vec4 ambient, + in float fShadowFactor, + inout vec4 oLight) +{ + oLight.rgb = mix(ambient.rgb, oLight.rgb, fShadowFactor); + +#ifdef DEBUG_PSSM + oLight.rgb += pssm_lod_info; +#endif +} + +float sampleDepth(in SAMPLER_TYPE shadowMap, vec2 uv, float depth) +{ +#ifdef PSSM_SAMPLE_CMP +# if defined(OGRE_GLSL) && OGRE_GLSL < 130 + return shadow2D(shadowMap, vec3(uv, depth)).r; +# else + return shadow2D(shadowMap, vec3(uv, depth)); +# endif +#else + return (depth <= texture2D(shadowMap, uv).r) ? 1.0 : 0.0; +#endif +} + +//----------------------------------------------------------------------------- +void SGX_ShadowPCF4(in SAMPLER_TYPE shadowMap, in vec4 shadowMapPos, in vec2 invTexSize, out float c) +{ + shadowMapPos = shadowMapPos / shadowMapPos.w; +#if !defined(OGRE_REVERSED_Z) && !defined(OGRE_HLSL) && !defined(VULKAN) + shadowMapPos.z = shadowMapPos.z * 0.5 + 0.5; // convert -1..1 to 0..1 +#endif + vec2 uv = shadowMapPos.xy; + + // depth must be clamped to support floating-point depth formats. This is to avoid comparing a + // value from the depth texture (which is never greater than 1.0) with a greater-than-one + // comparison value (which is possible with floating-point formats). + float depth = clamp(shadowMapPos.z, 0.0, 1.0); + + c = 0.0; + float scale = 1.0; + float offset = (PCF_XSAMPLES / 2.0 - 0.5) * scale; + for (float y = -offset; y <= offset; y += scale) + for (float x = -offset; x <= offset; x += scale) + c += sampleDepth(shadowMap, uv + invTexSize * vec2(x, y), depth); + + c /= PCF_XSAMPLES * PCF_XSAMPLES; +} + +//----------------------------------------------------------------------------- +void SGX_ComputeShadowFactor_PSSM3(in float fDepth, + in vec4 vSplitPoints, + in vec4 lightPosition0, + in SAMPLER_TYPE shadowMap0, + in vec2 invShadowMapSize0, + #if PSSM_NUM_SPLITS > 2 + in vec4 lightPosition1, + in SAMPLER_TYPE shadowMap1, + in vec2 invShadowMapSize1, + #endif + #if PSSM_NUM_SPLITS > 3 + in vec4 lightPosition2, + in SAMPLER_TYPE shadowMap2, + in vec2 invShadowMapSize2, + #endif + in vec4 lightPosition3, + in SAMPLER_TYPE shadowMap3, + in vec2 invShadowMapSize3, + out float oShadowFactor) +{ +#if defined(PROJ_SPACE_SPLITS) && !defined(OGRE_REVERSED_Z) && !defined(OGRE_HLSL) && !defined(VULKAN) + vSplitPoints = vSplitPoints * 0.5 + 0.5; // convert -1..1 to 0..1 +#endif + +#ifdef OGRE_REVERSED_Z + vSplitPoints = vec4_splat(1.0) - vSplitPoints; + fDepth = 1.0 - fDepth; +#endif + + if (fDepth <= vSplitPoints.x) + { +#ifdef PSSM_SAMPLE_COLOUR + oShadowFactor = texture2DProj(shadowMap0, lightPosition0).x; +#else + SGX_ShadowPCF4(shadowMap0, lightPosition0, invShadowMapSize0, oShadowFactor); +#endif +#ifdef DEBUG_PSSM + pssm_lod_info.r = 1.0; +#endif + } +#if PSSM_NUM_SPLITS > 2 + else if (fDepth <= vSplitPoints.y) + { +#ifdef PSSM_SAMPLE_COLOUR + oShadowFactor = texture2DProj(shadowMap1, lightPosition1).x; +#else + SGX_ShadowPCF4(shadowMap1, lightPosition1, invShadowMapSize1, oShadowFactor); +#endif +#ifdef DEBUG_PSSM + pssm_lod_info.g = 1.0; +#endif + } +#endif +#if PSSM_NUM_SPLITS > 3 + else if (fDepth <= vSplitPoints.z) + { +#ifdef PSSM_SAMPLE_COLOUR + oShadowFactor = texture2DProj(shadowMap2, lightPosition2).x; +#else + SGX_ShadowPCF4(shadowMap2, lightPosition2, invShadowMapSize2, oShadowFactor); +#endif +#ifdef DEBUG_PSSM + pssm_lod_info.r = 1.0; + pssm_lod_info.g = 1.0; +#endif + } +#endif + else if (fDepth <= vSplitPoints.w) + { +#ifdef PSSM_SAMPLE_COLOUR + oShadowFactor = texture2DProj(shadowMap3, lightPosition3).x; +#else + SGX_ShadowPCF4(shadowMap3, lightPosition3, invShadowMapSize3, oShadowFactor); +#endif +#ifdef DEBUG_PSSM + pssm_lod_info.b = 1.0; +#endif + } + else + { + // behind far distance + oShadowFactor = 1.0; + } +} diff --git a/Content/OgreInternal/SGXLib_LayeredBlending.glsl b/Content/OgreInternal/SGXLib_LayeredBlending.glsl new file mode 100644 index 0000000..8af709a --- /dev/null +++ b/Content/OgreInternal/SGXLib_LayeredBlending.glsl @@ -0,0 +1,825 @@ +/* +** layered blending & misc math +** Blending modes, RGB/HSL/Contrast/Desaturate, levels control +** +** The shaders below are base on the shaders created by: +** Romain Dura | Romz +** Blog: http://blog.mouaif.org +** Post: http://blog.mouaif.org/?p=94 +*/ + + +/* +** Desaturation +*/ + +vec4 Desaturate(in vec3 color, in float Desaturation) +{ + vec3 grayXfer = vec3(0.3, 0.59, 0.11); + float grayf = dot(grayXfer, color); + vec3 gray = vec3(grayf, grayf, grayf); + return vec4(mix(color, gray, Desaturation), 1.0); +} + + +/* +** Hue, saturation, luminance +*/ + +vec3 RGBToHSL(in vec3 color) +{ + vec3 hsl; // init to 0 to avoid warnings ? (and reverse if + remove first part) + + float fmin = min(min(color.r, color.g), color.b); //Min. value of RGB + float fmax = max(max(color.r, color.g), color.b); //Max. value of RGB + float delta = fmax - fmin; //Delta RGB value + + hsl.z = (fmax + fmin) / 2.0; // Luminance + + if (delta == 0.0) //This is a gray, no chroma... + { + hsl.x = 0.0; // Hue + hsl.y = 0.0; // Saturation + } + else //Chromatic data... + { + if (hsl.z < 0.5) + hsl.y = delta / (fmax + fmin); // Saturation + else + hsl.y = delta / (2.0 - fmax - fmin); // Saturation + + float deltaR = (((fmax - color.r) / 6.0) + (delta / 2.0)) / delta; + float deltaG = (((fmax - color.g) / 6.0) + (delta / 2.0)) / delta; + float deltaB = (((fmax - color.b) / 6.0) + (delta / 2.0)) / delta; + + if (color.r == fmax ) + hsl.x = deltaB - deltaG; // Hue + else if (color.g == fmax) + hsl.x = (1.0 / 3.0) + deltaR - deltaB; // Hue + else if (color.b == fmax) + hsl.x = (2.0 / 3.0) + deltaG - deltaR; // Hue + + if (hsl.x < 0.0) + hsl.x += 1.0; // Hue + else if (hsl.x > 1.0) + hsl.x -= 1.0; // Hue + } + + return hsl; +} + +float HueToRGB(in float f1, in float f2, in float hue) +{ + if (hue < 0.0) + hue += 1.0; + else if (hue > 1.0) + hue -= 1.0; + float res; + if ((6.0 * hue) < 1.0) + res = f1 + (f2 - f1) * 6.0 * hue; + else if ((2.0 * hue) < 1.0) + res = f2; + else if ((3.0 * hue) < 2.0) + res = f1 + (f2 - f1) * ((2.0 / 3.0) - hue) * 6.0; + else + res = f1; + return res; +} + +vec3 HSLToRGB(in vec3 hsl) +{ + vec3 rgb; + + if (hsl.y == 0.0) + rgb = hsl.zzz; // Luminance + else + { + float f2; + + if (hsl.z < 0.5) + f2 = hsl.z * (1.0 + hsl.y); + else + f2 = (hsl.z + hsl.y) - (hsl.y * hsl.z); + + float f1 = 2.0 * hsl.z - f2; + + rgb.r = HueToRGB(f1, f2, hsl.x + (1.0/3.0)); + rgb.g = HueToRGB(f1, f2, hsl.x); + rgb.b = HueToRGB(f1, f2, hsl.x - (1.0/3.0)); + } + + return rgb; +} + + +/* +** Contrast, saturation, brightness +** Code of this function is from TGM's shader pack +** http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=21057 +*/ + +// For all settings: 1.0 = 100% 0.5=50% 1.5 = 150% +vec3 ContrastSaturationBrightness(in vec3 color, in float brt, in float sat, in float con) +{ + // Increase or decrease these values to adjust r, g and b color channels separately + const float AvgLumR = 0.5; + const float AvgLumG = 0.5; + const float AvgLumB = 0.5; + + const vec3 LumCoeff = vec3(0.2125, 0.7154, 0.0721); + + vec3 AvgLumin = vec3(AvgLumR, AvgLumG, AvgLumB); + vec3 brtColor = color * brt; + float intensityf = dot(brtColor, LumCoeff); + vec3 intensity = vec3(intensityf, intensityf, intensityf); + vec3 satColor = mix(intensity, brtColor, sat); + vec3 conColor = mix(AvgLumin, satColor, con); + return conColor; +} + +/* +** Float blending modes +** Adapted from here: http://www.nathanm.com/photoshop-blending-math/ +** But I modified the HardMix (wrong condition), Overlay, SoftLight, ColorDodge, ColorBurn, VividLight, PinLight (inverted layers) ones to have correct results +*/ + +#define BlendLinearDodgef BlendAddf +#define BlendLinearBurnf BlendSubtractf +#define BlendAddf(base, blend) min(base + blend, 1.0) +#define BlendSubtractf(base, blend) max(base + blend - 1.0, 0.0) +#define BlendLightenf(base, blend) max(blend, base) +#define BlendDarkenf(base, blend) min(blend, base) +#define BlendScreenf(base, blend) (1.0 - ((1.0 - base) * (1.0 - blend))) +#define BlendOverlayf(base, blend) (base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend))) +#define BlendSoftLightf(base, blend) ((blend < 0.5) ? (2.0 * base * blend + base * base * (1.0 - 2.0 * blend)) : (sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend))) +#define BlendColorDodgef(base, blend) ((blend == 1.0) ? blend : min(base / (1.0 - blend), 1.0)) +#define BlendColorBurnf(base, blend) ((blend == 0.0) ? blend : max((1.0 - ((1.0 - base) / blend)), 0.0)) +#define BlendHardMixf(base, blend) ((BlendVividLightf(base, blend) < 0.5) ? 0.0 : 1.0) + + + +/* +** Vector3 blending modes +*/ + +// Component wise blending +#define Blend1(base, blend, funcf) funcf(base, blend) +#define Blend3(base, blend, funcf) vec3(funcf(base.r, blend.r), funcf(base.g, blend.g), funcf(base.b, blend.b)) +#define Blend4(base, blend, funcf) vec4(funcf(base.r, blend.r), funcf(base.g, blend.g), funcf(base.b, blend.b), funcf(base.a, blend.a)) + +#define BlendNormal(base, blend) (base) +#define BlendMultiply(base, blend) (base * blend) +#define BlendAverage(base, blend) ((base + blend) / 2.0) +#define BlendAdd(base, blend) min(base + blend, 1.0) +#define BlendSubtract(base, blend) max(base + blend - 1.0, 0.0) +#define BlendDifference(base, blend) abs(base - blend) +#define BlendNegation(base, blend) (1.0 - abs(1.0 - base - blend)) +#define BlendExclusion(base, blend) (base + blend - 2.0 * base * blend) +#define BlendPhoenix(base, blend) (min(base, blend) - max(base, blend) + 1.0) +#define BlendOpacity(base, blend, F, O) (F(base, blend) * O + blend * (1.0 - O)) + +// Hue Blend mode creates the result color by combining the luminance and saturation of the base color with the hue of the blend color. +float BlendHue1(in float base, in float blend) +{ + return base; +} + +vec3 BlendHue3(in vec3 base, in vec3 blend) +{ + vec3 baseHSL = RGBToHSL(base); + return HSLToRGB(vec3(RGBToHSL(blend).r, baseHSL.g, baseHSL.b)); +} + +vec4 BlendHue4(in vec4 base, in vec4 blend) +{ + vec3 hue = BlendHue3(base.xyz, blend.xyz); + return vec4(hue.x, hue.y, hue.z, BlendHue1(base.w, blend.w)); +} + +// Saturation Blend mode creates the result color by combining the luminance and hue of the base color with the saturation of the blend color. +float BlendSaturation1(in float base, in float blend) +{ + return base; +} + +vec3 BlendSaturation3(in vec3 base, in vec3 blend) +{ + vec3 baseHSL = RGBToHSL(base); + return HSLToRGB(vec3(baseHSL.r, RGBToHSL(blend).g, baseHSL.b)); +} + +vec4 BlendSaturation4(in vec4 base, in vec4 blend) +{ + vec3 hue = BlendSaturation3(base.xyz, blend.xyz); + return vec4(hue.x, hue.y, hue.z, BlendSaturation1(base.w, blend.w)); +} + +// Color Mode keeps the brightness of the base color and applies both the hue and saturation of the blend color. +float BlendColor1(in float base, in float blend) +{ + return base; +} + +vec3 BlendColor3(in vec3 base, in vec3 blend) +{ + vec3 blendHSL = RGBToHSL(blend); + return HSLToRGB(vec3(blendHSL.r, blendHSL.g, RGBToHSL(base).b)); +} + +vec4 BlendColor4(in vec4 base, in vec4 blend) +{ + vec3 hue = BlendColor3(base.xyz, blend.xyz); + return vec4(hue.x, hue.y, hue.z, BlendColor1(base.w, blend.w)); +} + + +// Luminosity Blend mode creates the result color by combining the hue and saturation of the base color with the luminance of the blend color. +float BlendLuminosity1(in float base, in float blend) +{ + return base; +} + +vec3 BlendLuminosity3(in vec3 base, in vec3 blend) +{ + vec3 baseHSL = RGBToHSL(base); + return HSLToRGB(vec3(baseHSL.r, baseHSL.g, RGBToHSL(blend).b)); +} + +vec4 BlendLuminosity4(in vec4 base, in vec4 blend) +{ + vec3 hue = BlendLuminosity3(base.xyz, blend.xyz); + return vec4(hue.x, hue.y, hue.z, BlendLuminosity1(base.w, blend.w)); +} + +float BlendLinearLightf(in float s1, in float s2) +{ + float oColor; + + if (s2 < 0.5) + { + float s2x = (2.0 * s2); + oColor = BlendSubtractf(s1, s2x); + } + else + { + float s2x = (2.0 * (s2 - 0.5)); + oColor = BlendAddf(s1, s2x); + } + + return oColor; +} + +float BlendVividLightf(in float s1, in float s2) +{ + float oColor; + + if (s2 < 0.5) + { + float s2x = (2.0 * s2); + oColor = BlendColorBurnf(s1, s2x); + } + else + { + float s2x = (2.0 * (s2 - 0.5)); + oColor = BlendColorDodgef(s1, s2x); + } + + return oColor; +} + +float BlendPinLightf(in float s1, in float s2) +{ + float oColor; + + if (s2 < 0.5) + { + float s2x = (2.0 * s2); + oColor = BlendDarkenf(s1, s2x); + } + else + { + float s2x = (2.0 * (s2 - 0.5)); + oColor = BlendLightenf(s1, s2x); + } + + return oColor; +} + +float BlendReflectf(in float s1, in float s2) +{ + float oColor; + + if (s2 == 1.0) + { + oColor = s2; + } + else + { + float s1x = (s1 * s1) / (1.0 - s2); + + oColor = min(s1x, 1.0); + } + + return oColor; +} + +//------------------------------------ +// Interface for RTShader +//------------------------------------ + + +void SGX_blend_normal(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor) +{ + oColor = BlendNormal(basePixel, blendPixel); +} + +void SGX_blend_normal(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor) +{ + oColor = BlendNormal(basePixel, blendPixel); +} + +void SGX_blend_normal(in float basePixel, in float blendPixel, out float oColor) +{ + oColor = BlendNormal(basePixel, blendPixel); +} + + +void SGX_blend_lighten(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor) +{ + oColor = BlendLightenf(basePixel, blendPixel); +} + +void SGX_blend_lighten(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor) +{ + oColor = BlendLightenf(basePixel, blendPixel); +} + +void SGX_blend_lighten(in float basePixel, in float blendPixel, out float oColor) +{ + oColor = BlendLightenf(basePixel, blendPixel); +} + + +void SGX_blend_darken(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor) +{ + oColor = BlendDarkenf(basePixel, blendPixel); +} + +void SGX_blend_darken(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor) +{ + oColor = BlendDarkenf(basePixel, blendPixel); +} + +void SGX_blend_darken(in float basePixel, in float blendPixel, out float oColor) +{ + oColor = BlendDarkenf(basePixel, blendPixel); +} + + +void SGX_blend_multiply(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor) +{ + oColor = BlendMultiply(basePixel, blendPixel); +} + +void SGX_blend_multiply(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor) +{ + oColor = BlendMultiply(basePixel, blendPixel); +} + +void SGX_blend_multiply(in float basePixel, in float blendPixel, out float oColor) +{ + oColor = BlendMultiply(basePixel, blendPixel); +} + + +void SGX_blend_average(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor) +{ + oColor = BlendAverage(basePixel, blendPixel); +} + +void SGX_blend_average(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor) +{ + oColor = BlendAverage(basePixel, blendPixel); +} + +void SGX_blend_average(in float basePixel, in float blendPixel, out float oColor) +{ + oColor = BlendAverage(basePixel, blendPixel); +} + + +void SGX_blend_add(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor) +{ + oColor = BlendAdd(basePixel, blendPixel); +} + +void SGX_blend_add(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor) +{ + oColor = BlendAdd(basePixel, blendPixel); +} + +void SGX_blend_add(in float basePixel, in float blendPixel, out float oColor) +{ + oColor = BlendAdd(basePixel, blendPixel); +} + + +void SGX_blend_subtract(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor) +{ + oColor = BlendSubtract(basePixel, blendPixel); +} + +void SGX_blend_subtract(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor) +{ + oColor = BlendSubtract(basePixel, blendPixel); +} + +void SGX_blend_subtract(in float basePixel, in float blendPixel, out float oColor) +{ + oColor = BlendSubtract(basePixel, blendPixel); +} + + +void SGX_blend_difference(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor) +{ + oColor = BlendDifference(basePixel, blendPixel); +} +void SGX_blend_difference(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor) +{ + oColor = BlendDifference(basePixel, blendPixel); +} +void SGX_blend_difference(in float basePixel, in float blendPixel, out float oColor) +{ + oColor = BlendDifference(basePixel, blendPixel); +} + + +void SGX_blend_negation(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor) +{ + oColor = BlendNegation(basePixel, blendPixel); +} +void SGX_blend_negation(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor) +{ + oColor = BlendNegation(basePixel, blendPixel); +} +void SGX_blend_negation(in float basePixel, in float blendPixel, out float oColor) +{ + oColor = BlendNegation(basePixel, blendPixel); +} + + +void SGX_blend_exclusion(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor) +{ + oColor = BlendExclusion(basePixel, blendPixel); +} +void SGX_blend_exclusion(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor) +{ + oColor = BlendExclusion(basePixel, blendPixel); +} +void SGX_blend_exclusion(in float basePixel, in float blendPixel, out float oColor) +{ + oColor = BlendExclusion(basePixel, blendPixel); +} + + +void SGX_blend_screen(in vec4 s1, in vec4 s2, out vec4 oColor) +{ + oColor = vec4(BlendScreenf(s1.r, s2.r), + BlendScreenf(s1.g, s2.g), + BlendScreenf(s1.b, s2.b), + BlendScreenf(s1.a, s2.a)); +} +void SGX_blend_screen(in vec3 s1, in vec3 s2, out vec3 oColor) +{ + oColor = vec3(BlendScreenf(s1.r, s2.r), + BlendScreenf(s1.g, s2.g), + BlendScreenf(s1.b, s2.b)); +} +void SGX_blend_screen(in float s1, in float s2, out float oColor) +{ + oColor = BlendScreenf(s1, s2); +} + + +void SGX_blend_overlay(in vec4 s1, in vec4 s2, out vec4 oColor) +{ + oColor = vec4(BlendOverlayf(s1.r, s2.r), + BlendOverlayf(s1.g, s2.g), + BlendOverlayf(s1.b, s2.b), + BlendOverlayf(s1.a, s2.a)); +} +void SGX_blend_overlay(in vec3 s1, in vec3 s2, out vec3 oColor) +{ + oColor = vec3(BlendOverlayf(s1.r, s2.r), + BlendOverlayf(s1.g, s2.g), + BlendOverlayf(s1.b, s2.b)); +} +void SGX_blend_overlay(in float s1, in float s2, out float oColor) +{ + oColor = BlendOverlayf(s1, s2); +} + + +void SGX_blend_softLight(in vec4 s1, in vec4 s2, out vec4 oColor) +{ + oColor = vec4(BlendSoftLightf(s1.r, s2.r), + BlendSoftLightf(s1.g, s2.g), + BlendSoftLightf(s1.b, s2.b), + BlendSoftLightf(s1.a, s2.a)); +} +void SGX_blend_softLight(in vec3 s1, in vec3 s2, out vec3 oColor) +{ + oColor = vec3(BlendSoftLightf(s1.r, s2.r), + BlendSoftLightf(s1.g, s2.g), + BlendSoftLightf(s1.b, s2.b)); +} +void SGX_blend_softLight(in float s1, in float s2, out float oColor) +{ + oColor = BlendSoftLightf(s1, s2); +} + + +void SGX_blend_hardLight(in vec4 s1, in vec4 s2, out vec4 oColor) +{ + oColor = vec4(BlendOverlayf(s1.r, s2.r), + BlendOverlayf(s1.g, s2.g), + BlendOverlayf(s1.b, s2.b), + BlendOverlayf(s1.a, s2.a)); +} +void SGX_blend_hardLight(in vec3 s1, in vec3 s2, out vec3 oColor) +{ + oColor = vec3(BlendOverlayf(s1.r, s2.r), + BlendOverlayf(s1.g, s2.g), + BlendOverlayf(s1.b, s2.b)); +} +void SGX_blend_hardLight(in float s1, in float s2, out float oColor) +{ + oColor = BlendOverlayf(s1, s2); +} + + +void SGX_blend_colorDodge(in vec4 s1, in vec4 s2, out vec4 oColor) +{ + oColor = vec4(BlendColorDodgef(s1.r, s2.r), + BlendColorDodgef(s1.g, s2.g), + BlendColorDodgef(s1.b, s2.b), + BlendColorDodgef(s1.a, s2.a)); +} +void SGX_blend_colorDodge(in vec3 s1, in vec3 s2, out vec3 oColor) +{ + oColor = vec3(BlendColorDodgef(s1.r, s2.r), + BlendColorDodgef(s1.g, s2.g), + BlendColorDodgef(s1.b, s2.b)); +} +void SGX_blend_colorDodge(in float s1, in float s2, out float oColor) +{ + oColor = BlendColorDodgef(s1, s2); +} + + +void SGX_blend_colorBurn(in vec4 s1, in vec4 s2, out vec4 oColor) +{ + oColor = vec4(BlendColorBurnf(s1.r, s2.r), + BlendColorBurnf(s1.g, s2.g), + BlendColorBurnf(s1.b, s2.b), + BlendColorBurnf(s1.a, s2.a)); +} +void SGX_blend_colorBurn(in vec3 s1, in vec3 s2, out vec3 oColor) +{ + oColor = vec3(BlendColorBurnf(s1.r, s2.r), + BlendColorBurnf(s1.g, s2.g), + BlendColorBurnf(s1.b, s2.b)); +} +void SGX_blend_colorBurn(in float s1, in float s2, out float oColor) +{ + oColor = BlendColorBurnf(s1, s2); +} + + +void SGX_blend_linearDodge(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor) +{ + oColor = BlendAddf(basePixel, blendPixel); +} +void SGX_blend_linearDodge(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor) +{ + oColor = BlendAddf(basePixel, blendPixel); +} +void SGX_blend_linearDodge(in float basePixel, in float blendPixel, out float oColor) +{ + oColor = BlendAddf(basePixel, blendPixel); +} + + +void SGX_blend_linearBurn(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor) +{ + oColor = BlendSubtractf(basePixel, blendPixel); +} +void SGX_blend_linearBurn(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor) +{ + oColor = BlendSubtractf(basePixel, blendPixel); +} +void SGX_blend_linearBurn(in float basePixel, in float blendPixel, out float oColor) +{ + oColor = BlendSubtractf(basePixel, blendPixel); +} + + +void SGX_blend_linearLight(in vec4 s1, in vec4 s2, out vec4 oColor) +{ + oColor = vec4(BlendLinearLightf(s1.r, s2.r), + BlendLinearLightf(s1.g, s2.g), + BlendLinearLightf(s1.b, s2.b), + BlendLinearLightf(s1.a, s2.a)); +} +void SGX_blend_linearLight(in vec3 s1, in vec3 s2, out vec3 oColor) +{ + oColor = vec3(BlendLinearLightf(s1.r, s2.r), + BlendLinearLightf(s1.g, s2.g), + BlendLinearLightf(s1.b, s2.b)); +} +void SGX_blend_linearLight(in float s1, in float s2, out float oColor) +{ + oColor = BlendLinearLightf(s1, s2); +} + + +void SGX_blend_vividLight(in vec4 s1, in vec4 s2, out vec4 oColor) +{ + oColor = vec4(BlendVividLightf(s1.r, s2.r), + BlendVividLightf(s1.g, s2.g), + BlendVividLightf(s1.b, s2.b), + BlendVividLightf(s1.a, s2.a)); +} +void SGX_blend_vividLight(in vec3 s1, in vec3 s2, out vec3 oColor) +{ + oColor = vec3(BlendVividLightf(s1.r, s2.r), + BlendVividLightf(s1.g, s2.g), + BlendVividLightf(s1.b, s2.b)); +} +void SGX_blend_vividLight(in float s1, in float s2, out float oColor) +{ + oColor = BlendVividLightf(s1, s2); +} + + +void SGX_blend_pinLight(in vec4 s1, in vec4 s2, out vec4 oColor) +{ + oColor = vec4(BlendPinLightf(s1.r, s2.r), + BlendPinLightf(s1.g, s2.g), + BlendPinLightf(s1.b, s2.b), + BlendPinLightf(s1.a, s2.a)); +} +void SGX_blend_pinLight(in vec3 s1, in vec3 s2, out vec3 oColor) +{ + oColor = vec3(BlendPinLightf(s1.r, s2.r), + BlendPinLightf(s1.g, s2.g), + BlendPinLightf(s1.b, s2.b)); +} +void SGX_blend_pinLight(in float s1, in float s2, out float oColor) +{ + oColor = BlendPinLightf(s1, s2); +} + + +void SGX_blend_hardMix(in vec4 s1, in vec4 s2, out vec4 oColor) +{ + oColor = vec4(BlendHardMixf(s1.r, s2.r), + BlendHardMixf(s1.g, s2.g), + BlendHardMixf(s1.b, s2.b), + BlendHardMixf(s1.a, s2.a)); +} +void SGX_blend_hardMix(in vec3 s1, in vec3 s2, out vec3 oColor) +{ + oColor = vec3(BlendHardMixf(s1.r, s2.r), + BlendHardMixf(s1.g, s2.g), + BlendHardMixf(s1.b, s2.b)); +} +void SGX_blend_hardMix(in float s1, in float s2, out float oColor) +{ + oColor = BlendHardMixf(s1, s2); +} + +void SGX_blend_reflect(in vec4 s1, in vec4 s2, out vec4 oColor) +{ + oColor = vec4(BlendReflectf(s1.r, s2.r), + BlendReflectf(s1.g, s2.g), + BlendReflectf(s1.b, s2.b), + BlendReflectf(s1.a, s2.a)); +} +void SGX_blend_reflect(in vec3 s1, in vec3 s2, out vec3 oColor) +{ + oColor = vec3(BlendReflectf(s1.r, s2.r), + BlendReflectf(s1.g, s2.g), + BlendReflectf(s1.b, s2.b)); +} +void SGX_blend_reflect(in float s1, in float s2, out float oColor) +{ + oColor = BlendReflectf(s1, s2); +} + + +void SGX_blend_glow(in vec4 s1, in vec4 s2, out vec4 oColor) +{ + oColor = vec4(BlendReflectf(s1.r, s2.r), + BlendReflectf(s1.g, s2.g), + BlendReflectf(s1.b, s2.b), + BlendReflectf(s1.a, s2.a)); +} +void SGX_blend_glow(in vec3 s1, in vec3 s2, out vec3 oColor) +{ + oColor = vec3(BlendReflectf(s1.r, s2.r), + BlendReflectf(s1.g, s2.g), + BlendReflectf(s1.b, s2.b)); +} +void SGX_blend_glow(in float s1, in float s2, out float oColor) +{ + oColor = BlendReflectf(s1, s2); +} + + +void SGX_blend_phoenix(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor) +{ + oColor = BlendPhoenix(basePixel, blendPixel); +} +void SGX_blend_phoenix(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor) +{ + oColor = BlendPhoenix(basePixel, blendPixel); +} +void SGX_blend_phoenix(in float basePixel, in float blendPixel, out float oColor) +{ + oColor = BlendPhoenix(basePixel, blendPixel); +} + + +void SGX_blend_saturation(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor) +{ + oColor = BlendSaturation4(basePixel, blendPixel); +} +void SGX_blend_saturation(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor) +{ + oColor = BlendSaturation3(basePixel, blendPixel); +} +void SGX_blend_saturation(in float basePixel, in float blendPixel, out float oColor) +{ + oColor = BlendSaturation1(basePixel, blendPixel); +} + + +void SGX_blend_color(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor) +{ + oColor = BlendColor4(basePixel, blendPixel); +} +void SGX_blend_color(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor) +{ + oColor = BlendColor3(basePixel, blendPixel); +} +void SGX_blend_color(in float basePixel, in float blendPixel, out float oColor) +{ + oColor = BlendColor1(basePixel, blendPixel); +} + + +void SGX_blend_luminosity(in vec4 basePixel, in vec4 blendPixel, out vec4 oColor) +{ + oColor = BlendLuminosity4(basePixel, blendPixel); +} +void SGX_blend_luminosity(in vec3 basePixel, in vec3 blendPixel, out vec3 oColor) +{ + oColor = BlendLuminosity3(basePixel, blendPixel); +} +void SGX_blend_luminosity(in float basePixel, in float blendPixel, out float oColor) +{ + oColor = BlendLuminosity1(basePixel, blendPixel); +} + + +//////////////////////////////////////////////////////////////////////////////////// +/// Source modification functions +//////////////////////////////////////////////////////////////////////////////////// + + +void SGX_src_mod_modulate(in vec4 iColor, in vec4 controlVal, out vec4 oColor) +{ + oColor = iColor * controlVal; +} +void SGX_src_mod_modulate(in vec3 iColor, in vec3 controlVal, out vec3 oColor) +{ + oColor = iColor * controlVal; +} +void SGX_src_mod_modulate(in float iColor, in float controlVal, out float oColor) +{ + oColor = iColor * controlVal; +} + +void SGX_src_mod_inv_modulate(in vec4 iColor, in vec4 controlVal, out vec4 oColor) +{ + oColor = mix(iColor, vec4(1.0,1.0,1.0,1.0), controlVal); +} +void SGX_src_mod_inv_modulate(in vec3 iColor, in vec3 controlVal, out vec3 oColor) +{ + oColor = mix(iColor, vec3(1.0,1.0,1.0), controlVal); +} +void SGX_src_mod_inv_modulate(in float iColor, in float controlVal, out float oColor) +{ + oColor = mix(iColor, 1.0, controlVal); +} diff --git a/Content/OgreInternal/SGXLib_NormalMap.glsl b/Content/OgreInternal/SGXLib_NormalMap.glsl new file mode 100644 index 0000000..9863d2e --- /dev/null +++ b/Content/OgreInternal/SGXLib_NormalMap.glsl @@ -0,0 +1,68 @@ +/* +----------------------------------------------------------------------------- +This source file is part of OGRE +(Object-oriented Graphics Rendering Engine) +For the latest info, see http://www.ogre3d.org + +Copyright (c) 2000-2014 Torus Knot Software Ltd +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +----------------------------------------------------------------------------- +*/ + +//----------------------------------------------------------------------------- +// Program Name: SGXLib_NormalMapLighting +// Program Desc: Normal map lighting functions. +// Program Type: Vertex/Pixel shader +// Language: GLSL +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +void SGX_FetchNormal(in sampler2D s, + in vec2 uv, + out vec3 vOut) +{ + vOut = 2.0 * texture2D(s, uv).xyz - 1.0; +} + +//----------------------------------------------------------------------------- +void SGX_TransformNormal(in vec3 vNormal, + in vec4 vTangent, + inout vec3 vNormalTS) +{ + // use non-normalised post-interpolation values as in mikktspace + // resulting normal will be normalised by lighting + vec3 vBinormal = cross(vNormal, vTangent.xyz) * sign(vTangent.w); + // direction: from tangent space to world + mat3 TBN = mtxFromCols(vTangent.xyz, vBinormal, vNormal); + vNormalTS = mul(TBN, vNormalTS); +} + +//----------------------------------------------------------------------------- +void SGX_Generate_Parallax_Texcoord(in sampler2D normalHeightMap, + in vec2 texCoord, + in vec3 viewPos, + in vec2 scaleBias, + out vec2 newTexCoord) +{ + vec3 eyeVec = -normalize(viewPos); + float height = texture2D(normalHeightMap, texCoord).a; + float displacement = (height * scaleBias.x) + scaleBias.y; + vec2 scaledEyeDir = eyeVec.xy * displacement; + newTexCoord = scaledEyeDir + texCoord; +} \ No newline at end of file diff --git a/Content/OgreInternal/SGXLib_PerPixelLighting.glsl b/Content/OgreInternal/SGXLib_PerPixelLighting.glsl new file mode 100644 index 0000000..ab85048 --- /dev/null +++ b/Content/OgreInternal/SGXLib_PerPixelLighting.glsl @@ -0,0 +1,236 @@ +/* +----------------------------------------------------------------------------- +This source file is part of OGRE +(Object-oriented Graphics Rendering Engine) +For the latest info, see http://www.ogre3d.org + +Copyright (c) 2000-2014 Torus Knot Software Ltd +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +----------------------------------------------------------------------------- +*/ + +//----------------------------------------------------------------------------- +// Program Name: SGXLib_Lighting +// Program Desc: Per pixel lighting functions. +// Program Type: Vertex/Pixel shader +// Language: GLSL +// Notes: Implements core functions for FFPLighting class. +// based on lighting engine. +// See http://msdn.microsoft.com/en-us/library/bb147178.aspx +//----------------------------------------------------------------------------- + +#define M_PI 3.141592654 + +#ifdef OGRE_HLSL +void SGX_Flip_Backface_Normal(in float triArea, in float targetFlipped, inout vec3 normal) +{ +#if OGRE_HLSL == 3 + triArea *= -1.0; +#endif + triArea *= targetFlipped; + if(triArea < 0.0) + normal *= -1.0; +} +#else +void SGX_Flip_Backface_Normal(in bool frontFacing, in float targetFlipped, inout vec3 normal) +{ +#ifdef VULKAN + targetFlipped *= -1.0; +#endif + if(targetFlipped < 0.0) + frontFacing = !frontFacing; + if(!frontFacing) + normal *= -1.0; +} +#endif + +//----------------------------------------------------------------------------- +void SGX_Light_Directional_Diffuse( + in vec3 vNormal, + in vec3 vLightDirView, + in vec3 vDiffuseColour, + inout vec3 vOut) +{ + vec3 vNormalView = normalize(vNormal); + float nDotL = dot(vNormalView, -vLightDirView); + + vOut += vDiffuseColour * clamp(nDotL, 0.0, 1.0); + vOut = clamp(vOut, 0.0, 1.0); +} + +//----------------------------------------------------------------------------- +void SGX_Light_Directional_DiffuseSpecular( + in vec3 vNormal, + in vec3 vViewPos, + in vec3 vLightDirView, + in vec3 vDiffuseColour, + in vec3 vSpecularColour, + in float fSpecularPower, + inout vec3 vOutDiffuse, + inout vec3 vOutSpecular) +{ + vec3 vNormalView = normalize(vNormal); + float nDotL = dot(vNormalView, -vLightDirView); + vec3 vView = -normalize(vViewPos); + vec3 vHalfWay = normalize(vView + -vLightDirView); + float nDotH = dot(vNormalView, vHalfWay); + + if (nDotL > 0.0) + { + vOutDiffuse += vDiffuseColour * nDotL; +#ifdef NORMALISED + vSpecularColour *= (fSpecularPower + 8.0)/(8.0 * M_PI); +#endif + vOutSpecular += vSpecularColour * pow(clamp(nDotH, 0.0, 1.0), fSpecularPower); + vOutDiffuse = clamp(vOutDiffuse, 0.0, 1.0); + vOutSpecular = clamp(vOutSpecular, 0.0, 1.0); + } +} + +//----------------------------------------------------------------------------- +void SGX_Light_Point_Diffuse( + in vec3 vNormal, + in vec3 vViewPos, + in vec3 vLightPos, + in vec4 vAttParams, + in vec3 vDiffuseColour, + inout vec3 vOut) +{ + vec3 vLightView = vLightPos - vViewPos; + float fLightD = length(vLightView); + vec3 vNormalView = normalize(vNormal); + float nDotL = dot(vNormalView, normalize(vLightView)); + + if (nDotL > 0.0 && fLightD <= vAttParams.x) + { + float fAtten = 1.0 / (vAttParams.y + vAttParams.z*fLightD + vAttParams.w*fLightD*fLightD); + + vOut += vDiffuseColour * nDotL * fAtten; + vOut = clamp(vOut, 0.0, 1.0); + } +} + + + +//----------------------------------------------------------------------------- +void SGX_Light_Point_DiffuseSpecular( + in vec3 vNormal, + in vec3 vViewPos, + in vec3 vLightPos, + in vec4 vAttParams, + in vec3 vDiffuseColour, + in vec3 vSpecularColour, + in float fSpecularPower, + inout vec3 vOutDiffuse, + inout vec3 vOutSpecular) +{ + vec3 vLightView = vLightPos - vViewPos; + float fLightD = length(vLightView); + vLightView = normalize(vLightView); + vec3 vNormalView = normalize(vNormal); + float nDotL = dot(vNormalView, vLightView); + + if (nDotL > 0.0 && fLightD <= vAttParams.x) + { + vec3 vView = -normalize(vViewPos); + vec3 vHalfWay = normalize(vView + vLightView); + float nDotH = dot(vNormalView, vHalfWay); + float fAtten = 1.0 / (vAttParams.y + vAttParams.z*fLightD + vAttParams.w*fLightD*fLightD); + + vOutDiffuse += vDiffuseColour * nDotL * fAtten; +#ifdef NORMALISED + vSpecularColour *= (fSpecularPower + 8.0)/(8.0 * M_PI); +#endif + vOutSpecular += vSpecularColour * pow(clamp(nDotH, 0.0, 1.0), fSpecularPower) * fAtten; + + vOutDiffuse = clamp(vOutDiffuse, 0.0, 1.0); + vOutSpecular = clamp(vOutSpecular, 0.0, 1.0); + } +} + +//----------------------------------------------------------------------------- +void SGX_Light_Spot_Diffuse( + in vec3 vNormal, + in vec3 vViewPos, + in vec3 vLightPos, + in vec3 vLightDirView, + in vec4 vAttParams, + in vec3 vSpotParams, + in vec3 vDiffuseColour, + inout vec3 vOut) +{ + vec3 vLightView = vLightPos - vViewPos; + float fLightD = length(vLightView); + vLightView = normalize(vLightView); + vec3 vNormalView = normalize(vNormal); + float nDotL = dot(vNormalView, vLightView); + + if (nDotL > 0.0 && fLightD <= vAttParams.x) + { + float fAtten = 1.0 / (vAttParams.y + vAttParams.z*fLightD + vAttParams.w*fLightD*fLightD); + float rho = dot(-vLightDirView, vLightView); + float fSpotE = clamp((rho - vSpotParams.y) / (vSpotParams.x - vSpotParams.y), 0.0, 1.0); + float fSpotT = pow(fSpotE, vSpotParams.z); + + vOut += vDiffuseColour * nDotL * fAtten * fSpotT; + vOut = clamp(vOut, 0.0, 1.0); + } +} + +//----------------------------------------------------------------------------- +void SGX_Light_Spot_DiffuseSpecular( + in vec3 vNormal, + in vec3 vViewPos, + in vec3 vLightPos, + in vec3 vLightDirView, + in vec4 vAttParams, + in vec3 vSpotParams, + in vec3 vDiffuseColour, + in vec3 vSpecularColour, + in float fSpecularPower, + inout vec3 vOutDiffuse, + inout vec3 vOutSpecular) +{ + vec3 vLightView = vLightPos - vViewPos; + float fLightD = length(vLightView); + vLightView = normalize(vLightView); + vec3 vNormalView = normalize(vNormal); + float nDotL = dot(vNormalView, vLightView); + + + if (nDotL > 0.0 && fLightD <= vAttParams.x) + { + vec3 vView = -normalize(vViewPos); + vec3 vHalfWay = normalize(vView + vLightView); + float nDotH = dot(vNormalView, vHalfWay); + float fAtten = 1.0 / (vAttParams.y + vAttParams.z*fLightD + vAttParams.w*fLightD*fLightD); + float rho = dot(-vLightDirView, vLightView); + float fSpotE = clamp((rho - vSpotParams.y) / (vSpotParams.x - vSpotParams.y), 0.0, 1.0); + float fSpotT = pow(fSpotE, vSpotParams.z); + + vOutDiffuse += vDiffuseColour * nDotL * fAtten * fSpotT; +#ifdef NORMALISED + vSpecularColour *= (fSpecularPower + 8.0)/(8.0 * M_PI); +#endif + vOutSpecular += vSpecularColour * pow(clamp(nDotH, 0.0, 1.0), fSpecularPower) * fAtten * fSpotT; + vOutDiffuse = clamp(vOutDiffuse, 0.0, 1.0); + vOutSpecular = clamp(vOutSpecular, 0.0, 1.0); + } +} + diff --git a/Content/OgreInternal/SGXLib_TriplanarTexturing.glsl b/Content/OgreInternal/SGXLib_TriplanarTexturing.glsl new file mode 100644 index 0000000..179c4d7 --- /dev/null +++ b/Content/OgreInternal/SGXLib_TriplanarTexturing.glsl @@ -0,0 +1,47 @@ +/* +----------------------------------------------------------------------------- +This source file is part of OGRE +(Object-oriented Graphics Rendering Engine) +For the latest info, see http://www.ogre3d.org + +Copyright (c) 2000-2014 Torus Knot Software Ltd +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +----------------------------------------------------------------------------- +*/ + +void SGX_TriplanarTexturing(in vec4 diffuse, in vec3 normal, in vec4 position, in sampler2D texFromX, in sampler2D texFromY, in sampler2D texFromZ, in vec3 parameters, out vec4 cOut) +{ + vec3 blendWeights = abs(normalize(normal)); + blendWeights = blendWeights - parameters.y; + blendWeights = pow(max(blendWeights, vec3(0.0, 0.0, 0.0)), parameters.zzz); + float tot = (blendWeights.x + blendWeights.y + blendWeights.z); + blendWeights /= vec3(tot, tot, tot); + // Move the planar mapping a bit according to the normal length to avoid bad looking skirts. + float nLength = length(normal - 1.0); + vec2 coord1 = (position.yz + nLength) * parameters.x; + vec2 coord2 = (position.zx + nLength) * parameters.x; + vec2 coord3 = (position.xy + nLength) * parameters.x; + + vec4 col1 = texture2D(texFromX, coord1); + vec4 col2 = texture2D(texFromY, coord2); + vec4 col3 = texture2D(texFromZ, coord3); + cOut = diffuse * vec4(col1.xyz * blendWeights.x + + col2.xyz * blendWeights.y + + col3.xyz * blendWeights.z, 1); +} diff --git a/Content/OgreInternal/SGXLib_WBOIT.glsl b/Content/OgreInternal/SGXLib_WBOIT.glsl new file mode 100644 index 0000000..961cc3d --- /dev/null +++ b/Content/OgreInternal/SGXLib_WBOIT.glsl @@ -0,0 +1,19 @@ +// This file is part of the OGRE project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at https://www.ogre3d.org/licensing. +// SPDX-License-Identifier: MIT + +float weight(float z, float a) +{ + // from https://casual-effects.blogspot.com/2015/03/implemented-weighted-blended-order.html + return clamp(pow(min(1.0, a * 10.0) + 0.01, 3.0) * 1e8 * pow(1.0 - z * 0.9, 3.0), 1e-2, 3e3); +} + +void SGX_WBOIT(float depth, inout vec4 accum, out vec4 revealage) +{ + vec4 colour = accum; + // Weighted Blended Order-Independent Transparency, Listing 4 + float w = weight(depth, colour.a); + accum = vec4(colour.rgb * w * colour.a, colour.a); + revealage = vec4_splat(colour.a * w); +} \ No newline at end of file diff --git a/Content/OgreInternal/dfgLUTmultiscatter.dds b/Content/OgreInternal/dfgLUTmultiscatter.dds new file mode 100644 index 0000000..51e397b Binary files /dev/null and b/Content/OgreInternal/dfgLUTmultiscatter.dds differ diff --git a/Content/fonts/Cube.mesh b/Content/fonts/Cube.mesh new file mode 100644 index 0000000..7ca09ae Binary files /dev/null and b/Content/fonts/Cube.mesh differ diff --git a/Content/fonts/Material.material b/Content/fonts/Material.material new file mode 100644 index 0000000..5a4c9c8 --- /dev/null +++ b/Content/fonts/Material.material @@ -0,0 +1,11 @@ +// generated by blender2ogre 0.8.3 on 2023-07-10 17:26:00 +material Material { + receive_shadows on + technique { + pass { + diffuse 0.8 0.8 0.8 1.0 + specular 0.512 0.512 0.512 1.0 64.0 + + } + } +} diff --git a/Content/fonts/OgreXMLConverter.log b/Content/fonts/OgreXMLConverter.log new file mode 100644 index 0000000..07d3641 --- /dev/null +++ b/Content/fonts/OgreXMLConverter.log @@ -0,0 +1,21 @@ +17:26:00: XMLMeshSerializer reading mesh data from /home/caesium/projects/rbxnu/Content/fonts/Cube.mesh.xml... +17:26:00: Reading geometry... +17:26:00: Geometry done... +17:26:00: Reading submeshes... +17:26:00: Submeshes done. +17:26:00: Reading mesh names... +17:26:00: Mesh names done. +17:26:00: XMLMeshSerializer import successful. +17:26:00: MeshSerializer writing mesh data to stream /home/caesium/projects/rbxnu/Content/fonts/Cube.mesh... +17:26:00: File header written. +17:26:00: Writing mesh data... +17:26:00: Writing submesh... +17:26:00: Exporting submesh texture aliases... +17:26:00: Submesh texture aliases exported. +17:26:00: Submesh exported. +17:26:00: Exporting bounds information.... +17:26:00: Bounds information exported. +17:26:00: Exporting submesh name table... +17:26:00: Submesh name table exported. +17:26:00: Mesh data exported. +17:26:00: MeshSerializer export successful. diff --git a/Content/fonts/part_mesh.mtl b/Content/fonts/part_mesh.mtl new file mode 100644 index 0000000..2c63179 --- /dev/null +++ b/Content/fonts/part_mesh.mtl @@ -0,0 +1,12 @@ +# Blender 3.5.1 MTL File: 'None' +# www.blender.org + +newmtl Material +Ns 250.000000 +Ka 1.000000 1.000000 1.000000 +Kd 0.800000 0.800000 0.800000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 diff --git a/Content/fonts/part_mesh.obj b/Content/fonts/part_mesh.obj new file mode 100644 index 0000000..7ef1677 --- /dev/null +++ b/Content/fonts/part_mesh.obj @@ -0,0 +1,40 @@ +# Blender 3.5.1 +# www.blender.org +mtllib part_mesh.mtl +o FormFactor_Brick +v 1.000000 1.000000 -1.000000 +v 1.000000 -1.000000 -1.000000 +v 1.000000 1.000000 1.000000 +v 1.000000 -1.000000 1.000000 +v -1.000000 1.000000 -1.000000 +v -1.000000 -1.000000 -1.000000 +v -1.000000 1.000000 1.000000 +v -1.000000 -1.000000 1.000000 +vn -0.0000 1.0000 -0.0000 +vn -0.0000 -0.0000 1.0000 +vn -1.0000 -0.0000 -0.0000 +vn -0.0000 -1.0000 -0.0000 +vn 1.0000 -0.0000 -0.0000 +vn -0.0000 -0.0000 -1.0000 +vt 0.625000 0.500000 +vt 0.375000 0.500000 +vt 0.625000 0.750000 +vt 0.375000 0.750000 +vt 0.875000 0.500000 +vt 0.625000 0.250000 +vt 0.125000 0.500000 +vt 0.375000 0.250000 +vt 0.875000 0.750000 +vt 0.625000 1.000000 +vt 0.625000 0.000000 +vt 0.375000 1.000000 +vt 0.375000 0.000000 +vt 0.125000 0.750000 +s 0 +usemtl Material +f 1/1/1 5/5/1 7/9/1 3/3/1 +f 4/4/2 3/3/2 7/10/2 8/12/2 +f 8/13/3 7/11/3 5/6/3 6/8/3 +f 6/7/4 2/2/4 4/4/4 8/14/4 +f 2/2/5 1/1/5 3/3/5 4/4/5 +f 6/8/6 5/6/6 1/1/6 2/2/6 diff --git a/Content/fonts/part_mesh.scene b/Content/fonts/part_mesh.scene new file mode 100644 index 0000000..62b1ab7 --- /dev/null +++ b/Content/fonts/part_mesh.scene @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Projects/Client/Common/CMakeLists.txt b/Projects/Client/Common/CMakeLists.txt index 00de331..b6cea5a 100644 --- a/Projects/Client/Common/CMakeLists.txt +++ b/Projects/Client/Common/CMakeLists.txt @@ -12,11 +12,13 @@ qt_add_library(Common STATIC Source/OgreWidget.cpp ) -add_custom_command(TARGET Common POST_BUILD - COMMAND ${TOOL_WINDEPLOYQT} - $ - COMMENT "Running windeployqt..." -) +if(WIN32) + add_custom_command(TARGET Common POST_BUILD + COMMAND ${TOOL_WINDEPLOYQT} + $ + COMMENT "Running windeployqt..." + ) +endif() target_include_directories(Common PUBLIC Header) target_link_libraries(Common PUBLIC ${QT6_LIBRARIES_INCL} Engine) \ No newline at end of file diff --git a/Projects/Client/Common/Header/OgreWidget.hpp b/Projects/Client/Common/Header/OgreWidget.hpp index e0b32ca..437e980 100644 --- a/Projects/Client/Common/Header/OgreWidget.hpp +++ b/Projects/Client/Common/Header/OgreWidget.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -29,6 +30,7 @@ namespace RNR Ogre::RenderWindow* ogreWindow; Ogre::SceneManager* ogreSceneManager; Ogre::Camera* ogreCamera; + Ogre::RTShader::ShaderGenerator* ogreShaderGen; void render(); void initializeOgre(); diff --git a/Projects/Client/Common/Source/OgreWidget.cpp b/Projects/Client/Common/Source/OgreWidget.cpp index 6d1f596..8a8d6e3 100644 --- a/Projects/Client/Common/Source/OgreWidget.cpp +++ b/Projects/Client/Common/Source/OgreWidget.cpp @@ -1,6 +1,9 @@ #include #include +#include +#include + #ifdef __unix__ #include #include @@ -26,7 +29,7 @@ namespace RNR { Ogre::NameValuePairList options = this->getRenderOptions(); - printf("Widget::initializeOgre: initializing render window\n"); + printf("OgreWidget::initializeOgre: initializing render window\n"); ogreWindow = ogreRoot->createRenderWindow("GLWidget-RenderWindow", width(), height(), false, &options); ogreWindow->setActive(true); ogreWindow->setVisible(true); @@ -34,16 +37,26 @@ namespace RNR Ogre::ResourceGroupManager::getSingletonPtr()->addResourceLocation("content", "FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true); Ogre::ResourceGroupManager::getSingletonPtr()->addResourceLocation("../Content", "FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true); + Ogre::ResourceGroupManager::getSingletonPtr()->addResourceLocation("content/OgreInternal", "FileSystem", Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, true); + Ogre::ResourceGroupManager::getSingletonPtr()->addResourceLocation("../Content/OgreInternal", "FileSystem", Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, true); Ogre::ResourceGroupManager::getSingletonPtr()->initialiseAllResourceGroups(); Ogre::MaterialManager::getSingletonPtr()->load("sky", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + Ogre::MaterialManager::getSingletonPtr()->load("materials", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); ogreSceneManager = ogreRoot->createSceneManager(); ogreSceneManager->setSkyBox(true, "sky/null_plainsky512", 5.f); ogreSceneManager->setAmbientLight(Ogre::ColourValue::White); - //Ogre::RTShader::ShaderGenerator* shadergen = Ogre::RTShader::ShaderGenerator::getSingletonPtr(); - //shadergen->addSceneManager(ogreSceneManager); + if(Ogre::RTShader::ShaderGenerator::initialize()) + { + ogreShaderGen = Ogre::RTShader::ShaderGenerator::getSingletonPtr(); + ogreShaderGen->addSceneManager(ogreSceneManager); + OgreBites::SGTechniqueResolverListener* schemeNotFoundHandler = new OgreBites::SGTechniqueResolverListener(ogreShaderGen); + Ogre::MaterialManager::getSingleton().addListener(schemeNotFoundHandler); + } + else + printf("OgreWidget::initializeOgre: unable to initialize ShaderGenerator\n"); Ogre::Light* light = ogreSceneManager->createLight("MainLight"); Ogre::SceneNode* lightNode = ogreSceneManager->getRootSceneNode()->createChildSceneNode(); @@ -70,8 +83,8 @@ namespace RNR this->render_time += ogreRoot->getTimer()->getMilliseconds() / 1000.0; ogreRoot->getTimer()->reset(); - ogreCamera->getParentSceneNode()->lookAt(Ogre::Vector3(sinf(render_time)*5.f, cosf(render_time)*5.f, 0.f), Ogre::Node::TS_PARENT); - + ogreCamera->getParentSceneNode()->lookAt(Ogre::Vector3(sinf(this->render_time)*10.f,0,cosf(this->render_time)*10.f), Ogre::Node::TS_PARENT); + ogreRoot->renderOneFrame(this->delta); } @@ -92,7 +105,7 @@ namespace RNR { Ogre::String windowHandle; windowHandle = Ogre::StringConverter::toString((unsigned long)winId()); - printf("Widget::getWindowHandle(): %s\n", windowHandle.c_str()); + printf("OgreWidget::getWindowHandle(): %s\n", windowHandle.c_str()); return windowHandle; } diff --git a/Projects/Client/Studio/Source/MainWindow.cpp b/Projects/Client/Studio/Source/MainWindow.cpp index 83073a3..a5cadd6 100644 --- a/Projects/Client/Studio/Source/MainWindow.cpp +++ b/Projects/Client/Studio/Source/MainWindow.cpp @@ -2,6 +2,8 @@ #include #include #include +#include + #include "Resources/StudioResources.hpp" @@ -14,7 +16,8 @@ MainWindow::MainWindow() QGridLayout* grid = new QGridLayout(); ogreRoot = new Ogre::Root(); - ogreRoot->showConfigDialog(NULL); + Ogre::ConfigDialog* config = OgreBites::getNativeConfigDialog(); + ogreRoot->showConfigDialog(config); ogreRoot->initialise(false); menubar = new QMenuBar(); diff --git a/Projects/Client/Studio/Source/main.cpp b/Projects/Client/Studio/Source/main.cpp index 8bd7785..20092b2 100644 --- a/Projects/Client/Studio/Source/main.cpp +++ b/Projects/Client/Studio/Source/main.cpp @@ -21,6 +21,10 @@ int main(int argc, char** argv) window.ogreWidget->initializeOgre(); RNR::World* world = new RNR::World(); + Ogre::SceneNode* workspace_node = window.ogreWidget->ogreSceneManager->createSceneNode("Workspace"); + workspace_node->attachObject(world->getWorkspace()); + workspace_node->setVisible(true); + printf("main: workspace = %p (%p)\n",workspace_node, world->getWorkspace()); window.updateTree(world->getDatamodel()); while (window.isVisible()) diff --git a/Projects/Engine/CMakeLists.txt b/Projects/Engine/CMakeLists.txt index e06c3b0..c2a9a08 100644 --- a/Projects/Engine/CMakeLists.txt +++ b/Projects/Engine/CMakeLists.txt @@ -6,8 +6,12 @@ add_library(Engine STATIC Header/Helpers/Strings.hpp Header/App/Humanoid/Humanoid.hpp Header/App/V8/DataModel/ForceField.hpp + Header/App/V8/DataModel/BasePart.hpp Header/App/V8/Tree/Instance.hpp + Header/App/V8/Tree/PVInstance.hpp Header/App/V8/World/World.hpp + Header/App/V8/World/Workspace.hpp + Header/App/CoordinateFrame.hpp Header/Network/GUID.hpp Header/Rendering/Adorn.hpp @@ -15,8 +19,12 @@ add_library(Engine STATIC Source/Helpers/Strings.cpp Source/App/Humanoid/Humanoid.cpp Source/App/V8/DataModel/ForceField.cpp + Source/App/V8/DataModel/BasePart.cpp Source/App/V8/Tree/Instance.cpp + Source/App/V8/Tree/PVInstance.cpp + Source/App/CoordinateFrame.cpp Source/App/V8/World/World.cpp + Source/App/V8/World/Workspace.cpp Source/Network/GUID.cpp Source/Rendering/Adorn.cpp ) diff --git a/Projects/Engine/Header/App/CoordinateFrame.hpp b/Projects/Engine/Header/App/CoordinateFrame.hpp new file mode 100644 index 0000000..3ec459a --- /dev/null +++ b/Projects/Engine/Header/App/CoordinateFrame.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace RNR +{ + class CoordinateFrame + { + Ogre::Vector3 m_position; + Ogre::Matrix3 m_rotation; +public: + CoordinateFrame(); + + Ogre::Matrix3 getRotation() { return m_rotation; } + Ogre::Vector3 getPosition() { return m_position; } + + Ogre::Matrix4 getMatrix(); + + CoordinateFrame operator+(Ogre::Vector3 vector); + CoordinateFrame operator*(CoordinateFrame frame); + }; +} \ No newline at end of file diff --git a/Projects/Engine/Header/App/V8/DataModel/BasePart.hpp b/Projects/Engine/Header/App/V8/DataModel/BasePart.hpp new file mode 100644 index 0000000..1f4494f --- /dev/null +++ b/Projects/Engine/Header/App/V8/DataModel/BasePart.hpp @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +namespace RNR +{ + class BasePart : public PVInstance, public Ogre::Renderable + { + Ogre::MaterialPtr m_material; + Ogre::Matrix4 m_matrix; + Ogre::Vector3 m_position; + Ogre::LightList m_nearbyLights; + static Ogre::MeshPtr m_partMesh; + public: + BasePart(); + + void updateMatrix(); + + virtual const Ogre::MaterialPtr& getMaterial() const; + virtual void getRenderOperation(Ogre::RenderOperation& op); + virtual Ogre::Real getSquaredViewDepth(const Ogre::Camera* cam) const; + virtual const Ogre::LightList& getLights() const; + virtual void getWorldTransforms(Ogre::Matrix4* xform) const; + }; +} \ No newline at end of file diff --git a/Projects/Engine/Header/App/V8/Tree/Instance.hpp b/Projects/Engine/Header/App/V8/Tree/Instance.hpp index 87b35ad..79716f7 100644 --- a/Projects/Engine/Header/App/V8/Tree/Instance.hpp +++ b/Projects/Engine/Header/App/V8/Tree/Instance.hpp @@ -19,7 +19,6 @@ namespace RNR public: Instance(); - Instance(std::string name); ~Instance(); bool contains(RNR::Instance* child); diff --git a/Projects/Engine/Header/App/V8/Tree/PVInstance.hpp b/Projects/Engine/Header/App/V8/Tree/PVInstance.hpp new file mode 100644 index 0000000..870ce09 --- /dev/null +++ b/Projects/Engine/Header/App/V8/Tree/PVInstance.hpp @@ -0,0 +1,20 @@ +#pragma once +#include +#include + +namespace RNR +{ + class PVInstance : public Instance + { + protected: + CoordinateFrame m_cframe; + public: + PVInstance(); + + CoordinateFrame getCFrame() { return m_cframe; }; + void setCFrame(CoordinateFrame cframe) { m_cframe = cframe; }; + + Ogre::Vector3 getPosition() { return m_cframe.getPosition(); } + Ogre::Matrix3 getRotation() { return m_cframe.getRotation(); } + }; +} diff --git a/Projects/Engine/Header/App/V8/World/Workspace.hpp b/Projects/Engine/Header/App/V8/World/Workspace.hpp new file mode 100644 index 0000000..33df1ff --- /dev/null +++ b/Projects/Engine/Header/App/V8/World/Workspace.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +namespace RNR +{ + // this acts as both an Instance to fit in the RNR graph, and as an Ogre MovableObject to fit in the Ogre graph + // all instances that are Renderable are stored in the children of this + class Workspace : public Instance, public Ogre::MovableObject + { + public: + Workspace(); + + virtual void _updateRenderQueue(Ogre::RenderQueue* queue); + virtual const Ogre::String& getMovableType(void) const; + virtual const Ogre::AxisAlignedBox& getBoundingBox(void) const; + virtual Ogre::Real getBoundingRadius(void) const; + virtual void visitRenderables(Ogre::Renderable::Visitor* visitor, bool debugRenderables); + private: + void renderQueueAddInstance(Ogre::RenderQueue* queue, Instance* instance); + }; +} diff --git a/Projects/Engine/Header/App/V8/World/World.hpp b/Projects/Engine/Header/App/V8/World/World.hpp index ee38d52..1dd9f62 100644 --- a/Projects/Engine/Header/App/V8/World/World.hpp +++ b/Projects/Engine/Header/App/V8/World/World.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace RNR { @@ -8,6 +9,7 @@ namespace RNR { private: Instance* m_datamodel; + Workspace* m_workspace; public: World(); @@ -19,5 +21,7 @@ namespace RNR Instance* getDatamodel() { return m_datamodel; } void setDatamodel(Instance* instance) { m_datamodel = instance; } + Workspace* getWorkspace() { return m_workspace; } + void setWorkspace(Workspace* workspace) { m_workspace = workspace; } }; } \ No newline at end of file diff --git a/Projects/Engine/Header/Rendering/PartMeshFactory.hpp b/Projects/Engine/Header/Rendering/PartMeshFactory.hpp new file mode 100644 index 0000000..e69de29 diff --git a/Projects/Engine/Source/App/CoordinateFrame.cpp b/Projects/Engine/Source/App/CoordinateFrame.cpp new file mode 100644 index 0000000..852d7ca --- /dev/null +++ b/Projects/Engine/Source/App/CoordinateFrame.cpp @@ -0,0 +1,31 @@ +#include + +namespace RNR +{ + CoordinateFrame::CoordinateFrame() : m_position(0.f,0.f,0.f), m_rotation() + { + m_rotation.FromEulerAnglesXYZ(Ogre::Radian(0.f), Ogre::Radian(0.f), Ogre::Radian(0.f)); + } + + Ogre::Matrix4 CoordinateFrame::getMatrix() + { + Ogre::Matrix4 res = Ogre::Matrix4(); + res.makeTransform(m_position, Ogre::Vector3(1.f,1.f,1.f), Ogre::Quaternion(m_rotation)); + return res; + } + + CoordinateFrame CoordinateFrame::operator+(Ogre::Vector3 vector) + { + CoordinateFrame res; + res.m_position = m_position + vector; + return res; + } + + CoordinateFrame CoordinateFrame::operator*(CoordinateFrame frame) + { + CoordinateFrame res; + res.m_position = m_position * frame.m_position; + res.m_rotation = m_rotation * frame.m_rotation; + return res; + } +} \ No newline at end of file diff --git a/Projects/Engine/Source/App/V8/DataModel/BasePart.cpp b/Projects/Engine/Source/App/V8/DataModel/BasePart.cpp new file mode 100644 index 0000000..d51de13 --- /dev/null +++ b/Projects/Engine/Source/App/V8/DataModel/BasePart.cpp @@ -0,0 +1,58 @@ +#include + +namespace RNR +{ + Ogre::MeshPtr BasePart::m_partMesh = 0; + + BasePart::BasePart() : m_matrix(), PVInstance() + { + setName("Part"); + + updateMatrix(); + + m_material = Ogre::MaterialManager::getSingletonPtr()->create("part", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + + if(m_partMesh == 0) + m_partMesh = Ogre::Root::getSingletonPtr()->getMeshManager()->load("fonts/Cube.mesh", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + } + + void BasePart::updateMatrix() + { + m_matrix = m_cframe.getMatrix(); + m_position = m_cframe.getPosition(); + m_nearbyLights = Ogre::LightList(); + + } + + const Ogre::MaterialPtr& BasePart::getMaterial() const + { + return m_material; + } + + void BasePart::getRenderOperation(Ogre::RenderOperation& op) + { + Ogre::SubMesh* submesh = m_partMesh->getSubMesh(0); + op.operationType = op.OT_TRIANGLE_LIST; + op.vertexData = submesh->vertexData; + op.indexData = submesh->indexData; + op.numberOfInstances = 1; + op.srcRenderable = this; + op.useIndexes = true; + } + + Ogre::Real BasePart::getSquaredViewDepth(const Ogre::Camera* cam) const + { + Ogre::Vector3 diff = m_position - cam->getDerivedPosition(); + return diff.squaredLength(); + } + + const Ogre::LightList& BasePart::getLights() const + { + return m_nearbyLights; + } + + void BasePart::getWorldTransforms(Ogre::Matrix4* xform) const + { + xform[0] = m_matrix; + } +} \ No newline at end of file diff --git a/Projects/Engine/Source/App/V8/Tree/Instance.cpp b/Projects/Engine/Source/App/V8/Tree/Instance.cpp index cb70281..827e2f3 100644 --- a/Projects/Engine/Source/App/V8/Tree/Instance.cpp +++ b/Projects/Engine/Source/App/V8/Tree/Instance.cpp @@ -8,22 +8,21 @@ namespace RNR setName("Instance"); } - Instance::Instance(std::string name) + Instance::~Instance() { - m_parent = 0; - setName(name); + setParent(NULL); } - bool Instance::contains(RNR::Instance* child) + bool Instance::contains(Instance* child) { auto child_it = std::find(m_children.begin(), m_children.end(), child); return child_it != m_children.end(); } - bool RNR::Instance::isAncestorOf(RNR::Instance* instance) + bool Instance::isAncestorOf(Instance* instance) { - RNR::Instance* instance_parent = instance->m_parent; + Instance* instance_parent = instance->m_parent; while (instance_parent != 0) { instance_parent = instance_parent->m_parent; @@ -35,22 +34,22 @@ namespace RNR return false; } - bool RNR::Instance::askSetParent(RNR::Instance* instance) + bool Instance::askSetParent(Instance* instance) { return true; } - bool RNR::Instance::canSetParent(RNR::Instance* instance) + bool Instance::canSetParent(Instance* instance) { return !instance || instance->canAddChild(this); } - bool RNR::Instance::askAddChild(RNR::Instance* instance) + bool Instance::askAddChild(Instance* instance) { return true; } - bool RNR::Instance::canAddChild(RNR::Instance* instance) + bool Instance::canAddChild(Instance* instance) { if (instance->contains(this) || instance->m_parent == this) return false; @@ -61,7 +60,7 @@ namespace RNR return instance->askSetParent(this); } - void RNR::Instance::setName(std::string name) + void Instance::setName(std::string name) { if (name != this->m_name) { @@ -70,7 +69,7 @@ namespace RNR } } - void RNR::Instance::setParent(RNR::Instance* newParent) + void Instance::setParent(Instance* newParent) { if (newParent != m_parent) { @@ -88,7 +87,7 @@ namespace RNR if (m_parent) { - std::vector* children = m_parent->getChildren(); + std::vector* children = m_parent->getChildren(); auto child_it = std::find(children->begin(), children->end(), this); if (child_it != children->end()) @@ -101,12 +100,15 @@ namespace RNR } m_parent = newParent; - m_parent->m_children.push_back(this); - newParent->onChildAdded(this); + if(m_parent) + { + m_parent->m_children.push_back(this); + newParent->onChildAdded(this); + } } } - void RNR::Instance::onChildAdded(RNR::Instance* childAdded) + void Instance::onChildAdded(Instance* childAdded) { // } diff --git a/Projects/Engine/Source/App/V8/Tree/PVInstance.cpp b/Projects/Engine/Source/App/V8/Tree/PVInstance.cpp new file mode 100644 index 0000000..f4cac8e --- /dev/null +++ b/Projects/Engine/Source/App/V8/Tree/PVInstance.cpp @@ -0,0 +1,9 @@ +#include + +namespace RNR +{ + PVInstance::PVInstance() : m_cframe(), Instance() + { + + } +} \ No newline at end of file diff --git a/Projects/Engine/Source/App/V8/World/Workspace.cpp b/Projects/Engine/Source/App/V8/World/Workspace.cpp new file mode 100644 index 0000000..aad767a --- /dev/null +++ b/Projects/Engine/Source/App/V8/World/Workspace.cpp @@ -0,0 +1,51 @@ +#include +#include + +namespace RNR +{ + Workspace::Workspace() : Instance(), Ogre::MovableObject() + { + setName("Workspace"); + } + + void Workspace::_updateRenderQueue(Ogre::RenderQueue* queue) + { + printf("!!!!!!!!!!!!!!!!!!!!1 _updateRenderQueue\n"); + std::vector* children = getChildren(); + for(auto& child : *children) + { + renderQueueAddInstance(queue, child); + } + } + + void Workspace::renderQueueAddInstance(Ogre::RenderQueue* queue, Instance* instance) + { + std::vector* children = instance->getChildren(); + for(auto& child : *children) + { + renderQueueAddInstance(queue, child); + } + BasePart* rend = dynamic_cast(instance); + queue->addRenderable(rend); + } + + const Ogre::String& Workspace::getMovableType(void) const + { + return Ogre::String("Entity"); + } + + const Ogre::AxisAlignedBox& Workspace::getBoundingBox(void) const + { + return Ogre::AxisAlignedBox(Ogre::Vector3(-1000,-1000,-1000),Ogre::Vector3(1000,1000,1000)); + } + + Ogre::Real Workspace::getBoundingRadius(void) const + { + return 100; + } + + void Workspace::visitRenderables(Ogre::Renderable::Visitor* visitor, bool debugRenderables) + { + + } +} \ No newline at end of file diff --git a/Projects/Engine/Source/App/V8/World/World.cpp b/Projects/Engine/Source/App/V8/World/World.cpp index 8f56d7b..7b6a69d 100644 --- a/Projects/Engine/Source/App/V8/World/World.cpp +++ b/Projects/Engine/Source/App/V8/World/World.cpp @@ -1,4 +1,5 @@ #include +#include namespace RNR { @@ -6,15 +7,13 @@ namespace RNR { m_datamodel = new Instance(); m_datamodel->setName("DataModel"); + m_workspace = new Workspace(); + m_workspace->setParent(m_datamodel); Instance* test = new Instance(); - Instance* test2 = new Instance(); - test->setParent(m_datamodel); - test2->setParent(test); - test = new Instance(); - test->setParent(m_datamodel); - test = new Instance(); + BasePart* test2 = new BasePart(); test->setParent(m_datamodel); + test2->setParent(m_workspace); } World::~World() diff --git a/Projects/Engine/Source/Rendering/PartMeshFactory.cpp b/Projects/Engine/Source/Rendering/PartMeshFactory.cpp new file mode 100644 index 0000000..e69de29