Skip to content

Instantly share code, notes, and snippets.

@strzlee
Created June 29, 2020 06:18
Show Gist options
  • Save strzlee/35003b6143328db672f6d6ca72564222 to your computer and use it in GitHub Desktop.
Save strzlee/35003b6143328db672f6d6ca72564222 to your computer and use it in GitHub Desktop.
nms shader
#version 450 core
#define D_PLATFORM_PC
#define D_FRAGMENT
// ---- Flags ----
#define _F01_
#define _F02_
#define _F07_
#define _F10_
#define _F27_
#define _F29_
// ---------------
// PIXEL SHADER: SHADERS/SCREEN.SHADER.BIN
// CONTEXT: ICON_FORWARD_NS
// =================================================================================================
#define D_NO_SHADOWS
#define D_NO_POSTPROCESS
////////////////////////////////////////////////////////////////////////////////
///
/// @file ScreenFragmentShader.h
/// @author User
/// @date
///
/// @brief ScreenFragmentShader
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Compilation defines
#ifdef _F20_
#define _F03_
#endif
#if defined( _F25_ ) || defined( _F41_ ) || defined( _F42_ )
#define D_MASKS
#endif
#if defined( _F01_ ) || defined( _F03_ ) || defined( _F42_ ) || defined( _F41_ )
#define D_TEXCOORDS
#endif
//TRAILERHACKS
//#if defined( _F04_ENVMAP ) || !defined( _F07_UNLIT ) || defined( _F23_FOG )
#define D_USES_WORLD_POSITION
//#endif
#ifndef _F03_
#if defined( _F04_ ) || !defined( _F07_ )
#define D_USES_VERTEX_NORMAL
#endif
#endif
#define D_FADE
#if defined( _F02_ )
#define D_SKINNING_UNIFORMS
#endif
#if !defined( D_DEFER ) || defined( D_OUTPUT_MOTION_VECTORS )
#define D_USE_SCREEN_POSITION
#endif
//-----------------------------------------------------------------------------
// Include files
////////////////////////////////////////////////////////////////////////////////
///
/// @file CommonUniforms.h
/// @author User
/// @date
///
/// @brief CommonUniforms
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
#ifndef D_COMMONUNIFORMS2_H
#define D_COMMONUNIFORMS2_H
// =================================================================================================
#ifndef D_DEFINES
#define D_DEFINES
// =================================================================================================
// Platform defines
// =================================================================================================
#ifdef D_PLATFORM_PC
#define D_ENABLE_REVERSEZ_PROJECTION (1)
#pragma optionNV(strict on)
#extension GL_ARB_gpu_shader5 : enable
#extension GL_ARB_fragment_coord_conventions : enable
#extension GL_ARB_derivative_control : enable
#if defined( D_FRAGMENT ) && defined( _F64_ )
layout(early_fragment_tests) in;
#endif
#elif defined(D_PLATFORM_ORBIS)
#define D_ENABLE_REVERSEZ_PROJECTION (1)
// use this with sdk 2.0 compiler
// #pragma argument (allow-scratch-buffer-spill)
//define these flags so they don't get ignored in build process and in the comb mask
//this is because materials, vertex layouts and shaders need to be synced on 360 to avoid patching
#ifdef _F27_
#endif
#ifdef _F28_
#endif
#ifdef _F29_
#endif
#ifdef _F21_
#endif
#ifdef _F02_
#endif
#ifdef _F03_
#endif
#if defined( _F01_ ) || defined( D_LOD0 ) || defined( D_LOD1 ) || defined( D_LOD2 ) || defined( D_LOD3) || defined( D_LOD4 )
#endif
#ifdef _F01_
#endif
#ifdef _F09_
#endif
#ifdef _F10_
#endif
// disable warnings for unused parameters. This happens a lot because of defining different things.
#pragma warning (disable: 5203)
// temp thing to know what things are still required on ps4.
#define D_PLATFORM_ORBIS_FIX
#ifdef __PSSL_CS__
#define D_PLATFORM_ORBIS_COMPUTE
#endif
#ifdef __PSSL_HS__
#define D_HULL
#endif
#ifdef __PSSL_DS__
#define D_DOMAIN
#endif
#ifdef __PSSL_VS__
#define D_VERTEX
#endif
#ifdef __PSSL_GS__
#define D_GEOMETRY
#endif
#endif
#if !D_ENABLE_REVERSEZ_PROJECTION
#define D_USING_LOGDEPTH
#endif
// =================================================================================================
// Basic Types
// =================================================================================================
#ifdef D_PLATFORM_PC
#define JOINT_TYPE vec4
//#define CONST const
#define STATIC_CONST const
#elif defined(D_PLATFORM_ORBIS)
#define JOINT_TYPE int4
#define float float
#define vec2 float2
#define vec3 float3
#define vec4 float4
#define ivec2 int2
#define ivec3 int3
#define ivec4 int4
#define uvec2 uint2
#define uvec3 uint3
#define uvec4 uint4
// NOTE:
// operator[] accesses rows, not columns
// matrix constructors interpret the passed vectors as row vectors, not column vectors
#define mat2 row_major float2x2
#define mat3 row_major float3x3
#define mat4 row_major float4x4
//#define CONST
#define STATIC_CONST static const
// #define const ERROR, DON'T USE CONST FOR PS4. USE STATIC_CONST INSTEAD FOR A COMPILED IN CONSTANT. OTHERWISE IT TRIES TO PUT IT IN A CONSTANT BUFFER AND FOR SOME REASON IT DOESN'T WORK.
#endif
// =================================================================================================
// Functions
// =================================================================================================
#ifdef D_PLATFORM_PC
#define saturate( V ) min( max( V, 0.0) , 1.0)
#define atan2( Y, X ) atan( Y, X )
#define invsqrt( X ) inversesqrt( X )
#ifdef D_COMPUTE
#define groupID gl_WorkGroupID
#define groupThreadID gl_LocalInvocationID
#define dispatchThreadID gl_GlobalInvocationID
#endif
#elif defined(D_PLATFORM_ORBIS)
#if defined(D_PLATFORM_ORBIS_COMPUTE)
float dFdx( float var ) { float delta = var - LaneSwizzle( var, 0x1f, 0, 1 ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
float dFdy( float var ) { float delta = var - LaneSwizzle( var, 0x1f, 0, 8 ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec2 dFdx( vec2 var ) { vec2 delta = vec2( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec2 dFdy( vec2 var ) { vec2 delta = vec2( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec3 dFdx( vec3 var ) { vec3 delta = vec3( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec3 dFdy( vec3 var ) { vec3 delta = vec3( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec4 dFdx( vec4 var ) { vec4 delta = vec4( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.w, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec4 dFdy( vec4 var ) { vec4 delta = vec4( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.w, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
#define dFdxFine dFdx
#define dFdyFine dFdy
#else
#define dFdx ddx
#define dFdy ddy
#define dFdxFine ddx_fine
#define dFdyFine ddy_fine
#endif
#define mix lerp
#define fract frac
#define mod fmod
#define saturate( V ) ( min( max( V, 0.0) , 1.0) )
#define invsqrt( X ) rsqrt( X )
#endif
// =================================================================================================
// Samplers and textures
// =================================================================================================
#ifdef D_PLATFORM_PC
#define shadow2D( S, UV ) texture( S, UV )
#define SAMPLER2DSHADOW( NAME, REG ) uniform sampler2DShadow NAME
#define SAMPLERCUBE( NAME ) samplerCube NAME
#define SAMPLERCUBEARG( NAME ) in samplerCube NAME
#define SAMPLERCUBEPARAM( NAME ) NAME
#define imageAtomicAddOut( T, C, V, O ) O = imageAtomicAdd( T, C, V )
#if defined( D_TEXTURE_FEEDBACK )
#define texture2D( T, C ) Tex2dFeedback( T, T##FB, C )
#define texture2DLod( T, C, N ) Tex2dLodFeedback( T, T##FB, C, N )
#define texture2DArray( T, C ) Tex2dArrayFeedback( T, T##FB, C )
#define texture3D( S, UV ) Tex3dFeedback( S, S##FB, UV )
#define texture3DLod( S, UV, LOD ) Tex3dLodFeedback( S, S##FB, UV, LOD )
#define SAMPLER2DARG( NAME ) in sampler2D NAME, in int NAME##FB
#define SAMPLER2DPARAM( NAME ) NAME, NAME##FB
#define SAMPLER2DARRAYARG( NAME ) in sampler2DArray NAME, in int NAME##FB
#define SAMPLER2DARRAYPARAM( NAME ) NAME, NAME##FB
#define SAMPLER2D( NAME ) sampler2D NAME; int NAME##FB
#define SAMPLER2DARRAY( NAME ) sampler2DArray NAME; int NAME##FB
#define SAMPLER3D( NAME ) sampler3D NAME; int NAME##FB
#define SAMPLER2DSHADOW_SRT( NAME ) sampler2DShadow NAME; int NAME##FB
#else
#define texture2DLod( S, UV, LOD ) textureLod( S, UV, LOD )
#define texture3DLod( S, UV, LOD ) textureLod( S, UV, LOD )
#define SAMPLER2DARG( NAME ) in sampler2D NAME
#define SAMPLER2DPARAM( NAME ) NAME
#define SAMPLER2DARRAYARG( NAME ) in sampler2DArray NAME
#define SAMPLER2DARRAYPARAM( NAME ) NAME
#define SAMPLER2D( NAME ) sampler2D NAME
#define SAMPLER2DARRAY( NAME ) sampler2DArray NAME
#define SAMPLER3D( NAME ) sampler3D NAME
#define SAMPLER2DSHADOW_SRT( NAME ) sampler2DShadow NAME
#endif
#define textureGatherRed( lTex, lSamp ) textureGather( lTex, lSamp, 0 )
#define textureGatherGreen( lTex, lSamp ) textureGather( lTex, lSamp, 1 )
#define textureGatherBlue( lTex, lSamp ) textureGather( lTex, lSamp, 2 )
#define textureGatherAlpha( lTex, lSamp ) textureGather( lTex, lSamp, 3 )
#define texture2DComputeGrad( T, C ) texture2D( T, C )
#elif defined(D_PLATFORM_ORBIS)
#define SAMPLERCUBE( NAME, REG ) SamplerState NAME##SS : register( s##REG ); TextureCube NAME##TU : register( t##REG )
#define SAMPLER2D( NAME ) Texture2D NAME; SamplerState NAME##SS
#define SAMPLER2DSHADOW_SRT( NAME ) Texture2D NAME; SamplerComparisonState NAME##SS //SAMPLER2D( NAME )
#define SAMPLER3D( NAME ) Texture3D NAME; SamplerState NAME##SS
#define SAMPLER2DARRAY( NAME ) Texture2D_Array NAME; SamplerState NAME##SS
#define SAMPLER2DARRAYARG( NAME ) Texture2D_Array NAME, SamplerState NAME##SS
#define SAMPLER2DARRAYPARAM( NAME ) NAME, NAME##SS
#define SAMPLER2DPARAM( NAME ) NAME, NAME##SS
#define SAMPLER2DARG( NAME ) Texture2D NAME, SamplerState NAME##SS
#define texture2D( T, C ) T.Sample( T##SS, C )
#if defined(D_PLATFORM_ORBIS_COMPUTE)
#define texture2DComputeGrad( T, C ) T.SampleGradient( T##SS, C, vec2( dFdx( C ) ), vec2( dFdy( C ) ) )
#define shadow2D( T, C ) T.SampleCmpLOD0( T##SS, C.xy, C.z )
#else
#define texture2DComputeGrad( T, C ) T.Sample( T##SS, C )
#define shadow2D( T, C ) T.SampleCmp( T##SS, C.xy, C.z )
#endif
#define texture2DLod( T, C, N ) T.SampleLOD( T##SS, C, N )
#define texture2DArray( T, C ) T.Sample( T##SS, C )
#define texture3DLod( T, C, N ) T.SampleLOD( T##SS, C, N )
//#define shadow2D( T, C ) vec3( C.z > T.Sample( T##SS, C.xy ).x ? 1.0 : 0.0 )
//#define shadow2D( T, C ) T.GatherCmp( T##SS, C.xy, C.z )
//#define shadow2D( T, C ) T.SampleCmpLOD0( T##SS, C.xy, C.z )
#define textureCube( T, C ) T##TU.Sample( T##SS, C )
#define textureCubeLod( T, C, N ) T##TU.Sample( T##SS, C, N )
#define textureGrad( T, C, DDX, DDY ) T.SampleGradient( T##SS, C, DDX, DDY )
#define imageAtomicAdd( T, C, V ) AtomicAdd( T[ C ], V )
#define imageAtomicAddOut( T, C, V, O ) AtomicAdd( T[ C ], V, O )
#define imageStore( T, C, V ) ( T[C] = V )
#define textureGatherRed( lTex, lSamp ) lTex.GatherRed ( lTex##SS, lSamp )
#define textureGatherGreen( lTex, lSamp ) lTex.GatherGreen( lTex##SS, lSamp )
#define textureGatherBlue( lTex, lSamp ) lTex.GatherBlue ( lTex##SS, lSamp )
#define textureGatherAlpha( lTex, lSamp ) lTex.GatherAlpha( lTex##SS, lSamp )
#define texelFetch( lTex, lSamp, lLod ) lTex.MipMaps((lLod), (lSamp))
#endif
#if defined(D_PLATFORM_ORBIS_COMPUTE)
#define THREADGROUP_LOCAL thread_group_memory
#define THREADGROUP_BARRIER ThreadGroupMemoryBarrier()
#elif defined(D_PLATFORM_PC_COMPUTE)
#define THREADGROUP_LOCAL layout( shared )
#define THREADGROUP_BARRIER groupMemoryBarrier()
#endif
// =================================================================================================
// Matrices
// =================================================================================================
#ifdef D_PLATFORM_PC
#define MUL( INPUT_A, INPUT_B ) (INPUT_A * INPUT_B)
#define PLATFORM_TRANSPOSE
#define MAT4_SET_POS( M, P ) M[ 3 ] = P
#define MAT4_SET_TRANSLATION( M, T ) M[ 3 ].xyz = T
#define MAT4_GET_COLUMN( M, C ) M[ C ].xyz
#define MAT3_GET_COLUMN( M, C ) M[ C ]
#define MAT4_GET_COLUMN_VEC4( M, C ) M[ C ]
#define MAT3_SET_COLUMN( M, C, V ) M[ C ] = V;
#define MAT4_SET_COLUMN( M, C, V ) M[ C ] = V;
#elif defined(D_PLATFORM_ORBIS)
#define MUL( INPUT_A, INPUT_B ) mul( INPUT_B, INPUT_A )
#define PLATFORM_TRANSPOSE
#define MAT4_SET_POS( M, P ) M[ 3 ] = P
#define MAT4_SET_TRANSLATION( M, T ) M[ 3 ].xyz = T
#define MAT4_GET_COLUMN( M, C ) M[ C ].xyz
#define MAT3_GET_COLUMN( M, C ) M[ C ]
#define MAT4_GET_COLUMN_VEC4( M, C ) M[ C ]
#define MAT3_SET_COLUMN( M, C, V ) M[ C ] = V;
#define MAT4_SET_COLUMN( M, C, V ) M[ C ] = V;
#endif
// =================================================================================================
// Arrays (workaround AMD shader compiler issues by making arrays have global scope)
// =================================================================================================
#if defined(D_PLATFORM_ORBIS)
#define ARRAY_LOOKUP_FS( _UNIFORMS, _ELEMENT, _INDEX) _UNIFORMS._ELEMENT[_INDEX]
#define ARRAY_LOOKUP_FP( _UNIFORMS, _ELEMENT, _INDEX) _UNIFORMS._ELEMENT[_INDEX]
#else
#define ARRAY_LOOKUP_FS( _UNIFORMS, _ELEMENT, _INDEX) _ELEMENT[_INDEX]
#define ARRAY_LOOKUP_FP( _UNIFORMS, _ELEMENT, _INDEX) _ELEMENT[_INDEX]
#endif
// =================================================================================================
// Input and Output
// =================================================================================================
#ifdef D_PLATFORM_PC
#define UNIFORM( TYPE, NAME ) uniform TYPE NAME
#define UNIFORM_SRT( TYPE, NAME ) uniform TYPE NAME
#define DECLARE_INPUT
#define DECLARE_OUTPUT
#define DECLARE_END
#define DECLARE_PTR( TYPE, NAME ) TYPE NAME;
#define DECLARE_PATCH_INPUT_TRI
#define DECLARE_PATCH_OUTPUT_TRI
#define IN_PATCH_TRI_TESS_CONSTANTS
#define OUT_PATCH_TRI_TESS_CONSTANTS
#define DECLARE_PATCH_INPUT_QUAD
#define DECLARE_PATCH_OUTPUT_QUAD
#define IN_PATCH_QUAD_TESS_CONSTANTS
#define OUT_PATCH_QUAD_TESS_CONSTANTS
#if defined( D_HULL )
#define INPUT( TYPE, NAME, REG ) in TYPE NAME [];
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME [];
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME [];
#define PATCH_OUTPUT( TYPE, NAME, REG ) patch out TYPE NAME;
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME [];
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME [];
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME [];
#elif defined( D_DOMAIN )
#define PATCH_INPUT( TYPE, NAME, REG ) patch in TYPE NAME;
#define INPUT( TYPE, NAME, REG ) in TYPE NAME [];
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME [];
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME [];
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME;
#else
#define INPUT( TYPE, NAME, REG ) in TYPE NAME;
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME;
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME;
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME;
#endif
#define FRAGMENT_COLOUR_UVEC4_DEFINE layout(location = 0) out uvec4 outu_color0;
#define FRAGMENT_COLOUR_UVEC4 outu_color0
#define FRAGMENT_COLOUR out_color0
#define FRAGMENT_COLOUR0 out_color0
#define FRAGMENT_COLOUR1 out_color1
#define FRAGMENT_COLOUR2 out_color2
#define FRAGMENT_COLOUR3 out_color3
#define FRAGMENT_COLOUR4 out_color4
#if defined( D_TAA_RENDER_TARGETS )
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1; layout(location = 2) out vec4 out_color2;
#elif !defined(D_ATTRIBUTES)
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0;
#else
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1; layout(location = 2) out vec4 out_color2; layout(location = 3) out vec4 out_color3; layout(location = 4) out vec4 out_color4;
#endif
#define FRAGMENT_COLOUR01_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1;
#define FRAGMENT_DEPTH gl_FragDepth
#define FRAGMENT_FRONTFACE gl_FrontFacing
#define INPUT_FRONTFACING
#define DEREF_PTR( VAR ) VAR
#if defined( D_HULL )
#define IN( VAR ) VAR[ gl_InvocationID ]
#define OUT( VAR ) VAR[ gl_InvocationID ]
#define PATCH_OUT( VAR ) VAR
#define OUTPUT_VERTEX_SCREEN_POSITION gl_out[ gl_InvocationID ].gl_Position
#define INPUT_VERTEX_SCREEN_POSITION gl_in [ gl_InvocationID ].gl_Position
#define TESS_LEVEL_EDGE( IND ) gl_TessLevelOuter[ IND ]
#define TESS_LEVEL_INNER( IND ) gl_TessLevelInner[ IND ]
#elif defined( D_DOMAIN )
#define PATCH_IN( VAR, IND ) VAR[ IND ]
#define IN( VAR, IND ) VAR[ IND ]
#define OUT( VAR ) VAR
#define INPUT_VERTEX_SCREEN_POSITION( IND ) gl_in [ IND ].gl_Position
#define DOMAIN_COORDS gl_TessCoord
#elif defined( D_GEOMETRY )
#define OUTPUT_VERTEX_SCREEN_POSITION gl_Position
#define INPUT_VERTEX_SCREEN_POSITION( IND ) gl_in [ IND ].gl_Position
#define IN( VAR, IND ) VAR[ IND ]
#define OUT( VAR ) VAR
#else
#define IN( VAR ) VAR
#define OUT( VAR ) VAR
#endif
#define OUT_VERTEX_SCREEN_POSITION
#define IN_SCREEN_POSITION
#define VERTEX_SCREEN_POSITION gl_Position
#elif defined(D_PLATFORM_ORBIS_COMPUTE)
#define DECLARE_INPUT struct cInput {
#define DECLARE_END };
#define DECLARE_PTR( TYPE, NAME ) TYPE* NAME;
#define INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define INPUT_NOINTERP( TYPE, NAME, REG ) TYPE NAME : REG;
#define IN_SCREEN_POSITION
#define FRAGMENT_COLOUR lUniforms.mpCmpOutPerMesh.gOutTexture0[dispatchThreadID.xy]
#define FRAGMENT_COLOUR0 lUniforms.mpCmpOutPerMesh.gOutTexture0[dispatchThreadID.xy]
#define FRAGMENT_COLOUR1 lUniforms.mpCmpOutPerMesh.gOutTexture1[dispatchThreadID.xy]
#define FRAGMENT_COLOUR2 lUniforms.mpCmpOutPerMesh.gOutTexture2[dispatchThreadID.xy]
#define FRAGMENT_COLOUR3 lUniforms.mpCmpOutPerMesh.gOutTexture3[dispatchThreadID.xy]
#define FRAGMENT_COLOUR4 lUniforms.mpCmpOutPerMesh.gOutTexture4[dispatchThreadID.xy]
#define FRAGMENT_DEPTH lUniforms.mpCmpOutPerMesh.gOutTextureDepth[dispatchThreadID.xy]
#define DEREF_PTR( VAR ) *VAR
#elif defined(D_PLATFORM_ORBIS)
#define UNIFORM( TYPE, NAME ) ConstantBuffer NAME##CB{ TYPE NAME; };
#define UNIFORM_SRT( TYPE, NAME ) ConstantBuffer NAME##CB{ TYPE NAME : S_SRT_DATA; };
#define DECLARE_OUTPUT struct cOutput {
#define DECLARE_INPUT struct cInput {
#define DECLARE_END };
#define DECLARE_PTR( TYPE, NAME ) TYPE* NAME;
#define INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define INPUT_NOINTERP( TYPE, NAME, REG ) nointerp TYPE NAME : REG;
#define INPUT_NOPERSP( TYPE, NAME, REG ) nopersp TYPE NAME : REG;
#define OUTPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) nointerp TYPE NAME : REG;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) nopersp TYPE NAME : REG;
#define FRAGMENT_COLOUR_UVEC4_DEFINE
#define FRAGMENT_COLOUR_UVEC4 Out.mColour
#define FRAGMENT_COLOUR Out.mColour
#define FRAGMENT_COLOUR0 Out.mColour0
#define FRAGMENT_COLOUR1 Out.mColour1
#define FRAGMENT_COLOUR2 Out.mColour2
#define FRAGMENT_COLOUR3 Out.mColour3
#define FRAGMENT_COLOUR4 Out.mColour4
#define FRAGMENT_DEPTH Out.mDepth
#define FRAGMENT_FRONTFACE In.mbFrontFacing
#define INPUT_FRONTFACING bool mbFrontFacing : S_FRONT_FACE;
#if defined( D_HULL )
#define IN( VAR ) In[ uCPID ].VAR
#define OUT( VAR ) Out.VAR
#define PATCH_OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION IN( mScreenPositionVec4 )
#define TESS_LEVEL_EDGE( IND ) Out.edge_ts[ IND ]
#define TESS_LEVEL_INNER( IND ) Out.insi_ts[ IND ]
#define DECLARE_PATCH_OUTPUT_TRI [DOMAIN_PATCH_TYPE("tri")] struct HSConstantOutputData {
#define OUT_PATCH_TRI_TESS_CONSTANTS float edge_ts[3] : S_EDGE_TESS_FACTOR; \
float insi_ts[1] : S_INSIDE_TESS_FACTOR;
#define DECLARE_PATCH_OUTPUT_QUAD [DOMAIN_PATCH_TYPE("quad")] struct HSConstantOutputData (
#define OUT_PATCH_QUAD_TESS_CONSTANTS float edge_ts[4] : S_EDGE_TESS_FACTOR; \
float insi_ts[2] : S_INSIDE_TESS_FACTOR;
#define PATCH_OUTPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#elif defined( D_DOMAIN )
#define PATCH_IN( VAR, IND ) patchIn.VAR
#define IN( VAR, IND ) In[ IND ].VAR
#define OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION( IND ) IN( mScreenPositionVec4, IND )
#define DOMAIN_COORDS domainCoordinates
#define DECLARE_PATCH_INPUT_TRI [DOMAIN_PATCH_TYPE("tri")] struct HSConstantOutputData {
#define IN_PATCH_TRI_TESS_CONSTANTS float edge_ts[3] : S_EDGE_TESS_FACTOR; \
float insi_ts[1] : S_INSIDE_TESS_FACTOR;
#define DECLARE_PATCH_INPUT_QUAD [DOMAIN_PATCH_TYPE("quad")] struct HSConstantOutputData {
#define IN_PATCH_QUAD_TESS_CONSTANTS float edge_ts[4] : S_EDGE_TESS_FACTOR; \
float insi_ts[2] : S_INSIDE_TESS_FACTOR;
#define PATCH_INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#elif defined( D_GEOMETRY )
#define IN( VAR, IND ) In[ IND ].VAR
#define OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION( IND ) IN( mScreenPositionVec4, IND )
#define EMIT_VERTEX TriStream.Append( Out )
#define END_PRIMITIVE TriStream.RestartStrip()
#else
#define IN( VAR ) In.VAR
#define OUT( VAR ) Out.VAR
#endif
// TODO get rid of this - don't pass struct through functinos, pass members.
#define DEREF_PTR( VAR ) *VAR
#define OUT_VERTEX_SCREEN_POSITION OUTPUT( vec4, mScreenPositionVec4, S_POSITION )
#define IN_SCREEN_POSITION INPUT ( vec4, mScreenPositionVec4, S_POSITION )
#define VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#endif
// =================================================================================================
// Main
// =================================================================================================
#ifdef D_PLATFORM_PC
#define VERTEX_MAIN void main( void )
#define VERTEX_MAIN_SRT uniform UniformBuffer lUniforms; void main( void )
#define HULL_TRI_MAIN_SRT layout( vertices = 3 ) out; uniform UniformBuffer lUniforms; void main( void )
#define HULL_QUAD_MAIN_SRT layout( vertices = 4 ) out; uniform UniformBuffer lUniforms; void main( void )
#define DOMAIN_TRI_MAIN_SRT layout( triangles, fractional_even_spacing ) in; uniform UniformBuffer lUniforms; void main( void )
#define DOMAIN_QUAD_MAIN_SRT layout( quads, fractional_even_spacing ) in; uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define VOID_MAIN_COLOUR FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_GE_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_LE_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_EARLYZ_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_UICOLOUR_SRT FRAGMENT_COLOUR_UVEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define VOID_MAIN_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define VOID_MAIN_DEPTH_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR01_SRT FRAGMENT_COLOUR01_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR01_DEPTH_SRT FRAGMENT_COLOUR01_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#elif defined( D_PLATFORM_PC_COMPUTE )
#define COMPUTE_MAIN_SRT( X, Y, Z ) layout (local_size_x = X, local_size_y = Y, local_size_z = Z) in; void main( void )
#define FRAGMENT_MAIN_COLOUR_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR01_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#elif defined( D_PLATFORM_ORBIS_COMPUTE )
#define COMPUTE_MAIN_SRT( X, Y, Z ) [NUM_THREADS(X, Y, Z)] void main(uint3 groupID : S_GROUP_ID, uint3 groupThreadID : S_GROUP_THREAD_ID, uint3 dispatchThreadID : S_DISPATCH_THREAD_ID, UniformBuffer lUniforms : S_SRT_DATA)
#define FRAGMENT_MAIN_COLOUR_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR01_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#elif defined( D_PLATFORM_ORBIS )
#define VERTEX_MAIN void main( cInput In, out cOutput Out )
#define VERTEX_MAIN_SRT void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define HULL_TRI_MAIN_SRT [DOMAIN_PATCH_TYPE("tri")] \
[PARTITIONING_TYPE("integer")] \
[OUTPUT_TOPOLOGY_TYPE("triangle_cw")] \
[OUTPUT_CONTROL_POINTS(3)] \
[PATCH_CONSTANT_FUNC("ConstantsHS")] \
[MAX_TESS_FACTOR(16.0)] \
void main( \
InputPatch<cInput, 3> In, \
uint uCPID : S_OUTPUT_CONTROL_POINT_ID, \
UniformBuffer lUniforms : S_SRT_DATA, \
out cOutput Out )
#define HULL_QUAD_MAIN_SRT [DOMAIN_PATCH_TYPE("quad")] \
[PARTITIONING_TYPE("integer")] \
[OUTPUT_TOPOLOGY_TYPE("triangle_cw")] \
[OUTPUT_CONTROL_POINTS(4)] \
[PATCH_CONSTANT_FUNC("ConstantsHS")] \
[MAX_TESS_FACTOR(16.0)] \
void main( \
InputPatch<cInput, 4> In, \
uint uCPID : S_OUTPUT_CONTROL_POINT_ID, \
UniformBuffer lUniforms : S_SRT_DATA, \
out cOutput Out )
#define DOMAIN_TRI_MAIN_SRT [DOMAIN_PATCH_TYPE("tri")] \
void main( \
HSConstantOutputData patchIn, \
const OutputPatch<cInput, 3> In, \
out cOutput Out, \
UniformBuffer lUniforms : S_SRT_DATA, \
float3 domainCoordinates : S_DOMAIN_LOCATION )
#define DOMAIN_QUAD_MAIN_SRT [DOMAIN_PATCH_TYPE("quad")] \
void main( \
HSConstantOutputData patchIn, \
const OutputPatch<cInput, 4> In, \
out cOutput Out, \
UniformBuffer lUniforms : S_SRT_DATA, \
float2 domainCoordinates : S_DOMAIN_LOCATION )
#define GEOMETRY_MAIN_SRT( MAX_VERTS ) cOutput Out; [MAX_VERTEX_COUNT(MAX_VERTS)] void main( inout TriangleBuffer<cOutput> TriStream, Triangle cInput In[3], UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out )
#define VOID_MAIN_COLOUR struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; void main( cInput In, out cOutput Out )
#define FRAGMENT_MAIN_COLOUR_DEPTH struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out )
#define VOID_MAIN_SRT void main( cInput In, UniformBuffer lUniforms : S_SRT_DATA )
#if defined( D_TAA_RENDER_TARGETS )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#elif !defined( D_ATTRIBUTES )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_DEPTH_GE_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_GE_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_DEPTH_LE_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_LE_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define VOID_MAIN_DEPTH_SRT struct cOutput { float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define VOID_MAIN_COLOUR_EARLYZ_SRT [FORCE_EARLY_DEPTH_STENCIL] void main( cInput In, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR01_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR01_DEPTH_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
float mDepth : S_DEPTH_OUTPUT; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#else
// #pragma PSSL_target_output_format(target 1 FMT_32_AR)
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; \
float mDepth : S_DEPTH_OUTPUT; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_EARLYZ_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; }; \
[FORCE_EARLY_DEPTH_STENCIL] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#endif
#endif
// =================================================================================================
// Texture resolution
// =================================================================================================
#ifdef D_PLATFORM_ORBIS
uvec2 GetResolution( Texture2D lTexture )
{
uvec2 lResolution;
lTexture.GetDimensionsFast(lResolution.x, lResolution.y);
return lResolution;
}
uvec2 GetResolution( RW_Texture2D<float4> lTexture )
{
uvec2 lResolution;
lTexture.GetDimensionsFast(lResolution.x, lResolution.y);
return lResolution;
}
#else
uvec2 GetResolution( sampler2D lTexture )
{
return textureSize( lTexture, 0 );
}
#endif
// =================================================================================================
// Viewport
// =================================================================================================
#ifdef D_PLATFORM_PC
#define SCREENSPACE_AS_RENDERTARGET_UVS( A ) A.xy
#elif defined(D_PLATFORM_ORBIS)
#define SCREENSPACE_AS_RENDERTARGET_UVS( A ) ( float2( A.x, 1.0 - A.y ) )
#endif
#ifdef D_USING_LOGDEPTH
#define D_DEPTH_CLEARVALUE (1.0)
#else
#define D_DEPTH_CLEARVALUE (0.0)
#endif
// =================================================================================================
// Texture usage feedback
// =================================================================================================
#if defined( D_TEXTURE_FEEDBACK ) && defined( D_PLATFORM_PC )
layout(r32i) uniform iimage2D gTexFeedbackImg;
void WriteTexFeedback( in int liCounter, in float liMip )
{
if( liCounter != 0 )
{
#if defined( GL_ARB_shader_ballot ) && ( GL_ARB_shader_ballot == 1 )
if( readFirstInvocationARB( gl_SubGroupInvocationARB ) == gl_SubGroupInvocationARB )
#endif
{
int liIntMip = int(floor(liMip));
//imageStore( gTexFeedbackImg, ivec2( liCounter, liIntMip ), ivec4(1,0,0,0) );
imageAtomicAdd( gTexFeedbackImg, ivec2( liCounter, liIntMip ), int(1) );
}
}
}
vec4 Tex2dFeedback( in sampler2D lSamp, in int liCounter, in vec2 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex2dLodFeedback( in sampler2D lSamp, in int liCounter, in vec2 lCoords, in float liLod )
{
WriteTexFeedback( liCounter, liLod );
return textureLod( lSamp, lCoords, liLod );
}
vec4 Tex2dArrayFeedback( in sampler2DArray lSamp, in int liCounter, in vec3 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords.xy ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex3dFeedback( in sampler3D lSamp, in int liCounter, in vec3 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex3dLodFeedback( in sampler3D lSamp, in int liCounter, in vec3 lCoords, in float liLod )
{
WriteTexFeedback( liCounter, liLod );
return textureLod( lSamp, lCoords, liLod );
}
#endif
#endif
struct PerFrameUniforms
{
vec4 gLightPositionVec4; // EShaderConst_LightPositionVec4
vec4 gLightDirectionVec4; // EShaderConst_LightDirectionVec4
vec3 gViewPositionVec3; // EShaderConst_ViewPositionVec3
float gfTime; // EShaderConst_Time
float gfPrevTime; // EShaderConst_PrevTime
vec4 gClipPlanesVec4; // EShaderConst_ClipPlanesVec4
vec4 gClipPlanesRVec4; // EShaderConst_ClipPlanesRVec4
mat4 gCameraMat4; // EShaderConst_CameraMat4
mat4 gCameraDeltaMat4; // EShaderConst_CameraDeltaMat4
mat4 gPrevViewProjectionMat4; // EShaderConst_PrevViewProjectionMat4
vec4 gMBlurSettingsVec4; // EShaderConst_BlurSettingsVec4
vec4 gDeJitterVec4; // EShaderConst_DeJitterVec4
vec4 gTaaSettingsVec4; // EShaderConst_TaaSettingsVec4
vec4 gFrameBufferSizeVec4;
vec4 gFoVValuesVec4; // EShaderConst_FoVValuesVec4
vec4 gShadowSizeVec4;
vec4 gShadowFadeParamVec4;
vec4 gShadowProjScaleVec4[3]; // EShaderConst_ShadowProjScaleVec4
mat4 gViewMat4; // EShaderConst_ViewMat4
};
struct CommonPerMeshUniforms
{
// These are planet specific. Should they be here?
vec4 gPlanetPositionVec4;
vec4 gLightOriginVec4;
mat4 gWorldMat4; // EShaderConst_WorldMat4
mat4 gWorldMotionMat4; // EShaderConst_WorldMotionMat4
mat4 gWorldViewProjectionMat4; // EShaderConst_WorldViewProjectionMat4
mat4 gWorldNormalMat4; // EShaderConst_WorldNormalMat4
#if defined( D_FADE ) && !defined( D_INSTANCE )
float gfFadeValue; // EShaderConst_FadeTime
#else
float fdFadeValueDummy;
#endif
#if defined( D_SKINNING_UNIFORMS ) && defined( D_PLATFORM_ORBIS )
vec4 gaSkinMatrixRowsVec4[ 75 * 3 ];
vec4 gaPrevSkinMatrixRowsVec4[ 75 * 3 ];
#endif
//float gfShadowBias; // EShaderConst_ShadowBias
// have particle shader use a particlecommon instead of uber, and put these into it.
#if defined( D_PARTICLE_UNIFORMS ) && defined( D_PLATFORM_ORBIS )
vec4 gaParticleCornersVec4[ 4 ]; // EShaderConst_ParticleCornersVec4
vec4 gaParticlePositionsVec4[ 32 ]; // EShaderConst_ParticlePositionsVec4
vec4 gaParticleSizeAndRotationsVec4[ 32 ]; // EShaderConst_ParticleSizeAndRotationsVec4
vec4 gaParticleNormalsVec4[ 32 ]; // EShaderConst_ParticleNormalsVec4
vec4 gaParticleColoursVec4[ 32 ]; // EShaderConst_ParticleColoursVec4
#endif
// This stuff is here atm because of shadows. The shadow shader is one thing, but renders twice, with these needing to be set differently.
// ideally we don't want them set per mesh though, probably a SRT for 'percamera' or something
//
//
mat4 gProjectionMat4; // EShaderConst_ProjectionMat4
mat4 gViewProjectionMat4; // EShaderConst_ViewProjectionMat4
#if !defined( D_DEPTHONLY )
mat4 gInverseWorldUpMat4;
// Stop these being compiled in when recolouring as the recolour shader needs ALL tex units.
#if defined( D_DEFERRED_DECAL )
mat4 gInverseModelMat4; // EShaderConst_InverseModelMat4 = 0
#else
mat4 gInverseProjectionSCMat4; // EShaderConst_InverseProjectionSCMat4
#endif
mat4 gInverseViewMat4; // EShaderConst_InverseViewMat4
mat4 gInverseProjectionMat4; // EShaderConst_InverseProjectionMat4
//mat4 gInverseViewProjectionMat4; // EShaderConst_InverseViewProjectionMat4
mat4 gaShadowMat4[ 3 ]; // EShaderConst_ShadowMat4
vec4 gLightColourVec4; // EShaderConst_LightColourVec4
#ifdef D_IBL
vec4 gGenericParam0Vec4; // EShaderConst_GenericParam0Vec4
#else
vec4 gGenericParam0DummyVec4;
#endif
// These shouldn't be per mesh, the should be per rendertarget. BUT we need to add them to the enum
// in egShader and SetPErRenderTargetUniforms for that to work and we're trying to do a build for sony
// so that will have to wait. (also probably need a way of setting per RT uniforms from Game).
vec4 gScanParamsPosVec4;
vec4 gScanParamsCfg1Vec4;
vec4 gScanParamsCfg2Vec4;
vec4 gScanParamsCfg3Vec4;
vec4 gScanColourVec4;
vec4 gSpotlightPositionVec4;
vec4 gSpotlightDirectionVec4;
#endif
vec4 gUserDataVec4;
};
#if defined( D_PARTICLE_UNIFORMS ) && defined( D_PLATFORM_PC )
uniform vec4 gaParticleCornersVec4[4]; // EShaderConst_ParticleCornersVec4
uniform vec4 gaParticlePositionsVec4[32]; // EShaderConst_ParticlePositionsVec4
uniform vec4 gaParticleSizeAndRotationsVec4[32]; // EShaderConst_ParticleSizeAndRotationsVec4
uniform vec4 gaParticleNormalsVec4[32]; // EShaderConst_ParticleNormalsVec4
uniform vec4 gaParticleColoursVec4[32]; // EShaderConst_ParticleColoursVec4
#endif
#endif
////////////////////////////////////////////////////////////////////////////////
///
/// @file UberCommon.h
/// @author User
/// @date
///
/// @brief UberCommon
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
///
/// CustomPerMeshUniforms
///
/// @brief CustomPerMeshUniforms
///
/// Stuff that is only used for these types of meshes.
//-----------------------------------------------------------------------------
struct CustomPerMeshUniforms
{
vec4 gUVScrollStepVec4;
vec4 gCustomParams01Vec4;
#if defined( D_SHADOW )
vec4 gBboxDepthAndClips;
#else
#if defined( D_PARTICLE_UNIFORMS )
vec4 gHeavyAirFadeOutVec4;
vec4 gMultiTextureVec4;
#else
vec4 gCustomParams02Vec4;
vec4 gObjectColourVec4;
#endif
#endif
};
//-----------------------------------------------------------------------------
///
/// CustomPerMaterialUniforms
///
/// @brief CustomPerMaterialUniforms
///
/// Stuff that is only used for these materials.
//-----------------------------------------------------------------------------
struct CustomPerMaterialUniforms
{
vec4 gImposterDataVec4;
#if defined( D_SHADOW )
#ifdef _F55_
SAMPLER2DARRAY(gDiffuseMap);
#else
SAMPLER2D(gDiffuseMap);
#endif
#else
// Lighting
// [ Roughness | NonMetalSpecularScale | Metallic | 0 ]
vec4 gMaterialParamsVec4;
vec4 gMaterialColourVec4;
vec4 gMaterialSFXVec4;
vec4 gMaterialSFXColVec4;
vec4 gAverageColour1Vec4;
vec4 gAverageColour2Vec4;
vec4 gRecolour1Vec4;
vec4 gRecolour2Vec4;
vec4 gSkyColourVec4;
vec4 gHorizonColourVec4;
vec4 gSunColourVec4;
vec4 gWaterColourNearVec4;
vec4 gWaterColourFarVec4;
vec4 gWaterFogVec4;
vec4 gHeightFogParamsVec4;
vec4 gHeightFogColourVec4;
vec4 gSpaceHorizonColourVec4;
vec4 gFogColourVec4;
vec4 gFogParamsVec4;
vec4 gScatteringParamsVec4;
vec4 gFogFadeHeightsVec4;
vec4 gSunPositionVec4;
vec4 gSpaceScatteringParamsVec4;
vec4 gSkyUpperColourVec4;
vec4 gLightTopColourVec4;
vec4 gPlaneSpotPositionVec4;
#ifdef _F55_
SAMPLER2DARRAY( gDiffuseMap );
SAMPLER2DARRAY( gNormalMap );
#else
SAMPLER2D( gDiffuseMap );
SAMPLER2D( gNormalMap );
#endif
// TODO add these ifdefs. Move them from uberfrag etc? SHouldn't need to....
#if !defined( D_PARTICLE_UNIFORMS )
//#ifdef _F41_DETAIL_DIFFUSE
SAMPLER2DARRAY( gDetailDiffuseMap );
//#endif
//#ifdef D_DETAIL
SAMPLER2DARRAY( gDetailNormalMap );
//#endif
//#ifdef _F16_DIFFUSE2MAP
SAMPLER2D( gDiffuse2Map );
//#endif
//#ifdef D_MASKS
#ifdef _F55_
SAMPLER2DARRAY( gMasksMap );
#else
SAMPLER2D( gMasksMap );
#endif
//#endif
#if !defined( D_RECOLOUR ) && !defined( D_COMBINE ) && !defined( D_DEFER )
SAMPLER2D( gCausticMap );
SAMPLER2D( gCausticOffsetMap );
SAMPLER2D( gDualPMapFront );
SAMPLER2D( gDualPMapBack );
#endif
#if !defined( D_DEFER ) || (defined( D_TERRAIN ) && defined( D_DEFER ))
SAMPLER2D(gCloudShadowMap);
SAMPLER2DSHADOW_SRT(gShadowMap);
#endif
#else
// move to particle common
SAMPLER2D(gDepthBuffer);
#endif
#if defined( D_DEFERRED_DECAL ) || defined( D_SKY )
SAMPLER2D( gBufferMap );
#endif
#ifdef D_SKY
vec4 gSpaceSkyColour1Vec4;
vec4 gSpaceSkyColour2Vec4;
vec4 gSpaceSkyColour3Vec4;
vec4 gSpaceCloudColourVec4;
vec4 gSpaceSunColourVec4;
vec4 gSpaceNebulaColour1Vec4;
vec4 gSpaceNebulaColour2Vec4;
vec4 gSpaceNebulaColour3Vec4;
vec4 gSpaceNebulaColour4Vec4;
vec4 gSpaceNormalParamsVec4;
vec4 gSpaceNebulaParamsVec4;
#endif
SAMPLER3D(gPerlin3D);
SAMPLER2D(gNoiseMap);
vec4 gTileBlendScalesVec4;
SAMPLER2D(gHSVOverlay);
SAMPLER2D(gHSVNormalOverlay);
vec4 gHueOverlayParamsVec4;
vec4 gSaturationOverlayParamsVec4;
vec4 gValueOverlayParamsVec4;
vec4 gTerrainColour1Vec4;
vec4 gTerrainColour2Vec4;
#endif
#ifdef _F31_
vec4 gWaveOneAmplitudeVec4;
vec4 gWaveOneFrequencyVec4;
vec4 gWaveOneFallOffAndSpeedVec4;
vec4 gWaveTwoAmplitudeVec4;
vec4 gWaveTwoFrequencyVec4;
vec4 gWaveTwoFallOffAndSpeedVec4;
#endif
#ifdef D_FADE
SAMPLER2D(gFadeNoiseMap);
#endif
};
//
// This is the SRT buffer that everything gets uploaded to (on PS4). PC just functions as normal.
//
struct UniformBuffer
{
// DECLARE_PTR( CommonPerMaterialUniforms, mpCommonPerMaterial ) /*: PER_MATERIAL*/ // sematics currently crash the compiler so the parser is hardcoded to look for names.
DECLARE_PTR( PerFrameUniforms, mpPerFrame ) /*: PER_MATERIAL*/ // sematics currently crash the compiler so the parser is hardcoded to look for names.
DECLARE_PTR( CommonPerMeshUniforms, mpCommonPerMesh ) /*: PER_MESH*/
DECLARE_PTR( CustomPerMaterialUniforms, mpCustomPerMaterial ) /*: PER_MATERIAL*/
DECLARE_PTR( CustomPerMeshUniforms, mpCustomPerMesh ) /*: PER_MESH*/
};
#if defined( D_DEFER )
////////////////////////////////////////////////////////////////////////////////
///
/// @file CommonGBuffer.h
/// @author User
/// @date
///
/// @brief CommonLighting
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Compilation defines
#ifndef D_COMMONGBUFFER_H
#define D_COMMONGBUFFER_H
//-----------------------------------------------------------------------------
// Include files
#define D_DETAILOVERLAY ( 1 << 0 )
#define D_NORECEIVESHADOW ( 1 << 1 )
#define D_DISABLE_POSTPROCESS ( 1 << 2 )
#define D_UNLIT ( 1 << 3 )
#define D_NOWATER ( 1 << 4 )
#define D_DISABLE_AMBIENT ( 1 << 5 )
#define D_EMBEDDED_SHADOW ( 1 << 6 )
#define D_CLAMP_AA ( 1 << 7 )
#define D_CLAMPAMBIENT ( 1 << 7 )
// =================================================================================================
#ifndef D_DEFINES
#define D_DEFINES
// =================================================================================================
// Platform defines
// =================================================================================================
#ifdef D_PLATFORM_PC
#define D_ENABLE_REVERSEZ_PROJECTION (1)
#pragma optionNV(strict on)
#extension GL_ARB_gpu_shader5 : enable
#extension GL_ARB_fragment_coord_conventions : enable
#extension GL_ARB_derivative_control : enable
#if defined( D_FRAGMENT ) && defined( _F64_ )
layout(early_fragment_tests) in;
#endif
#elif defined(D_PLATFORM_ORBIS)
#define D_ENABLE_REVERSEZ_PROJECTION (1)
// use this with sdk 2.0 compiler
// #pragma argument (allow-scratch-buffer-spill)
//define these flags so they don't get ignored in build process and in the comb mask
//this is because materials, vertex layouts and shaders need to be synced on 360 to avoid patching
#ifdef _F27_
#endif
#ifdef _F28_
#endif
#ifdef _F29_
#endif
#ifdef _F21_
#endif
#ifdef _F02_
#endif
#ifdef _F03_
#endif
#if defined( _F01_ ) || defined( D_LOD0 ) || defined( D_LOD1 ) || defined( D_LOD2 ) || defined( D_LOD3) || defined( D_LOD4 )
#endif
#ifdef _F01_
#endif
#ifdef _F09_
#endif
#ifdef _F10_
#endif
// disable warnings for unused parameters. This happens a lot because of defining different things.
#pragma warning (disable: 5203)
// temp thing to know what things are still required on ps4.
#define D_PLATFORM_ORBIS_FIX
#ifdef __PSSL_CS__
#define D_PLATFORM_ORBIS_COMPUTE
#endif
#ifdef __PSSL_HS__
#define D_HULL
#endif
#ifdef __PSSL_DS__
#define D_DOMAIN
#endif
#ifdef __PSSL_VS__
#define D_VERTEX
#endif
#ifdef __PSSL_GS__
#define D_GEOMETRY
#endif
#endif
#if !D_ENABLE_REVERSEZ_PROJECTION
#define D_USING_LOGDEPTH
#endif
// =================================================================================================
// Basic Types
// =================================================================================================
#ifdef D_PLATFORM_PC
#define JOINT_TYPE vec4
//#define CONST const
#define STATIC_CONST const
#elif defined(D_PLATFORM_ORBIS)
#define JOINT_TYPE int4
#define float float
#define vec2 float2
#define vec3 float3
#define vec4 float4
#define ivec2 int2
#define ivec3 int3
#define ivec4 int4
#define uvec2 uint2
#define uvec3 uint3
#define uvec4 uint4
// NOTE:
// operator[] accesses rows, not columns
// matrix constructors interpret the passed vectors as row vectors, not column vectors
#define mat2 row_major float2x2
#define mat3 row_major float3x3
#define mat4 row_major float4x4
//#define CONST
#define STATIC_CONST static const
// #define const ERROR, DON'T USE CONST FOR PS4. USE STATIC_CONST INSTEAD FOR A COMPILED IN CONSTANT. OTHERWISE IT TRIES TO PUT IT IN A CONSTANT BUFFER AND FOR SOME REASON IT DOESN'T WORK.
#endif
// =================================================================================================
// Functions
// =================================================================================================
#ifdef D_PLATFORM_PC
#define saturate( V ) min( max( V, 0.0) , 1.0)
#define atan2( Y, X ) atan( Y, X )
#define invsqrt( X ) inversesqrt( X )
#ifdef D_COMPUTE
#define groupID gl_WorkGroupID
#define groupThreadID gl_LocalInvocationID
#define dispatchThreadID gl_GlobalInvocationID
#endif
#elif defined(D_PLATFORM_ORBIS)
#if defined(D_PLATFORM_ORBIS_COMPUTE)
float dFdx( float var ) { float delta = var - LaneSwizzle( var, 0x1f, 0, 1 ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
float dFdy( float var ) { float delta = var - LaneSwizzle( var, 0x1f, 0, 8 ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec2 dFdx( vec2 var ) { vec2 delta = vec2( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec2 dFdy( vec2 var ) { vec2 delta = vec2( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec3 dFdx( vec3 var ) { vec3 delta = vec3( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec3 dFdy( vec3 var ) { vec3 delta = vec3( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec4 dFdx( vec4 var ) { vec4 delta = vec4( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.w, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec4 dFdy( vec4 var ) { vec4 delta = vec4( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.w, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
#define dFdxFine dFdx
#define dFdyFine dFdy
#else
#define dFdx ddx
#define dFdy ddy
#define dFdxFine ddx_fine
#define dFdyFine ddy_fine
#endif
#define mix lerp
#define fract frac
#define mod fmod
#define saturate( V ) ( min( max( V, 0.0) , 1.0) )
#define invsqrt( X ) rsqrt( X )
#endif
// =================================================================================================
// Samplers and textures
// =================================================================================================
#ifdef D_PLATFORM_PC
#define shadow2D( S, UV ) texture( S, UV )
#define SAMPLER2DSHADOW( NAME, REG ) uniform sampler2DShadow NAME
#define SAMPLERCUBE( NAME ) samplerCube NAME
#define SAMPLERCUBEARG( NAME ) in samplerCube NAME
#define SAMPLERCUBEPARAM( NAME ) NAME
#define imageAtomicAddOut( T, C, V, O ) O = imageAtomicAdd( T, C, V )
#if defined( D_TEXTURE_FEEDBACK )
#define texture2D( T, C ) Tex2dFeedback( T, T##FB, C )
#define texture2DLod( T, C, N ) Tex2dLodFeedback( T, T##FB, C, N )
#define texture2DArray( T, C ) Tex2dArrayFeedback( T, T##FB, C )
#define texture3D( S, UV ) Tex3dFeedback( S, S##FB, UV )
#define texture3DLod( S, UV, LOD ) Tex3dLodFeedback( S, S##FB, UV, LOD )
#define SAMPLER2DARG( NAME ) in sampler2D NAME, in int NAME##FB
#define SAMPLER2DPARAM( NAME ) NAME, NAME##FB
#define SAMPLER2DARRAYARG( NAME ) in sampler2DArray NAME, in int NAME##FB
#define SAMPLER2DARRAYPARAM( NAME ) NAME, NAME##FB
#define SAMPLER2D( NAME ) sampler2D NAME; int NAME##FB
#define SAMPLER2DARRAY( NAME ) sampler2DArray NAME; int NAME##FB
#define SAMPLER3D( NAME ) sampler3D NAME; int NAME##FB
#define SAMPLER2DSHADOW_SRT( NAME ) sampler2DShadow NAME; int NAME##FB
#else
#define texture2DLod( S, UV, LOD ) textureLod( S, UV, LOD )
#define texture3DLod( S, UV, LOD ) textureLod( S, UV, LOD )
#define SAMPLER2DARG( NAME ) in sampler2D NAME
#define SAMPLER2DPARAM( NAME ) NAME
#define SAMPLER2DARRAYARG( NAME ) in sampler2DArray NAME
#define SAMPLER2DARRAYPARAM( NAME ) NAME
#define SAMPLER2D( NAME ) sampler2D NAME
#define SAMPLER2DARRAY( NAME ) sampler2DArray NAME
#define SAMPLER3D( NAME ) sampler3D NAME
#define SAMPLER2DSHADOW_SRT( NAME ) sampler2DShadow NAME
#endif
#define textureGatherRed( lTex, lSamp ) textureGather( lTex, lSamp, 0 )
#define textureGatherGreen( lTex, lSamp ) textureGather( lTex, lSamp, 1 )
#define textureGatherBlue( lTex, lSamp ) textureGather( lTex, lSamp, 2 )
#define textureGatherAlpha( lTex, lSamp ) textureGather( lTex, lSamp, 3 )
#define texture2DComputeGrad( T, C ) texture2D( T, C )
#elif defined(D_PLATFORM_ORBIS)
#define SAMPLERCUBE( NAME, REG ) SamplerState NAME##SS : register( s##REG ); TextureCube NAME##TU : register( t##REG )
#define SAMPLER2D( NAME ) Texture2D NAME; SamplerState NAME##SS
#define SAMPLER2DSHADOW_SRT( NAME ) Texture2D NAME; SamplerComparisonState NAME##SS //SAMPLER2D( NAME )
#define SAMPLER3D( NAME ) Texture3D NAME; SamplerState NAME##SS
#define SAMPLER2DARRAY( NAME ) Texture2D_Array NAME; SamplerState NAME##SS
#define SAMPLER2DARRAYARG( NAME ) Texture2D_Array NAME, SamplerState NAME##SS
#define SAMPLER2DARRAYPARAM( NAME ) NAME, NAME##SS
#define SAMPLER2DPARAM( NAME ) NAME, NAME##SS
#define SAMPLER2DARG( NAME ) Texture2D NAME, SamplerState NAME##SS
#define texture2D( T, C ) T.Sample( T##SS, C )
#if defined(D_PLATFORM_ORBIS_COMPUTE)
#define texture2DComputeGrad( T, C ) T.SampleGradient( T##SS, C, vec2( dFdx( C ) ), vec2( dFdy( C ) ) )
#define shadow2D( T, C ) T.SampleCmpLOD0( T##SS, C.xy, C.z )
#else
#define texture2DComputeGrad( T, C ) T.Sample( T##SS, C )
#define shadow2D( T, C ) T.SampleCmp( T##SS, C.xy, C.z )
#endif
#define texture2DLod( T, C, N ) T.SampleLOD( T##SS, C, N )
#define texture2DArray( T, C ) T.Sample( T##SS, C )
#define texture3DLod( T, C, N ) T.SampleLOD( T##SS, C, N )
//#define shadow2D( T, C ) vec3( C.z > T.Sample( T##SS, C.xy ).x ? 1.0 : 0.0 )
//#define shadow2D( T, C ) T.GatherCmp( T##SS, C.xy, C.z )
//#define shadow2D( T, C ) T.SampleCmpLOD0( T##SS, C.xy, C.z )
#define textureCube( T, C ) T##TU.Sample( T##SS, C )
#define textureCubeLod( T, C, N ) T##TU.Sample( T##SS, C, N )
#define textureGrad( T, C, DDX, DDY ) T.SampleGradient( T##SS, C, DDX, DDY )
#define imageAtomicAdd( T, C, V ) AtomicAdd( T[ C ], V )
#define imageAtomicAddOut( T, C, V, O ) AtomicAdd( T[ C ], V, O )
#define imageStore( T, C, V ) ( T[C] = V )
#define textureGatherRed( lTex, lSamp ) lTex.GatherRed ( lTex##SS, lSamp )
#define textureGatherGreen( lTex, lSamp ) lTex.GatherGreen( lTex##SS, lSamp )
#define textureGatherBlue( lTex, lSamp ) lTex.GatherBlue ( lTex##SS, lSamp )
#define textureGatherAlpha( lTex, lSamp ) lTex.GatherAlpha( lTex##SS, lSamp )
#define texelFetch( lTex, lSamp, lLod ) lTex.MipMaps((lLod), (lSamp))
#endif
#if defined(D_PLATFORM_ORBIS_COMPUTE)
#define THREADGROUP_LOCAL thread_group_memory
#define THREADGROUP_BARRIER ThreadGroupMemoryBarrier()
#elif defined(D_PLATFORM_PC_COMPUTE)
#define THREADGROUP_LOCAL layout( shared )
#define THREADGROUP_BARRIER groupMemoryBarrier()
#endif
// =================================================================================================
// Matrices
// =================================================================================================
#ifdef D_PLATFORM_PC
#define MUL( INPUT_A, INPUT_B ) (INPUT_A * INPUT_B)
#define PLATFORM_TRANSPOSE
#define MAT4_SET_POS( M, P ) M[ 3 ] = P
#define MAT4_SET_TRANSLATION( M, T ) M[ 3 ].xyz = T
#define MAT4_GET_COLUMN( M, C ) M[ C ].xyz
#define MAT3_GET_COLUMN( M, C ) M[ C ]
#define MAT4_GET_COLUMN_VEC4( M, C ) M[ C ]
#define MAT3_SET_COLUMN( M, C, V ) M[ C ] = V;
#define MAT4_SET_COLUMN( M, C, V ) M[ C ] = V;
#elif defined(D_PLATFORM_ORBIS)
#define MUL( INPUT_A, INPUT_B ) mul( INPUT_B, INPUT_A )
#define PLATFORM_TRANSPOSE
#define MAT4_SET_POS( M, P ) M[ 3 ] = P
#define MAT4_SET_TRANSLATION( M, T ) M[ 3 ].xyz = T
#define MAT4_GET_COLUMN( M, C ) M[ C ].xyz
#define MAT3_GET_COLUMN( M, C ) M[ C ]
#define MAT4_GET_COLUMN_VEC4( M, C ) M[ C ]
#define MAT3_SET_COLUMN( M, C, V ) M[ C ] = V;
#define MAT4_SET_COLUMN( M, C, V ) M[ C ] = V;
#endif
// =================================================================================================
// Arrays (workaround AMD shader compiler issues by making arrays have global scope)
// =================================================================================================
#if defined(D_PLATFORM_ORBIS)
#define ARRAY_LOOKUP_FS( _UNIFORMS, _ELEMENT, _INDEX) _UNIFORMS._ELEMENT[_INDEX]
#define ARRAY_LOOKUP_FP( _UNIFORMS, _ELEMENT, _INDEX) _UNIFORMS._ELEMENT[_INDEX]
#else
#define ARRAY_LOOKUP_FS( _UNIFORMS, _ELEMENT, _INDEX) _ELEMENT[_INDEX]
#define ARRAY_LOOKUP_FP( _UNIFORMS, _ELEMENT, _INDEX) _ELEMENT[_INDEX]
#endif
// =================================================================================================
// Input and Output
// =================================================================================================
#ifdef D_PLATFORM_PC
#define UNIFORM( TYPE, NAME ) uniform TYPE NAME
#define UNIFORM_SRT( TYPE, NAME ) uniform TYPE NAME
#define DECLARE_INPUT
#define DECLARE_OUTPUT
#define DECLARE_END
#define DECLARE_PTR( TYPE, NAME ) TYPE NAME;
#define DECLARE_PATCH_INPUT_TRI
#define DECLARE_PATCH_OUTPUT_TRI
#define IN_PATCH_TRI_TESS_CONSTANTS
#define OUT_PATCH_TRI_TESS_CONSTANTS
#define DECLARE_PATCH_INPUT_QUAD
#define DECLARE_PATCH_OUTPUT_QUAD
#define IN_PATCH_QUAD_TESS_CONSTANTS
#define OUT_PATCH_QUAD_TESS_CONSTANTS
#if defined( D_HULL )
#define INPUT( TYPE, NAME, REG ) in TYPE NAME [];
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME [];
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME [];
#define PATCH_OUTPUT( TYPE, NAME, REG ) patch out TYPE NAME;
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME [];
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME [];
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME [];
#elif defined( D_DOMAIN )
#define PATCH_INPUT( TYPE, NAME, REG ) patch in TYPE NAME;
#define INPUT( TYPE, NAME, REG ) in TYPE NAME [];
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME [];
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME [];
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME;
#else
#define INPUT( TYPE, NAME, REG ) in TYPE NAME;
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME;
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME;
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME;
#endif
#define FRAGMENT_COLOUR_UVEC4_DEFINE layout(location = 0) out uvec4 outu_color0;
#define FRAGMENT_COLOUR_UVEC4 outu_color0
#define FRAGMENT_COLOUR out_color0
#define FRAGMENT_COLOUR0 out_color0
#define FRAGMENT_COLOUR1 out_color1
#define FRAGMENT_COLOUR2 out_color2
#define FRAGMENT_COLOUR3 out_color3
#define FRAGMENT_COLOUR4 out_color4
#if defined( D_TAA_RENDER_TARGETS )
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1; layout(location = 2) out vec4 out_color2;
#elif !defined(D_ATTRIBUTES)
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0;
#else
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1; layout(location = 2) out vec4 out_color2; layout(location = 3) out vec4 out_color3; layout(location = 4) out vec4 out_color4;
#endif
#define FRAGMENT_COLOUR01_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1;
#define FRAGMENT_DEPTH gl_FragDepth
#define FRAGMENT_FRONTFACE gl_FrontFacing
#define INPUT_FRONTFACING
#define DEREF_PTR( VAR ) VAR
#if defined( D_HULL )
#define IN( VAR ) VAR[ gl_InvocationID ]
#define OUT( VAR ) VAR[ gl_InvocationID ]
#define PATCH_OUT( VAR ) VAR
#define OUTPUT_VERTEX_SCREEN_POSITION gl_out[ gl_InvocationID ].gl_Position
#define INPUT_VERTEX_SCREEN_POSITION gl_in [ gl_InvocationID ].gl_Position
#define TESS_LEVEL_EDGE( IND ) gl_TessLevelOuter[ IND ]
#define TESS_LEVEL_INNER( IND ) gl_TessLevelInner[ IND ]
#elif defined( D_DOMAIN )
#define PATCH_IN( VAR, IND ) VAR[ IND ]
#define IN( VAR, IND ) VAR[ IND ]
#define OUT( VAR ) VAR
#define INPUT_VERTEX_SCREEN_POSITION( IND ) gl_in [ IND ].gl_Position
#define DOMAIN_COORDS gl_TessCoord
#elif defined( D_GEOMETRY )
#define OUTPUT_VERTEX_SCREEN_POSITION gl_Position
#define INPUT_VERTEX_SCREEN_POSITION( IND ) gl_in [ IND ].gl_Position
#define IN( VAR, IND ) VAR[ IND ]
#define OUT( VAR ) VAR
#else
#define IN( VAR ) VAR
#define OUT( VAR ) VAR
#endif
#define OUT_VERTEX_SCREEN_POSITION
#define IN_SCREEN_POSITION
#define VERTEX_SCREEN_POSITION gl_Position
#elif defined(D_PLATFORM_ORBIS_COMPUTE)
#define DECLARE_INPUT struct cInput {
#define DECLARE_END };
#define DECLARE_PTR( TYPE, NAME ) TYPE* NAME;
#define INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define INPUT_NOINTERP( TYPE, NAME, REG ) TYPE NAME : REG;
#define IN_SCREEN_POSITION
#define FRAGMENT_COLOUR lUniforms.mpCmpOutPerMesh.gOutTexture0[dispatchThreadID.xy]
#define FRAGMENT_COLOUR0 lUniforms.mpCmpOutPerMesh.gOutTexture0[dispatchThreadID.xy]
#define FRAGMENT_COLOUR1 lUniforms.mpCmpOutPerMesh.gOutTexture1[dispatchThreadID.xy]
#define FRAGMENT_COLOUR2 lUniforms.mpCmpOutPerMesh.gOutTexture2[dispatchThreadID.xy]
#define FRAGMENT_COLOUR3 lUniforms.mpCmpOutPerMesh.gOutTexture3[dispatchThreadID.xy]
#define FRAGMENT_COLOUR4 lUniforms.mpCmpOutPerMesh.gOutTexture4[dispatchThreadID.xy]
#define FRAGMENT_DEPTH lUniforms.mpCmpOutPerMesh.gOutTextureDepth[dispatchThreadID.xy]
#define DEREF_PTR( VAR ) *VAR
#elif defined(D_PLATFORM_ORBIS)
#define UNIFORM( TYPE, NAME ) ConstantBuffer NAME##CB{ TYPE NAME; };
#define UNIFORM_SRT( TYPE, NAME ) ConstantBuffer NAME##CB{ TYPE NAME : S_SRT_DATA; };
#define DECLARE_OUTPUT struct cOutput {
#define DECLARE_INPUT struct cInput {
#define DECLARE_END };
#define DECLARE_PTR( TYPE, NAME ) TYPE* NAME;
#define INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define INPUT_NOINTERP( TYPE, NAME, REG ) nointerp TYPE NAME : REG;
#define INPUT_NOPERSP( TYPE, NAME, REG ) nopersp TYPE NAME : REG;
#define OUTPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) nointerp TYPE NAME : REG;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) nopersp TYPE NAME : REG;
#define FRAGMENT_COLOUR_UVEC4_DEFINE
#define FRAGMENT_COLOUR_UVEC4 Out.mColour
#define FRAGMENT_COLOUR Out.mColour
#define FRAGMENT_COLOUR0 Out.mColour0
#define FRAGMENT_COLOUR1 Out.mColour1
#define FRAGMENT_COLOUR2 Out.mColour2
#define FRAGMENT_COLOUR3 Out.mColour3
#define FRAGMENT_COLOUR4 Out.mColour4
#define FRAGMENT_DEPTH Out.mDepth
#define FRAGMENT_FRONTFACE In.mbFrontFacing
#define INPUT_FRONTFACING bool mbFrontFacing : S_FRONT_FACE;
#if defined( D_HULL )
#define IN( VAR ) In[ uCPID ].VAR
#define OUT( VAR ) Out.VAR
#define PATCH_OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION IN( mScreenPositionVec4 )
#define TESS_LEVEL_EDGE( IND ) Out.edge_ts[ IND ]
#define TESS_LEVEL_INNER( IND ) Out.insi_ts[ IND ]
#define DECLARE_PATCH_OUTPUT_TRI [DOMAIN_PATCH_TYPE("tri")] struct HSConstantOutputData {
#define OUT_PATCH_TRI_TESS_CONSTANTS float edge_ts[3] : S_EDGE_TESS_FACTOR; \
float insi_ts[1] : S_INSIDE_TESS_FACTOR;
#define DECLARE_PATCH_OUTPUT_QUAD [DOMAIN_PATCH_TYPE("quad")] struct HSConstantOutputData (
#define OUT_PATCH_QUAD_TESS_CONSTANTS float edge_ts[4] : S_EDGE_TESS_FACTOR; \
float insi_ts[2] : S_INSIDE_TESS_FACTOR;
#define PATCH_OUTPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#elif defined( D_DOMAIN )
#define PATCH_IN( VAR, IND ) patchIn.VAR
#define IN( VAR, IND ) In[ IND ].VAR
#define OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION( IND ) IN( mScreenPositionVec4, IND )
#define DOMAIN_COORDS domainCoordinates
#define DECLARE_PATCH_INPUT_TRI [DOMAIN_PATCH_TYPE("tri")] struct HSConstantOutputData {
#define IN_PATCH_TRI_TESS_CONSTANTS float edge_ts[3] : S_EDGE_TESS_FACTOR; \
float insi_ts[1] : S_INSIDE_TESS_FACTOR;
#define DECLARE_PATCH_INPUT_QUAD [DOMAIN_PATCH_TYPE("quad")] struct HSConstantOutputData {
#define IN_PATCH_QUAD_TESS_CONSTANTS float edge_ts[4] : S_EDGE_TESS_FACTOR; \
float insi_ts[2] : S_INSIDE_TESS_FACTOR;
#define PATCH_INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#elif defined( D_GEOMETRY )
#define IN( VAR, IND ) In[ IND ].VAR
#define OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION( IND ) IN( mScreenPositionVec4, IND )
#define EMIT_VERTEX TriStream.Append( Out )
#define END_PRIMITIVE TriStream.RestartStrip()
#else
#define IN( VAR ) In.VAR
#define OUT( VAR ) Out.VAR
#endif
// TODO get rid of this - don't pass struct through functinos, pass members.
#define DEREF_PTR( VAR ) *VAR
#define OUT_VERTEX_SCREEN_POSITION OUTPUT( vec4, mScreenPositionVec4, S_POSITION )
#define IN_SCREEN_POSITION INPUT ( vec4, mScreenPositionVec4, S_POSITION )
#define VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#endif
// =================================================================================================
// Main
// =================================================================================================
#ifdef D_PLATFORM_PC
#define VERTEX_MAIN void main( void )
#define VERTEX_MAIN_SRT uniform UniformBuffer lUniforms; void main( void )
#define HULL_TRI_MAIN_SRT layout( vertices = 3 ) out; uniform UniformBuffer lUniforms; void main( void )
#define HULL_QUAD_MAIN_SRT layout( vertices = 4 ) out; uniform UniformBuffer lUniforms; void main( void )
#define DOMAIN_TRI_MAIN_SRT layout( triangles, fractional_even_spacing ) in; uniform UniformBuffer lUniforms; void main( void )
#define DOMAIN_QUAD_MAIN_SRT layout( quads, fractional_even_spacing ) in; uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define VOID_MAIN_COLOUR FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_GE_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_LE_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_EARLYZ_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_UICOLOUR_SRT FRAGMENT_COLOUR_UVEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define VOID_MAIN_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define VOID_MAIN_DEPTH_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR01_SRT FRAGMENT_COLOUR01_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR01_DEPTH_SRT FRAGMENT_COLOUR01_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#elif defined( D_PLATFORM_PC_COMPUTE )
#define COMPUTE_MAIN_SRT( X, Y, Z ) layout (local_size_x = X, local_size_y = Y, local_size_z = Z) in; void main( void )
#define FRAGMENT_MAIN_COLOUR_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR01_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#elif defined( D_PLATFORM_ORBIS_COMPUTE )
#define COMPUTE_MAIN_SRT( X, Y, Z ) [NUM_THREADS(X, Y, Z)] void main(uint3 groupID : S_GROUP_ID, uint3 groupThreadID : S_GROUP_THREAD_ID, uint3 dispatchThreadID : S_DISPATCH_THREAD_ID, UniformBuffer lUniforms : S_SRT_DATA)
#define FRAGMENT_MAIN_COLOUR_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR01_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#elif defined( D_PLATFORM_ORBIS )
#define VERTEX_MAIN void main( cInput In, out cOutput Out )
#define VERTEX_MAIN_SRT void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define HULL_TRI_MAIN_SRT [DOMAIN_PATCH_TYPE("tri")] \
[PARTITIONING_TYPE("integer")] \
[OUTPUT_TOPOLOGY_TYPE("triangle_cw")] \
[OUTPUT_CONTROL_POINTS(3)] \
[PATCH_CONSTANT_FUNC("ConstantsHS")] \
[MAX_TESS_FACTOR(16.0)] \
void main( \
InputPatch<cInput, 3> In, \
uint uCPID : S_OUTPUT_CONTROL_POINT_ID, \
UniformBuffer lUniforms : S_SRT_DATA, \
out cOutput Out )
#define HULL_QUAD_MAIN_SRT [DOMAIN_PATCH_TYPE("quad")] \
[PARTITIONING_TYPE("integer")] \
[OUTPUT_TOPOLOGY_TYPE("triangle_cw")] \
[OUTPUT_CONTROL_POINTS(4)] \
[PATCH_CONSTANT_FUNC("ConstantsHS")] \
[MAX_TESS_FACTOR(16.0)] \
void main( \
InputPatch<cInput, 4> In, \
uint uCPID : S_OUTPUT_CONTROL_POINT_ID, \
UniformBuffer lUniforms : S_SRT_DATA, \
out cOutput Out )
#define DOMAIN_TRI_MAIN_SRT [DOMAIN_PATCH_TYPE("tri")] \
void main( \
HSConstantOutputData patchIn, \
const OutputPatch<cInput, 3> In, \
out cOutput Out, \
UniformBuffer lUniforms : S_SRT_DATA, \
float3 domainCoordinates : S_DOMAIN_LOCATION )
#define DOMAIN_QUAD_MAIN_SRT [DOMAIN_PATCH_TYPE("quad")] \
void main( \
HSConstantOutputData patchIn, \
const OutputPatch<cInput, 4> In, \
out cOutput Out, \
UniformBuffer lUniforms : S_SRT_DATA, \
float2 domainCoordinates : S_DOMAIN_LOCATION )
#define GEOMETRY_MAIN_SRT( MAX_VERTS ) cOutput Out; [MAX_VERTEX_COUNT(MAX_VERTS)] void main( inout TriangleBuffer<cOutput> TriStream, Triangle cInput In[3], UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out )
#define VOID_MAIN_COLOUR struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; void main( cInput In, out cOutput Out )
#define FRAGMENT_MAIN_COLOUR_DEPTH struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out )
#define VOID_MAIN_SRT void main( cInput In, UniformBuffer lUniforms : S_SRT_DATA )
#if defined( D_TAA_RENDER_TARGETS )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#elif !defined( D_ATTRIBUTES )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_DEPTH_GE_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_GE_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_DEPTH_LE_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_LE_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define VOID_MAIN_DEPTH_SRT struct cOutput { float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define VOID_MAIN_COLOUR_EARLYZ_SRT [FORCE_EARLY_DEPTH_STENCIL] void main( cInput In, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR01_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR01_DEPTH_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
float mDepth : S_DEPTH_OUTPUT; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#else
// #pragma PSSL_target_output_format(target 1 FMT_32_AR)
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; \
float mDepth : S_DEPTH_OUTPUT; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_EARLYZ_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; }; \
[FORCE_EARLY_DEPTH_STENCIL] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#endif
#endif
// =================================================================================================
// Texture resolution
// =================================================================================================
#ifdef D_PLATFORM_ORBIS
uvec2 GetResolution( Texture2D lTexture )
{
uvec2 lResolution;
lTexture.GetDimensionsFast(lResolution.x, lResolution.y);
return lResolution;
}
uvec2 GetResolution( RW_Texture2D<float4> lTexture )
{
uvec2 lResolution;
lTexture.GetDimensionsFast(lResolution.x, lResolution.y);
return lResolution;
}
#else
uvec2 GetResolution( sampler2D lTexture )
{
return textureSize( lTexture, 0 );
}
#endif
// =================================================================================================
// Viewport
// =================================================================================================
#ifdef D_PLATFORM_PC
#define SCREENSPACE_AS_RENDERTARGET_UVS( A ) A.xy
#elif defined(D_PLATFORM_ORBIS)
#define SCREENSPACE_AS_RENDERTARGET_UVS( A ) ( float2( A.x, 1.0 - A.y ) )
#endif
#ifdef D_USING_LOGDEPTH
#define D_DEPTH_CLEARVALUE (1.0)
#else
#define D_DEPTH_CLEARVALUE (0.0)
#endif
// =================================================================================================
// Texture usage feedback
// =================================================================================================
#if defined( D_TEXTURE_FEEDBACK ) && defined( D_PLATFORM_PC )
layout(r32i) uniform iimage2D gTexFeedbackImg;
void WriteTexFeedback( in int liCounter, in float liMip )
{
if( liCounter != 0 )
{
#if defined( GL_ARB_shader_ballot ) && ( GL_ARB_shader_ballot == 1 )
if( readFirstInvocationARB( gl_SubGroupInvocationARB ) == gl_SubGroupInvocationARB )
#endif
{
int liIntMip = int(floor(liMip));
//imageStore( gTexFeedbackImg, ivec2( liCounter, liIntMip ), ivec4(1,0,0,0) );
imageAtomicAdd( gTexFeedbackImg, ivec2( liCounter, liIntMip ), int(1) );
}
}
}
vec4 Tex2dFeedback( in sampler2D lSamp, in int liCounter, in vec2 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex2dLodFeedback( in sampler2D lSamp, in int liCounter, in vec2 lCoords, in float liLod )
{
WriteTexFeedback( liCounter, liLod );
return textureLod( lSamp, lCoords, liLod );
}
vec4 Tex2dArrayFeedback( in sampler2DArray lSamp, in int liCounter, in vec3 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords.xy ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex3dFeedback( in sampler3D lSamp, in int liCounter, in vec3 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex3dLodFeedback( in sampler3D lSamp, in int liCounter, in vec3 lCoords, in float liLod )
{
WriteTexFeedback( liCounter, liLod );
return textureLod( lSamp, lCoords, liLod );
}
#endif
#endif
////////////////////////////////////////////////////////////////////////////////
///
/// @file Common.h
/// @author User
/// @date
///
/// @brief Common
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
#ifndef D_COMMON_H
#define D_COMMON_H
#define D_TERRAINCOLOURARRAY_SIZE 23
STATIC_CONST vec3 kGammaOutVec3 = vec3( 1.0 / 2.2 );
STATIC_CONST vec3 kGammaInVec3 = vec3( 2.2 );
STATIC_CONST vec4 RGBToHSV_K = vec4( 0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0 );
STATIC_CONST vec4 HSVToRGB_K = vec4( 1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0 );
#ifdef D_PLATFORM_ORBIS
STATIC_CONST float3x3 BT709_TO_BT2020 = float3x3( //ref: ARIB STD-B62 and BT.2087
#else
STATIC_CONST mat3 BT709_TO_BT2020 = mat3( //ref: ARIB STD-B62 and BT.2087
#endif
0.6274, 0.3293, 0.0433,
0.0691, 0.9195, 0.0114,
0.0164, 0.0880, 0.8956
);
#ifdef D_PLATFORM_ORBIS
STATIC_CONST float3x3 BT2020_TO_BT709 = float3x3(
#else
STATIC_CONST mat3 BT2020_TO_BT709 = mat3(
#endif
1.6605, -0.5877, -0.0728,
-0.1246, 1.1330, -0.0084,
-0.0182, -0.1006, 1.1187
);
//-----------------------------------------------------------------------------
///
/// GammaCorrect
///
//-----------------------------------------------------------------------------
vec3
GammaCorrectInput(
in vec3 lColourVec3 )
{
vec3 lCorrectColourVec3;
lCorrectColourVec3 = lColourVec3 * ( lColourVec3 * ( lColourVec3 * vec3( 0.305306011 ) + vec3( 0.682171111 ) ) + vec3( 0.012522878 ) );
return lCorrectColourVec3;
}
//-----------------------------------------------------------------------------
///
/// GammaCorrect
///
//-----------------------------------------------------------------------------
vec3
GammaCorrectOutput(
in vec3 lColourVec3 )
{
vec3 lCorrectColourVec3;
lCorrectColourVec3 = pow( lColourVec3, kGammaOutVec3 );
return lCorrectColourVec3;
}
//-----------------------------------------------------------------------------
///
/// RGBToHSV
///
//-----------------------------------------------------------------------------
vec3
RGBToHSV(
vec3 lRGB )
{
//vec4 p = mix( vec4(lRGB.bg, RGBToHSV_K.wz), vec4(lRGB.gb, RGBToHSV_K.xy), step(lRGB.b, lRGB.g) );
//vec4 q = mix( vec4(p.xyw, lRGB.r), vec4(lRGB.r, p.yzx), step(p.x, lRGB.r) );
// This variant is faster, since it generates conditional moves
vec4 p = lRGB.g < lRGB.b ? vec4(lRGB.bg, RGBToHSV_K.wz) : vec4(lRGB.gb, RGBToHSV_K.xy);
vec4 q = lRGB.r < p.x ? vec4(p.xyw, lRGB.r) : vec4(lRGB.r, p.yzx);
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
//-----------------------------------------------------------------------------
///
/// HSVToRGB
///
/// @brief http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
///
//-----------------------------------------------------------------------------
vec3
HSVToRGB(
vec3 lHSV )
{
vec3 p = abs(fract(lHSV.xxx + HSVToRGB_K.xyz) * 6.0 - HSVToRGB_K.www);
return lHSV.z * mix(HSVToRGB_K.xxx, saturate(p - HSVToRGB_K.xxx), lHSV.y);
}
//-----------------------------------------------------------------------------
///
/// HDR ( Perceptual Quantizer(PQ), Rec. 2020 color space. ) helpers
///
//------------------------------------------------------------------------------
#ifdef D_PLATFORM_PC
float CndMask(bool cnd, float src0, float src1)
{
return cnd ? src0 : src1;
}
#endif
STATIC_CONST float kRefWhiteLevel = 100.0;
vec4 SRGB_OETF(vec4 L)
{
vec3 dark = L.xyz * 12.92;
vec3 light = 1.055 * pow(L.xyz, vec3(1.0 / 2.4)) - 0.055;
vec4 r;
r.x = CndMask(L.x <= 0.0031308, dark.x, light.x);
r.y = CndMask(L.y <= 0.0031308, dark.y, light.y);
r.z = CndMask(L.z <= 0.0031308, dark.z, light.z);
r.w = L.w;
return r;
}
vec4 SRGB_EOTF(vec4 E)
{
vec3 dark = E.xyz / 12.92;
vec3 light = pow((E.xyz + 0.055) / (1 + 0.055), vec3(2.4));
vec4 r;
r.x = CndMask(E.x <= 0.04045, dark.x, light.x);
r.y = CndMask(E.y <= 0.04045, dark.y, light.y);
r.z = CndMask(E.z <= 0.04045, dark.z, light.z);
r.w = E.w;
return r;
}
//apply gamma adjustment to (minL, maxL).
vec4 GammaAdjOOTF(vec4 L, float minLNits, float maxLNits, float gamma, bool inverse)
{
vec3 nits = L.xyz * kRefWhiteLevel;
vec4 i = vec4((nits - minLNits) / (maxLNits - minLNits), 1.0);
vec3 j;
if (inverse){
j = SRGB_EOTF(pow(i, vec4(1 / gamma))).xyz;
}
else{
j = pow(SRGB_OETF(i).xyz,vec3(gamma));
}
vec3 adj = (minLNits + (maxLNits - minLNits) * j) / kRefWhiteLevel;
vec4 ret;
ret.x = CndMask(nits.x >= minLNits && nits.x < maxLNits, adj.x, L.x);
ret.y = CndMask(nits.y >= minLNits && nits.y < maxLNits, adj.y, L.y);
ret.z = CndMask(nits.z >= minLNits && nits.z < maxLNits, adj.z, L.z);
ret.w = L.w;
return ret;
}
//input: normalized L in units of RefWhite (1.0=100nits), output: normalized E
vec4 PQ_OETF(vec4 L, uint gamma_adj, float gamma)
{
if (gamma_adj != 0)
L = GammaAdjOOTF(L, 0.0, 300.0, gamma, false);
const float c1 = 0.8359375;//3424.f/4096.f;
const float c2 = 18.8515625;//2413.f/4096.f*32.f;
const float c3 = 18.6875; //2392.f/4096.f*32.f;
const float m1 = 0.159301758125; //2610.f / 4096.f / 4;
const float m2 = 78.84375;// 2523.f / 4096.f * 128.f;
L = L * kRefWhiteLevel / 10000.0;
vec3 Lm1 = pow(L.xyz, vec3(m1));
vec3 X = (c1 + c2 * Lm1) / (1 + c3 * Lm1);
vec4 res = vec4(pow(X, vec3(m2)), L.w);
return res;
}
//input: normalized E (0.0, 1.0), output: normalized L in units of RefWhite
vec4 PQ_EOTF(vec4 E, uint gamma_adj, float gamma)
{
const float c1 = 0.8359375;//3424.f/4096.f;
const float c2 = 18.8515625;//2413.f/4096.f*32.f;
const float c3 = 18.6875; //2392.f/4096.f*32.f;
const float m1 = 0.159301758125; //2610.f / 4096.f / 4;
const float m2 = 78.84375;// 2523.f / 4096.f * 128.f;
vec3 M = c2 - c3 * pow(E.xyz, vec3(1 / m2));
vec3 N = max(pow(E.xyz, vec3(1 / m2)) - c1, 0);
vec3 L = pow(N / M, vec3(1 / m1)); //normalized nits (1.0 = 10000nits)
L = L * 10000.0 / kRefWhiteLevel; //convert to normalized L in units of RefWhite
return (gamma_adj !=0) ? GammaAdjOOTF(vec4(L, E.w), 0.0, 300.0, gamma, true) : vec4(L, E.w);
}
// PQ OETF fast approximation
// http://www.glowybits.com/blog/2017/01/04/ifl_iss_hdr_2/
vec3 PQ_OETF_Fast(vec3 x)
{
x = (x * (x * (x * (x * (x * 533095.76 + 47438306.2) + 29063622.1) + 575216.76) + 383.09104) + 0.000487781) /
(x * (x * (x * (x * 66391357.4 + 81884528.2) + 4182885.1) + 10668.404) + 1.0);
return x;
}
//-----------------------------------------------------------------------------
///
/// BrightnessVibranceContrast
///
//-----------------------------------------------------------------------------
vec3 BrightnessVibranceContrast(
vec3 lInputColour,
float lfBrightness,
float lfVibrance,
float lfContrast)
{
vec3 lBrtResult = lInputColour * lfBrightness;
// get lum
vec3 lLuma = vec3( dot(lBrtResult, vec3( 0.2125, 0.7154, 0.0721 )) );
// get saturation
float lfMaxCol = max( lBrtResult.r, max(lBrtResult.g, lBrtResult.b) );
float lfMinCol = min( lBrtResult.r, min(lBrtResult.g, lBrtResult.b) );
float lfCurSatV = lfMaxCol - lfMinCol;
// lerp by 1 + (1 - vibrance) - current saturation
float lfVibranceMix = (1.0 + (lfVibrance * (1.0 - (sign(lfVibrance) * lfCurSatV))));
vec3 lVibResult = mix( lLuma, lBrtResult, lfVibranceMix );
// lerp from mid gray for contrast
vec3 lContrastBase = vec3( 0.5, 0.5, 0.5 );
vec3 lConResult = mix( lContrastBase , lVibResult, lfContrast );
return lConResult;
}
//-----------------------------------------------------------------------------
///
/// Desaturate
///
//-----------------------------------------------------------------------------
vec3 Desaturate( vec3 color, float lfAmount )
{
vec3 gray = vec3( dot( vec3( 0.299, 0.587, 0.114 ), color) );
return mix( color, gray, lfAmount );
}
// improved rgb lerp by @stormoid
// https://www.shadertoy.com/view/lsdGzN
//---------------Improved RGB--------------
/*
The idea behind this function is to avoid the low saturation area in the
rgb color space. This is done by getting the direction to that diagonal
and displacing the interpolated color by it's inverse while scaling it
by saturation error and desired lightness.
I find it behaves very well under most circumstances, the only instance
where it doesn't behave ideally is when the hues are very close to 180
degrees apart, since the method I am using to find the displacement vector
does not compensate for non-curving motion. I tried a few things to
circumvent this problem but none were cheap and effective enough..
*/
//Changes the strength of the displacement
#define DSP_STR 1.5
//-----------------------------------------------------------------------------
float _getsat( vec3 lColour )
{
float mi = min(min(lColour.x, lColour.y), lColour.z);
float ma = max(max(lColour.x, lColour.y), lColour.z);
return (ma - mi) / (ma + 1e-7);
}
vec3 NmzRgbLerp( vec3 a, vec3 b, float x )
{
// interpolated base color (with singularity fix)
vec3 ic = mix( a, b, x ) + vec3( 1e-6, 0.0, 0.0 );
// saturation difference from ideal scenario
float sd = abs( _getsat( ic ) - mix( _getsat( a ), _getsat( b ), x ) );
// displacement direction
vec3 dir = normalize(
vec3( 2.0 * ic.x - ic.y - ic.z,
2.0 * ic.y - ic.x - ic.z,
2.0 * ic.z - ic.y - ic.x )
);
// simple Lighntess
float lgt = dot( vec3( 1.0 ), ic );
// extra scaling factor for the displacement
float ff = dot( dir, normalize( ic ) );
// displace the color
ic += DSP_STR * dir * sd * ff * lgt;
return clamp( ic, 0.0, 1.0 );
}
//-----------------------------------------------------------------------------
///
/// Inverse
///
//-----------------------------------------------------------------------------
mat4
Inverse(
const mat4 lInMat4 )
{
#ifdef D_PLATFORM_PC
return inverse( lInMat4 );
#else
float det = determinant( lInMat4 );
det = 1.0f / det;
mat4 M = lInMat4;
mat4 IM;
IM[0][0] = det * ( M[1][2]*M[2][3]*M[3][1] - M[1][3]*M[2][2]*M[3][1] + M[1][3]*M[2][1]*M[3][2] - M[1][1]*M[2][3]*M[3][2] - M[1][2]*M[2][1]*M[3][3] + M[1][1]*M[2][2]*M[3][3] );
IM[0][1] = det * ( M[0][3]*M[2][2]*M[3][1] - M[0][2]*M[2][3]*M[3][1] - M[0][3]*M[2][1]*M[3][2] + M[0][1]*M[2][3]*M[3][2] + M[0][2]*M[2][1]*M[3][3] - M[0][1]*M[2][2]*M[3][3] );
IM[0][2] = det * ( M[0][2]*M[1][3]*M[3][1] - M[0][3]*M[1][2]*M[3][1] + M[0][3]*M[1][1]*M[3][2] - M[0][1]*M[1][3]*M[3][2] - M[0][2]*M[1][1]*M[3][3] + M[0][1]*M[1][2]*M[3][3] );
IM[0][3] = det * ( M[0][3]*M[1][2]*M[2][1] - M[0][2]*M[1][3]*M[2][1] - M[0][3]*M[1][1]*M[2][2] + M[0][1]*M[1][3]*M[2][2] + M[0][2]*M[1][1]*M[2][3] - M[0][1]*M[1][2]*M[2][3] );
IM[1][0] = det * ( M[1][3]*M[2][2]*M[3][0] - M[1][2]*M[2][3]*M[3][0] - M[1][3]*M[2][0]*M[3][2] + M[1][0]*M[2][3]*M[3][2] + M[1][2]*M[2][0]*M[3][3] - M[1][0]*M[2][2]*M[3][3] );
IM[1][1] = det * ( M[0][2]*M[2][3]*M[3][0] - M[0][3]*M[2][2]*M[3][0] + M[0][3]*M[2][0]*M[3][2] - M[0][0]*M[2][3]*M[3][2] - M[0][2]*M[2][0]*M[3][3] + M[0][0]*M[2][2]*M[3][3] );
IM[1][2] = det * ( M[0][3]*M[1][2]*M[3][0] - M[0][2]*M[1][3]*M[3][0] - M[0][3]*M[1][0]*M[3][2] + M[0][0]*M[1][3]*M[3][2] + M[0][2]*M[1][0]*M[3][3] - M[0][0]*M[1][2]*M[3][3] );
IM[1][3] = det * ( M[0][2]*M[1][3]*M[2][0] - M[0][3]*M[1][2]*M[2][0] + M[0][3]*M[1][0]*M[2][2] - M[0][0]*M[1][3]*M[2][2] - M[0][2]*M[1][0]*M[2][3] + M[0][0]*M[1][2]*M[2][3] );
IM[2][0] = det * ( M[1][1]*M[2][3]*M[3][0] - M[1][3]*M[2][1]*M[3][0] + M[1][3]*M[2][0]*M[3][1] - M[1][0]*M[2][3]*M[3][1] - M[1][1]*M[2][0]*M[3][3] + M[1][0]*M[2][1]*M[3][3] );
IM[2][1] = det * ( M[0][3]*M[2][1]*M[3][0] - M[0][1]*M[2][3]*M[3][0] - M[0][3]*M[2][0]*M[3][1] + M[0][0]*M[2][3]*M[3][1] + M[0][1]*M[2][0]*M[3][3] - M[0][0]*M[2][1]*M[3][3] );
IM[2][2] = det * ( M[0][1]*M[1][3]*M[3][0] - M[0][3]*M[1][1]*M[3][0] + M[0][3]*M[1][0]*M[3][1] - M[0][0]*M[1][3]*M[3][1] - M[0][1]*M[1][0]*M[3][3] + M[0][0]*M[1][1]*M[3][3] );
IM[2][3] = det * ( M[0][3]*M[1][1]*M[2][0] - M[0][1]*M[1][3]*M[2][0] - M[0][3]*M[1][0]*M[2][1] + M[0][0]*M[1][3]*M[2][1] + M[0][1]*M[1][0]*M[2][3] - M[0][0]*M[1][1]*M[2][3] );
IM[3][0] = det * ( M[1][2]*M[2][1]*M[3][0] - M[1][1]*M[2][2]*M[3][0] - M[1][2]*M[2][0]*M[3][1] + M[1][0]*M[2][2]*M[3][1] + M[1][1]*M[2][0]*M[3][2] - M[1][0]*M[2][1]*M[3][2] );
IM[3][1] = det * ( M[0][1]*M[2][2]*M[3][0] - M[0][2]*M[2][1]*M[3][0] + M[0][2]*M[2][0]*M[3][1] - M[0][0]*M[2][2]*M[3][1] - M[0][1]*M[2][0]*M[3][2] + M[0][0]*M[2][1]*M[3][2] );
IM[3][2] = det * ( M[0][2]*M[1][1]*M[3][0] - M[0][1]*M[1][2]*M[3][0] - M[0][2]*M[1][0]*M[3][1] + M[0][0]*M[1][2]*M[3][1] + M[0][1]*M[1][0]*M[3][2] - M[0][0]*M[1][1]*M[3][2] );
IM[3][3] = det * ( M[0][1]*M[1][2]*M[2][0] - M[0][2]*M[1][1]*M[2][0] + M[0][2]*M[1][0]*M[2][1] - M[0][0]*M[1][2]*M[2][1] - M[0][1]*M[1][0]*M[2][2] + M[0][0]*M[1][1]*M[2][2] );
return IM;
#endif
}
float
lengthSquared( vec3 lInVec3 )
{
return dot( lInVec3, lInVec3 );
}
#endif
////////////////////////////////////////////////////////////////////////////////
///
/// @file CommonDepth.h
/// @author User
/// @date
///
/// @brief CommonDepth
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Compilation defines
#ifndef D_COMMONDEPTH_H
#define D_COMMONDEPTH_H
//-----------------------------------------------------------------------------
// Include files
//#include "Common/CommonUniforms.shader.h"
//-----------------------------------------------------------------------------
// Global Data
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
///
/// LinearToLogDepth
///
/// @brief LinearToLogDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
#ifdef D_USING_LOGDEPTH
vec4
LinearToLogDepth_Vertex(
in vec4 lClipPlanes,
in vec4 lScreenPos )
{
vec4 lLogScreenPos = lScreenPos;
float kfFarPlane = lClipPlanes.y;
float FC = lClipPlanes.z; // 2.0 / log2(farplane + 1.0)
float lfLogz = log2( max( 1e-6, lScreenPos.w + 1 ) ) * FC - 1.0;
lLogScreenPos.z = ( lfLogz ) * lScreenPos.w;
return lLogScreenPos;
}
//-----------------------------------------------------------------------------
///
/// LinearToLogDepth_Pixel
///
/// @brief LinearToLogDepth_Pixel
///
/// @param in float lfLogZ
/// @param in vec4 lClipPlanes
/// @return float
///
//-----------------------------------------------------------------------------
float
LinearToLogDepth_Pixel(
in float lfLogZ,
in vec4 lClipPlanes )
{
return log2( lfLogZ ) * lClipPlanes.w; // 1.0 / log2(farplane + 1.0)
}
//-----------------------------------------------------------------------------
///
/// LogToLinearDepth
///
/// @brief LogToLinearDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
LogToLinearDepth2(
in vec4 lClipPlanes,
float lfLogDepth )
{
return exp2( lfLogDepth / lClipPlanes.w ); // 1.0 / log2(farplane + 1.0)
}
//-----------------------------------------------------------------------------
///
/// LogToLinearDepth
///
/// @brief LogToLinearDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
#if 0
float
LogToLinearDepth(
in vec4 lClipPlanes,
float lfLogDepth )
{
float kfNearClip = lClipPlanes.x;
float kfFar = lClipPlanes.y;
float kfFarClip = 1.0 / log( kfFar*kfNearClip + 1.0 );
float lfLinearDepth = ( exp( lfLogDepth/kfFarClip ) - 1.0 ) / kfNearClip;
return lfLinearDepth;
}
#else
float
LogToLinearDepth(
in vec4 lClipPlanesR,
float lfLogDepth )
{
float lfLinearDepth = ( exp2( lfLogDepth*lClipPlanesR.z ) - 1.0 ) * lClipPlanesR.x;
return lfLinearDepth;
}
#endif
#else
vec4
LinearToLogDepth_Vertex(
in vec4 lClipPlanes,
in vec4 lScreenPos)
{
// This is a NOP with ReverseZ
return lScreenPos;
}
float
ReverseZToLinearDepth(
in vec4 lClipPlanes,
float lfDepth)
{
float zNear = lClipPlanes.x;
float zFar = lClipPlanes.y;
return zNear * zFar / ( zNear + lfDepth * (zFar - zNear));
}
float
ReverseZToLinearDepthNorm(
in vec4 lClipPlanes,
float lfDepth)
{
float zNear = lClipPlanes.x;
float zFar = lClipPlanes.y;
return zNear / (zNear + lfDepth * (zFar - zNear));
}
float
LinearToReverseZDepth(
in vec4 lClipPlanes,
float lfDepth)
{
float zNear = lClipPlanes.x;
float zFar = lClipPlanes.y;
return ( zNear * zFar / lfDepth - zNear ) / ( zFar - zNear );
}
#endif
#if 0
// These are no longer used
//-----------------------------------------------------------------------------
///
/// NormaliseDepth
///
/// @brief LogToLinearDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
NormaliseDepth(
in vec4 lClipPlanes,
float lfDepth )
{
float kfNearClip = lClipPlanes.x;
float kfFar = lClipPlanes.y;
return (lfDepth - kfNearClip) / (kfFar-kfNearClip);
}
//-----------------------------------------------------------------------------
///
/// NormaliseDepth
///
/// @brief LogToLinearDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
DenormaliseDepth(
in vec4 lClipPlanes,
float lfDepth )
{
float kfNearClip = lClipPlanes.x;
float kfFar = lClipPlanes.y;
return lfDepth * ( kfFar-kfNearClip ) + kfNearClip;
}
#endif
//-----------------------------------------------------------------------------
///
/// FastNormaliseDepth
///
/// @brief FastNormaliseDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
FastNormaliseDepth(
in vec4 lClipPlanesR,
float lfDepth )
{
float kfRecip_Far = lClipPlanesR.y;
return (lfDepth * kfRecip_Far);
}
//-----------------------------------------------------------------------------
///
/// FastDenormaliseDepth
///
/// @brief FastDenormaliseDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
FastDenormaliseDepth(
in vec4 lClipPlanes,
float lfDepth )
{
float kfFar = lClipPlanes.y;
return lfDepth * kfFar;
}
//-----------------------------------------------------------------------------
///
/// EncodeDepthToColour
///
/// @brief EncodeDepthToColour
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
vec4
EncodeDepthToColour(
float lDepth )
{
#if 0
vec4 enc = vec4( 1.0, 255.0, 65025.0, 16581375.0 ) * vec4(lDepth);
enc = fract(enc);
enc.xyz -= enc.yzw * vec3( 1.0f/255.0, 1.0f/255.0, 1.0f/255.0 );
return enc;
#else
return vec4(lDepth,0.0,0.0,0.0);
#endif
}
//-----------------------------------------------------------------------------
///
/// DecodeDepthFromColour
///
/// @brief DecodeDepthFromColour
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
DecodeDepthFromColour(
vec4 lColour )
{
#if 0
return dot( lColour, vec4( 1.0, 1.0f/255.0, 1.0f/65025.0, 1.0 / 16581375.0 ) );
#else
return lColour.x;
#endif
}
vec3
RecreatePositionFromDepthWithIVP(
in float lfDepth,
in vec2 lFragCoordsVec2,
in vec3 lViewPosition,
in mat4 lInverseViewProjectionMatrix,
in vec4 lClipPlanes)
{
vec4 lPositionVec4;
lPositionVec4.x = lFragCoordsVec2.x * 2.0 - 1.0;
#ifdef D_PLATFORM_ORBIS
lPositionVec4.y = (1.0f - lFragCoordsVec2.y) * 2.0 - 1.0;
#else
lPositionVec4.y = lFragCoordsVec2.y * 2.0 - 1.0;
#endif
lPositionVec4.z = LinearToReverseZDepth( lClipPlanes, lfDepth );
lPositionVec4.w = 1.0;
lPositionVec4 = MUL(lInverseViewProjectionMatrix, lPositionVec4);
lPositionVec4.xyz = lPositionVec4.xyz / lPositionVec4.w;
lPositionVec4.xyz += lViewPosition;
return lPositionVec4.xyz;
}
vec3
RecreatePositionFromDepth(
in float lfDepth,
in vec2 lFragCoordsVec2,
in vec3 lViewPosition,
in mat4 lInverseProjectionMatrix,
in mat4 lInverseViewMatrix )
{
vec4 lPositionVec4;
lPositionVec4.x = lFragCoordsVec2.x * 2.0 - 1.0;
#ifdef D_PLATFORM_ORBIS
lPositionVec4.y = ( 1.0f-lFragCoordsVec2.y ) * 2.0 - 1.0;
#else
lPositionVec4.y = lFragCoordsVec2.y * 2.0 - 1.0;
#endif
lPositionVec4.z = 0.0;
lPositionVec4.w = 1.0;
// Inverse projection
lPositionVec4 = MUL( lInverseProjectionMatrix, lPositionVec4 );
//lPositionVec4 = lPositionVec4 / lPositionVec4.w;
lPositionVec4 = lPositionVec4 / abs(lPositionVec4.z);
lPositionVec4 *= lfDepth;
// Inverse view
mat4 lViewMat = lInverseViewMatrix;
MAT4_SET_POS( lViewMat, vec4( 0.0, 0.0, 0.0, 1.0 ) );
lPositionVec4 = MUL( lViewMat, lPositionVec4 );
//lPositionVec4 = lPositionVec4 / lPositionVec4.w;
//lPositionVec4.xyz -= lViewPosition;
lPositionVec4.xyz = lPositionVec4.xyz + lViewPosition;
return lPositionVec4.xyz;
}
vec4
GetDepthColour(
in float lfDepth )
{
vec4 lColourVec4;
if( lfDepth < 1.0 )
{
lColourVec4 = vec4( 0.0, 0.0, 1.0, 1.0 );
}
else if( lfDepth < 10.0 )
{
lColourVec4 = vec4( 1.0, 0.0, 0.0, 1.0 );
}
else if( lfDepth < 20.0 )
{
lColourVec4 = vec4( 1.0, 1.0, 0.0, 1.0 );
}
else if( lfDepth < 40.0 )
{
lColourVec4 = vec4( 0.0, 1.0, 0.0, 1.0 );
}
else if( lfDepth < 80.0 )
{
lColourVec4 = vec4( 0.0, 1.0, 1.0, 1.0 );
}
else if( lfDepth < 160.0 )
{
lColourVec4 = vec4( 1.0, 0.0, 1.0, 1.0 );
}
else if( lfDepth < 320.0 )
{
lColourVec4 = vec4( 1.0, 0.5, 0.0, 1.0 );
}
else if( lfDepth < 640.0 )
{
lColourVec4 = vec4( 0.5, 1.0, 0.0, 1.0 );
}
else if( lfDepth < 1280.0 )
{
lColourVec4 = vec4( 0.0, 1.0, 0.5, 1.0 );
}
else if( lfDepth < 2560.0 )
{
lColourVec4 = vec4( 0.5, 0.0, 1.0, 1.0 );
}
else
{
lColourVec4 = vec4( 1.0, 0.0, 0.5, 1.0 );
}
return lColourVec4;
}
#endif
float
EncodeUnitScalars(
in float lfUnitScalarA,
in float lfUnitScalarB )
{
int liUpper = int( saturate( lfUnitScalarB ) * 255.0 ) << 8;
int liLower = int( saturate( lfUnitScalarA ) * 255.0 );
return float( liUpper | liLower );
//return lfUnitScalarA;
}
void
DecodeUnitScalars(
in float lfEncodedFloat,
out float lfUnitScalarA,
out float lfUnitScalarB )
{
lfUnitScalarA = float( int( lfEncodedFloat ) & 0xFF ) / 255.0;
lfUnitScalarB = float( ( int( lfEncodedFloat ) >> 8 ) & 0xFF ) / 255.0;
}
float
EncodeUnitScalars(
in int liUnitScalarA,
in float lfUnitScalarB )
{
int liUpper = int( saturate( lfUnitScalarB ) * 255.0 ) << 8;
int liLower = liUnitScalarA & 0xFF;
return float( liUpper | liLower );
//return lfUnitScalarA;
}
void
DecodeUnitScalars(
in float lfEncodedFloat,
out int liUnitScalarA,
out float lfUnitScalarB )
{
liUnitScalarA = int( lfEncodedFloat ) & 0xFF;
lfUnitScalarB = float( ( int( lfEncodedFloat ) >> 8 ) & 0xFF ) / 255.0;
}
// 4bit
float
Encode4BitUnitScalars(
in float lfUnitScalarA,
in float lfUnitScalarB )
{
int liUpper = int( saturate( lfUnitScalarB ) * 15.0 ) << 4;
int liLower = int( saturate( lfUnitScalarA ) * 15.0 );
return float( liUpper | liLower ) / 255.0;
//return lfUnitScalarA;
}
void
Decode4BitUnitScalars(
in float lfEncodedFloat,
out float lfUnitScalarA,
out float lfUnitScalarB )
{
lfEncodedFloat *= 255.0;
lfUnitScalarA = float( int( lfEncodedFloat ) & 0xF ) / 15.0;
lfUnitScalarB = float( ( int( lfEncodedFloat ) >> 4 ) & 0xF ) / 15.0;
}
float
Encode4BitUnitScalars(
in int liUnitScalarA,
in float lfUnitScalarB )
{
int liUpper = int( saturate( lfUnitScalarB ) * 15.0 ) << 4;
int liLower = liUnitScalarA & 0xF;
return float( liUpper | liLower ) / 255.0;
//return lfUnitScalarA;
}
void
Decode4BitUnitScalars(
in float lfEncodedFloat,
out int liUnitScalarA,
out float lfUnitScalarB )
{
lfEncodedFloat *= 255.0;
liUnitScalarA = int( lfEncodedFloat ) & 0xF;
lfUnitScalarB = float( ( int( lfEncodedFloat ) >> 4 ) & 0xF ) / 15.0;
}
//-----------------------------------------------------------------------------
///
/// EncodeScalarAsVector
///
//-----------------------------------------------------------------------------
vec4
EncodeScalarAsVector(
in float lfScalar )
{
vec4 lEncoded;
float lfScaled = lfScalar * 2048.0;
lEncoded = vec4( floor( lfScaled ), fract( lfScaled ), 0.0, 0.0 );
return lEncoded;
}
//-----------------------------------------------------------------------------
///
/// EncodeScalarAsVector
///
//-----------------------------------------------------------------------------
float
DecodeScalarAsVector(
in vec4 lEncoded )
{
return dot( lEncoded, vec4( 1.0 / 2048.0 ) );
}
//-----------------------------------------------------------------------------
///
/// EncodeNormal
///
//-----------------------------------------------------------------------------
void
EncodeNormal(
in vec3 lNormal,
out vec3 lBuffer )
{
lBuffer = lNormal * 0.5 + vec3( 0.5 );
}
//-----------------------------------------------------------------------------
///
/// DecodeNormal
///
//-----------------------------------------------------------------------------
vec3
DecodeNormal(
in vec3 lBuffer )
{
return lBuffer * 2.0 - 1.0;
}
//-----------------------------------------------------------------------------
///
/// EncodeMotion
///
//-----------------------------------------------------------------------------
vec2
EncodeMotion(
in vec2 lMotion )
{
// gamma 2.0 encoding to pack a reasonable value into RG8 targets
// corresponding decode is in CommonPostProcess to save rebuilds
vec2 lMotionScaled = lMotion * 16.0;
#ifdef D_PLATFORM_ORBIS
lMotionScaled.y = -lMotionScaled.y;
#endif
//float lLength = length( lMotionScaled * vec2( 9.0 / 16.0, 1.0 ) );
float lLength = length( lMotionScaled );
lMotionScaled /= max( 1.0, lLength );
if( lLength > 0.0 )
{
// set length to sqrt( the clamped length )
lMotionScaled /= sqrt( length( lMotionScaled ) );
}
// reserve 1.0 for signaling values`
vec2 lMaxRealValue = vec2( 254.0 / 255.0 );
return min( lMaxRealValue, lMotionScaled * ( 127.0 / 255.0 ) + 0.5 );
}
//-----------------------------------------------------------------------------
///
/// DecodeGBufferPosition
///
//-----------------------------------------------------------------------------
vec3
DecodeGBufferPosition(
in vec2 lScreenPosVec2,
in vec4 lClipPlanes,
in mat4 lInverseProjectionMat4,
in mat4 lInverseViewMat4,
in vec3 lViewPositionVec3,
in vec4 lBuffer1_Vec4,
in bool lbWithIVP
)
{
float lfDepth = FastDenormaliseDepth(lClipPlanes, DecodeDepthFromColour(lBuffer1_Vec4));
if (lbWithIVP)
{
// fast path with lInverseProjectionMat4 as invView(zero position) * invProj
return RecreatePositionFromDepthWithIVP(lfDepth, lScreenPosVec2, lViewPositionVec3, lInverseProjectionMat4, lClipPlanes);
}
else
{
return RecreatePositionFromDepth(lfDepth, lScreenPosVec2, lViewPositionVec3, lInverseProjectionMat4, lInverseViewMat4);
}
}
//-----------------------------------------------------------------------------
///
/// DecodeGBuffer
///
//-----------------------------------------------------------------------------
void
DecodeGBuffer(
in vec2 lScreenPosVec2,
in vec4 lClipPlanes,
in mat4 lInverseProjectionMat4,
in mat4 lInverseViewMat4,
in vec3 lViewPositionVec3,
in vec4 lBuffer0_Vec4,
in vec4 lBuffer1_Vec4,
in vec4 lBuffer2_Vec4,
in vec4 lBuffer3_Vec4,
in bool lbDecodePosition,
in bool lbWithIVP,
out vec3 lColourVec3,
inout vec3 lPositionVec3,
out vec3 lNormalVec3,
out int liMaterialID,
out float lfRoughness,
out float lfMetallic,
out float lfSubsurface,
out float lfGlow )
{
if (lbDecodePosition)
{
lPositionVec3 = DecodeGBufferPosition(lScreenPosVec2, lClipPlanes, lInverseProjectionMat4, lInverseViewMat4, lViewPositionVec3, lBuffer1_Vec4, lbWithIVP);
}
lColourVec3 = lBuffer0_Vec4.rgb;
lfGlow = lBuffer0_Vec4.a;
lNormalVec3 = DecodeNormal( lBuffer2_Vec4.xyz );
liMaterialID = int(lBuffer3_Vec4.r * 255.0 );
lfRoughness = ( lBuffer3_Vec4.g * lBuffer3_Vec4.g * 2.0 );
lfMetallic = lBuffer3_Vec4.b;
lfSubsurface = lBuffer3_Vec4.a;
}
//-----------------------------------------------------------------------------
///
/// EncodeGBuffer
///
//-----------------------------------------------------------------------------
void
EncodeGBuffer(
in vec4 lClipPlanes,
in vec4 lClipPlanesR,
in vec3 lViewPositionVec3,
in mat4 lViewMat4,
out vec4 lBuffer0_Vec4,
out vec4 lBuffer1_Vec4,
out vec4 lBuffer2_Vec4,
out vec4 lBuffer3_Vec4,
out vec4 lBuffer4_Vec4,
in vec3 lColourVec3,
in vec3 lPositionVec3,
in vec3 lNormalVec3,
in int liMaterialID,
in float lfRoughness,
in float lfMetallic,
in float lfSubsurface,
in float lfGlow,
in vec2 lScreenSpaceMotionVec2 )
{
lBuffer0_Vec4.xyz = lColourVec3;
lBuffer0_Vec4.a = saturate(lfGlow);
//float lDepth = FastNormaliseDepth( lClipPlanesR, length( lPositionVec3 - lViewPositionVec3 ) );
//lBuffer4_Vec4 = EncodeDepthToColour( lDepth );
EncodeNormal( lNormalVec3, lBuffer2_Vec4.xyz );
lBuffer2_Vec4.w = 0.0;
float lfRoughnessEncoded = sqrt( lfRoughness * ( 1.0 / 2.0 ) );
lBuffer3_Vec4.r = float(liMaterialID) / 255.0;
lBuffer3_Vec4.g = lfRoughnessEncoded;
lBuffer3_Vec4.b = saturate(lfMetallic);
lBuffer3_Vec4.a = saturate(lfSubsurface);
#ifdef D_OUTPUT_MOTION_VECTORS
lBuffer1_Vec4 = vec4( EncodeMotion( lScreenSpaceMotionVec2 * 0.5 ), 0.0, 0.0 );
#else
lBuffer1_Vec4 = vec4( lScreenSpaceMotionVec2, 0.0, 0.0 );
#endif
}
#endif
#else
////////////////////////////////////////////////////////////////////////////////
///
/// @file CommonLighting.h
/// @author User
/// @date
///
/// @brief CommonLighting
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Compilation defines
#ifndef D_COMMONLIGHTING_H
#define D_COMMONLIGHTING_H
//-----------------------------------------------------------------------------
// Include files
// =================================================================================================
#ifndef D_DEFINES
#define D_DEFINES
// =================================================================================================
// Platform defines
// =================================================================================================
#ifdef D_PLATFORM_PC
#define D_ENABLE_REVERSEZ_PROJECTION (1)
#pragma optionNV(strict on)
#extension GL_ARB_gpu_shader5 : enable
#extension GL_ARB_fragment_coord_conventions : enable
#extension GL_ARB_derivative_control : enable
#if defined( D_FRAGMENT ) && defined( _F64_ )
layout(early_fragment_tests) in;
#endif
#elif defined(D_PLATFORM_ORBIS)
#define D_ENABLE_REVERSEZ_PROJECTION (1)
// use this with sdk 2.0 compiler
// #pragma argument (allow-scratch-buffer-spill)
//define these flags so they don't get ignored in build process and in the comb mask
//this is because materials, vertex layouts and shaders need to be synced on 360 to avoid patching
#ifdef _F27_
#endif
#ifdef _F28_
#endif
#ifdef _F29_
#endif
#ifdef _F21_
#endif
#ifdef _F02_
#endif
#ifdef _F03_
#endif
#if defined( _F01_ ) || defined( D_LOD0 ) || defined( D_LOD1 ) || defined( D_LOD2 ) || defined( D_LOD3) || defined( D_LOD4 )
#endif
#ifdef _F01_
#endif
#ifdef _F09_
#endif
#ifdef _F10_
#endif
// disable warnings for unused parameters. This happens a lot because of defining different things.
#pragma warning (disable: 5203)
// temp thing to know what things are still required on ps4.
#define D_PLATFORM_ORBIS_FIX
#ifdef __PSSL_CS__
#define D_PLATFORM_ORBIS_COMPUTE
#endif
#ifdef __PSSL_HS__
#define D_HULL
#endif
#ifdef __PSSL_DS__
#define D_DOMAIN
#endif
#ifdef __PSSL_VS__
#define D_VERTEX
#endif
#ifdef __PSSL_GS__
#define D_GEOMETRY
#endif
#endif
#if !D_ENABLE_REVERSEZ_PROJECTION
#define D_USING_LOGDEPTH
#endif
// =================================================================================================
// Basic Types
// =================================================================================================
#ifdef D_PLATFORM_PC
#define JOINT_TYPE vec4
//#define CONST const
#define STATIC_CONST const
#elif defined(D_PLATFORM_ORBIS)
#define JOINT_TYPE int4
#define float float
#define vec2 float2
#define vec3 float3
#define vec4 float4
#define ivec2 int2
#define ivec3 int3
#define ivec4 int4
#define uvec2 uint2
#define uvec3 uint3
#define uvec4 uint4
// NOTE:
// operator[] accesses rows, not columns
// matrix constructors interpret the passed vectors as row vectors, not column vectors
#define mat2 row_major float2x2
#define mat3 row_major float3x3
#define mat4 row_major float4x4
//#define CONST
#define STATIC_CONST static const
// #define const ERROR, DON'T USE CONST FOR PS4. USE STATIC_CONST INSTEAD FOR A COMPILED IN CONSTANT. OTHERWISE IT TRIES TO PUT IT IN A CONSTANT BUFFER AND FOR SOME REASON IT DOESN'T WORK.
#endif
// =================================================================================================
// Functions
// =================================================================================================
#ifdef D_PLATFORM_PC
#define saturate( V ) min( max( V, 0.0) , 1.0)
#define atan2( Y, X ) atan( Y, X )
#define invsqrt( X ) inversesqrt( X )
#ifdef D_COMPUTE
#define groupID gl_WorkGroupID
#define groupThreadID gl_LocalInvocationID
#define dispatchThreadID gl_GlobalInvocationID
#endif
#elif defined(D_PLATFORM_ORBIS)
#if defined(D_PLATFORM_ORBIS_COMPUTE)
float dFdx( float var ) { float delta = var - LaneSwizzle( var, 0x1f, 0, 1 ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
float dFdy( float var ) { float delta = var - LaneSwizzle( var, 0x1f, 0, 8 ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec2 dFdx( vec2 var ) { vec2 delta = vec2( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec2 dFdy( vec2 var ) { vec2 delta = vec2( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec3 dFdx( vec3 var ) { vec3 delta = vec3( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec3 dFdy( vec3 var ) { vec3 delta = vec3( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec4 dFdx( vec4 var ) { vec4 delta = vec4( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.w, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec4 dFdy( vec4 var ) { vec4 delta = vec4( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.w, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
#define dFdxFine dFdx
#define dFdyFine dFdy
#else
#define dFdx ddx
#define dFdy ddy
#define dFdxFine ddx_fine
#define dFdyFine ddy_fine
#endif
#define mix lerp
#define fract frac
#define mod fmod
#define saturate( V ) ( min( max( V, 0.0) , 1.0) )
#define invsqrt( X ) rsqrt( X )
#endif
// =================================================================================================
// Samplers and textures
// =================================================================================================
#ifdef D_PLATFORM_PC
#define shadow2D( S, UV ) texture( S, UV )
#define SAMPLER2DSHADOW( NAME, REG ) uniform sampler2DShadow NAME
#define SAMPLERCUBE( NAME ) samplerCube NAME
#define SAMPLERCUBEARG( NAME ) in samplerCube NAME
#define SAMPLERCUBEPARAM( NAME ) NAME
#define imageAtomicAddOut( T, C, V, O ) O = imageAtomicAdd( T, C, V )
#if defined( D_TEXTURE_FEEDBACK )
#define texture2D( T, C ) Tex2dFeedback( T, T##FB, C )
#define texture2DLod( T, C, N ) Tex2dLodFeedback( T, T##FB, C, N )
#define texture2DArray( T, C ) Tex2dArrayFeedback( T, T##FB, C )
#define texture3D( S, UV ) Tex3dFeedback( S, S##FB, UV )
#define texture3DLod( S, UV, LOD ) Tex3dLodFeedback( S, S##FB, UV, LOD )
#define SAMPLER2DARG( NAME ) in sampler2D NAME, in int NAME##FB
#define SAMPLER2DPARAM( NAME ) NAME, NAME##FB
#define SAMPLER2DARRAYARG( NAME ) in sampler2DArray NAME, in int NAME##FB
#define SAMPLER2DARRAYPARAM( NAME ) NAME, NAME##FB
#define SAMPLER2D( NAME ) sampler2D NAME; int NAME##FB
#define SAMPLER2DARRAY( NAME ) sampler2DArray NAME; int NAME##FB
#define SAMPLER3D( NAME ) sampler3D NAME; int NAME##FB
#define SAMPLER2DSHADOW_SRT( NAME ) sampler2DShadow NAME; int NAME##FB
#else
#define texture2DLod( S, UV, LOD ) textureLod( S, UV, LOD )
#define texture3DLod( S, UV, LOD ) textureLod( S, UV, LOD )
#define SAMPLER2DARG( NAME ) in sampler2D NAME
#define SAMPLER2DPARAM( NAME ) NAME
#define SAMPLER2DARRAYARG( NAME ) in sampler2DArray NAME
#define SAMPLER2DARRAYPARAM( NAME ) NAME
#define SAMPLER2D( NAME ) sampler2D NAME
#define SAMPLER2DARRAY( NAME ) sampler2DArray NAME
#define SAMPLER3D( NAME ) sampler3D NAME
#define SAMPLER2DSHADOW_SRT( NAME ) sampler2DShadow NAME
#endif
#define textureGatherRed( lTex, lSamp ) textureGather( lTex, lSamp, 0 )
#define textureGatherGreen( lTex, lSamp ) textureGather( lTex, lSamp, 1 )
#define textureGatherBlue( lTex, lSamp ) textureGather( lTex, lSamp, 2 )
#define textureGatherAlpha( lTex, lSamp ) textureGather( lTex, lSamp, 3 )
#define texture2DComputeGrad( T, C ) texture2D( T, C )
#elif defined(D_PLATFORM_ORBIS)
#define SAMPLERCUBE( NAME, REG ) SamplerState NAME##SS : register( s##REG ); TextureCube NAME##TU : register( t##REG )
#define SAMPLER2D( NAME ) Texture2D NAME; SamplerState NAME##SS
#define SAMPLER2DSHADOW_SRT( NAME ) Texture2D NAME; SamplerComparisonState NAME##SS //SAMPLER2D( NAME )
#define SAMPLER3D( NAME ) Texture3D NAME; SamplerState NAME##SS
#define SAMPLER2DARRAY( NAME ) Texture2D_Array NAME; SamplerState NAME##SS
#define SAMPLER2DARRAYARG( NAME ) Texture2D_Array NAME, SamplerState NAME##SS
#define SAMPLER2DARRAYPARAM( NAME ) NAME, NAME##SS
#define SAMPLER2DPARAM( NAME ) NAME, NAME##SS
#define SAMPLER2DARG( NAME ) Texture2D NAME, SamplerState NAME##SS
#define texture2D( T, C ) T.Sample( T##SS, C )
#if defined(D_PLATFORM_ORBIS_COMPUTE)
#define texture2DComputeGrad( T, C ) T.SampleGradient( T##SS, C, vec2( dFdx( C ) ), vec2( dFdy( C ) ) )
#define shadow2D( T, C ) T.SampleCmpLOD0( T##SS, C.xy, C.z )
#else
#define texture2DComputeGrad( T, C ) T.Sample( T##SS, C )
#define shadow2D( T, C ) T.SampleCmp( T##SS, C.xy, C.z )
#endif
#define texture2DLod( T, C, N ) T.SampleLOD( T##SS, C, N )
#define texture2DArray( T, C ) T.Sample( T##SS, C )
#define texture3DLod( T, C, N ) T.SampleLOD( T##SS, C, N )
//#define shadow2D( T, C ) vec3( C.z > T.Sample( T##SS, C.xy ).x ? 1.0 : 0.0 )
//#define shadow2D( T, C ) T.GatherCmp( T##SS, C.xy, C.z )
//#define shadow2D( T, C ) T.SampleCmpLOD0( T##SS, C.xy, C.z )
#define textureCube( T, C ) T##TU.Sample( T##SS, C )
#define textureCubeLod( T, C, N ) T##TU.Sample( T##SS, C, N )
#define textureGrad( T, C, DDX, DDY ) T.SampleGradient( T##SS, C, DDX, DDY )
#define imageAtomicAdd( T, C, V ) AtomicAdd( T[ C ], V )
#define imageAtomicAddOut( T, C, V, O ) AtomicAdd( T[ C ], V, O )
#define imageStore( T, C, V ) ( T[C] = V )
#define textureGatherRed( lTex, lSamp ) lTex.GatherRed ( lTex##SS, lSamp )
#define textureGatherGreen( lTex, lSamp ) lTex.GatherGreen( lTex##SS, lSamp )
#define textureGatherBlue( lTex, lSamp ) lTex.GatherBlue ( lTex##SS, lSamp )
#define textureGatherAlpha( lTex, lSamp ) lTex.GatherAlpha( lTex##SS, lSamp )
#define texelFetch( lTex, lSamp, lLod ) lTex.MipMaps((lLod), (lSamp))
#endif
#if defined(D_PLATFORM_ORBIS_COMPUTE)
#define THREADGROUP_LOCAL thread_group_memory
#define THREADGROUP_BARRIER ThreadGroupMemoryBarrier()
#elif defined(D_PLATFORM_PC_COMPUTE)
#define THREADGROUP_LOCAL layout( shared )
#define THREADGROUP_BARRIER groupMemoryBarrier()
#endif
// =================================================================================================
// Matrices
// =================================================================================================
#ifdef D_PLATFORM_PC
#define MUL( INPUT_A, INPUT_B ) (INPUT_A * INPUT_B)
#define PLATFORM_TRANSPOSE
#define MAT4_SET_POS( M, P ) M[ 3 ] = P
#define MAT4_SET_TRANSLATION( M, T ) M[ 3 ].xyz = T
#define MAT4_GET_COLUMN( M, C ) M[ C ].xyz
#define MAT3_GET_COLUMN( M, C ) M[ C ]
#define MAT4_GET_COLUMN_VEC4( M, C ) M[ C ]
#define MAT3_SET_COLUMN( M, C, V ) M[ C ] = V;
#define MAT4_SET_COLUMN( M, C, V ) M[ C ] = V;
#elif defined(D_PLATFORM_ORBIS)
#define MUL( INPUT_A, INPUT_B ) mul( INPUT_B, INPUT_A )
#define PLATFORM_TRANSPOSE
#define MAT4_SET_POS( M, P ) M[ 3 ] = P
#define MAT4_SET_TRANSLATION( M, T ) M[ 3 ].xyz = T
#define MAT4_GET_COLUMN( M, C ) M[ C ].xyz
#define MAT3_GET_COLUMN( M, C ) M[ C ]
#define MAT4_GET_COLUMN_VEC4( M, C ) M[ C ]
#define MAT3_SET_COLUMN( M, C, V ) M[ C ] = V;
#define MAT4_SET_COLUMN( M, C, V ) M[ C ] = V;
#endif
// =================================================================================================
// Arrays (workaround AMD shader compiler issues by making arrays have global scope)
// =================================================================================================
#if defined(D_PLATFORM_ORBIS)
#define ARRAY_LOOKUP_FS( _UNIFORMS, _ELEMENT, _INDEX) _UNIFORMS._ELEMENT[_INDEX]
#define ARRAY_LOOKUP_FP( _UNIFORMS, _ELEMENT, _INDEX) _UNIFORMS._ELEMENT[_INDEX]
#else
#define ARRAY_LOOKUP_FS( _UNIFORMS, _ELEMENT, _INDEX) _ELEMENT[_INDEX]
#define ARRAY_LOOKUP_FP( _UNIFORMS, _ELEMENT, _INDEX) _ELEMENT[_INDEX]
#endif
// =================================================================================================
// Input and Output
// =================================================================================================
#ifdef D_PLATFORM_PC
#define UNIFORM( TYPE, NAME ) uniform TYPE NAME
#define UNIFORM_SRT( TYPE, NAME ) uniform TYPE NAME
#define DECLARE_INPUT
#define DECLARE_OUTPUT
#define DECLARE_END
#define DECLARE_PTR( TYPE, NAME ) TYPE NAME;
#define DECLARE_PATCH_INPUT_TRI
#define DECLARE_PATCH_OUTPUT_TRI
#define IN_PATCH_TRI_TESS_CONSTANTS
#define OUT_PATCH_TRI_TESS_CONSTANTS
#define DECLARE_PATCH_INPUT_QUAD
#define DECLARE_PATCH_OUTPUT_QUAD
#define IN_PATCH_QUAD_TESS_CONSTANTS
#define OUT_PATCH_QUAD_TESS_CONSTANTS
#if defined( D_HULL )
#define INPUT( TYPE, NAME, REG ) in TYPE NAME [];
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME [];
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME [];
#define PATCH_OUTPUT( TYPE, NAME, REG ) patch out TYPE NAME;
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME [];
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME [];
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME [];
#elif defined( D_DOMAIN )
#define PATCH_INPUT( TYPE, NAME, REG ) patch in TYPE NAME;
#define INPUT( TYPE, NAME, REG ) in TYPE NAME [];
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME [];
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME [];
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME;
#else
#define INPUT( TYPE, NAME, REG ) in TYPE NAME;
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME;
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME;
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME;
#endif
#define FRAGMENT_COLOUR_UVEC4_DEFINE layout(location = 0) out uvec4 outu_color0;
#define FRAGMENT_COLOUR_UVEC4 outu_color0
#define FRAGMENT_COLOUR out_color0
#define FRAGMENT_COLOUR0 out_color0
#define FRAGMENT_COLOUR1 out_color1
#define FRAGMENT_COLOUR2 out_color2
#define FRAGMENT_COLOUR3 out_color3
#define FRAGMENT_COLOUR4 out_color4
#if defined( D_TAA_RENDER_TARGETS )
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1; layout(location = 2) out vec4 out_color2;
#elif !defined(D_ATTRIBUTES)
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0;
#else
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1; layout(location = 2) out vec4 out_color2; layout(location = 3) out vec4 out_color3; layout(location = 4) out vec4 out_color4;
#endif
#define FRAGMENT_COLOUR01_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1;
#define FRAGMENT_DEPTH gl_FragDepth
#define FRAGMENT_FRONTFACE gl_FrontFacing
#define INPUT_FRONTFACING
#define DEREF_PTR( VAR ) VAR
#if defined( D_HULL )
#define IN( VAR ) VAR[ gl_InvocationID ]
#define OUT( VAR ) VAR[ gl_InvocationID ]
#define PATCH_OUT( VAR ) VAR
#define OUTPUT_VERTEX_SCREEN_POSITION gl_out[ gl_InvocationID ].gl_Position
#define INPUT_VERTEX_SCREEN_POSITION gl_in [ gl_InvocationID ].gl_Position
#define TESS_LEVEL_EDGE( IND ) gl_TessLevelOuter[ IND ]
#define TESS_LEVEL_INNER( IND ) gl_TessLevelInner[ IND ]
#elif defined( D_DOMAIN )
#define PATCH_IN( VAR, IND ) VAR[ IND ]
#define IN( VAR, IND ) VAR[ IND ]
#define OUT( VAR ) VAR
#define INPUT_VERTEX_SCREEN_POSITION( IND ) gl_in [ IND ].gl_Position
#define DOMAIN_COORDS gl_TessCoord
#elif defined( D_GEOMETRY )
#define OUTPUT_VERTEX_SCREEN_POSITION gl_Position
#define INPUT_VERTEX_SCREEN_POSITION( IND ) gl_in [ IND ].gl_Position
#define IN( VAR, IND ) VAR[ IND ]
#define OUT( VAR ) VAR
#else
#define IN( VAR ) VAR
#define OUT( VAR ) VAR
#endif
#define OUT_VERTEX_SCREEN_POSITION
#define IN_SCREEN_POSITION
#define VERTEX_SCREEN_POSITION gl_Position
#elif defined(D_PLATFORM_ORBIS_COMPUTE)
#define DECLARE_INPUT struct cInput {
#define DECLARE_END };
#define DECLARE_PTR( TYPE, NAME ) TYPE* NAME;
#define INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define INPUT_NOINTERP( TYPE, NAME, REG ) TYPE NAME : REG;
#define IN_SCREEN_POSITION
#define FRAGMENT_COLOUR lUniforms.mpCmpOutPerMesh.gOutTexture0[dispatchThreadID.xy]
#define FRAGMENT_COLOUR0 lUniforms.mpCmpOutPerMesh.gOutTexture0[dispatchThreadID.xy]
#define FRAGMENT_COLOUR1 lUniforms.mpCmpOutPerMesh.gOutTexture1[dispatchThreadID.xy]
#define FRAGMENT_COLOUR2 lUniforms.mpCmpOutPerMesh.gOutTexture2[dispatchThreadID.xy]
#define FRAGMENT_COLOUR3 lUniforms.mpCmpOutPerMesh.gOutTexture3[dispatchThreadID.xy]
#define FRAGMENT_COLOUR4 lUniforms.mpCmpOutPerMesh.gOutTexture4[dispatchThreadID.xy]
#define FRAGMENT_DEPTH lUniforms.mpCmpOutPerMesh.gOutTextureDepth[dispatchThreadID.xy]
#define DEREF_PTR( VAR ) *VAR
#elif defined(D_PLATFORM_ORBIS)
#define UNIFORM( TYPE, NAME ) ConstantBuffer NAME##CB{ TYPE NAME; };
#define UNIFORM_SRT( TYPE, NAME ) ConstantBuffer NAME##CB{ TYPE NAME : S_SRT_DATA; };
#define DECLARE_OUTPUT struct cOutput {
#define DECLARE_INPUT struct cInput {
#define DECLARE_END };
#define DECLARE_PTR( TYPE, NAME ) TYPE* NAME;
#define INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define INPUT_NOINTERP( TYPE, NAME, REG ) nointerp TYPE NAME : REG;
#define INPUT_NOPERSP( TYPE, NAME, REG ) nopersp TYPE NAME : REG;
#define OUTPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) nointerp TYPE NAME : REG;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) nopersp TYPE NAME : REG;
#define FRAGMENT_COLOUR_UVEC4_DEFINE
#define FRAGMENT_COLOUR_UVEC4 Out.mColour
#define FRAGMENT_COLOUR Out.mColour
#define FRAGMENT_COLOUR0 Out.mColour0
#define FRAGMENT_COLOUR1 Out.mColour1
#define FRAGMENT_COLOUR2 Out.mColour2
#define FRAGMENT_COLOUR3 Out.mColour3
#define FRAGMENT_COLOUR4 Out.mColour4
#define FRAGMENT_DEPTH Out.mDepth
#define FRAGMENT_FRONTFACE In.mbFrontFacing
#define INPUT_FRONTFACING bool mbFrontFacing : S_FRONT_FACE;
#if defined( D_HULL )
#define IN( VAR ) In[ uCPID ].VAR
#define OUT( VAR ) Out.VAR
#define PATCH_OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION IN( mScreenPositionVec4 )
#define TESS_LEVEL_EDGE( IND ) Out.edge_ts[ IND ]
#define TESS_LEVEL_INNER( IND ) Out.insi_ts[ IND ]
#define DECLARE_PATCH_OUTPUT_TRI [DOMAIN_PATCH_TYPE("tri")] struct HSConstantOutputData {
#define OUT_PATCH_TRI_TESS_CONSTANTS float edge_ts[3] : S_EDGE_TESS_FACTOR; \
float insi_ts[1] : S_INSIDE_TESS_FACTOR;
#define DECLARE_PATCH_OUTPUT_QUAD [DOMAIN_PATCH_TYPE("quad")] struct HSConstantOutputData (
#define OUT_PATCH_QUAD_TESS_CONSTANTS float edge_ts[4] : S_EDGE_TESS_FACTOR; \
float insi_ts[2] : S_INSIDE_TESS_FACTOR;
#define PATCH_OUTPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#elif defined( D_DOMAIN )
#define PATCH_IN( VAR, IND ) patchIn.VAR
#define IN( VAR, IND ) In[ IND ].VAR
#define OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION( IND ) IN( mScreenPositionVec4, IND )
#define DOMAIN_COORDS domainCoordinates
#define DECLARE_PATCH_INPUT_TRI [DOMAIN_PATCH_TYPE("tri")] struct HSConstantOutputData {
#define IN_PATCH_TRI_TESS_CONSTANTS float edge_ts[3] : S_EDGE_TESS_FACTOR; \
float insi_ts[1] : S_INSIDE_TESS_FACTOR;
#define DECLARE_PATCH_INPUT_QUAD [DOMAIN_PATCH_TYPE("quad")] struct HSConstantOutputData {
#define IN_PATCH_QUAD_TESS_CONSTANTS float edge_ts[4] : S_EDGE_TESS_FACTOR; \
float insi_ts[2] : S_INSIDE_TESS_FACTOR;
#define PATCH_INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#elif defined( D_GEOMETRY )
#define IN( VAR, IND ) In[ IND ].VAR
#define OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION( IND ) IN( mScreenPositionVec4, IND )
#define EMIT_VERTEX TriStream.Append( Out )
#define END_PRIMITIVE TriStream.RestartStrip()
#else
#define IN( VAR ) In.VAR
#define OUT( VAR ) Out.VAR
#endif
// TODO get rid of this - don't pass struct through functinos, pass members.
#define DEREF_PTR( VAR ) *VAR
#define OUT_VERTEX_SCREEN_POSITION OUTPUT( vec4, mScreenPositionVec4, S_POSITION )
#define IN_SCREEN_POSITION INPUT ( vec4, mScreenPositionVec4, S_POSITION )
#define VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#endif
// =================================================================================================
// Main
// =================================================================================================
#ifdef D_PLATFORM_PC
#define VERTEX_MAIN void main( void )
#define VERTEX_MAIN_SRT uniform UniformBuffer lUniforms; void main( void )
#define HULL_TRI_MAIN_SRT layout( vertices = 3 ) out; uniform UniformBuffer lUniforms; void main( void )
#define HULL_QUAD_MAIN_SRT layout( vertices = 4 ) out; uniform UniformBuffer lUniforms; void main( void )
#define DOMAIN_TRI_MAIN_SRT layout( triangles, fractional_even_spacing ) in; uniform UniformBuffer lUniforms; void main( void )
#define DOMAIN_QUAD_MAIN_SRT layout( quads, fractional_even_spacing ) in; uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define VOID_MAIN_COLOUR FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_GE_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_LE_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_EARLYZ_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_UICOLOUR_SRT FRAGMENT_COLOUR_UVEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define VOID_MAIN_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define VOID_MAIN_DEPTH_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR01_SRT FRAGMENT_COLOUR01_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR01_DEPTH_SRT FRAGMENT_COLOUR01_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#elif defined( D_PLATFORM_PC_COMPUTE )
#define COMPUTE_MAIN_SRT( X, Y, Z ) layout (local_size_x = X, local_size_y = Y, local_size_z = Z) in; void main( void )
#define FRAGMENT_MAIN_COLOUR_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR01_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#elif defined( D_PLATFORM_ORBIS_COMPUTE )
#define COMPUTE_MAIN_SRT( X, Y, Z ) [NUM_THREADS(X, Y, Z)] void main(uint3 groupID : S_GROUP_ID, uint3 groupThreadID : S_GROUP_THREAD_ID, uint3 dispatchThreadID : S_DISPATCH_THREAD_ID, UniformBuffer lUniforms : S_SRT_DATA)
#define FRAGMENT_MAIN_COLOUR_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR01_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#elif defined( D_PLATFORM_ORBIS )
#define VERTEX_MAIN void main( cInput In, out cOutput Out )
#define VERTEX_MAIN_SRT void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define HULL_TRI_MAIN_SRT [DOMAIN_PATCH_TYPE("tri")] \
[PARTITIONING_TYPE("integer")] \
[OUTPUT_TOPOLOGY_TYPE("triangle_cw")] \
[OUTPUT_CONTROL_POINTS(3)] \
[PATCH_CONSTANT_FUNC("ConstantsHS")] \
[MAX_TESS_FACTOR(16.0)] \
void main( \
InputPatch<cInput, 3> In, \
uint uCPID : S_OUTPUT_CONTROL_POINT_ID, \
UniformBuffer lUniforms : S_SRT_DATA, \
out cOutput Out )
#define HULL_QUAD_MAIN_SRT [DOMAIN_PATCH_TYPE("quad")] \
[PARTITIONING_TYPE("integer")] \
[OUTPUT_TOPOLOGY_TYPE("triangle_cw")] \
[OUTPUT_CONTROL_POINTS(4)] \
[PATCH_CONSTANT_FUNC("ConstantsHS")] \
[MAX_TESS_FACTOR(16.0)] \
void main( \
InputPatch<cInput, 4> In, \
uint uCPID : S_OUTPUT_CONTROL_POINT_ID, \
UniformBuffer lUniforms : S_SRT_DATA, \
out cOutput Out )
#define DOMAIN_TRI_MAIN_SRT [DOMAIN_PATCH_TYPE("tri")] \
void main( \
HSConstantOutputData patchIn, \
const OutputPatch<cInput, 3> In, \
out cOutput Out, \
UniformBuffer lUniforms : S_SRT_DATA, \
float3 domainCoordinates : S_DOMAIN_LOCATION )
#define DOMAIN_QUAD_MAIN_SRT [DOMAIN_PATCH_TYPE("quad")] \
void main( \
HSConstantOutputData patchIn, \
const OutputPatch<cInput, 4> In, \
out cOutput Out, \
UniformBuffer lUniforms : S_SRT_DATA, \
float2 domainCoordinates : S_DOMAIN_LOCATION )
#define GEOMETRY_MAIN_SRT( MAX_VERTS ) cOutput Out; [MAX_VERTEX_COUNT(MAX_VERTS)] void main( inout TriangleBuffer<cOutput> TriStream, Triangle cInput In[3], UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out )
#define VOID_MAIN_COLOUR struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; void main( cInput In, out cOutput Out )
#define FRAGMENT_MAIN_COLOUR_DEPTH struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out )
#define VOID_MAIN_SRT void main( cInput In, UniformBuffer lUniforms : S_SRT_DATA )
#if defined( D_TAA_RENDER_TARGETS )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#elif !defined( D_ATTRIBUTES )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_DEPTH_GE_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_GE_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_DEPTH_LE_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_LE_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define VOID_MAIN_DEPTH_SRT struct cOutput { float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define VOID_MAIN_COLOUR_EARLYZ_SRT [FORCE_EARLY_DEPTH_STENCIL] void main( cInput In, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR01_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR01_DEPTH_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
float mDepth : S_DEPTH_OUTPUT; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#else
// #pragma PSSL_target_output_format(target 1 FMT_32_AR)
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; \
float mDepth : S_DEPTH_OUTPUT; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_EARLYZ_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; }; \
[FORCE_EARLY_DEPTH_STENCIL] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#endif
#endif
// =================================================================================================
// Texture resolution
// =================================================================================================
#ifdef D_PLATFORM_ORBIS
uvec2 GetResolution( Texture2D lTexture )
{
uvec2 lResolution;
lTexture.GetDimensionsFast(lResolution.x, lResolution.y);
return lResolution;
}
uvec2 GetResolution( RW_Texture2D<float4> lTexture )
{
uvec2 lResolution;
lTexture.GetDimensionsFast(lResolution.x, lResolution.y);
return lResolution;
}
#else
uvec2 GetResolution( sampler2D lTexture )
{
return textureSize( lTexture, 0 );
}
#endif
// =================================================================================================
// Viewport
// =================================================================================================
#ifdef D_PLATFORM_PC
#define SCREENSPACE_AS_RENDERTARGET_UVS( A ) A.xy
#elif defined(D_PLATFORM_ORBIS)
#define SCREENSPACE_AS_RENDERTARGET_UVS( A ) ( float2( A.x, 1.0 - A.y ) )
#endif
#ifdef D_USING_LOGDEPTH
#define D_DEPTH_CLEARVALUE (1.0)
#else
#define D_DEPTH_CLEARVALUE (0.0)
#endif
// =================================================================================================
// Texture usage feedback
// =================================================================================================
#if defined( D_TEXTURE_FEEDBACK ) && defined( D_PLATFORM_PC )
layout(r32i) uniform iimage2D gTexFeedbackImg;
void WriteTexFeedback( in int liCounter, in float liMip )
{
if( liCounter != 0 )
{
#if defined( GL_ARB_shader_ballot ) && ( GL_ARB_shader_ballot == 1 )
if( readFirstInvocationARB( gl_SubGroupInvocationARB ) == gl_SubGroupInvocationARB )
#endif
{
int liIntMip = int(floor(liMip));
//imageStore( gTexFeedbackImg, ivec2( liCounter, liIntMip ), ivec4(1,0,0,0) );
imageAtomicAdd( gTexFeedbackImg, ivec2( liCounter, liIntMip ), int(1) );
}
}
}
vec4 Tex2dFeedback( in sampler2D lSamp, in int liCounter, in vec2 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex2dLodFeedback( in sampler2D lSamp, in int liCounter, in vec2 lCoords, in float liLod )
{
WriteTexFeedback( liCounter, liLod );
return textureLod( lSamp, lCoords, liLod );
}
vec4 Tex2dArrayFeedback( in sampler2DArray lSamp, in int liCounter, in vec3 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords.xy ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex3dFeedback( in sampler3D lSamp, in int liCounter, in vec3 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex3dLodFeedback( in sampler3D lSamp, in int liCounter, in vec3 lCoords, in float liLod )
{
WriteTexFeedback( liCounter, liLod );
return textureLod( lSamp, lCoords, liLod );
}
#endif
#endif
////////////////////////////////////////////////////////////////////////////////
///
/// @file Common.h
/// @author User
/// @date
///
/// @brief Common
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
#ifndef D_COMMON_H
#define D_COMMON_H
#define D_TERRAINCOLOURARRAY_SIZE 23
STATIC_CONST vec3 kGammaOutVec3 = vec3( 1.0 / 2.2 );
STATIC_CONST vec3 kGammaInVec3 = vec3( 2.2 );
STATIC_CONST vec4 RGBToHSV_K = vec4( 0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0 );
STATIC_CONST vec4 HSVToRGB_K = vec4( 1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0 );
#ifdef D_PLATFORM_ORBIS
STATIC_CONST float3x3 BT709_TO_BT2020 = float3x3( //ref: ARIB STD-B62 and BT.2087
#else
STATIC_CONST mat3 BT709_TO_BT2020 = mat3( //ref: ARIB STD-B62 and BT.2087
#endif
0.6274, 0.3293, 0.0433,
0.0691, 0.9195, 0.0114,
0.0164, 0.0880, 0.8956
);
#ifdef D_PLATFORM_ORBIS
STATIC_CONST float3x3 BT2020_TO_BT709 = float3x3(
#else
STATIC_CONST mat3 BT2020_TO_BT709 = mat3(
#endif
1.6605, -0.5877, -0.0728,
-0.1246, 1.1330, -0.0084,
-0.0182, -0.1006, 1.1187
);
//-----------------------------------------------------------------------------
///
/// GammaCorrect
///
//-----------------------------------------------------------------------------
vec3
GammaCorrectInput(
in vec3 lColourVec3 )
{
vec3 lCorrectColourVec3;
lCorrectColourVec3 = lColourVec3 * ( lColourVec3 * ( lColourVec3 * vec3( 0.305306011 ) + vec3( 0.682171111 ) ) + vec3( 0.012522878 ) );
return lCorrectColourVec3;
}
//-----------------------------------------------------------------------------
///
/// GammaCorrect
///
//-----------------------------------------------------------------------------
vec3
GammaCorrectOutput(
in vec3 lColourVec3 )
{
vec3 lCorrectColourVec3;
lCorrectColourVec3 = pow( lColourVec3, kGammaOutVec3 );
return lCorrectColourVec3;
}
//-----------------------------------------------------------------------------
///
/// RGBToHSV
///
//-----------------------------------------------------------------------------
vec3
RGBToHSV(
vec3 lRGB )
{
//vec4 p = mix( vec4(lRGB.bg, RGBToHSV_K.wz), vec4(lRGB.gb, RGBToHSV_K.xy), step(lRGB.b, lRGB.g) );
//vec4 q = mix( vec4(p.xyw, lRGB.r), vec4(lRGB.r, p.yzx), step(p.x, lRGB.r) );
// This variant is faster, since it generates conditional moves
vec4 p = lRGB.g < lRGB.b ? vec4(lRGB.bg, RGBToHSV_K.wz) : vec4(lRGB.gb, RGBToHSV_K.xy);
vec4 q = lRGB.r < p.x ? vec4(p.xyw, lRGB.r) : vec4(lRGB.r, p.yzx);
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
//-----------------------------------------------------------------------------
///
/// HSVToRGB
///
/// @brief http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
///
//-----------------------------------------------------------------------------
vec3
HSVToRGB(
vec3 lHSV )
{
vec3 p = abs(fract(lHSV.xxx + HSVToRGB_K.xyz) * 6.0 - HSVToRGB_K.www);
return lHSV.z * mix(HSVToRGB_K.xxx, saturate(p - HSVToRGB_K.xxx), lHSV.y);
}
//-----------------------------------------------------------------------------
///
/// HDR ( Perceptual Quantizer(PQ), Rec. 2020 color space. ) helpers
///
//------------------------------------------------------------------------------
#ifdef D_PLATFORM_PC
float CndMask(bool cnd, float src0, float src1)
{
return cnd ? src0 : src1;
}
#endif
STATIC_CONST float kRefWhiteLevel = 100.0;
vec4 SRGB_OETF(vec4 L)
{
vec3 dark = L.xyz * 12.92;
vec3 light = 1.055 * pow(L.xyz, vec3(1.0 / 2.4)) - 0.055;
vec4 r;
r.x = CndMask(L.x <= 0.0031308, dark.x, light.x);
r.y = CndMask(L.y <= 0.0031308, dark.y, light.y);
r.z = CndMask(L.z <= 0.0031308, dark.z, light.z);
r.w = L.w;
return r;
}
vec4 SRGB_EOTF(vec4 E)
{
vec3 dark = E.xyz / 12.92;
vec3 light = pow((E.xyz + 0.055) / (1 + 0.055), vec3(2.4));
vec4 r;
r.x = CndMask(E.x <= 0.04045, dark.x, light.x);
r.y = CndMask(E.y <= 0.04045, dark.y, light.y);
r.z = CndMask(E.z <= 0.04045, dark.z, light.z);
r.w = E.w;
return r;
}
//apply gamma adjustment to (minL, maxL).
vec4 GammaAdjOOTF(vec4 L, float minLNits, float maxLNits, float gamma, bool inverse)
{
vec3 nits = L.xyz * kRefWhiteLevel;
vec4 i = vec4((nits - minLNits) / (maxLNits - minLNits), 1.0);
vec3 j;
if (inverse){
j = SRGB_EOTF(pow(i, vec4(1 / gamma))).xyz;
}
else{
j = pow(SRGB_OETF(i).xyz,vec3(gamma));
}
vec3 adj = (minLNits + (maxLNits - minLNits) * j) / kRefWhiteLevel;
vec4 ret;
ret.x = CndMask(nits.x >= minLNits && nits.x < maxLNits, adj.x, L.x);
ret.y = CndMask(nits.y >= minLNits && nits.y < maxLNits, adj.y, L.y);
ret.z = CndMask(nits.z >= minLNits && nits.z < maxLNits, adj.z, L.z);
ret.w = L.w;
return ret;
}
//input: normalized L in units of RefWhite (1.0=100nits), output: normalized E
vec4 PQ_OETF(vec4 L, uint gamma_adj, float gamma)
{
if (gamma_adj != 0)
L = GammaAdjOOTF(L, 0.0, 300.0, gamma, false);
const float c1 = 0.8359375;//3424.f/4096.f;
const float c2 = 18.8515625;//2413.f/4096.f*32.f;
const float c3 = 18.6875; //2392.f/4096.f*32.f;
const float m1 = 0.159301758125; //2610.f / 4096.f / 4;
const float m2 = 78.84375;// 2523.f / 4096.f * 128.f;
L = L * kRefWhiteLevel / 10000.0;
vec3 Lm1 = pow(L.xyz, vec3(m1));
vec3 X = (c1 + c2 * Lm1) / (1 + c3 * Lm1);
vec4 res = vec4(pow(X, vec3(m2)), L.w);
return res;
}
//input: normalized E (0.0, 1.0), output: normalized L in units of RefWhite
vec4 PQ_EOTF(vec4 E, uint gamma_adj, float gamma)
{
const float c1 = 0.8359375;//3424.f/4096.f;
const float c2 = 18.8515625;//2413.f/4096.f*32.f;
const float c3 = 18.6875; //2392.f/4096.f*32.f;
const float m1 = 0.159301758125; //2610.f / 4096.f / 4;
const float m2 = 78.84375;// 2523.f / 4096.f * 128.f;
vec3 M = c2 - c3 * pow(E.xyz, vec3(1 / m2));
vec3 N = max(pow(E.xyz, vec3(1 / m2)) - c1, 0);
vec3 L = pow(N / M, vec3(1 / m1)); //normalized nits (1.0 = 10000nits)
L = L * 10000.0 / kRefWhiteLevel; //convert to normalized L in units of RefWhite
return (gamma_adj !=0) ? GammaAdjOOTF(vec4(L, E.w), 0.0, 300.0, gamma, true) : vec4(L, E.w);
}
// PQ OETF fast approximation
// http://www.glowybits.com/blog/2017/01/04/ifl_iss_hdr_2/
vec3 PQ_OETF_Fast(vec3 x)
{
x = (x * (x * (x * (x * (x * 533095.76 + 47438306.2) + 29063622.1) + 575216.76) + 383.09104) + 0.000487781) /
(x * (x * (x * (x * 66391357.4 + 81884528.2) + 4182885.1) + 10668.404) + 1.0);
return x;
}
//-----------------------------------------------------------------------------
///
/// BrightnessVibranceContrast
///
//-----------------------------------------------------------------------------
vec3 BrightnessVibranceContrast(
vec3 lInputColour,
float lfBrightness,
float lfVibrance,
float lfContrast)
{
vec3 lBrtResult = lInputColour * lfBrightness;
// get lum
vec3 lLuma = vec3( dot(lBrtResult, vec3( 0.2125, 0.7154, 0.0721 )) );
// get saturation
float lfMaxCol = max( lBrtResult.r, max(lBrtResult.g, lBrtResult.b) );
float lfMinCol = min( lBrtResult.r, min(lBrtResult.g, lBrtResult.b) );
float lfCurSatV = lfMaxCol - lfMinCol;
// lerp by 1 + (1 - vibrance) - current saturation
float lfVibranceMix = (1.0 + (lfVibrance * (1.0 - (sign(lfVibrance) * lfCurSatV))));
vec3 lVibResult = mix( lLuma, lBrtResult, lfVibranceMix );
// lerp from mid gray for contrast
vec3 lContrastBase = vec3( 0.5, 0.5, 0.5 );
vec3 lConResult = mix( lContrastBase , lVibResult, lfContrast );
return lConResult;
}
//-----------------------------------------------------------------------------
///
/// Desaturate
///
//-----------------------------------------------------------------------------
vec3 Desaturate( vec3 color, float lfAmount )
{
vec3 gray = vec3( dot( vec3( 0.299, 0.587, 0.114 ), color) );
return mix( color, gray, lfAmount );
}
// improved rgb lerp by @stormoid
// https://www.shadertoy.com/view/lsdGzN
//---------------Improved RGB--------------
/*
The idea behind this function is to avoid the low saturation area in the
rgb color space. This is done by getting the direction to that diagonal
and displacing the interpolated color by it's inverse while scaling it
by saturation error and desired lightness.
I find it behaves very well under most circumstances, the only instance
where it doesn't behave ideally is when the hues are very close to 180
degrees apart, since the method I am using to find the displacement vector
does not compensate for non-curving motion. I tried a few things to
circumvent this problem but none were cheap and effective enough..
*/
//Changes the strength of the displacement
#define DSP_STR 1.5
//-----------------------------------------------------------------------------
float _getsat( vec3 lColour )
{
float mi = min(min(lColour.x, lColour.y), lColour.z);
float ma = max(max(lColour.x, lColour.y), lColour.z);
return (ma - mi) / (ma + 1e-7);
}
vec3 NmzRgbLerp( vec3 a, vec3 b, float x )
{
// interpolated base color (with singularity fix)
vec3 ic = mix( a, b, x ) + vec3( 1e-6, 0.0, 0.0 );
// saturation difference from ideal scenario
float sd = abs( _getsat( ic ) - mix( _getsat( a ), _getsat( b ), x ) );
// displacement direction
vec3 dir = normalize(
vec3( 2.0 * ic.x - ic.y - ic.z,
2.0 * ic.y - ic.x - ic.z,
2.0 * ic.z - ic.y - ic.x )
);
// simple Lighntess
float lgt = dot( vec3( 1.0 ), ic );
// extra scaling factor for the displacement
float ff = dot( dir, normalize( ic ) );
// displace the color
ic += DSP_STR * dir * sd * ff * lgt;
return clamp( ic, 0.0, 1.0 );
}
//-----------------------------------------------------------------------------
///
/// Inverse
///
//-----------------------------------------------------------------------------
mat4
Inverse(
const mat4 lInMat4 )
{
#ifdef D_PLATFORM_PC
return inverse( lInMat4 );
#else
float det = determinant( lInMat4 );
det = 1.0f / det;
mat4 M = lInMat4;
mat4 IM;
IM[0][0] = det * ( M[1][2]*M[2][3]*M[3][1] - M[1][3]*M[2][2]*M[3][1] + M[1][3]*M[2][1]*M[3][2] - M[1][1]*M[2][3]*M[3][2] - M[1][2]*M[2][1]*M[3][3] + M[1][1]*M[2][2]*M[3][3] );
IM[0][1] = det * ( M[0][3]*M[2][2]*M[3][1] - M[0][2]*M[2][3]*M[3][1] - M[0][3]*M[2][1]*M[3][2] + M[0][1]*M[2][3]*M[3][2] + M[0][2]*M[2][1]*M[3][3] - M[0][1]*M[2][2]*M[3][3] );
IM[0][2] = det * ( M[0][2]*M[1][3]*M[3][1] - M[0][3]*M[1][2]*M[3][1] + M[0][3]*M[1][1]*M[3][2] - M[0][1]*M[1][3]*M[3][2] - M[0][2]*M[1][1]*M[3][3] + M[0][1]*M[1][2]*M[3][3] );
IM[0][3] = det * ( M[0][3]*M[1][2]*M[2][1] - M[0][2]*M[1][3]*M[2][1] - M[0][3]*M[1][1]*M[2][2] + M[0][1]*M[1][3]*M[2][2] + M[0][2]*M[1][1]*M[2][3] - M[0][1]*M[1][2]*M[2][3] );
IM[1][0] = det * ( M[1][3]*M[2][2]*M[3][0] - M[1][2]*M[2][3]*M[3][0] - M[1][3]*M[2][0]*M[3][2] + M[1][0]*M[2][3]*M[3][2] + M[1][2]*M[2][0]*M[3][3] - M[1][0]*M[2][2]*M[3][3] );
IM[1][1] = det * ( M[0][2]*M[2][3]*M[3][0] - M[0][3]*M[2][2]*M[3][0] + M[0][3]*M[2][0]*M[3][2] - M[0][0]*M[2][3]*M[3][2] - M[0][2]*M[2][0]*M[3][3] + M[0][0]*M[2][2]*M[3][3] );
IM[1][2] = det * ( M[0][3]*M[1][2]*M[3][0] - M[0][2]*M[1][3]*M[3][0] - M[0][3]*M[1][0]*M[3][2] + M[0][0]*M[1][3]*M[3][2] + M[0][2]*M[1][0]*M[3][3] - M[0][0]*M[1][2]*M[3][3] );
IM[1][3] = det * ( M[0][2]*M[1][3]*M[2][0] - M[0][3]*M[1][2]*M[2][0] + M[0][3]*M[1][0]*M[2][2] - M[0][0]*M[1][3]*M[2][2] - M[0][2]*M[1][0]*M[2][3] + M[0][0]*M[1][2]*M[2][3] );
IM[2][0] = det * ( M[1][1]*M[2][3]*M[3][0] - M[1][3]*M[2][1]*M[3][0] + M[1][3]*M[2][0]*M[3][1] - M[1][0]*M[2][3]*M[3][1] - M[1][1]*M[2][0]*M[3][3] + M[1][0]*M[2][1]*M[3][3] );
IM[2][1] = det * ( M[0][3]*M[2][1]*M[3][0] - M[0][1]*M[2][3]*M[3][0] - M[0][3]*M[2][0]*M[3][1] + M[0][0]*M[2][3]*M[3][1] + M[0][1]*M[2][0]*M[3][3] - M[0][0]*M[2][1]*M[3][3] );
IM[2][2] = det * ( M[0][1]*M[1][3]*M[3][0] - M[0][3]*M[1][1]*M[3][0] + M[0][3]*M[1][0]*M[3][1] - M[0][0]*M[1][3]*M[3][1] - M[0][1]*M[1][0]*M[3][3] + M[0][0]*M[1][1]*M[3][3] );
IM[2][3] = det * ( M[0][3]*M[1][1]*M[2][0] - M[0][1]*M[1][3]*M[2][0] - M[0][3]*M[1][0]*M[2][1] + M[0][0]*M[1][3]*M[2][1] + M[0][1]*M[1][0]*M[2][3] - M[0][0]*M[1][1]*M[2][3] );
IM[3][0] = det * ( M[1][2]*M[2][1]*M[3][0] - M[1][1]*M[2][2]*M[3][0] - M[1][2]*M[2][0]*M[3][1] + M[1][0]*M[2][2]*M[3][1] + M[1][1]*M[2][0]*M[3][2] - M[1][0]*M[2][1]*M[3][2] );
IM[3][1] = det * ( M[0][1]*M[2][2]*M[3][0] - M[0][2]*M[2][1]*M[3][0] + M[0][2]*M[2][0]*M[3][1] - M[0][0]*M[2][2]*M[3][1] - M[0][1]*M[2][0]*M[3][2] + M[0][0]*M[2][1]*M[3][2] );
IM[3][2] = det * ( M[0][2]*M[1][1]*M[3][0] - M[0][1]*M[1][2]*M[3][0] - M[0][2]*M[1][0]*M[3][1] + M[0][0]*M[1][2]*M[3][1] + M[0][1]*M[1][0]*M[3][2] - M[0][0]*M[1][1]*M[3][2] );
IM[3][3] = det * ( M[0][1]*M[1][2]*M[2][0] - M[0][2]*M[1][1]*M[2][0] + M[0][2]*M[1][0]*M[2][1] - M[0][0]*M[1][2]*M[2][1] - M[0][1]*M[1][0]*M[2][2] + M[0][0]*M[1][1]*M[2][2] );
return IM;
#endif
}
float
lengthSquared( vec3 lInVec3 )
{
return dot( lInVec3, lInVec3 );
}
#endif
////////////////////////////////////////////////////////////////////////////////
///
/// @file CommonDepth.h
/// @author User
/// @date
///
/// @brief CommonDepth
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Compilation defines
#ifndef D_COMMONDEPTH_H
#define D_COMMONDEPTH_H
//-----------------------------------------------------------------------------
// Include files
//#include "Common/CommonUniforms.shader.h"
//-----------------------------------------------------------------------------
// Global Data
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
///
/// LinearToLogDepth
///
/// @brief LinearToLogDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
#ifdef D_USING_LOGDEPTH
vec4
LinearToLogDepth_Vertex(
in vec4 lClipPlanes,
in vec4 lScreenPos )
{
vec4 lLogScreenPos = lScreenPos;
float kfFarPlane = lClipPlanes.y;
float FC = lClipPlanes.z; // 2.0 / log2(farplane + 1.0)
float lfLogz = log2( max( 1e-6, lScreenPos.w + 1 ) ) * FC - 1.0;
lLogScreenPos.z = ( lfLogz ) * lScreenPos.w;
return lLogScreenPos;
}
//-----------------------------------------------------------------------------
///
/// LinearToLogDepth_Pixel
///
/// @brief LinearToLogDepth_Pixel
///
/// @param in float lfLogZ
/// @param in vec4 lClipPlanes
/// @return float
///
//-----------------------------------------------------------------------------
float
LinearToLogDepth_Pixel(
in float lfLogZ,
in vec4 lClipPlanes )
{
return log2( lfLogZ ) * lClipPlanes.w; // 1.0 / log2(farplane + 1.0)
}
//-----------------------------------------------------------------------------
///
/// LogToLinearDepth
///
/// @brief LogToLinearDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
LogToLinearDepth2(
in vec4 lClipPlanes,
float lfLogDepth )
{
return exp2( lfLogDepth / lClipPlanes.w ); // 1.0 / log2(farplane + 1.0)
}
//-----------------------------------------------------------------------------
///
/// LogToLinearDepth
///
/// @brief LogToLinearDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
#if 0
float
LogToLinearDepth(
in vec4 lClipPlanes,
float lfLogDepth )
{
float kfNearClip = lClipPlanes.x;
float kfFar = lClipPlanes.y;
float kfFarClip = 1.0 / log( kfFar*kfNearClip + 1.0 );
float lfLinearDepth = ( exp( lfLogDepth/kfFarClip ) - 1.0 ) / kfNearClip;
return lfLinearDepth;
}
#else
float
LogToLinearDepth(
in vec4 lClipPlanesR,
float lfLogDepth )
{
float lfLinearDepth = ( exp2( lfLogDepth*lClipPlanesR.z ) - 1.0 ) * lClipPlanesR.x;
return lfLinearDepth;
}
#endif
#else
vec4
LinearToLogDepth_Vertex(
in vec4 lClipPlanes,
in vec4 lScreenPos)
{
// This is a NOP with ReverseZ
return lScreenPos;
}
float
ReverseZToLinearDepth(
in vec4 lClipPlanes,
float lfDepth)
{
float zNear = lClipPlanes.x;
float zFar = lClipPlanes.y;
return zNear * zFar / ( zNear + lfDepth * (zFar - zNear));
}
float
ReverseZToLinearDepthNorm(
in vec4 lClipPlanes,
float lfDepth)
{
float zNear = lClipPlanes.x;
float zFar = lClipPlanes.y;
return zNear / (zNear + lfDepth * (zFar - zNear));
}
float
LinearToReverseZDepth(
in vec4 lClipPlanes,
float lfDepth)
{
float zNear = lClipPlanes.x;
float zFar = lClipPlanes.y;
return ( zNear * zFar / lfDepth - zNear ) / ( zFar - zNear );
}
#endif
#if 0
// These are no longer used
//-----------------------------------------------------------------------------
///
/// NormaliseDepth
///
/// @brief LogToLinearDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
NormaliseDepth(
in vec4 lClipPlanes,
float lfDepth )
{
float kfNearClip = lClipPlanes.x;
float kfFar = lClipPlanes.y;
return (lfDepth - kfNearClip) / (kfFar-kfNearClip);
}
//-----------------------------------------------------------------------------
///
/// NormaliseDepth
///
/// @brief LogToLinearDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
DenormaliseDepth(
in vec4 lClipPlanes,
float lfDepth )
{
float kfNearClip = lClipPlanes.x;
float kfFar = lClipPlanes.y;
return lfDepth * ( kfFar-kfNearClip ) + kfNearClip;
}
#endif
//-----------------------------------------------------------------------------
///
/// FastNormaliseDepth
///
/// @brief FastNormaliseDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
FastNormaliseDepth(
in vec4 lClipPlanesR,
float lfDepth )
{
float kfRecip_Far = lClipPlanesR.y;
return (lfDepth * kfRecip_Far);
}
//-----------------------------------------------------------------------------
///
/// FastDenormaliseDepth
///
/// @brief FastDenormaliseDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
FastDenormaliseDepth(
in vec4 lClipPlanes,
float lfDepth )
{
float kfFar = lClipPlanes.y;
return lfDepth * kfFar;
}
//-----------------------------------------------------------------------------
///
/// EncodeDepthToColour
///
/// @brief EncodeDepthToColour
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
vec4
EncodeDepthToColour(
float lDepth )
{
#if 0
vec4 enc = vec4( 1.0, 255.0, 65025.0, 16581375.0 ) * vec4(lDepth);
enc = fract(enc);
enc.xyz -= enc.yzw * vec3( 1.0f/255.0, 1.0f/255.0, 1.0f/255.0 );
return enc;
#else
return vec4(lDepth,0.0,0.0,0.0);
#endif
}
//-----------------------------------------------------------------------------
///
/// DecodeDepthFromColour
///
/// @brief DecodeDepthFromColour
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
DecodeDepthFromColour(
vec4 lColour )
{
#if 0
return dot( lColour, vec4( 1.0, 1.0f/255.0, 1.0f/65025.0, 1.0 / 16581375.0 ) );
#else
return lColour.x;
#endif
}
vec3
RecreatePositionFromDepthWithIVP(
in float lfDepth,
in vec2 lFragCoordsVec2,
in vec3 lViewPosition,
in mat4 lInverseViewProjectionMatrix,
in vec4 lClipPlanes)
{
vec4 lPositionVec4;
lPositionVec4.x = lFragCoordsVec2.x * 2.0 - 1.0;
#ifdef D_PLATFORM_ORBIS
lPositionVec4.y = (1.0f - lFragCoordsVec2.y) * 2.0 - 1.0;
#else
lPositionVec4.y = lFragCoordsVec2.y * 2.0 - 1.0;
#endif
lPositionVec4.z = LinearToReverseZDepth( lClipPlanes, lfDepth );
lPositionVec4.w = 1.0;
lPositionVec4 = MUL(lInverseViewProjectionMatrix, lPositionVec4);
lPositionVec4.xyz = lPositionVec4.xyz / lPositionVec4.w;
lPositionVec4.xyz += lViewPosition;
return lPositionVec4.xyz;
}
vec3
RecreatePositionFromDepth(
in float lfDepth,
in vec2 lFragCoordsVec2,
in vec3 lViewPosition,
in mat4 lInverseProjectionMatrix,
in mat4 lInverseViewMatrix )
{
vec4 lPositionVec4;
lPositionVec4.x = lFragCoordsVec2.x * 2.0 - 1.0;
#ifdef D_PLATFORM_ORBIS
lPositionVec4.y = ( 1.0f-lFragCoordsVec2.y ) * 2.0 - 1.0;
#else
lPositionVec4.y = lFragCoordsVec2.y * 2.0 - 1.0;
#endif
lPositionVec4.z = 0.0;
lPositionVec4.w = 1.0;
// Inverse projection
lPositionVec4 = MUL( lInverseProjectionMatrix, lPositionVec4 );
//lPositionVec4 = lPositionVec4 / lPositionVec4.w;
lPositionVec4 = lPositionVec4 / abs(lPositionVec4.z);
lPositionVec4 *= lfDepth;
// Inverse view
mat4 lViewMat = lInverseViewMatrix;
MAT4_SET_POS( lViewMat, vec4( 0.0, 0.0, 0.0, 1.0 ) );
lPositionVec4 = MUL( lViewMat, lPositionVec4 );
//lPositionVec4 = lPositionVec4 / lPositionVec4.w;
//lPositionVec4.xyz -= lViewPosition;
lPositionVec4.xyz = lPositionVec4.xyz + lViewPosition;
return lPositionVec4.xyz;
}
vec4
GetDepthColour(
in float lfDepth )
{
vec4 lColourVec4;
if( lfDepth < 1.0 )
{
lColourVec4 = vec4( 0.0, 0.0, 1.0, 1.0 );
}
else if( lfDepth < 10.0 )
{
lColourVec4 = vec4( 1.0, 0.0, 0.0, 1.0 );
}
else if( lfDepth < 20.0 )
{
lColourVec4 = vec4( 1.0, 1.0, 0.0, 1.0 );
}
else if( lfDepth < 40.0 )
{
lColourVec4 = vec4( 0.0, 1.0, 0.0, 1.0 );
}
else if( lfDepth < 80.0 )
{
lColourVec4 = vec4( 0.0, 1.0, 1.0, 1.0 );
}
else if( lfDepth < 160.0 )
{
lColourVec4 = vec4( 1.0, 0.0, 1.0, 1.0 );
}
else if( lfDepth < 320.0 )
{
lColourVec4 = vec4( 1.0, 0.5, 0.0, 1.0 );
}
else if( lfDepth < 640.0 )
{
lColourVec4 = vec4( 0.5, 1.0, 0.0, 1.0 );
}
else if( lfDepth < 1280.0 )
{
lColourVec4 = vec4( 0.0, 1.0, 0.5, 1.0 );
}
else if( lfDepth < 2560.0 )
{
lColourVec4 = vec4( 0.5, 0.0, 1.0, 1.0 );
}
else
{
lColourVec4 = vec4( 1.0, 0.0, 0.5, 1.0 );
}
return lColourVec4;
}
#endif
////////////////////////////////////////////////////////////////////////////////
///
/// @file CommonPlanet.h
/// @author User
/// @date
///
/// @brief CommonPlanetShader
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Compilation defines
#ifndef D_COMMONPLANET_H
#define D_COMMONPLANET_H
//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------
// Global Data
STATIC_CONST vec3 kUp = vec3( 0.0, 1.0, 0.0 );
STATIC_CONST float kfPi = 3.14159;
STATIC_CONST float kfAccuracy = 0.001;
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
///
/// GetHeight
///
/// @brief GetHeight
///
/// @param in vec3 lWorldPosition
/// @return float
///
//-----------------------------------------------------------------------------
float
GetHeight(
in vec3 lWorldPosition,
in vec4 lPlanetPosition )
{
vec3 lOffset = lWorldPosition - lPlanetPosition.xyz;
return length(lOffset) - lPlanetPosition.w;
}
//-----------------------------------------------------------------------------
///
/// GetHeight
///
/// @brief GetHeight
///
/// @param in vec3 lWorldPosition
/// @return float
///
//-----------------------------------------------------------------------------
float
GetDistanceFromCenter(
in vec3 lWorldPosition,
in vec4 lPlanetPosition )
{
vec3 lOffset = lWorldPosition - lPlanetPosition.xyz;
return length(lOffset);
}
//-----------------------------------------------------------------------------
///
/// GetWorldUp
///
/// @brief GetWorldUp
///
/// @param in vec3 lWorldPosition
/// @return vec3
///
//-----------------------------------------------------------------------------
vec3
GetWorldUp(
in vec3 lWorldPosition,
in vec4 lPlanetPosition )
{
#ifdef D_ASTEROID
return kUp;
#else
return normalize(lWorldPosition / lPlanetPosition.w - lPlanetPosition.xyz / lPlanetPosition.w);
#endif
}
//-----------------------------------------------------------------------------
///
/// GetWorldUp
///
/// @brief GetWorldUp
///
/// @param in vec3 lWorldPosition
/// @param out float lfHeight
/// @return vec3
///
//-----------------------------------------------------------------------------
vec3
GetWorldUp(
in vec3 lWorldPosition,
in vec4 lPlanetPosition,
out float lfHeight )
{
vec3 lOffset;
// Get the offset from planet centre
lOffset = (lWorldPosition - lPlanetPosition.xyz);
// Get the length of the offset
lfHeight = length(lOffset);
// Normalise the offset to get the world up
lOffset /= lfHeight;
// Remove the planet radius to get the height
lfHeight -= lPlanetPosition.w;
return lOffset;
}
//-----------------------------------------------------------------------------
///
/// GetWorldUpTransform
///
/// @brief GetWorldUpTransform
///
/// @param in vec3 lViewPosition
/// @return mat3
///
//-----------------------------------------------------------------------------
mat3
GetRotation(
in vec3 lFromVec3,
in vec3 lToVec3 )
{
mat3 lMatrix;
vec3 lAxisVec3 = cross( lFromVec3, lToVec3 );
float lfDot = dot( lFromVec3, lToVec3 );
float lfAngle = length( lAxisVec3 );
if( lfAngle > kfAccuracy && lfDot < ( 1.0 - kfAccuracy ) && lfDot > -( 1.0 - kfAccuracy ) )
{
lfAngle = length( lAxisVec3 );
lAxisVec3 = normalize( lAxisVec3 );
}
else
{
return mat3( vec3( 1.0, 0.0, 0.0 ), vec3( 0.0, 1.0, 0.0 ), vec3( 0.0, 0.0, 1.0 ) );
}
lfAngle = clamp( lfAngle, -1.0, 1.0 );
lfAngle = asin( lfAngle );
if( lfDot < 0.0 )
{
lfAngle = kfPi - lfAngle;
}
float lfCos = cos( lfAngle );
float lfInv = 1.0 - lfCos;
float lfSin = sin( lfAngle );
MAT3_SET_COLUMN( lMatrix, 0, vec3( lfCos + lAxisVec3.x * lAxisVec3.x * lfInv, lAxisVec3.y * lAxisVec3.z * lfInv + lAxisVec3.z * lfSin, lAxisVec3.z * lAxisVec3.x * lfInv - lAxisVec3.y * lfSin ) );
MAT3_SET_COLUMN( lMatrix, 1, vec3( lAxisVec3.x * lAxisVec3.y * lfInv - lAxisVec3.z * lfSin, lfCos + lAxisVec3.y * lAxisVec3.y * lfInv, lAxisVec3.z * lAxisVec3.y * lfInv + lAxisVec3.x * lfSin ) );
MAT3_SET_COLUMN( lMatrix, 2, vec3( lAxisVec3.x * lAxisVec3.z * lfInv + lAxisVec3.y * lfSin, lAxisVec3.y * lAxisVec3.z * lfInv - lAxisVec3.x * lfSin, lfCos + lAxisVec3.z * lAxisVec3.z * lfInv ) );
return lMatrix;
}
//-----------------------------------------------------------------------------
///
/// GetWorldUpTransform
///
/// @brief GetWorldUpTransform
///
/// @param in vec3 lViewPosition
/// @return mat3
///
//-----------------------------------------------------------------------------
mat3
GetWorldUpTransform(
in vec3 lViewPosition,
in vec4 lPlanetPosition )
{
vec3 lUp = vec3( 0.0, 1.0, 0.0);
vec3 lWorldUp = GetWorldUp( lViewPosition, lPlanetPosition );
return GetRotation( lUp, lWorldUp );
}
//-----------------------------------------------------------------------------
///
/// GetWorldUpTransform
///
/// @brief GetWorldUpTransform
///
/// @param in vec3 lViewPosition
/// @return mat3
///
//-----------------------------------------------------------------------------
mat3
GetInverseWorldUpTransform(
in vec3 lViewPosition,
in vec4 lPlanetPosition )
{
vec3 lUp = vec3( 0.0, 1.0, 0.0 );
vec3 lWorldUp = GetWorldUp( lViewPosition, lPlanetPosition );
return GetRotation( lWorldUp, lUp );
}
#endif
////////////////////////////////////////////////////////////////////////////////
///
/// @file CommonUniforms.h
/// @author User
/// @date
///
/// @brief CommonUniforms
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
#ifndef D_COMMONUNIFORMS2_H
#define D_COMMONUNIFORMS2_H
// =================================================================================================
#ifndef D_DEFINES
#define D_DEFINES
// =================================================================================================
// Platform defines
// =================================================================================================
#ifdef D_PLATFORM_PC
#define D_ENABLE_REVERSEZ_PROJECTION (1)
#pragma optionNV(strict on)
#extension GL_ARB_gpu_shader5 : enable
#extension GL_ARB_fragment_coord_conventions : enable
#extension GL_ARB_derivative_control : enable
#if defined( D_FRAGMENT ) && defined( _F64_ )
layout(early_fragment_tests) in;
#endif
#elif defined(D_PLATFORM_ORBIS)
#define D_ENABLE_REVERSEZ_PROJECTION (1)
// use this with sdk 2.0 compiler
// #pragma argument (allow-scratch-buffer-spill)
//define these flags so they don't get ignored in build process and in the comb mask
//this is because materials, vertex layouts and shaders need to be synced on 360 to avoid patching
#ifdef _F27_
#endif
#ifdef _F28_
#endif
#ifdef _F29_
#endif
#ifdef _F21_
#endif
#ifdef _F02_
#endif
#ifdef _F03_
#endif
#if defined( _F01_ ) || defined( D_LOD0 ) || defined( D_LOD1 ) || defined( D_LOD2 ) || defined( D_LOD3) || defined( D_LOD4 )
#endif
#ifdef _F01_
#endif
#ifdef _F09_
#endif
#ifdef _F10_
#endif
// disable warnings for unused parameters. This happens a lot because of defining different things.
#pragma warning (disable: 5203)
// temp thing to know what things are still required on ps4.
#define D_PLATFORM_ORBIS_FIX
#ifdef __PSSL_CS__
#define D_PLATFORM_ORBIS_COMPUTE
#endif
#ifdef __PSSL_HS__
#define D_HULL
#endif
#ifdef __PSSL_DS__
#define D_DOMAIN
#endif
#ifdef __PSSL_VS__
#define D_VERTEX
#endif
#ifdef __PSSL_GS__
#define D_GEOMETRY
#endif
#endif
#if !D_ENABLE_REVERSEZ_PROJECTION
#define D_USING_LOGDEPTH
#endif
// =================================================================================================
// Basic Types
// =================================================================================================
#ifdef D_PLATFORM_PC
#define JOINT_TYPE vec4
//#define CONST const
#define STATIC_CONST const
#elif defined(D_PLATFORM_ORBIS)
#define JOINT_TYPE int4
#define float float
#define vec2 float2
#define vec3 float3
#define vec4 float4
#define ivec2 int2
#define ivec3 int3
#define ivec4 int4
#define uvec2 uint2
#define uvec3 uint3
#define uvec4 uint4
// NOTE:
// operator[] accesses rows, not columns
// matrix constructors interpret the passed vectors as row vectors, not column vectors
#define mat2 row_major float2x2
#define mat3 row_major float3x3
#define mat4 row_major float4x4
//#define CONST
#define STATIC_CONST static const
// #define const ERROR, DON'T USE CONST FOR PS4. USE STATIC_CONST INSTEAD FOR A COMPILED IN CONSTANT. OTHERWISE IT TRIES TO PUT IT IN A CONSTANT BUFFER AND FOR SOME REASON IT DOESN'T WORK.
#endif
// =================================================================================================
// Functions
// =================================================================================================
#ifdef D_PLATFORM_PC
#define saturate( V ) min( max( V, 0.0) , 1.0)
#define atan2( Y, X ) atan( Y, X )
#define invsqrt( X ) inversesqrt( X )
#ifdef D_COMPUTE
#define groupID gl_WorkGroupID
#define groupThreadID gl_LocalInvocationID
#define dispatchThreadID gl_GlobalInvocationID
#endif
#elif defined(D_PLATFORM_ORBIS)
#if defined(D_PLATFORM_ORBIS_COMPUTE)
float dFdx( float var ) { float delta = var - LaneSwizzle( var, 0x1f, 0, 1 ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
float dFdy( float var ) { float delta = var - LaneSwizzle( var, 0x1f, 0, 8 ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec2 dFdx( vec2 var ) { vec2 delta = vec2( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec2 dFdy( vec2 var ) { vec2 delta = vec2( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec3 dFdx( vec3 var ) { vec3 delta = vec3( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec3 dFdy( vec3 var ) { vec3 delta = vec3( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec4 dFdx( vec4 var ) { vec4 delta = vec4( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.w, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec4 dFdy( vec4 var ) { vec4 delta = vec4( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.w, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
#define dFdxFine dFdx
#define dFdyFine dFdy
#else
#define dFdx ddx
#define dFdy ddy
#define dFdxFine ddx_fine
#define dFdyFine ddy_fine
#endif
#define mix lerp
#define fract frac
#define mod fmod
#define saturate( V ) ( min( max( V, 0.0) , 1.0) )
#define invsqrt( X ) rsqrt( X )
#endif
// =================================================================================================
// Samplers and textures
// =================================================================================================
#ifdef D_PLATFORM_PC
#define shadow2D( S, UV ) texture( S, UV )
#define SAMPLER2DSHADOW( NAME, REG ) uniform sampler2DShadow NAME
#define SAMPLERCUBE( NAME ) samplerCube NAME
#define SAMPLERCUBEARG( NAME ) in samplerCube NAME
#define SAMPLERCUBEPARAM( NAME ) NAME
#define imageAtomicAddOut( T, C, V, O ) O = imageAtomicAdd( T, C, V )
#if defined( D_TEXTURE_FEEDBACK )
#define texture2D( T, C ) Tex2dFeedback( T, T##FB, C )
#define texture2DLod( T, C, N ) Tex2dLodFeedback( T, T##FB, C, N )
#define texture2DArray( T, C ) Tex2dArrayFeedback( T, T##FB, C )
#define texture3D( S, UV ) Tex3dFeedback( S, S##FB, UV )
#define texture3DLod( S, UV, LOD ) Tex3dLodFeedback( S, S##FB, UV, LOD )
#define SAMPLER2DARG( NAME ) in sampler2D NAME, in int NAME##FB
#define SAMPLER2DPARAM( NAME ) NAME, NAME##FB
#define SAMPLER2DARRAYARG( NAME ) in sampler2DArray NAME, in int NAME##FB
#define SAMPLER2DARRAYPARAM( NAME ) NAME, NAME##FB
#define SAMPLER2D( NAME ) sampler2D NAME; int NAME##FB
#define SAMPLER2DARRAY( NAME ) sampler2DArray NAME; int NAME##FB
#define SAMPLER3D( NAME ) sampler3D NAME; int NAME##FB
#define SAMPLER2DSHADOW_SRT( NAME ) sampler2DShadow NAME; int NAME##FB
#else
#define texture2DLod( S, UV, LOD ) textureLod( S, UV, LOD )
#define texture3DLod( S, UV, LOD ) textureLod( S, UV, LOD )
#define SAMPLER2DARG( NAME ) in sampler2D NAME
#define SAMPLER2DPARAM( NAME ) NAME
#define SAMPLER2DARRAYARG( NAME ) in sampler2DArray NAME
#define SAMPLER2DARRAYPARAM( NAME ) NAME
#define SAMPLER2D( NAME ) sampler2D NAME
#define SAMPLER2DARRAY( NAME ) sampler2DArray NAME
#define SAMPLER3D( NAME ) sampler3D NAME
#define SAMPLER2DSHADOW_SRT( NAME ) sampler2DShadow NAME
#endif
#define textureGatherRed( lTex, lSamp ) textureGather( lTex, lSamp, 0 )
#define textureGatherGreen( lTex, lSamp ) textureGather( lTex, lSamp, 1 )
#define textureGatherBlue( lTex, lSamp ) textureGather( lTex, lSamp, 2 )
#define textureGatherAlpha( lTex, lSamp ) textureGather( lTex, lSamp, 3 )
#define texture2DComputeGrad( T, C ) texture2D( T, C )
#elif defined(D_PLATFORM_ORBIS)
#define SAMPLERCUBE( NAME, REG ) SamplerState NAME##SS : register( s##REG ); TextureCube NAME##TU : register( t##REG )
#define SAMPLER2D( NAME ) Texture2D NAME; SamplerState NAME##SS
#define SAMPLER2DSHADOW_SRT( NAME ) Texture2D NAME; SamplerComparisonState NAME##SS //SAMPLER2D( NAME )
#define SAMPLER3D( NAME ) Texture3D NAME; SamplerState NAME##SS
#define SAMPLER2DARRAY( NAME ) Texture2D_Array NAME; SamplerState NAME##SS
#define SAMPLER2DARRAYARG( NAME ) Texture2D_Array NAME, SamplerState NAME##SS
#define SAMPLER2DARRAYPARAM( NAME ) NAME, NAME##SS
#define SAMPLER2DPARAM( NAME ) NAME, NAME##SS
#define SAMPLER2DARG( NAME ) Texture2D NAME, SamplerState NAME##SS
#define texture2D( T, C ) T.Sample( T##SS, C )
#if defined(D_PLATFORM_ORBIS_COMPUTE)
#define texture2DComputeGrad( T, C ) T.SampleGradient( T##SS, C, vec2( dFdx( C ) ), vec2( dFdy( C ) ) )
#define shadow2D( T, C ) T.SampleCmpLOD0( T##SS, C.xy, C.z )
#else
#define texture2DComputeGrad( T, C ) T.Sample( T##SS, C )
#define shadow2D( T, C ) T.SampleCmp( T##SS, C.xy, C.z )
#endif
#define texture2DLod( T, C, N ) T.SampleLOD( T##SS, C, N )
#define texture2DArray( T, C ) T.Sample( T##SS, C )
#define texture3DLod( T, C, N ) T.SampleLOD( T##SS, C, N )
//#define shadow2D( T, C ) vec3( C.z > T.Sample( T##SS, C.xy ).x ? 1.0 : 0.0 )
//#define shadow2D( T, C ) T.GatherCmp( T##SS, C.xy, C.z )
//#define shadow2D( T, C ) T.SampleCmpLOD0( T##SS, C.xy, C.z )
#define textureCube( T, C ) T##TU.Sample( T##SS, C )
#define textureCubeLod( T, C, N ) T##TU.Sample( T##SS, C, N )
#define textureGrad( T, C, DDX, DDY ) T.SampleGradient( T##SS, C, DDX, DDY )
#define imageAtomicAdd( T, C, V ) AtomicAdd( T[ C ], V )
#define imageAtomicAddOut( T, C, V, O ) AtomicAdd( T[ C ], V, O )
#define imageStore( T, C, V ) ( T[C] = V )
#define textureGatherRed( lTex, lSamp ) lTex.GatherRed ( lTex##SS, lSamp )
#define textureGatherGreen( lTex, lSamp ) lTex.GatherGreen( lTex##SS, lSamp )
#define textureGatherBlue( lTex, lSamp ) lTex.GatherBlue ( lTex##SS, lSamp )
#define textureGatherAlpha( lTex, lSamp ) lTex.GatherAlpha( lTex##SS, lSamp )
#define texelFetch( lTex, lSamp, lLod ) lTex.MipMaps((lLod), (lSamp))
#endif
#if defined(D_PLATFORM_ORBIS_COMPUTE)
#define THREADGROUP_LOCAL thread_group_memory
#define THREADGROUP_BARRIER ThreadGroupMemoryBarrier()
#elif defined(D_PLATFORM_PC_COMPUTE)
#define THREADGROUP_LOCAL layout( shared )
#define THREADGROUP_BARRIER groupMemoryBarrier()
#endif
// =================================================================================================
// Matrices
// =================================================================================================
#ifdef D_PLATFORM_PC
#define MUL( INPUT_A, INPUT_B ) (INPUT_A * INPUT_B)
#define PLATFORM_TRANSPOSE
#define MAT4_SET_POS( M, P ) M[ 3 ] = P
#define MAT4_SET_TRANSLATION( M, T ) M[ 3 ].xyz = T
#define MAT4_GET_COLUMN( M, C ) M[ C ].xyz
#define MAT3_GET_COLUMN( M, C ) M[ C ]
#define MAT4_GET_COLUMN_VEC4( M, C ) M[ C ]
#define MAT3_SET_COLUMN( M, C, V ) M[ C ] = V;
#define MAT4_SET_COLUMN( M, C, V ) M[ C ] = V;
#elif defined(D_PLATFORM_ORBIS)
#define MUL( INPUT_A, INPUT_B ) mul( INPUT_B, INPUT_A )
#define PLATFORM_TRANSPOSE
#define MAT4_SET_POS( M, P ) M[ 3 ] = P
#define MAT4_SET_TRANSLATION( M, T ) M[ 3 ].xyz = T
#define MAT4_GET_COLUMN( M, C ) M[ C ].xyz
#define MAT3_GET_COLUMN( M, C ) M[ C ]
#define MAT4_GET_COLUMN_VEC4( M, C ) M[ C ]
#define MAT3_SET_COLUMN( M, C, V ) M[ C ] = V;
#define MAT4_SET_COLUMN( M, C, V ) M[ C ] = V;
#endif
// =================================================================================================
// Arrays (workaround AMD shader compiler issues by making arrays have global scope)
// =================================================================================================
#if defined(D_PLATFORM_ORBIS)
#define ARRAY_LOOKUP_FS( _UNIFORMS, _ELEMENT, _INDEX) _UNIFORMS._ELEMENT[_INDEX]
#define ARRAY_LOOKUP_FP( _UNIFORMS, _ELEMENT, _INDEX) _UNIFORMS._ELEMENT[_INDEX]
#else
#define ARRAY_LOOKUP_FS( _UNIFORMS, _ELEMENT, _INDEX) _ELEMENT[_INDEX]
#define ARRAY_LOOKUP_FP( _UNIFORMS, _ELEMENT, _INDEX) _ELEMENT[_INDEX]
#endif
// =================================================================================================
// Input and Output
// =================================================================================================
#ifdef D_PLATFORM_PC
#define UNIFORM( TYPE, NAME ) uniform TYPE NAME
#define UNIFORM_SRT( TYPE, NAME ) uniform TYPE NAME
#define DECLARE_INPUT
#define DECLARE_OUTPUT
#define DECLARE_END
#define DECLARE_PTR( TYPE, NAME ) TYPE NAME;
#define DECLARE_PATCH_INPUT_TRI
#define DECLARE_PATCH_OUTPUT_TRI
#define IN_PATCH_TRI_TESS_CONSTANTS
#define OUT_PATCH_TRI_TESS_CONSTANTS
#define DECLARE_PATCH_INPUT_QUAD
#define DECLARE_PATCH_OUTPUT_QUAD
#define IN_PATCH_QUAD_TESS_CONSTANTS
#define OUT_PATCH_QUAD_TESS_CONSTANTS
#if defined( D_HULL )
#define INPUT( TYPE, NAME, REG ) in TYPE NAME [];
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME [];
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME [];
#define PATCH_OUTPUT( TYPE, NAME, REG ) patch out TYPE NAME;
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME [];
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME [];
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME [];
#elif defined( D_DOMAIN )
#define PATCH_INPUT( TYPE, NAME, REG ) patch in TYPE NAME;
#define INPUT( TYPE, NAME, REG ) in TYPE NAME [];
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME [];
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME [];
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME;
#else
#define INPUT( TYPE, NAME, REG ) in TYPE NAME;
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME;
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME;
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME;
#endif
#define FRAGMENT_COLOUR_UVEC4_DEFINE layout(location = 0) out uvec4 outu_color0;
#define FRAGMENT_COLOUR_UVEC4 outu_color0
#define FRAGMENT_COLOUR out_color0
#define FRAGMENT_COLOUR0 out_color0
#define FRAGMENT_COLOUR1 out_color1
#define FRAGMENT_COLOUR2 out_color2
#define FRAGMENT_COLOUR3 out_color3
#define FRAGMENT_COLOUR4 out_color4
#if defined( D_TAA_RENDER_TARGETS )
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1; layout(location = 2) out vec4 out_color2;
#elif !defined(D_ATTRIBUTES)
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0;
#else
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1; layout(location = 2) out vec4 out_color2; layout(location = 3) out vec4 out_color3; layout(location = 4) out vec4 out_color4;
#endif
#define FRAGMENT_COLOUR01_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1;
#define FRAGMENT_DEPTH gl_FragDepth
#define FRAGMENT_FRONTFACE gl_FrontFacing
#define INPUT_FRONTFACING
#define DEREF_PTR( VAR ) VAR
#if defined( D_HULL )
#define IN( VAR ) VAR[ gl_InvocationID ]
#define OUT( VAR ) VAR[ gl_InvocationID ]
#define PATCH_OUT( VAR ) VAR
#define OUTPUT_VERTEX_SCREEN_POSITION gl_out[ gl_InvocationID ].gl_Position
#define INPUT_VERTEX_SCREEN_POSITION gl_in [ gl_InvocationID ].gl_Position
#define TESS_LEVEL_EDGE( IND ) gl_TessLevelOuter[ IND ]
#define TESS_LEVEL_INNER( IND ) gl_TessLevelInner[ IND ]
#elif defined( D_DOMAIN )
#define PATCH_IN( VAR, IND ) VAR[ IND ]
#define IN( VAR, IND ) VAR[ IND ]
#define OUT( VAR ) VAR
#define INPUT_VERTEX_SCREEN_POSITION( IND ) gl_in [ IND ].gl_Position
#define DOMAIN_COORDS gl_TessCoord
#elif defined( D_GEOMETRY )
#define OUTPUT_VERTEX_SCREEN_POSITION gl_Position
#define INPUT_VERTEX_SCREEN_POSITION( IND ) gl_in [ IND ].gl_Position
#define IN( VAR, IND ) VAR[ IND ]
#define OUT( VAR ) VAR
#else
#define IN( VAR ) VAR
#define OUT( VAR ) VAR
#endif
#define OUT_VERTEX_SCREEN_POSITION
#define IN_SCREEN_POSITION
#define VERTEX_SCREEN_POSITION gl_Position
#elif defined(D_PLATFORM_ORBIS_COMPUTE)
#define DECLARE_INPUT struct cInput {
#define DECLARE_END };
#define DECLARE_PTR( TYPE, NAME ) TYPE* NAME;
#define INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define INPUT_NOINTERP( TYPE, NAME, REG ) TYPE NAME : REG;
#define IN_SCREEN_POSITION
#define FRAGMENT_COLOUR lUniforms.mpCmpOutPerMesh.gOutTexture0[dispatchThreadID.xy]
#define FRAGMENT_COLOUR0 lUniforms.mpCmpOutPerMesh.gOutTexture0[dispatchThreadID.xy]
#define FRAGMENT_COLOUR1 lUniforms.mpCmpOutPerMesh.gOutTexture1[dispatchThreadID.xy]
#define FRAGMENT_COLOUR2 lUniforms.mpCmpOutPerMesh.gOutTexture2[dispatchThreadID.xy]
#define FRAGMENT_COLOUR3 lUniforms.mpCmpOutPerMesh.gOutTexture3[dispatchThreadID.xy]
#define FRAGMENT_COLOUR4 lUniforms.mpCmpOutPerMesh.gOutTexture4[dispatchThreadID.xy]
#define FRAGMENT_DEPTH lUniforms.mpCmpOutPerMesh.gOutTextureDepth[dispatchThreadID.xy]
#define DEREF_PTR( VAR ) *VAR
#elif defined(D_PLATFORM_ORBIS)
#define UNIFORM( TYPE, NAME ) ConstantBuffer NAME##CB{ TYPE NAME; };
#define UNIFORM_SRT( TYPE, NAME ) ConstantBuffer NAME##CB{ TYPE NAME : S_SRT_DATA; };
#define DECLARE_OUTPUT struct cOutput {
#define DECLARE_INPUT struct cInput {
#define DECLARE_END };
#define DECLARE_PTR( TYPE, NAME ) TYPE* NAME;
#define INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define INPUT_NOINTERP( TYPE, NAME, REG ) nointerp TYPE NAME : REG;
#define INPUT_NOPERSP( TYPE, NAME, REG ) nopersp TYPE NAME : REG;
#define OUTPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) nointerp TYPE NAME : REG;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) nopersp TYPE NAME : REG;
#define FRAGMENT_COLOUR_UVEC4_DEFINE
#define FRAGMENT_COLOUR_UVEC4 Out.mColour
#define FRAGMENT_COLOUR Out.mColour
#define FRAGMENT_COLOUR0 Out.mColour0
#define FRAGMENT_COLOUR1 Out.mColour1
#define FRAGMENT_COLOUR2 Out.mColour2
#define FRAGMENT_COLOUR3 Out.mColour3
#define FRAGMENT_COLOUR4 Out.mColour4
#define FRAGMENT_DEPTH Out.mDepth
#define FRAGMENT_FRONTFACE In.mbFrontFacing
#define INPUT_FRONTFACING bool mbFrontFacing : S_FRONT_FACE;
#if defined( D_HULL )
#define IN( VAR ) In[ uCPID ].VAR
#define OUT( VAR ) Out.VAR
#define PATCH_OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION IN( mScreenPositionVec4 )
#define TESS_LEVEL_EDGE( IND ) Out.edge_ts[ IND ]
#define TESS_LEVEL_INNER( IND ) Out.insi_ts[ IND ]
#define DECLARE_PATCH_OUTPUT_TRI [DOMAIN_PATCH_TYPE("tri")] struct HSConstantOutputData {
#define OUT_PATCH_TRI_TESS_CONSTANTS float edge_ts[3] : S_EDGE_TESS_FACTOR; \
float insi_ts[1] : S_INSIDE_TESS_FACTOR;
#define DECLARE_PATCH_OUTPUT_QUAD [DOMAIN_PATCH_TYPE("quad")] struct HSConstantOutputData (
#define OUT_PATCH_QUAD_TESS_CONSTANTS float edge_ts[4] : S_EDGE_TESS_FACTOR; \
float insi_ts[2] : S_INSIDE_TESS_FACTOR;
#define PATCH_OUTPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#elif defined( D_DOMAIN )
#define PATCH_IN( VAR, IND ) patchIn.VAR
#define IN( VAR, IND ) In[ IND ].VAR
#define OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION( IND ) IN( mScreenPositionVec4, IND )
#define DOMAIN_COORDS domainCoordinates
#define DECLARE_PATCH_INPUT_TRI [DOMAIN_PATCH_TYPE("tri")] struct HSConstantOutputData {
#define IN_PATCH_TRI_TESS_CONSTANTS float edge_ts[3] : S_EDGE_TESS_FACTOR; \
float insi_ts[1] : S_INSIDE_TESS_FACTOR;
#define DECLARE_PATCH_INPUT_QUAD [DOMAIN_PATCH_TYPE("quad")] struct HSConstantOutputData {
#define IN_PATCH_QUAD_TESS_CONSTANTS float edge_ts[4] : S_EDGE_TESS_FACTOR; \
float insi_ts[2] : S_INSIDE_TESS_FACTOR;
#define PATCH_INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#elif defined( D_GEOMETRY )
#define IN( VAR, IND ) In[ IND ].VAR
#define OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION( IND ) IN( mScreenPositionVec4, IND )
#define EMIT_VERTEX TriStream.Append( Out )
#define END_PRIMITIVE TriStream.RestartStrip()
#else
#define IN( VAR ) In.VAR
#define OUT( VAR ) Out.VAR
#endif
// TODO get rid of this - don't pass struct through functinos, pass members.
#define DEREF_PTR( VAR ) *VAR
#define OUT_VERTEX_SCREEN_POSITION OUTPUT( vec4, mScreenPositionVec4, S_POSITION )
#define IN_SCREEN_POSITION INPUT ( vec4, mScreenPositionVec4, S_POSITION )
#define VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#endif
// =================================================================================================
// Main
// =================================================================================================
#ifdef D_PLATFORM_PC
#define VERTEX_MAIN void main( void )
#define VERTEX_MAIN_SRT uniform UniformBuffer lUniforms; void main( void )
#define HULL_TRI_MAIN_SRT layout( vertices = 3 ) out; uniform UniformBuffer lUniforms; void main( void )
#define HULL_QUAD_MAIN_SRT layout( vertices = 4 ) out; uniform UniformBuffer lUniforms; void main( void )
#define DOMAIN_TRI_MAIN_SRT layout( triangles, fractional_even_spacing ) in; uniform UniformBuffer lUniforms; void main( void )
#define DOMAIN_QUAD_MAIN_SRT layout( quads, fractional_even_spacing ) in; uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define VOID_MAIN_COLOUR FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_GE_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_LE_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_EARLYZ_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_UICOLOUR_SRT FRAGMENT_COLOUR_UVEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define VOID_MAIN_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define VOID_MAIN_DEPTH_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR01_SRT FRAGMENT_COLOUR01_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR01_DEPTH_SRT FRAGMENT_COLOUR01_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#elif defined( D_PLATFORM_PC_COMPUTE )
#define COMPUTE_MAIN_SRT( X, Y, Z ) layout (local_size_x = X, local_size_y = Y, local_size_z = Z) in; void main( void )
#define FRAGMENT_MAIN_COLOUR_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR01_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#elif defined( D_PLATFORM_ORBIS_COMPUTE )
#define COMPUTE_MAIN_SRT( X, Y, Z ) [NUM_THREADS(X, Y, Z)] void main(uint3 groupID : S_GROUP_ID, uint3 groupThreadID : S_GROUP_THREAD_ID, uint3 dispatchThreadID : S_DISPATCH_THREAD_ID, UniformBuffer lUniforms : S_SRT_DATA)
#define FRAGMENT_MAIN_COLOUR_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR01_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#elif defined( D_PLATFORM_ORBIS )
#define VERTEX_MAIN void main( cInput In, out cOutput Out )
#define VERTEX_MAIN_SRT void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define HULL_TRI_MAIN_SRT [DOMAIN_PATCH_TYPE("tri")] \
[PARTITIONING_TYPE("integer")] \
[OUTPUT_TOPOLOGY_TYPE("triangle_cw")] \
[OUTPUT_CONTROL_POINTS(3)] \
[PATCH_CONSTANT_FUNC("ConstantsHS")] \
[MAX_TESS_FACTOR(16.0)] \
void main( \
InputPatch<cInput, 3> In, \
uint uCPID : S_OUTPUT_CONTROL_POINT_ID, \
UniformBuffer lUniforms : S_SRT_DATA, \
out cOutput Out )
#define HULL_QUAD_MAIN_SRT [DOMAIN_PATCH_TYPE("quad")] \
[PARTITIONING_TYPE("integer")] \
[OUTPUT_TOPOLOGY_TYPE("triangle_cw")] \
[OUTPUT_CONTROL_POINTS(4)] \
[PATCH_CONSTANT_FUNC("ConstantsHS")] \
[MAX_TESS_FACTOR(16.0)] \
void main( \
InputPatch<cInput, 4> In, \
uint uCPID : S_OUTPUT_CONTROL_POINT_ID, \
UniformBuffer lUniforms : S_SRT_DATA, \
out cOutput Out )
#define DOMAIN_TRI_MAIN_SRT [DOMAIN_PATCH_TYPE("tri")] \
void main( \
HSConstantOutputData patchIn, \
const OutputPatch<cInput, 3> In, \
out cOutput Out, \
UniformBuffer lUniforms : S_SRT_DATA, \
float3 domainCoordinates : S_DOMAIN_LOCATION )
#define DOMAIN_QUAD_MAIN_SRT [DOMAIN_PATCH_TYPE("quad")] \
void main( \
HSConstantOutputData patchIn, \
const OutputPatch<cInput, 4> In, \
out cOutput Out, \
UniformBuffer lUniforms : S_SRT_DATA, \
float2 domainCoordinates : S_DOMAIN_LOCATION )
#define GEOMETRY_MAIN_SRT( MAX_VERTS ) cOutput Out; [MAX_VERTEX_COUNT(MAX_VERTS)] void main( inout TriangleBuffer<cOutput> TriStream, Triangle cInput In[3], UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out )
#define VOID_MAIN_COLOUR struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; void main( cInput In, out cOutput Out )
#define FRAGMENT_MAIN_COLOUR_DEPTH struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out )
#define VOID_MAIN_SRT void main( cInput In, UniformBuffer lUniforms : S_SRT_DATA )
#if defined( D_TAA_RENDER_TARGETS )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#elif !defined( D_ATTRIBUTES )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_DEPTH_GE_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_GE_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_DEPTH_LE_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_LE_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define VOID_MAIN_DEPTH_SRT struct cOutput { float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define VOID_MAIN_COLOUR_EARLYZ_SRT [FORCE_EARLY_DEPTH_STENCIL] void main( cInput In, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR01_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR01_DEPTH_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
float mDepth : S_DEPTH_OUTPUT; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#else
// #pragma PSSL_target_output_format(target 1 FMT_32_AR)
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; \
float mDepth : S_DEPTH_OUTPUT; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_EARLYZ_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; }; \
[FORCE_EARLY_DEPTH_STENCIL] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#endif
#endif
// =================================================================================================
// Texture resolution
// =================================================================================================
#ifdef D_PLATFORM_ORBIS
uvec2 GetResolution( Texture2D lTexture )
{
uvec2 lResolution;
lTexture.GetDimensionsFast(lResolution.x, lResolution.y);
return lResolution;
}
uvec2 GetResolution( RW_Texture2D<float4> lTexture )
{
uvec2 lResolution;
lTexture.GetDimensionsFast(lResolution.x, lResolution.y);
return lResolution;
}
#else
uvec2 GetResolution( sampler2D lTexture )
{
return textureSize( lTexture, 0 );
}
#endif
// =================================================================================================
// Viewport
// =================================================================================================
#ifdef D_PLATFORM_PC
#define SCREENSPACE_AS_RENDERTARGET_UVS( A ) A.xy
#elif defined(D_PLATFORM_ORBIS)
#define SCREENSPACE_AS_RENDERTARGET_UVS( A ) ( float2( A.x, 1.0 - A.y ) )
#endif
#ifdef D_USING_LOGDEPTH
#define D_DEPTH_CLEARVALUE (1.0)
#else
#define D_DEPTH_CLEARVALUE (0.0)
#endif
// =================================================================================================
// Texture usage feedback
// =================================================================================================
#if defined( D_TEXTURE_FEEDBACK ) && defined( D_PLATFORM_PC )
layout(r32i) uniform iimage2D gTexFeedbackImg;
void WriteTexFeedback( in int liCounter, in float liMip )
{
if( liCounter != 0 )
{
#if defined( GL_ARB_shader_ballot ) && ( GL_ARB_shader_ballot == 1 )
if( readFirstInvocationARB( gl_SubGroupInvocationARB ) == gl_SubGroupInvocationARB )
#endif
{
int liIntMip = int(floor(liMip));
//imageStore( gTexFeedbackImg, ivec2( liCounter, liIntMip ), ivec4(1,0,0,0) );
imageAtomicAdd( gTexFeedbackImg, ivec2( liCounter, liIntMip ), int(1) );
}
}
}
vec4 Tex2dFeedback( in sampler2D lSamp, in int liCounter, in vec2 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex2dLodFeedback( in sampler2D lSamp, in int liCounter, in vec2 lCoords, in float liLod )
{
WriteTexFeedback( liCounter, liLod );
return textureLod( lSamp, lCoords, liLod );
}
vec4 Tex2dArrayFeedback( in sampler2DArray lSamp, in int liCounter, in vec3 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords.xy ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex3dFeedback( in sampler3D lSamp, in int liCounter, in vec3 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex3dLodFeedback( in sampler3D lSamp, in int liCounter, in vec3 lCoords, in float liLod )
{
WriteTexFeedback( liCounter, liLod );
return textureLod( lSamp, lCoords, liLod );
}
#endif
#endif
struct PerFrameUniforms
{
vec4 gLightPositionVec4; // EShaderConst_LightPositionVec4
vec4 gLightDirectionVec4; // EShaderConst_LightDirectionVec4
vec3 gViewPositionVec3; // EShaderConst_ViewPositionVec3
float gfTime; // EShaderConst_Time
float gfPrevTime; // EShaderConst_PrevTime
vec4 gClipPlanesVec4; // EShaderConst_ClipPlanesVec4
vec4 gClipPlanesRVec4; // EShaderConst_ClipPlanesRVec4
mat4 gCameraMat4; // EShaderConst_CameraMat4
mat4 gCameraDeltaMat4; // EShaderConst_CameraDeltaMat4
mat4 gPrevViewProjectionMat4; // EShaderConst_PrevViewProjectionMat4
vec4 gMBlurSettingsVec4; // EShaderConst_BlurSettingsVec4
vec4 gDeJitterVec4; // EShaderConst_DeJitterVec4
vec4 gTaaSettingsVec4; // EShaderConst_TaaSettingsVec4
vec4 gFrameBufferSizeVec4;
vec4 gFoVValuesVec4; // EShaderConst_FoVValuesVec4
vec4 gShadowSizeVec4;
vec4 gShadowFadeParamVec4;
vec4 gShadowProjScaleVec4[3]; // EShaderConst_ShadowProjScaleVec4
mat4 gViewMat4; // EShaderConst_ViewMat4
};
struct CommonPerMeshUniforms
{
// These are planet specific. Should they be here?
vec4 gPlanetPositionVec4;
vec4 gLightOriginVec4;
mat4 gWorldMat4; // EShaderConst_WorldMat4
mat4 gWorldMotionMat4; // EShaderConst_WorldMotionMat4
mat4 gWorldViewProjectionMat4; // EShaderConst_WorldViewProjectionMat4
mat4 gWorldNormalMat4; // EShaderConst_WorldNormalMat4
#if defined( D_FADE ) && !defined( D_INSTANCE )
float gfFadeValue; // EShaderConst_FadeTime
#else
float fdFadeValueDummy;
#endif
#if defined( D_SKINNING_UNIFORMS ) && defined( D_PLATFORM_ORBIS )
vec4 gaSkinMatrixRowsVec4[ 75 * 3 ];
vec4 gaPrevSkinMatrixRowsVec4[ 75 * 3 ];
#endif
//float gfShadowBias; // EShaderConst_ShadowBias
// have particle shader use a particlecommon instead of uber, and put these into it.
#if defined( D_PARTICLE_UNIFORMS ) && defined( D_PLATFORM_ORBIS )
vec4 gaParticleCornersVec4[ 4 ]; // EShaderConst_ParticleCornersVec4
vec4 gaParticlePositionsVec4[ 32 ]; // EShaderConst_ParticlePositionsVec4
vec4 gaParticleSizeAndRotationsVec4[ 32 ]; // EShaderConst_ParticleSizeAndRotationsVec4
vec4 gaParticleNormalsVec4[ 32 ]; // EShaderConst_ParticleNormalsVec4
vec4 gaParticleColoursVec4[ 32 ]; // EShaderConst_ParticleColoursVec4
#endif
// This stuff is here atm because of shadows. The shadow shader is one thing, but renders twice, with these needing to be set differently.
// ideally we don't want them set per mesh though, probably a SRT for 'percamera' or something
//
//
mat4 gProjectionMat4; // EShaderConst_ProjectionMat4
mat4 gViewProjectionMat4; // EShaderConst_ViewProjectionMat4
#if !defined( D_DEPTHONLY )
mat4 gInverseWorldUpMat4;
// Stop these being compiled in when recolouring as the recolour shader needs ALL tex units.
#if defined( D_DEFERRED_DECAL )
mat4 gInverseModelMat4; // EShaderConst_InverseModelMat4 = 0
#else
mat4 gInverseProjectionSCMat4; // EShaderConst_InverseProjectionSCMat4
#endif
mat4 gInverseViewMat4; // EShaderConst_InverseViewMat4
mat4 gInverseProjectionMat4; // EShaderConst_InverseProjectionMat4
//mat4 gInverseViewProjectionMat4; // EShaderConst_InverseViewProjectionMat4
mat4 gaShadowMat4[ 3 ]; // EShaderConst_ShadowMat4
vec4 gLightColourVec4; // EShaderConst_LightColourVec4
#ifdef D_IBL
vec4 gGenericParam0Vec4; // EShaderConst_GenericParam0Vec4
#else
vec4 gGenericParam0DummyVec4;
#endif
// These shouldn't be per mesh, the should be per rendertarget. BUT we need to add them to the enum
// in egShader and SetPErRenderTargetUniforms for that to work and we're trying to do a build for sony
// so that will have to wait. (also probably need a way of setting per RT uniforms from Game).
vec4 gScanParamsPosVec4;
vec4 gScanParamsCfg1Vec4;
vec4 gScanParamsCfg2Vec4;
vec4 gScanParamsCfg3Vec4;
vec4 gScanColourVec4;
vec4 gSpotlightPositionVec4;
vec4 gSpotlightDirectionVec4;
#endif
vec4 gUserDataVec4;
};
#if defined( D_PARTICLE_UNIFORMS ) && defined( D_PLATFORM_PC )
uniform vec4 gaParticleCornersVec4[4]; // EShaderConst_ParticleCornersVec4
uniform vec4 gaParticlePositionsVec4[32]; // EShaderConst_ParticlePositionsVec4
uniform vec4 gaParticleSizeAndRotationsVec4[32]; // EShaderConst_ParticleSizeAndRotationsVec4
uniform vec4 gaParticleNormalsVec4[32]; // EShaderConst_ParticleNormalsVec4
uniform vec4 gaParticleColoursVec4[32]; // EShaderConst_ParticleColoursVec4
#endif
#endif
////////////////////////////////////////////////////////////////////////////////
///
/// @file CommonFragment.h
/// @author User
/// @date
///
/// @brief CommonFogShader
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Compilation defines
#ifndef D_COMMONFRAGMENT_H
#define D_COMMONFRAGMENT_H
// =================================================================================================
#ifndef D_DEFINES
#define D_DEFINES
// =================================================================================================
// Platform defines
// =================================================================================================
#ifdef D_PLATFORM_PC
#define D_ENABLE_REVERSEZ_PROJECTION (1)
#pragma optionNV(strict on)
#extension GL_ARB_gpu_shader5 : enable
#extension GL_ARB_fragment_coord_conventions : enable
#extension GL_ARB_derivative_control : enable
#if defined( D_FRAGMENT ) && defined( _F64_ )
layout(early_fragment_tests) in;
#endif
#elif defined(D_PLATFORM_ORBIS)
#define D_ENABLE_REVERSEZ_PROJECTION (1)
// use this with sdk 2.0 compiler
// #pragma argument (allow-scratch-buffer-spill)
//define these flags so they don't get ignored in build process and in the comb mask
//this is because materials, vertex layouts and shaders need to be synced on 360 to avoid patching
#ifdef _F27_
#endif
#ifdef _F28_
#endif
#ifdef _F29_
#endif
#ifdef _F21_
#endif
#ifdef _F02_
#endif
#ifdef _F03_
#endif
#if defined( _F01_ ) || defined( D_LOD0 ) || defined( D_LOD1 ) || defined( D_LOD2 ) || defined( D_LOD3) || defined( D_LOD4 )
#endif
#ifdef _F01_
#endif
#ifdef _F09_
#endif
#ifdef _F10_
#endif
// disable warnings for unused parameters. This happens a lot because of defining different things.
#pragma warning (disable: 5203)
// temp thing to know what things are still required on ps4.
#define D_PLATFORM_ORBIS_FIX
#ifdef __PSSL_CS__
#define D_PLATFORM_ORBIS_COMPUTE
#endif
#ifdef __PSSL_HS__
#define D_HULL
#endif
#ifdef __PSSL_DS__
#define D_DOMAIN
#endif
#ifdef __PSSL_VS__
#define D_VERTEX
#endif
#ifdef __PSSL_GS__
#define D_GEOMETRY
#endif
#endif
#if !D_ENABLE_REVERSEZ_PROJECTION
#define D_USING_LOGDEPTH
#endif
// =================================================================================================
// Basic Types
// =================================================================================================
#ifdef D_PLATFORM_PC
#define JOINT_TYPE vec4
//#define CONST const
#define STATIC_CONST const
#elif defined(D_PLATFORM_ORBIS)
#define JOINT_TYPE int4
#define float float
#define vec2 float2
#define vec3 float3
#define vec4 float4
#define ivec2 int2
#define ivec3 int3
#define ivec4 int4
#define uvec2 uint2
#define uvec3 uint3
#define uvec4 uint4
// NOTE:
// operator[] accesses rows, not columns
// matrix constructors interpret the passed vectors as row vectors, not column vectors
#define mat2 row_major float2x2
#define mat3 row_major float3x3
#define mat4 row_major float4x4
//#define CONST
#define STATIC_CONST static const
// #define const ERROR, DON'T USE CONST FOR PS4. USE STATIC_CONST INSTEAD FOR A COMPILED IN CONSTANT. OTHERWISE IT TRIES TO PUT IT IN A CONSTANT BUFFER AND FOR SOME REASON IT DOESN'T WORK.
#endif
// =================================================================================================
// Functions
// =================================================================================================
#ifdef D_PLATFORM_PC
#define saturate( V ) min( max( V, 0.0) , 1.0)
#define atan2( Y, X ) atan( Y, X )
#define invsqrt( X ) inversesqrt( X )
#ifdef D_COMPUTE
#define groupID gl_WorkGroupID
#define groupThreadID gl_LocalInvocationID
#define dispatchThreadID gl_GlobalInvocationID
#endif
#elif defined(D_PLATFORM_ORBIS)
#if defined(D_PLATFORM_ORBIS_COMPUTE)
float dFdx( float var ) { float delta = var - LaneSwizzle( var, 0x1f, 0, 1 ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
float dFdy( float var ) { float delta = var - LaneSwizzle( var, 0x1f, 0, 8 ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec2 dFdx( vec2 var ) { vec2 delta = vec2( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec2 dFdy( vec2 var ) { vec2 delta = vec2( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec3 dFdx( vec3 var ) { vec3 delta = vec3( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec3 dFdy( vec3 var ) { vec3 delta = vec3( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec4 dFdx( vec4 var ) { vec4 delta = vec4( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.w, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec4 dFdy( vec4 var ) { vec4 delta = vec4( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.w, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
#define dFdxFine dFdx
#define dFdyFine dFdy
#else
#define dFdx ddx
#define dFdy ddy
#define dFdxFine ddx_fine
#define dFdyFine ddy_fine
#endif
#define mix lerp
#define fract frac
#define mod fmod
#define saturate( V ) ( min( max( V, 0.0) , 1.0) )
#define invsqrt( X ) rsqrt( X )
#endif
// =================================================================================================
// Samplers and textures
// =================================================================================================
#ifdef D_PLATFORM_PC
#define shadow2D( S, UV ) texture( S, UV )
#define SAMPLER2DSHADOW( NAME, REG ) uniform sampler2DShadow NAME
#define SAMPLERCUBE( NAME ) samplerCube NAME
#define SAMPLERCUBEARG( NAME ) in samplerCube NAME
#define SAMPLERCUBEPARAM( NAME ) NAME
#define imageAtomicAddOut( T, C, V, O ) O = imageAtomicAdd( T, C, V )
#if defined( D_TEXTURE_FEEDBACK )
#define texture2D( T, C ) Tex2dFeedback( T, T##FB, C )
#define texture2DLod( T, C, N ) Tex2dLodFeedback( T, T##FB, C, N )
#define texture2DArray( T, C ) Tex2dArrayFeedback( T, T##FB, C )
#define texture3D( S, UV ) Tex3dFeedback( S, S##FB, UV )
#define texture3DLod( S, UV, LOD ) Tex3dLodFeedback( S, S##FB, UV, LOD )
#define SAMPLER2DARG( NAME ) in sampler2D NAME, in int NAME##FB
#define SAMPLER2DPARAM( NAME ) NAME, NAME##FB
#define SAMPLER2DARRAYARG( NAME ) in sampler2DArray NAME, in int NAME##FB
#define SAMPLER2DARRAYPARAM( NAME ) NAME, NAME##FB
#define SAMPLER2D( NAME ) sampler2D NAME; int NAME##FB
#define SAMPLER2DARRAY( NAME ) sampler2DArray NAME; int NAME##FB
#define SAMPLER3D( NAME ) sampler3D NAME; int NAME##FB
#define SAMPLER2DSHADOW_SRT( NAME ) sampler2DShadow NAME; int NAME##FB
#else
#define texture2DLod( S, UV, LOD ) textureLod( S, UV, LOD )
#define texture3DLod( S, UV, LOD ) textureLod( S, UV, LOD )
#define SAMPLER2DARG( NAME ) in sampler2D NAME
#define SAMPLER2DPARAM( NAME ) NAME
#define SAMPLER2DARRAYARG( NAME ) in sampler2DArray NAME
#define SAMPLER2DARRAYPARAM( NAME ) NAME
#define SAMPLER2D( NAME ) sampler2D NAME
#define SAMPLER2DARRAY( NAME ) sampler2DArray NAME
#define SAMPLER3D( NAME ) sampler3D NAME
#define SAMPLER2DSHADOW_SRT( NAME ) sampler2DShadow NAME
#endif
#define textureGatherRed( lTex, lSamp ) textureGather( lTex, lSamp, 0 )
#define textureGatherGreen( lTex, lSamp ) textureGather( lTex, lSamp, 1 )
#define textureGatherBlue( lTex, lSamp ) textureGather( lTex, lSamp, 2 )
#define textureGatherAlpha( lTex, lSamp ) textureGather( lTex, lSamp, 3 )
#define texture2DComputeGrad( T, C ) texture2D( T, C )
#elif defined(D_PLATFORM_ORBIS)
#define SAMPLERCUBE( NAME, REG ) SamplerState NAME##SS : register( s##REG ); TextureCube NAME##TU : register( t##REG )
#define SAMPLER2D( NAME ) Texture2D NAME; SamplerState NAME##SS
#define SAMPLER2DSHADOW_SRT( NAME ) Texture2D NAME; SamplerComparisonState NAME##SS //SAMPLER2D( NAME )
#define SAMPLER3D( NAME ) Texture3D NAME; SamplerState NAME##SS
#define SAMPLER2DARRAY( NAME ) Texture2D_Array NAME; SamplerState NAME##SS
#define SAMPLER2DARRAYARG( NAME ) Texture2D_Array NAME, SamplerState NAME##SS
#define SAMPLER2DARRAYPARAM( NAME ) NAME, NAME##SS
#define SAMPLER2DPARAM( NAME ) NAME, NAME##SS
#define SAMPLER2DARG( NAME ) Texture2D NAME, SamplerState NAME##SS
#define texture2D( T, C ) T.Sample( T##SS, C )
#if defined(D_PLATFORM_ORBIS_COMPUTE)
#define texture2DComputeGrad( T, C ) T.SampleGradient( T##SS, C, vec2( dFdx( C ) ), vec2( dFdy( C ) ) )
#define shadow2D( T, C ) T.SampleCmpLOD0( T##SS, C.xy, C.z )
#else
#define texture2DComputeGrad( T, C ) T.Sample( T##SS, C )
#define shadow2D( T, C ) T.SampleCmp( T##SS, C.xy, C.z )
#endif
#define texture2DLod( T, C, N ) T.SampleLOD( T##SS, C, N )
#define texture2DArray( T, C ) T.Sample( T##SS, C )
#define texture3DLod( T, C, N ) T.SampleLOD( T##SS, C, N )
//#define shadow2D( T, C ) vec3( C.z > T.Sample( T##SS, C.xy ).x ? 1.0 : 0.0 )
//#define shadow2D( T, C ) T.GatherCmp( T##SS, C.xy, C.z )
//#define shadow2D( T, C ) T.SampleCmpLOD0( T##SS, C.xy, C.z )
#define textureCube( T, C ) T##TU.Sample( T##SS, C )
#define textureCubeLod( T, C, N ) T##TU.Sample( T##SS, C, N )
#define textureGrad( T, C, DDX, DDY ) T.SampleGradient( T##SS, C, DDX, DDY )
#define imageAtomicAdd( T, C, V ) AtomicAdd( T[ C ], V )
#define imageAtomicAddOut( T, C, V, O ) AtomicAdd( T[ C ], V, O )
#define imageStore( T, C, V ) ( T[C] = V )
#define textureGatherRed( lTex, lSamp ) lTex.GatherRed ( lTex##SS, lSamp )
#define textureGatherGreen( lTex, lSamp ) lTex.GatherGreen( lTex##SS, lSamp )
#define textureGatherBlue( lTex, lSamp ) lTex.GatherBlue ( lTex##SS, lSamp )
#define textureGatherAlpha( lTex, lSamp ) lTex.GatherAlpha( lTex##SS, lSamp )
#define texelFetch( lTex, lSamp, lLod ) lTex.MipMaps((lLod), (lSamp))
#endif
#if defined(D_PLATFORM_ORBIS_COMPUTE)
#define THREADGROUP_LOCAL thread_group_memory
#define THREADGROUP_BARRIER ThreadGroupMemoryBarrier()
#elif defined(D_PLATFORM_PC_COMPUTE)
#define THREADGROUP_LOCAL layout( shared )
#define THREADGROUP_BARRIER groupMemoryBarrier()
#endif
// =================================================================================================
// Matrices
// =================================================================================================
#ifdef D_PLATFORM_PC
#define MUL( INPUT_A, INPUT_B ) (INPUT_A * INPUT_B)
#define PLATFORM_TRANSPOSE
#define MAT4_SET_POS( M, P ) M[ 3 ] = P
#define MAT4_SET_TRANSLATION( M, T ) M[ 3 ].xyz = T
#define MAT4_GET_COLUMN( M, C ) M[ C ].xyz
#define MAT3_GET_COLUMN( M, C ) M[ C ]
#define MAT4_GET_COLUMN_VEC4( M, C ) M[ C ]
#define MAT3_SET_COLUMN( M, C, V ) M[ C ] = V;
#define MAT4_SET_COLUMN( M, C, V ) M[ C ] = V;
#elif defined(D_PLATFORM_ORBIS)
#define MUL( INPUT_A, INPUT_B ) mul( INPUT_B, INPUT_A )
#define PLATFORM_TRANSPOSE
#define MAT4_SET_POS( M, P ) M[ 3 ] = P
#define MAT4_SET_TRANSLATION( M, T ) M[ 3 ].xyz = T
#define MAT4_GET_COLUMN( M, C ) M[ C ].xyz
#define MAT3_GET_COLUMN( M, C ) M[ C ]
#define MAT4_GET_COLUMN_VEC4( M, C ) M[ C ]
#define MAT3_SET_COLUMN( M, C, V ) M[ C ] = V;
#define MAT4_SET_COLUMN( M, C, V ) M[ C ] = V;
#endif
// =================================================================================================
// Arrays (workaround AMD shader compiler issues by making arrays have global scope)
// =================================================================================================
#if defined(D_PLATFORM_ORBIS)
#define ARRAY_LOOKUP_FS( _UNIFORMS, _ELEMENT, _INDEX) _UNIFORMS._ELEMENT[_INDEX]
#define ARRAY_LOOKUP_FP( _UNIFORMS, _ELEMENT, _INDEX) _UNIFORMS._ELEMENT[_INDEX]
#else
#define ARRAY_LOOKUP_FS( _UNIFORMS, _ELEMENT, _INDEX) _ELEMENT[_INDEX]
#define ARRAY_LOOKUP_FP( _UNIFORMS, _ELEMENT, _INDEX) _ELEMENT[_INDEX]
#endif
// =================================================================================================
// Input and Output
// =================================================================================================
#ifdef D_PLATFORM_PC
#define UNIFORM( TYPE, NAME ) uniform TYPE NAME
#define UNIFORM_SRT( TYPE, NAME ) uniform TYPE NAME
#define DECLARE_INPUT
#define DECLARE_OUTPUT
#define DECLARE_END
#define DECLARE_PTR( TYPE, NAME ) TYPE NAME;
#define DECLARE_PATCH_INPUT_TRI
#define DECLARE_PATCH_OUTPUT_TRI
#define IN_PATCH_TRI_TESS_CONSTANTS
#define OUT_PATCH_TRI_TESS_CONSTANTS
#define DECLARE_PATCH_INPUT_QUAD
#define DECLARE_PATCH_OUTPUT_QUAD
#define IN_PATCH_QUAD_TESS_CONSTANTS
#define OUT_PATCH_QUAD_TESS_CONSTANTS
#if defined( D_HULL )
#define INPUT( TYPE, NAME, REG ) in TYPE NAME [];
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME [];
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME [];
#define PATCH_OUTPUT( TYPE, NAME, REG ) patch out TYPE NAME;
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME [];
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME [];
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME [];
#elif defined( D_DOMAIN )
#define PATCH_INPUT( TYPE, NAME, REG ) patch in TYPE NAME;
#define INPUT( TYPE, NAME, REG ) in TYPE NAME [];
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME [];
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME [];
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME;
#else
#define INPUT( TYPE, NAME, REG ) in TYPE NAME;
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME;
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME;
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME;
#endif
#define FRAGMENT_COLOUR_UVEC4_DEFINE layout(location = 0) out uvec4 outu_color0;
#define FRAGMENT_COLOUR_UVEC4 outu_color0
#define FRAGMENT_COLOUR out_color0
#define FRAGMENT_COLOUR0 out_color0
#define FRAGMENT_COLOUR1 out_color1
#define FRAGMENT_COLOUR2 out_color2
#define FRAGMENT_COLOUR3 out_color3
#define FRAGMENT_COLOUR4 out_color4
#if defined( D_TAA_RENDER_TARGETS )
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1; layout(location = 2) out vec4 out_color2;
#elif !defined(D_ATTRIBUTES)
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0;
#else
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1; layout(location = 2) out vec4 out_color2; layout(location = 3) out vec4 out_color3; layout(location = 4) out vec4 out_color4;
#endif
#define FRAGMENT_COLOUR01_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1;
#define FRAGMENT_DEPTH gl_FragDepth
#define FRAGMENT_FRONTFACE gl_FrontFacing
#define INPUT_FRONTFACING
#define DEREF_PTR( VAR ) VAR
#if defined( D_HULL )
#define IN( VAR ) VAR[ gl_InvocationID ]
#define OUT( VAR ) VAR[ gl_InvocationID ]
#define PATCH_OUT( VAR ) VAR
#define OUTPUT_VERTEX_SCREEN_POSITION gl_out[ gl_InvocationID ].gl_Position
#define INPUT_VERTEX_SCREEN_POSITION gl_in [ gl_InvocationID ].gl_Position
#define TESS_LEVEL_EDGE( IND ) gl_TessLevelOuter[ IND ]
#define TESS_LEVEL_INNER( IND ) gl_TessLevelInner[ IND ]
#elif defined( D_DOMAIN )
#define PATCH_IN( VAR, IND ) VAR[ IND ]
#define IN( VAR, IND ) VAR[ IND ]
#define OUT( VAR ) VAR
#define INPUT_VERTEX_SCREEN_POSITION( IND ) gl_in [ IND ].gl_Position
#define DOMAIN_COORDS gl_TessCoord
#elif defined( D_GEOMETRY )
#define OUTPUT_VERTEX_SCREEN_POSITION gl_Position
#define INPUT_VERTEX_SCREEN_POSITION( IND ) gl_in [ IND ].gl_Position
#define IN( VAR, IND ) VAR[ IND ]
#define OUT( VAR ) VAR
#else
#define IN( VAR ) VAR
#define OUT( VAR ) VAR
#endif
#define OUT_VERTEX_SCREEN_POSITION
#define IN_SCREEN_POSITION
#define VERTEX_SCREEN_POSITION gl_Position
#elif defined(D_PLATFORM_ORBIS_COMPUTE)
#define DECLARE_INPUT struct cInput {
#define DECLARE_END };
#define DECLARE_PTR( TYPE, NAME ) TYPE* NAME;
#define INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define INPUT_NOINTERP( TYPE, NAME, REG ) TYPE NAME : REG;
#define IN_SCREEN_POSITION
#define FRAGMENT_COLOUR lUniforms.mpCmpOutPerMesh.gOutTexture0[dispatchThreadID.xy]
#define FRAGMENT_COLOUR0 lUniforms.mpCmpOutPerMesh.gOutTexture0[dispatchThreadID.xy]
#define FRAGMENT_COLOUR1 lUniforms.mpCmpOutPerMesh.gOutTexture1[dispatchThreadID.xy]
#define FRAGMENT_COLOUR2 lUniforms.mpCmpOutPerMesh.gOutTexture2[dispatchThreadID.xy]
#define FRAGMENT_COLOUR3 lUniforms.mpCmpOutPerMesh.gOutTexture3[dispatchThreadID.xy]
#define FRAGMENT_COLOUR4 lUniforms.mpCmpOutPerMesh.gOutTexture4[dispatchThreadID.xy]
#define FRAGMENT_DEPTH lUniforms.mpCmpOutPerMesh.gOutTextureDepth[dispatchThreadID.xy]
#define DEREF_PTR( VAR ) *VAR
#elif defined(D_PLATFORM_ORBIS)
#define UNIFORM( TYPE, NAME ) ConstantBuffer NAME##CB{ TYPE NAME; };
#define UNIFORM_SRT( TYPE, NAME ) ConstantBuffer NAME##CB{ TYPE NAME : S_SRT_DATA; };
#define DECLARE_OUTPUT struct cOutput {
#define DECLARE_INPUT struct cInput {
#define DECLARE_END };
#define DECLARE_PTR( TYPE, NAME ) TYPE* NAME;
#define INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define INPUT_NOINTERP( TYPE, NAME, REG ) nointerp TYPE NAME : REG;
#define INPUT_NOPERSP( TYPE, NAME, REG ) nopersp TYPE NAME : REG;
#define OUTPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) nointerp TYPE NAME : REG;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) nopersp TYPE NAME : REG;
#define FRAGMENT_COLOUR_UVEC4_DEFINE
#define FRAGMENT_COLOUR_UVEC4 Out.mColour
#define FRAGMENT_COLOUR Out.mColour
#define FRAGMENT_COLOUR0 Out.mColour0
#define FRAGMENT_COLOUR1 Out.mColour1
#define FRAGMENT_COLOUR2 Out.mColour2
#define FRAGMENT_COLOUR3 Out.mColour3
#define FRAGMENT_COLOUR4 Out.mColour4
#define FRAGMENT_DEPTH Out.mDepth
#define FRAGMENT_FRONTFACE In.mbFrontFacing
#define INPUT_FRONTFACING bool mbFrontFacing : S_FRONT_FACE;
#if defined( D_HULL )
#define IN( VAR ) In[ uCPID ].VAR
#define OUT( VAR ) Out.VAR
#define PATCH_OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION IN( mScreenPositionVec4 )
#define TESS_LEVEL_EDGE( IND ) Out.edge_ts[ IND ]
#define TESS_LEVEL_INNER( IND ) Out.insi_ts[ IND ]
#define DECLARE_PATCH_OUTPUT_TRI [DOMAIN_PATCH_TYPE("tri")] struct HSConstantOutputData {
#define OUT_PATCH_TRI_TESS_CONSTANTS float edge_ts[3] : S_EDGE_TESS_FACTOR; \
float insi_ts[1] : S_INSIDE_TESS_FACTOR;
#define DECLARE_PATCH_OUTPUT_QUAD [DOMAIN_PATCH_TYPE("quad")] struct HSConstantOutputData (
#define OUT_PATCH_QUAD_TESS_CONSTANTS float edge_ts[4] : S_EDGE_TESS_FACTOR; \
float insi_ts[2] : S_INSIDE_TESS_FACTOR;
#define PATCH_OUTPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#elif defined( D_DOMAIN )
#define PATCH_IN( VAR, IND ) patchIn.VAR
#define IN( VAR, IND ) In[ IND ].VAR
#define OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION( IND ) IN( mScreenPositionVec4, IND )
#define DOMAIN_COORDS domainCoordinates
#define DECLARE_PATCH_INPUT_TRI [DOMAIN_PATCH_TYPE("tri")] struct HSConstantOutputData {
#define IN_PATCH_TRI_TESS_CONSTANTS float edge_ts[3] : S_EDGE_TESS_FACTOR; \
float insi_ts[1] : S_INSIDE_TESS_FACTOR;
#define DECLARE_PATCH_INPUT_QUAD [DOMAIN_PATCH_TYPE("quad")] struct HSConstantOutputData {
#define IN_PATCH_QUAD_TESS_CONSTANTS float edge_ts[4] : S_EDGE_TESS_FACTOR; \
float insi_ts[2] : S_INSIDE_TESS_FACTOR;
#define PATCH_INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#elif defined( D_GEOMETRY )
#define IN( VAR, IND ) In[ IND ].VAR
#define OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION( IND ) IN( mScreenPositionVec4, IND )
#define EMIT_VERTEX TriStream.Append( Out )
#define END_PRIMITIVE TriStream.RestartStrip()
#else
#define IN( VAR ) In.VAR
#define OUT( VAR ) Out.VAR
#endif
// TODO get rid of this - don't pass struct through functinos, pass members.
#define DEREF_PTR( VAR ) *VAR
#define OUT_VERTEX_SCREEN_POSITION OUTPUT( vec4, mScreenPositionVec4, S_POSITION )
#define IN_SCREEN_POSITION INPUT ( vec4, mScreenPositionVec4, S_POSITION )
#define VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#endif
// =================================================================================================
// Main
// =================================================================================================
#ifdef D_PLATFORM_PC
#define VERTEX_MAIN void main( void )
#define VERTEX_MAIN_SRT uniform UniformBuffer lUniforms; void main( void )
#define HULL_TRI_MAIN_SRT layout( vertices = 3 ) out; uniform UniformBuffer lUniforms; void main( void )
#define HULL_QUAD_MAIN_SRT layout( vertices = 4 ) out; uniform UniformBuffer lUniforms; void main( void )
#define DOMAIN_TRI_MAIN_SRT layout( triangles, fractional_even_spacing ) in; uniform UniformBuffer lUniforms; void main( void )
#define DOMAIN_QUAD_MAIN_SRT layout( quads, fractional_even_spacing ) in; uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define VOID_MAIN_COLOUR FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_GE_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_LE_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_EARLYZ_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_UICOLOUR_SRT FRAGMENT_COLOUR_UVEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define VOID_MAIN_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define VOID_MAIN_DEPTH_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR01_SRT FRAGMENT_COLOUR01_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR01_DEPTH_SRT FRAGMENT_COLOUR01_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#elif defined( D_PLATFORM_PC_COMPUTE )
#define COMPUTE_MAIN_SRT( X, Y, Z ) layout (local_size_x = X, local_size_y = Y, local_size_z = Z) in; void main( void )
#define FRAGMENT_MAIN_COLOUR_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR01_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#elif defined( D_PLATFORM_ORBIS_COMPUTE )
#define COMPUTE_MAIN_SRT( X, Y, Z ) [NUM_THREADS(X, Y, Z)] void main(uint3 groupID : S_GROUP_ID, uint3 groupThreadID : S_GROUP_THREAD_ID, uint3 dispatchThreadID : S_DISPATCH_THREAD_ID, UniformBuffer lUniforms : S_SRT_DATA)
#define FRAGMENT_MAIN_COLOUR_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR01_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#elif defined( D_PLATFORM_ORBIS )
#define VERTEX_MAIN void main( cInput In, out cOutput Out )
#define VERTEX_MAIN_SRT void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define HULL_TRI_MAIN_SRT [DOMAIN_PATCH_TYPE("tri")] \
[PARTITIONING_TYPE("integer")] \
[OUTPUT_TOPOLOGY_TYPE("triangle_cw")] \
[OUTPUT_CONTROL_POINTS(3)] \
[PATCH_CONSTANT_FUNC("ConstantsHS")] \
[MAX_TESS_FACTOR(16.0)] \
void main( \
InputPatch<cInput, 3> In, \
uint uCPID : S_OUTPUT_CONTROL_POINT_ID, \
UniformBuffer lUniforms : S_SRT_DATA, \
out cOutput Out )
#define HULL_QUAD_MAIN_SRT [DOMAIN_PATCH_TYPE("quad")] \
[PARTITIONING_TYPE("integer")] \
[OUTPUT_TOPOLOGY_TYPE("triangle_cw")] \
[OUTPUT_CONTROL_POINTS(4)] \
[PATCH_CONSTANT_FUNC("ConstantsHS")] \
[MAX_TESS_FACTOR(16.0)] \
void main( \
InputPatch<cInput, 4> In, \
uint uCPID : S_OUTPUT_CONTROL_POINT_ID, \
UniformBuffer lUniforms : S_SRT_DATA, \
out cOutput Out )
#define DOMAIN_TRI_MAIN_SRT [DOMAIN_PATCH_TYPE("tri")] \
void main( \
HSConstantOutputData patchIn, \
const OutputPatch<cInput, 3> In, \
out cOutput Out, \
UniformBuffer lUniforms : S_SRT_DATA, \
float3 domainCoordinates : S_DOMAIN_LOCATION )
#define DOMAIN_QUAD_MAIN_SRT [DOMAIN_PATCH_TYPE("quad")] \
void main( \
HSConstantOutputData patchIn, \
const OutputPatch<cInput, 4> In, \
out cOutput Out, \
UniformBuffer lUniforms : S_SRT_DATA, \
float2 domainCoordinates : S_DOMAIN_LOCATION )
#define GEOMETRY_MAIN_SRT( MAX_VERTS ) cOutput Out; [MAX_VERTEX_COUNT(MAX_VERTS)] void main( inout TriangleBuffer<cOutput> TriStream, Triangle cInput In[3], UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out )
#define VOID_MAIN_COLOUR struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; void main( cInput In, out cOutput Out )
#define FRAGMENT_MAIN_COLOUR_DEPTH struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out )
#define VOID_MAIN_SRT void main( cInput In, UniformBuffer lUniforms : S_SRT_DATA )
#if defined( D_TAA_RENDER_TARGETS )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#elif !defined( D_ATTRIBUTES )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_DEPTH_GE_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_GE_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_DEPTH_LE_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_LE_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define VOID_MAIN_DEPTH_SRT struct cOutput { float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define VOID_MAIN_COLOUR_EARLYZ_SRT [FORCE_EARLY_DEPTH_STENCIL] void main( cInput In, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR01_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR01_DEPTH_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
float mDepth : S_DEPTH_OUTPUT; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#else
// #pragma PSSL_target_output_format(target 1 FMT_32_AR)
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; \
float mDepth : S_DEPTH_OUTPUT; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_EARLYZ_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; }; \
[FORCE_EARLY_DEPTH_STENCIL] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#endif
#endif
// =================================================================================================
// Texture resolution
// =================================================================================================
#ifdef D_PLATFORM_ORBIS
uvec2 GetResolution( Texture2D lTexture )
{
uvec2 lResolution;
lTexture.GetDimensionsFast(lResolution.x, lResolution.y);
return lResolution;
}
uvec2 GetResolution( RW_Texture2D<float4> lTexture )
{
uvec2 lResolution;
lTexture.GetDimensionsFast(lResolution.x, lResolution.y);
return lResolution;
}
#else
uvec2 GetResolution( sampler2D lTexture )
{
return textureSize( lTexture, 0 );
}
#endif
// =================================================================================================
// Viewport
// =================================================================================================
#ifdef D_PLATFORM_PC
#define SCREENSPACE_AS_RENDERTARGET_UVS( A ) A.xy
#elif defined(D_PLATFORM_ORBIS)
#define SCREENSPACE_AS_RENDERTARGET_UVS( A ) ( float2( A.x, 1.0 - A.y ) )
#endif
#ifdef D_USING_LOGDEPTH
#define D_DEPTH_CLEARVALUE (1.0)
#else
#define D_DEPTH_CLEARVALUE (0.0)
#endif
// =================================================================================================
// Texture usage feedback
// =================================================================================================
#if defined( D_TEXTURE_FEEDBACK ) && defined( D_PLATFORM_PC )
layout(r32i) uniform iimage2D gTexFeedbackImg;
void WriteTexFeedback( in int liCounter, in float liMip )
{
if( liCounter != 0 )
{
#if defined( GL_ARB_shader_ballot ) && ( GL_ARB_shader_ballot == 1 )
if( readFirstInvocationARB( gl_SubGroupInvocationARB ) == gl_SubGroupInvocationARB )
#endif
{
int liIntMip = int(floor(liMip));
//imageStore( gTexFeedbackImg, ivec2( liCounter, liIntMip ), ivec4(1,0,0,0) );
imageAtomicAdd( gTexFeedbackImg, ivec2( liCounter, liIntMip ), int(1) );
}
}
}
vec4 Tex2dFeedback( in sampler2D lSamp, in int liCounter, in vec2 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex2dLodFeedback( in sampler2D lSamp, in int liCounter, in vec2 lCoords, in float liLod )
{
WriteTexFeedback( liCounter, liLod );
return textureLod( lSamp, lCoords, liLod );
}
vec4 Tex2dArrayFeedback( in sampler2DArray lSamp, in int liCounter, in vec3 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords.xy ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex3dFeedback( in sampler3D lSamp, in int liCounter, in vec3 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex3dLodFeedback( in sampler3D lSamp, in int liCounter, in vec3 lCoords, in float liLod )
{
WriteTexFeedback( liCounter, liLod );
return textureLod( lSamp, lCoords, liLod );
}
#endif
#endif
//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------
// Global Data
//-----------------------------------------------------------------------------
///
/// CalculateFadeValue
///
/// @brief Hash
///
/// @param vec2 lPositionVec2
/// @return float
///
//-----------------------------------------------------------------------------
vec3
DecodeNormalMap(
vec4 lNormalTexVec4 )
{
lNormalTexVec4 = ( lNormalTexVec4 * ( 2.0 * 255.0 / 256.0 ) ) - 1.0;
return ( vec3( lNormalTexVec4.r, lNormalTexVec4.g, sqrt( max( 1.0 - lNormalTexVec4.r*lNormalTexVec4.r - lNormalTexVec4.g*lNormalTexVec4.g, 0.0 ) ) ) );
}
//-----------------------------------------------------------------------------
///
/// ReadDualParaboloidMap
///
/// @brief ReadDualParaboloidMap
///
/// @param lBackMap
/// @param lFrontMap
/// @param in vec3 lReflectionVec3
/// @return vec3
///
//-----------------------------------------------------------------------------
vec3
ReadDualParaboloidMap(
SAMPLER2DARG( lBackMap ),
SAMPLER2DARG( lFrontMap ),
in vec3 lReflectionVec3,
in int liMipLevel )
{
vec2 lEnvCoordsVec2;
lEnvCoordsVec2.xy = lReflectionVec3.xy / ( 1.0 + abs(lReflectionVec3.z) );
lEnvCoordsVec2.x = 0.5 * lEnvCoordsVec2.x + 0.5; //bias and scale to correctly sample a d3d texture
lEnvCoordsVec2.y = -0.5 * lEnvCoordsVec2.y + 0.5;
#if defined( D_PLATFORM_ORBIS )
//lEnvCoordsVec2.y = 1.0 - lFrontCoordsVec2.y;
#endif
// Potentially use clever math, and write them both to one image, ala Cascading Shadow Map
float lInEq = ( -lReflectionVec3.z + 1.0 );
float isBack = ( lReflectionVec3.x > -lInEq && lReflectionVec3.x < lInEq) &&
( lReflectionVec3.y > -lInEq && lReflectionVec3.y < lInEq) ? 1.0 : 0.0;
vec3 lEnvironmentMapBackVec3 = texture2DLod( lBackMap, lEnvCoordsVec2, float( liMipLevel ) ).xyz; // sample the front paraboloid map
vec3 lEnvironmentMapFrontVec3 = texture2DLod( lFrontMap, lEnvCoordsVec2, float( liMipLevel ) ).xyz; // sample the back paraboloid map
return lEnvironmentMapBackVec3 * isBack + lEnvironmentMapFrontVec3 * (1.0 - isBack);
}
//-----------------------------------------------------------------------------
///
/// GetUpperValue
///
///
//-----------------------------------------------------------------------------
float
GetUpperValue(
float lValue )
{
int a = int( lValue * 255 );
return ( float(a >> 4) / 16.0 );
}
//-----------------------------------------------------------------------------
///
/// GetLowerValue
///
///
//-----------------------------------------------------------------------------
float
GetLowerValue(
float lValue )
{
int a = int( lValue * 255 );
float lReturn = float( a & 0xf ) / 16.0;
lReturn = clamp( lReturn - GetUpperValue( lValue ), 0.0, 1.0 );
return lReturn;
}
#endif
////////////////////////////////////////////////////////////////////////////////
///
/// @file CommonGBuffer.h
/// @author User
/// @date
///
/// @brief CommonLighting
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Compilation defines
#ifndef D_COMMONGBUFFER_H
#define D_COMMONGBUFFER_H
//-----------------------------------------------------------------------------
// Include files
#define D_DETAILOVERLAY ( 1 << 0 )
#define D_NORECEIVESHADOW ( 1 << 1 )
#define D_DISABLE_POSTPROCESS ( 1 << 2 )
#define D_UNLIT ( 1 << 3 )
#define D_NOWATER ( 1 << 4 )
#define D_DISABLE_AMBIENT ( 1 << 5 )
#define D_EMBEDDED_SHADOW ( 1 << 6 )
#define D_CLAMP_AA ( 1 << 7 )
#define D_CLAMPAMBIENT ( 1 << 7 )
// =================================================================================================
#ifndef D_DEFINES
#define D_DEFINES
// =================================================================================================
// Platform defines
// =================================================================================================
#ifdef D_PLATFORM_PC
#define D_ENABLE_REVERSEZ_PROJECTION (1)
#pragma optionNV(strict on)
#extension GL_ARB_gpu_shader5 : enable
#extension GL_ARB_fragment_coord_conventions : enable
#extension GL_ARB_derivative_control : enable
#if defined( D_FRAGMENT ) && defined( _F64_ )
layout(early_fragment_tests) in;
#endif
#elif defined(D_PLATFORM_ORBIS)
#define D_ENABLE_REVERSEZ_PROJECTION (1)
// use this with sdk 2.0 compiler
// #pragma argument (allow-scratch-buffer-spill)
//define these flags so they don't get ignored in build process and in the comb mask
//this is because materials, vertex layouts and shaders need to be synced on 360 to avoid patching
#ifdef _F27_
#endif
#ifdef _F28_
#endif
#ifdef _F29_
#endif
#ifdef _F21_
#endif
#ifdef _F02_
#endif
#ifdef _F03_
#endif
#if defined( _F01_ ) || defined( D_LOD0 ) || defined( D_LOD1 ) || defined( D_LOD2 ) || defined( D_LOD3) || defined( D_LOD4 )
#endif
#ifdef _F01_
#endif
#ifdef _F09_
#endif
#ifdef _F10_
#endif
// disable warnings for unused parameters. This happens a lot because of defining different things.
#pragma warning (disable: 5203)
// temp thing to know what things are still required on ps4.
#define D_PLATFORM_ORBIS_FIX
#ifdef __PSSL_CS__
#define D_PLATFORM_ORBIS_COMPUTE
#endif
#ifdef __PSSL_HS__
#define D_HULL
#endif
#ifdef __PSSL_DS__
#define D_DOMAIN
#endif
#ifdef __PSSL_VS__
#define D_VERTEX
#endif
#ifdef __PSSL_GS__
#define D_GEOMETRY
#endif
#endif
#if !D_ENABLE_REVERSEZ_PROJECTION
#define D_USING_LOGDEPTH
#endif
// =================================================================================================
// Basic Types
// =================================================================================================
#ifdef D_PLATFORM_PC
#define JOINT_TYPE vec4
//#define CONST const
#define STATIC_CONST const
#elif defined(D_PLATFORM_ORBIS)
#define JOINT_TYPE int4
#define float float
#define vec2 float2
#define vec3 float3
#define vec4 float4
#define ivec2 int2
#define ivec3 int3
#define ivec4 int4
#define uvec2 uint2
#define uvec3 uint3
#define uvec4 uint4
// NOTE:
// operator[] accesses rows, not columns
// matrix constructors interpret the passed vectors as row vectors, not column vectors
#define mat2 row_major float2x2
#define mat3 row_major float3x3
#define mat4 row_major float4x4
//#define CONST
#define STATIC_CONST static const
// #define const ERROR, DON'T USE CONST FOR PS4. USE STATIC_CONST INSTEAD FOR A COMPILED IN CONSTANT. OTHERWISE IT TRIES TO PUT IT IN A CONSTANT BUFFER AND FOR SOME REASON IT DOESN'T WORK.
#endif
// =================================================================================================
// Functions
// =================================================================================================
#ifdef D_PLATFORM_PC
#define saturate( V ) min( max( V, 0.0) , 1.0)
#define atan2( Y, X ) atan( Y, X )
#define invsqrt( X ) inversesqrt( X )
#ifdef D_COMPUTE
#define groupID gl_WorkGroupID
#define groupThreadID gl_LocalInvocationID
#define dispatchThreadID gl_GlobalInvocationID
#endif
#elif defined(D_PLATFORM_ORBIS)
#if defined(D_PLATFORM_ORBIS_COMPUTE)
float dFdx( float var ) { float delta = var - LaneSwizzle( var, 0x1f, 0, 1 ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
float dFdy( float var ) { float delta = var - LaneSwizzle( var, 0x1f, 0, 8 ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec2 dFdx( vec2 var ) { vec2 delta = vec2( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec2 dFdy( vec2 var ) { vec2 delta = vec2( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec3 dFdx( vec3 var ) { vec3 delta = vec3( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec3 dFdy( vec3 var ) { vec3 delta = vec3( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec4 dFdx( vec4 var ) { vec4 delta = vec4( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.w, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec4 dFdy( vec4 var ) { vec4 delta = vec4( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.w, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
#define dFdxFine dFdx
#define dFdyFine dFdy
#else
#define dFdx ddx
#define dFdy ddy
#define dFdxFine ddx_fine
#define dFdyFine ddy_fine
#endif
#define mix lerp
#define fract frac
#define mod fmod
#define saturate( V ) ( min( max( V, 0.0) , 1.0) )
#define invsqrt( X ) rsqrt( X )
#endif
// =================================================================================================
// Samplers and textures
// =================================================================================================
#ifdef D_PLATFORM_PC
#define shadow2D( S, UV ) texture( S, UV )
#define SAMPLER2DSHADOW( NAME, REG ) uniform sampler2DShadow NAME
#define SAMPLERCUBE( NAME ) samplerCube NAME
#define SAMPLERCUBEARG( NAME ) in samplerCube NAME
#define SAMPLERCUBEPARAM( NAME ) NAME
#define imageAtomicAddOut( T, C, V, O ) O = imageAtomicAdd( T, C, V )
#if defined( D_TEXTURE_FEEDBACK )
#define texture2D( T, C ) Tex2dFeedback( T, T##FB, C )
#define texture2DLod( T, C, N ) Tex2dLodFeedback( T, T##FB, C, N )
#define texture2DArray( T, C ) Tex2dArrayFeedback( T, T##FB, C )
#define texture3D( S, UV ) Tex3dFeedback( S, S##FB, UV )
#define texture3DLod( S, UV, LOD ) Tex3dLodFeedback( S, S##FB, UV, LOD )
#define SAMPLER2DARG( NAME ) in sampler2D NAME, in int NAME##FB
#define SAMPLER2DPARAM( NAME ) NAME, NAME##FB
#define SAMPLER2DARRAYARG( NAME ) in sampler2DArray NAME, in int NAME##FB
#define SAMPLER2DARRAYPARAM( NAME ) NAME, NAME##FB
#define SAMPLER2D( NAME ) sampler2D NAME; int NAME##FB
#define SAMPLER2DARRAY( NAME ) sampler2DArray NAME; int NAME##FB
#define SAMPLER3D( NAME ) sampler3D NAME; int NAME##FB
#define SAMPLER2DSHADOW_SRT( NAME ) sampler2DShadow NAME; int NAME##FB
#else
#define texture2DLod( S, UV, LOD ) textureLod( S, UV, LOD )
#define texture3DLod( S, UV, LOD ) textureLod( S, UV, LOD )
#define SAMPLER2DARG( NAME ) in sampler2D NAME
#define SAMPLER2DPARAM( NAME ) NAME
#define SAMPLER2DARRAYARG( NAME ) in sampler2DArray NAME
#define SAMPLER2DARRAYPARAM( NAME ) NAME
#define SAMPLER2D( NAME ) sampler2D NAME
#define SAMPLER2DARRAY( NAME ) sampler2DArray NAME
#define SAMPLER3D( NAME ) sampler3D NAME
#define SAMPLER2DSHADOW_SRT( NAME ) sampler2DShadow NAME
#endif
#define textureGatherRed( lTex, lSamp ) textureGather( lTex, lSamp, 0 )
#define textureGatherGreen( lTex, lSamp ) textureGather( lTex, lSamp, 1 )
#define textureGatherBlue( lTex, lSamp ) textureGather( lTex, lSamp, 2 )
#define textureGatherAlpha( lTex, lSamp ) textureGather( lTex, lSamp, 3 )
#define texture2DComputeGrad( T, C ) texture2D( T, C )
#elif defined(D_PLATFORM_ORBIS)
#define SAMPLERCUBE( NAME, REG ) SamplerState NAME##SS : register( s##REG ); TextureCube NAME##TU : register( t##REG )
#define SAMPLER2D( NAME ) Texture2D NAME; SamplerState NAME##SS
#define SAMPLER2DSHADOW_SRT( NAME ) Texture2D NAME; SamplerComparisonState NAME##SS //SAMPLER2D( NAME )
#define SAMPLER3D( NAME ) Texture3D NAME; SamplerState NAME##SS
#define SAMPLER2DARRAY( NAME ) Texture2D_Array NAME; SamplerState NAME##SS
#define SAMPLER2DARRAYARG( NAME ) Texture2D_Array NAME, SamplerState NAME##SS
#define SAMPLER2DARRAYPARAM( NAME ) NAME, NAME##SS
#define SAMPLER2DPARAM( NAME ) NAME, NAME##SS
#define SAMPLER2DARG( NAME ) Texture2D NAME, SamplerState NAME##SS
#define texture2D( T, C ) T.Sample( T##SS, C )
#if defined(D_PLATFORM_ORBIS_COMPUTE)
#define texture2DComputeGrad( T, C ) T.SampleGradient( T##SS, C, vec2( dFdx( C ) ), vec2( dFdy( C ) ) )
#define shadow2D( T, C ) T.SampleCmpLOD0( T##SS, C.xy, C.z )
#else
#define texture2DComputeGrad( T, C ) T.Sample( T##SS, C )
#define shadow2D( T, C ) T.SampleCmp( T##SS, C.xy, C.z )
#endif
#define texture2DLod( T, C, N ) T.SampleLOD( T##SS, C, N )
#define texture2DArray( T, C ) T.Sample( T##SS, C )
#define texture3DLod( T, C, N ) T.SampleLOD( T##SS, C, N )
//#define shadow2D( T, C ) vec3( C.z > T.Sample( T##SS, C.xy ).x ? 1.0 : 0.0 )
//#define shadow2D( T, C ) T.GatherCmp( T##SS, C.xy, C.z )
//#define shadow2D( T, C ) T.SampleCmpLOD0( T##SS, C.xy, C.z )
#define textureCube( T, C ) T##TU.Sample( T##SS, C )
#define textureCubeLod( T, C, N ) T##TU.Sample( T##SS, C, N )
#define textureGrad( T, C, DDX, DDY ) T.SampleGradient( T##SS, C, DDX, DDY )
#define imageAtomicAdd( T, C, V ) AtomicAdd( T[ C ], V )
#define imageAtomicAddOut( T, C, V, O ) AtomicAdd( T[ C ], V, O )
#define imageStore( T, C, V ) ( T[C] = V )
#define textureGatherRed( lTex, lSamp ) lTex.GatherRed ( lTex##SS, lSamp )
#define textureGatherGreen( lTex, lSamp ) lTex.GatherGreen( lTex##SS, lSamp )
#define textureGatherBlue( lTex, lSamp ) lTex.GatherBlue ( lTex##SS, lSamp )
#define textureGatherAlpha( lTex, lSamp ) lTex.GatherAlpha( lTex##SS, lSamp )
#define texelFetch( lTex, lSamp, lLod ) lTex.MipMaps((lLod), (lSamp))
#endif
#if defined(D_PLATFORM_ORBIS_COMPUTE)
#define THREADGROUP_LOCAL thread_group_memory
#define THREADGROUP_BARRIER ThreadGroupMemoryBarrier()
#elif defined(D_PLATFORM_PC_COMPUTE)
#define THREADGROUP_LOCAL layout( shared )
#define THREADGROUP_BARRIER groupMemoryBarrier()
#endif
// =================================================================================================
// Matrices
// =================================================================================================
#ifdef D_PLATFORM_PC
#define MUL( INPUT_A, INPUT_B ) (INPUT_A * INPUT_B)
#define PLATFORM_TRANSPOSE
#define MAT4_SET_POS( M, P ) M[ 3 ] = P
#define MAT4_SET_TRANSLATION( M, T ) M[ 3 ].xyz = T
#define MAT4_GET_COLUMN( M, C ) M[ C ].xyz
#define MAT3_GET_COLUMN( M, C ) M[ C ]
#define MAT4_GET_COLUMN_VEC4( M, C ) M[ C ]
#define MAT3_SET_COLUMN( M, C, V ) M[ C ] = V;
#define MAT4_SET_COLUMN( M, C, V ) M[ C ] = V;
#elif defined(D_PLATFORM_ORBIS)
#define MUL( INPUT_A, INPUT_B ) mul( INPUT_B, INPUT_A )
#define PLATFORM_TRANSPOSE
#define MAT4_SET_POS( M, P ) M[ 3 ] = P
#define MAT4_SET_TRANSLATION( M, T ) M[ 3 ].xyz = T
#define MAT4_GET_COLUMN( M, C ) M[ C ].xyz
#define MAT3_GET_COLUMN( M, C ) M[ C ]
#define MAT4_GET_COLUMN_VEC4( M, C ) M[ C ]
#define MAT3_SET_COLUMN( M, C, V ) M[ C ] = V;
#define MAT4_SET_COLUMN( M, C, V ) M[ C ] = V;
#endif
// =================================================================================================
// Arrays (workaround AMD shader compiler issues by making arrays have global scope)
// =================================================================================================
#if defined(D_PLATFORM_ORBIS)
#define ARRAY_LOOKUP_FS( _UNIFORMS, _ELEMENT, _INDEX) _UNIFORMS._ELEMENT[_INDEX]
#define ARRAY_LOOKUP_FP( _UNIFORMS, _ELEMENT, _INDEX) _UNIFORMS._ELEMENT[_INDEX]
#else
#define ARRAY_LOOKUP_FS( _UNIFORMS, _ELEMENT, _INDEX) _ELEMENT[_INDEX]
#define ARRAY_LOOKUP_FP( _UNIFORMS, _ELEMENT, _INDEX) _ELEMENT[_INDEX]
#endif
// =================================================================================================
// Input and Output
// =================================================================================================
#ifdef D_PLATFORM_PC
#define UNIFORM( TYPE, NAME ) uniform TYPE NAME
#define UNIFORM_SRT( TYPE, NAME ) uniform TYPE NAME
#define DECLARE_INPUT
#define DECLARE_OUTPUT
#define DECLARE_END
#define DECLARE_PTR( TYPE, NAME ) TYPE NAME;
#define DECLARE_PATCH_INPUT_TRI
#define DECLARE_PATCH_OUTPUT_TRI
#define IN_PATCH_TRI_TESS_CONSTANTS
#define OUT_PATCH_TRI_TESS_CONSTANTS
#define DECLARE_PATCH_INPUT_QUAD
#define DECLARE_PATCH_OUTPUT_QUAD
#define IN_PATCH_QUAD_TESS_CONSTANTS
#define OUT_PATCH_QUAD_TESS_CONSTANTS
#if defined( D_HULL )
#define INPUT( TYPE, NAME, REG ) in TYPE NAME [];
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME [];
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME [];
#define PATCH_OUTPUT( TYPE, NAME, REG ) patch out TYPE NAME;
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME [];
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME [];
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME [];
#elif defined( D_DOMAIN )
#define PATCH_INPUT( TYPE, NAME, REG ) patch in TYPE NAME;
#define INPUT( TYPE, NAME, REG ) in TYPE NAME [];
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME [];
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME [];
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME;
#else
#define INPUT( TYPE, NAME, REG ) in TYPE NAME;
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME;
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME;
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME;
#endif
#define FRAGMENT_COLOUR_UVEC4_DEFINE layout(location = 0) out uvec4 outu_color0;
#define FRAGMENT_COLOUR_UVEC4 outu_color0
#define FRAGMENT_COLOUR out_color0
#define FRAGMENT_COLOUR0 out_color0
#define FRAGMENT_COLOUR1 out_color1
#define FRAGMENT_COLOUR2 out_color2
#define FRAGMENT_COLOUR3 out_color3
#define FRAGMENT_COLOUR4 out_color4
#if defined( D_TAA_RENDER_TARGETS )
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1; layout(location = 2) out vec4 out_color2;
#elif !defined(D_ATTRIBUTES)
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0;
#else
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1; layout(location = 2) out vec4 out_color2; layout(location = 3) out vec4 out_color3; layout(location = 4) out vec4 out_color4;
#endif
#define FRAGMENT_COLOUR01_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1;
#define FRAGMENT_DEPTH gl_FragDepth
#define FRAGMENT_FRONTFACE gl_FrontFacing
#define INPUT_FRONTFACING
#define DEREF_PTR( VAR ) VAR
#if defined( D_HULL )
#define IN( VAR ) VAR[ gl_InvocationID ]
#define OUT( VAR ) VAR[ gl_InvocationID ]
#define PATCH_OUT( VAR ) VAR
#define OUTPUT_VERTEX_SCREEN_POSITION gl_out[ gl_InvocationID ].gl_Position
#define INPUT_VERTEX_SCREEN_POSITION gl_in [ gl_InvocationID ].gl_Position
#define TESS_LEVEL_EDGE( IND ) gl_TessLevelOuter[ IND ]
#define TESS_LEVEL_INNER( IND ) gl_TessLevelInner[ IND ]
#elif defined( D_DOMAIN )
#define PATCH_IN( VAR, IND ) VAR[ IND ]
#define IN( VAR, IND ) VAR[ IND ]
#define OUT( VAR ) VAR
#define INPUT_VERTEX_SCREEN_POSITION( IND ) gl_in [ IND ].gl_Position
#define DOMAIN_COORDS gl_TessCoord
#elif defined( D_GEOMETRY )
#define OUTPUT_VERTEX_SCREEN_POSITION gl_Position
#define INPUT_VERTEX_SCREEN_POSITION( IND ) gl_in [ IND ].gl_Position
#define IN( VAR, IND ) VAR[ IND ]
#define OUT( VAR ) VAR
#else
#define IN( VAR ) VAR
#define OUT( VAR ) VAR
#endif
#define OUT_VERTEX_SCREEN_POSITION
#define IN_SCREEN_POSITION
#define VERTEX_SCREEN_POSITION gl_Position
#elif defined(D_PLATFORM_ORBIS_COMPUTE)
#define DECLARE_INPUT struct cInput {
#define DECLARE_END };
#define DECLARE_PTR( TYPE, NAME ) TYPE* NAME;
#define INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define INPUT_NOINTERP( TYPE, NAME, REG ) TYPE NAME : REG;
#define IN_SCREEN_POSITION
#define FRAGMENT_COLOUR lUniforms.mpCmpOutPerMesh.gOutTexture0[dispatchThreadID.xy]
#define FRAGMENT_COLOUR0 lUniforms.mpCmpOutPerMesh.gOutTexture0[dispatchThreadID.xy]
#define FRAGMENT_COLOUR1 lUniforms.mpCmpOutPerMesh.gOutTexture1[dispatchThreadID.xy]
#define FRAGMENT_COLOUR2 lUniforms.mpCmpOutPerMesh.gOutTexture2[dispatchThreadID.xy]
#define FRAGMENT_COLOUR3 lUniforms.mpCmpOutPerMesh.gOutTexture3[dispatchThreadID.xy]
#define FRAGMENT_COLOUR4 lUniforms.mpCmpOutPerMesh.gOutTexture4[dispatchThreadID.xy]
#define FRAGMENT_DEPTH lUniforms.mpCmpOutPerMesh.gOutTextureDepth[dispatchThreadID.xy]
#define DEREF_PTR( VAR ) *VAR
#elif defined(D_PLATFORM_ORBIS)
#define UNIFORM( TYPE, NAME ) ConstantBuffer NAME##CB{ TYPE NAME; };
#define UNIFORM_SRT( TYPE, NAME ) ConstantBuffer NAME##CB{ TYPE NAME : S_SRT_DATA; };
#define DECLARE_OUTPUT struct cOutput {
#define DECLARE_INPUT struct cInput {
#define DECLARE_END };
#define DECLARE_PTR( TYPE, NAME ) TYPE* NAME;
#define INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define INPUT_NOINTERP( TYPE, NAME, REG ) nointerp TYPE NAME : REG;
#define INPUT_NOPERSP( TYPE, NAME, REG ) nopersp TYPE NAME : REG;
#define OUTPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) nointerp TYPE NAME : REG;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) nopersp TYPE NAME : REG;
#define FRAGMENT_COLOUR_UVEC4_DEFINE
#define FRAGMENT_COLOUR_UVEC4 Out.mColour
#define FRAGMENT_COLOUR Out.mColour
#define FRAGMENT_COLOUR0 Out.mColour0
#define FRAGMENT_COLOUR1 Out.mColour1
#define FRAGMENT_COLOUR2 Out.mColour2
#define FRAGMENT_COLOUR3 Out.mColour3
#define FRAGMENT_COLOUR4 Out.mColour4
#define FRAGMENT_DEPTH Out.mDepth
#define FRAGMENT_FRONTFACE In.mbFrontFacing
#define INPUT_FRONTFACING bool mbFrontFacing : S_FRONT_FACE;
#if defined( D_HULL )
#define IN( VAR ) In[ uCPID ].VAR
#define OUT( VAR ) Out.VAR
#define PATCH_OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION IN( mScreenPositionVec4 )
#define TESS_LEVEL_EDGE( IND ) Out.edge_ts[ IND ]
#define TESS_LEVEL_INNER( IND ) Out.insi_ts[ IND ]
#define DECLARE_PATCH_OUTPUT_TRI [DOMAIN_PATCH_TYPE("tri")] struct HSConstantOutputData {
#define OUT_PATCH_TRI_TESS_CONSTANTS float edge_ts[3] : S_EDGE_TESS_FACTOR; \
float insi_ts[1] : S_INSIDE_TESS_FACTOR;
#define DECLARE_PATCH_OUTPUT_QUAD [DOMAIN_PATCH_TYPE("quad")] struct HSConstantOutputData (
#define OUT_PATCH_QUAD_TESS_CONSTANTS float edge_ts[4] : S_EDGE_TESS_FACTOR; \
float insi_ts[2] : S_INSIDE_TESS_FACTOR;
#define PATCH_OUTPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#elif defined( D_DOMAIN )
#define PATCH_IN( VAR, IND ) patchIn.VAR
#define IN( VAR, IND ) In[ IND ].VAR
#define OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION( IND ) IN( mScreenPositionVec4, IND )
#define DOMAIN_COORDS domainCoordinates
#define DECLARE_PATCH_INPUT_TRI [DOMAIN_PATCH_TYPE("tri")] struct HSConstantOutputData {
#define IN_PATCH_TRI_TESS_CONSTANTS float edge_ts[3] : S_EDGE_TESS_FACTOR; \
float insi_ts[1] : S_INSIDE_TESS_FACTOR;
#define DECLARE_PATCH_INPUT_QUAD [DOMAIN_PATCH_TYPE("quad")] struct HSConstantOutputData {
#define IN_PATCH_QUAD_TESS_CONSTANTS float edge_ts[4] : S_EDGE_TESS_FACTOR; \
float insi_ts[2] : S_INSIDE_TESS_FACTOR;
#define PATCH_INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#elif defined( D_GEOMETRY )
#define IN( VAR, IND ) In[ IND ].VAR
#define OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION( IND ) IN( mScreenPositionVec4, IND )
#define EMIT_VERTEX TriStream.Append( Out )
#define END_PRIMITIVE TriStream.RestartStrip()
#else
#define IN( VAR ) In.VAR
#define OUT( VAR ) Out.VAR
#endif
// TODO get rid of this - don't pass struct through functinos, pass members.
#define DEREF_PTR( VAR ) *VAR
#define OUT_VERTEX_SCREEN_POSITION OUTPUT( vec4, mScreenPositionVec4, S_POSITION )
#define IN_SCREEN_POSITION INPUT ( vec4, mScreenPositionVec4, S_POSITION )
#define VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#endif
// =================================================================================================
// Main
// =================================================================================================
#ifdef D_PLATFORM_PC
#define VERTEX_MAIN void main( void )
#define VERTEX_MAIN_SRT uniform UniformBuffer lUniforms; void main( void )
#define HULL_TRI_MAIN_SRT layout( vertices = 3 ) out; uniform UniformBuffer lUniforms; void main( void )
#define HULL_QUAD_MAIN_SRT layout( vertices = 4 ) out; uniform UniformBuffer lUniforms; void main( void )
#define DOMAIN_TRI_MAIN_SRT layout( triangles, fractional_even_spacing ) in; uniform UniformBuffer lUniforms; void main( void )
#define DOMAIN_QUAD_MAIN_SRT layout( quads, fractional_even_spacing ) in; uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define VOID_MAIN_COLOUR FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_GE_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_LE_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_EARLYZ_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_UICOLOUR_SRT FRAGMENT_COLOUR_UVEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define VOID_MAIN_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define VOID_MAIN_DEPTH_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR01_SRT FRAGMENT_COLOUR01_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR01_DEPTH_SRT FRAGMENT_COLOUR01_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#elif defined( D_PLATFORM_PC_COMPUTE )
#define COMPUTE_MAIN_SRT( X, Y, Z ) layout (local_size_x = X, local_size_y = Y, local_size_z = Z) in; void main( void )
#define FRAGMENT_MAIN_COLOUR_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR01_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#elif defined( D_PLATFORM_ORBIS_COMPUTE )
#define COMPUTE_MAIN_SRT( X, Y, Z ) [NUM_THREADS(X, Y, Z)] void main(uint3 groupID : S_GROUP_ID, uint3 groupThreadID : S_GROUP_THREAD_ID, uint3 dispatchThreadID : S_DISPATCH_THREAD_ID, UniformBuffer lUniforms : S_SRT_DATA)
#define FRAGMENT_MAIN_COLOUR_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR01_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#elif defined( D_PLATFORM_ORBIS )
#define VERTEX_MAIN void main( cInput In, out cOutput Out )
#define VERTEX_MAIN_SRT void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define HULL_TRI_MAIN_SRT [DOMAIN_PATCH_TYPE("tri")] \
[PARTITIONING_TYPE("integer")] \
[OUTPUT_TOPOLOGY_TYPE("triangle_cw")] \
[OUTPUT_CONTROL_POINTS(3)] \
[PATCH_CONSTANT_FUNC("ConstantsHS")] \
[MAX_TESS_FACTOR(16.0)] \
void main( \
InputPatch<cInput, 3> In, \
uint uCPID : S_OUTPUT_CONTROL_POINT_ID, \
UniformBuffer lUniforms : S_SRT_DATA, \
out cOutput Out )
#define HULL_QUAD_MAIN_SRT [DOMAIN_PATCH_TYPE("quad")] \
[PARTITIONING_TYPE("integer")] \
[OUTPUT_TOPOLOGY_TYPE("triangle_cw")] \
[OUTPUT_CONTROL_POINTS(4)] \
[PATCH_CONSTANT_FUNC("ConstantsHS")] \
[MAX_TESS_FACTOR(16.0)] \
void main( \
InputPatch<cInput, 4> In, \
uint uCPID : S_OUTPUT_CONTROL_POINT_ID, \
UniformBuffer lUniforms : S_SRT_DATA, \
out cOutput Out )
#define DOMAIN_TRI_MAIN_SRT [DOMAIN_PATCH_TYPE("tri")] \
void main( \
HSConstantOutputData patchIn, \
const OutputPatch<cInput, 3> In, \
out cOutput Out, \
UniformBuffer lUniforms : S_SRT_DATA, \
float3 domainCoordinates : S_DOMAIN_LOCATION )
#define DOMAIN_QUAD_MAIN_SRT [DOMAIN_PATCH_TYPE("quad")] \
void main( \
HSConstantOutputData patchIn, \
const OutputPatch<cInput, 4> In, \
out cOutput Out, \
UniformBuffer lUniforms : S_SRT_DATA, \
float2 domainCoordinates : S_DOMAIN_LOCATION )
#define GEOMETRY_MAIN_SRT( MAX_VERTS ) cOutput Out; [MAX_VERTEX_COUNT(MAX_VERTS)] void main( inout TriangleBuffer<cOutput> TriStream, Triangle cInput In[3], UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out )
#define VOID_MAIN_COLOUR struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; void main( cInput In, out cOutput Out )
#define FRAGMENT_MAIN_COLOUR_DEPTH struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out )
#define VOID_MAIN_SRT void main( cInput In, UniformBuffer lUniforms : S_SRT_DATA )
#if defined( D_TAA_RENDER_TARGETS )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#elif !defined( D_ATTRIBUTES )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_DEPTH_GE_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_GE_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_DEPTH_LE_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_LE_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define VOID_MAIN_DEPTH_SRT struct cOutput { float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define VOID_MAIN_COLOUR_EARLYZ_SRT [FORCE_EARLY_DEPTH_STENCIL] void main( cInput In, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR01_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR01_DEPTH_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
float mDepth : S_DEPTH_OUTPUT; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#else
// #pragma PSSL_target_output_format(target 1 FMT_32_AR)
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; \
float mDepth : S_DEPTH_OUTPUT; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_EARLYZ_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; }; \
[FORCE_EARLY_DEPTH_STENCIL] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#endif
#endif
// =================================================================================================
// Texture resolution
// =================================================================================================
#ifdef D_PLATFORM_ORBIS
uvec2 GetResolution( Texture2D lTexture )
{
uvec2 lResolution;
lTexture.GetDimensionsFast(lResolution.x, lResolution.y);
return lResolution;
}
uvec2 GetResolution( RW_Texture2D<float4> lTexture )
{
uvec2 lResolution;
lTexture.GetDimensionsFast(lResolution.x, lResolution.y);
return lResolution;
}
#else
uvec2 GetResolution( sampler2D lTexture )
{
return textureSize( lTexture, 0 );
}
#endif
// =================================================================================================
// Viewport
// =================================================================================================
#ifdef D_PLATFORM_PC
#define SCREENSPACE_AS_RENDERTARGET_UVS( A ) A.xy
#elif defined(D_PLATFORM_ORBIS)
#define SCREENSPACE_AS_RENDERTARGET_UVS( A ) ( float2( A.x, 1.0 - A.y ) )
#endif
#ifdef D_USING_LOGDEPTH
#define D_DEPTH_CLEARVALUE (1.0)
#else
#define D_DEPTH_CLEARVALUE (0.0)
#endif
// =================================================================================================
// Texture usage feedback
// =================================================================================================
#if defined( D_TEXTURE_FEEDBACK ) && defined( D_PLATFORM_PC )
layout(r32i) uniform iimage2D gTexFeedbackImg;
void WriteTexFeedback( in int liCounter, in float liMip )
{
if( liCounter != 0 )
{
#if defined( GL_ARB_shader_ballot ) && ( GL_ARB_shader_ballot == 1 )
if( readFirstInvocationARB( gl_SubGroupInvocationARB ) == gl_SubGroupInvocationARB )
#endif
{
int liIntMip = int(floor(liMip));
//imageStore( gTexFeedbackImg, ivec2( liCounter, liIntMip ), ivec4(1,0,0,0) );
imageAtomicAdd( gTexFeedbackImg, ivec2( liCounter, liIntMip ), int(1) );
}
}
}
vec4 Tex2dFeedback( in sampler2D lSamp, in int liCounter, in vec2 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex2dLodFeedback( in sampler2D lSamp, in int liCounter, in vec2 lCoords, in float liLod )
{
WriteTexFeedback( liCounter, liLod );
return textureLod( lSamp, lCoords, liLod );
}
vec4 Tex2dArrayFeedback( in sampler2DArray lSamp, in int liCounter, in vec3 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords.xy ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex3dFeedback( in sampler3D lSamp, in int liCounter, in vec3 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex3dLodFeedback( in sampler3D lSamp, in int liCounter, in vec3 lCoords, in float liLod )
{
WriteTexFeedback( liCounter, liLod );
return textureLod( lSamp, lCoords, liLod );
}
#endif
#endif
////////////////////////////////////////////////////////////////////////////////
///
/// @file Common.h
/// @author User
/// @date
///
/// @brief Common
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
#ifndef D_COMMON_H
#define D_COMMON_H
#define D_TERRAINCOLOURARRAY_SIZE 23
STATIC_CONST vec3 kGammaOutVec3 = vec3( 1.0 / 2.2 );
STATIC_CONST vec3 kGammaInVec3 = vec3( 2.2 );
STATIC_CONST vec4 RGBToHSV_K = vec4( 0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0 );
STATIC_CONST vec4 HSVToRGB_K = vec4( 1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0 );
#ifdef D_PLATFORM_ORBIS
STATIC_CONST float3x3 BT709_TO_BT2020 = float3x3( //ref: ARIB STD-B62 and BT.2087
#else
STATIC_CONST mat3 BT709_TO_BT2020 = mat3( //ref: ARIB STD-B62 and BT.2087
#endif
0.6274, 0.3293, 0.0433,
0.0691, 0.9195, 0.0114,
0.0164, 0.0880, 0.8956
);
#ifdef D_PLATFORM_ORBIS
STATIC_CONST float3x3 BT2020_TO_BT709 = float3x3(
#else
STATIC_CONST mat3 BT2020_TO_BT709 = mat3(
#endif
1.6605, -0.5877, -0.0728,
-0.1246, 1.1330, -0.0084,
-0.0182, -0.1006, 1.1187
);
//-----------------------------------------------------------------------------
///
/// GammaCorrect
///
//-----------------------------------------------------------------------------
vec3
GammaCorrectInput(
in vec3 lColourVec3 )
{
vec3 lCorrectColourVec3;
lCorrectColourVec3 = lColourVec3 * ( lColourVec3 * ( lColourVec3 * vec3( 0.305306011 ) + vec3( 0.682171111 ) ) + vec3( 0.012522878 ) );
return lCorrectColourVec3;
}
//-----------------------------------------------------------------------------
///
/// GammaCorrect
///
//-----------------------------------------------------------------------------
vec3
GammaCorrectOutput(
in vec3 lColourVec3 )
{
vec3 lCorrectColourVec3;
lCorrectColourVec3 = pow( lColourVec3, kGammaOutVec3 );
return lCorrectColourVec3;
}
//-----------------------------------------------------------------------------
///
/// RGBToHSV
///
//-----------------------------------------------------------------------------
vec3
RGBToHSV(
vec3 lRGB )
{
//vec4 p = mix( vec4(lRGB.bg, RGBToHSV_K.wz), vec4(lRGB.gb, RGBToHSV_K.xy), step(lRGB.b, lRGB.g) );
//vec4 q = mix( vec4(p.xyw, lRGB.r), vec4(lRGB.r, p.yzx), step(p.x, lRGB.r) );
// This variant is faster, since it generates conditional moves
vec4 p = lRGB.g < lRGB.b ? vec4(lRGB.bg, RGBToHSV_K.wz) : vec4(lRGB.gb, RGBToHSV_K.xy);
vec4 q = lRGB.r < p.x ? vec4(p.xyw, lRGB.r) : vec4(lRGB.r, p.yzx);
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
//-----------------------------------------------------------------------------
///
/// HSVToRGB
///
/// @brief http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
///
//-----------------------------------------------------------------------------
vec3
HSVToRGB(
vec3 lHSV )
{
vec3 p = abs(fract(lHSV.xxx + HSVToRGB_K.xyz) * 6.0 - HSVToRGB_K.www);
return lHSV.z * mix(HSVToRGB_K.xxx, saturate(p - HSVToRGB_K.xxx), lHSV.y);
}
//-----------------------------------------------------------------------------
///
/// HDR ( Perceptual Quantizer(PQ), Rec. 2020 color space. ) helpers
///
//------------------------------------------------------------------------------
#ifdef D_PLATFORM_PC
float CndMask(bool cnd, float src0, float src1)
{
return cnd ? src0 : src1;
}
#endif
STATIC_CONST float kRefWhiteLevel = 100.0;
vec4 SRGB_OETF(vec4 L)
{
vec3 dark = L.xyz * 12.92;
vec3 light = 1.055 * pow(L.xyz, vec3(1.0 / 2.4)) - 0.055;
vec4 r;
r.x = CndMask(L.x <= 0.0031308, dark.x, light.x);
r.y = CndMask(L.y <= 0.0031308, dark.y, light.y);
r.z = CndMask(L.z <= 0.0031308, dark.z, light.z);
r.w = L.w;
return r;
}
vec4 SRGB_EOTF(vec4 E)
{
vec3 dark = E.xyz / 12.92;
vec3 light = pow((E.xyz + 0.055) / (1 + 0.055), vec3(2.4));
vec4 r;
r.x = CndMask(E.x <= 0.04045, dark.x, light.x);
r.y = CndMask(E.y <= 0.04045, dark.y, light.y);
r.z = CndMask(E.z <= 0.04045, dark.z, light.z);
r.w = E.w;
return r;
}
//apply gamma adjustment to (minL, maxL).
vec4 GammaAdjOOTF(vec4 L, float minLNits, float maxLNits, float gamma, bool inverse)
{
vec3 nits = L.xyz * kRefWhiteLevel;
vec4 i = vec4((nits - minLNits) / (maxLNits - minLNits), 1.0);
vec3 j;
if (inverse){
j = SRGB_EOTF(pow(i, vec4(1 / gamma))).xyz;
}
else{
j = pow(SRGB_OETF(i).xyz,vec3(gamma));
}
vec3 adj = (minLNits + (maxLNits - minLNits) * j) / kRefWhiteLevel;
vec4 ret;
ret.x = CndMask(nits.x >= minLNits && nits.x < maxLNits, adj.x, L.x);
ret.y = CndMask(nits.y >= minLNits && nits.y < maxLNits, adj.y, L.y);
ret.z = CndMask(nits.z >= minLNits && nits.z < maxLNits, adj.z, L.z);
ret.w = L.w;
return ret;
}
//input: normalized L in units of RefWhite (1.0=100nits), output: normalized E
vec4 PQ_OETF(vec4 L, uint gamma_adj, float gamma)
{
if (gamma_adj != 0)
L = GammaAdjOOTF(L, 0.0, 300.0, gamma, false);
const float c1 = 0.8359375;//3424.f/4096.f;
const float c2 = 18.8515625;//2413.f/4096.f*32.f;
const float c3 = 18.6875; //2392.f/4096.f*32.f;
const float m1 = 0.159301758125; //2610.f / 4096.f / 4;
const float m2 = 78.84375;// 2523.f / 4096.f * 128.f;
L = L * kRefWhiteLevel / 10000.0;
vec3 Lm1 = pow(L.xyz, vec3(m1));
vec3 X = (c1 + c2 * Lm1) / (1 + c3 * Lm1);
vec4 res = vec4(pow(X, vec3(m2)), L.w);
return res;
}
//input: normalized E (0.0, 1.0), output: normalized L in units of RefWhite
vec4 PQ_EOTF(vec4 E, uint gamma_adj, float gamma)
{
const float c1 = 0.8359375;//3424.f/4096.f;
const float c2 = 18.8515625;//2413.f/4096.f*32.f;
const float c3 = 18.6875; //2392.f/4096.f*32.f;
const float m1 = 0.159301758125; //2610.f / 4096.f / 4;
const float m2 = 78.84375;// 2523.f / 4096.f * 128.f;
vec3 M = c2 - c3 * pow(E.xyz, vec3(1 / m2));
vec3 N = max(pow(E.xyz, vec3(1 / m2)) - c1, 0);
vec3 L = pow(N / M, vec3(1 / m1)); //normalized nits (1.0 = 10000nits)
L = L * 10000.0 / kRefWhiteLevel; //convert to normalized L in units of RefWhite
return (gamma_adj !=0) ? GammaAdjOOTF(vec4(L, E.w), 0.0, 300.0, gamma, true) : vec4(L, E.w);
}
// PQ OETF fast approximation
// http://www.glowybits.com/blog/2017/01/04/ifl_iss_hdr_2/
vec3 PQ_OETF_Fast(vec3 x)
{
x = (x * (x * (x * (x * (x * 533095.76 + 47438306.2) + 29063622.1) + 575216.76) + 383.09104) + 0.000487781) /
(x * (x * (x * (x * 66391357.4 + 81884528.2) + 4182885.1) + 10668.404) + 1.0);
return x;
}
//-----------------------------------------------------------------------------
///
/// BrightnessVibranceContrast
///
//-----------------------------------------------------------------------------
vec3 BrightnessVibranceContrast(
vec3 lInputColour,
float lfBrightness,
float lfVibrance,
float lfContrast)
{
vec3 lBrtResult = lInputColour * lfBrightness;
// get lum
vec3 lLuma = vec3( dot(lBrtResult, vec3( 0.2125, 0.7154, 0.0721 )) );
// get saturation
float lfMaxCol = max( lBrtResult.r, max(lBrtResult.g, lBrtResult.b) );
float lfMinCol = min( lBrtResult.r, min(lBrtResult.g, lBrtResult.b) );
float lfCurSatV = lfMaxCol - lfMinCol;
// lerp by 1 + (1 - vibrance) - current saturation
float lfVibranceMix = (1.0 + (lfVibrance * (1.0 - (sign(lfVibrance) * lfCurSatV))));
vec3 lVibResult = mix( lLuma, lBrtResult, lfVibranceMix );
// lerp from mid gray for contrast
vec3 lContrastBase = vec3( 0.5, 0.5, 0.5 );
vec3 lConResult = mix( lContrastBase , lVibResult, lfContrast );
return lConResult;
}
//-----------------------------------------------------------------------------
///
/// Desaturate
///
//-----------------------------------------------------------------------------
vec3 Desaturate( vec3 color, float lfAmount )
{
vec3 gray = vec3( dot( vec3( 0.299, 0.587, 0.114 ), color) );
return mix( color, gray, lfAmount );
}
// improved rgb lerp by @stormoid
// https://www.shadertoy.com/view/lsdGzN
//---------------Improved RGB--------------
/*
The idea behind this function is to avoid the low saturation area in the
rgb color space. This is done by getting the direction to that diagonal
and displacing the interpolated color by it's inverse while scaling it
by saturation error and desired lightness.
I find it behaves very well under most circumstances, the only instance
where it doesn't behave ideally is when the hues are very close to 180
degrees apart, since the method I am using to find the displacement vector
does not compensate for non-curving motion. I tried a few things to
circumvent this problem but none were cheap and effective enough..
*/
//Changes the strength of the displacement
#define DSP_STR 1.5
//-----------------------------------------------------------------------------
float _getsat( vec3 lColour )
{
float mi = min(min(lColour.x, lColour.y), lColour.z);
float ma = max(max(lColour.x, lColour.y), lColour.z);
return (ma - mi) / (ma + 1e-7);
}
vec3 NmzRgbLerp( vec3 a, vec3 b, float x )
{
// interpolated base color (with singularity fix)
vec3 ic = mix( a, b, x ) + vec3( 1e-6, 0.0, 0.0 );
// saturation difference from ideal scenario
float sd = abs( _getsat( ic ) - mix( _getsat( a ), _getsat( b ), x ) );
// displacement direction
vec3 dir = normalize(
vec3( 2.0 * ic.x - ic.y - ic.z,
2.0 * ic.y - ic.x - ic.z,
2.0 * ic.z - ic.y - ic.x )
);
// simple Lighntess
float lgt = dot( vec3( 1.0 ), ic );
// extra scaling factor for the displacement
float ff = dot( dir, normalize( ic ) );
// displace the color
ic += DSP_STR * dir * sd * ff * lgt;
return clamp( ic, 0.0, 1.0 );
}
//-----------------------------------------------------------------------------
///
/// Inverse
///
//-----------------------------------------------------------------------------
mat4
Inverse(
const mat4 lInMat4 )
{
#ifdef D_PLATFORM_PC
return inverse( lInMat4 );
#else
float det = determinant( lInMat4 );
det = 1.0f / det;
mat4 M = lInMat4;
mat4 IM;
IM[0][0] = det * ( M[1][2]*M[2][3]*M[3][1] - M[1][3]*M[2][2]*M[3][1] + M[1][3]*M[2][1]*M[3][2] - M[1][1]*M[2][3]*M[3][2] - M[1][2]*M[2][1]*M[3][3] + M[1][1]*M[2][2]*M[3][3] );
IM[0][1] = det * ( M[0][3]*M[2][2]*M[3][1] - M[0][2]*M[2][3]*M[3][1] - M[0][3]*M[2][1]*M[3][2] + M[0][1]*M[2][3]*M[3][2] + M[0][2]*M[2][1]*M[3][3] - M[0][1]*M[2][2]*M[3][3] );
IM[0][2] = det * ( M[0][2]*M[1][3]*M[3][1] - M[0][3]*M[1][2]*M[3][1] + M[0][3]*M[1][1]*M[3][2] - M[0][1]*M[1][3]*M[3][2] - M[0][2]*M[1][1]*M[3][3] + M[0][1]*M[1][2]*M[3][3] );
IM[0][3] = det * ( M[0][3]*M[1][2]*M[2][1] - M[0][2]*M[1][3]*M[2][1] - M[0][3]*M[1][1]*M[2][2] + M[0][1]*M[1][3]*M[2][2] + M[0][2]*M[1][1]*M[2][3] - M[0][1]*M[1][2]*M[2][3] );
IM[1][0] = det * ( M[1][3]*M[2][2]*M[3][0] - M[1][2]*M[2][3]*M[3][0] - M[1][3]*M[2][0]*M[3][2] + M[1][0]*M[2][3]*M[3][2] + M[1][2]*M[2][0]*M[3][3] - M[1][0]*M[2][2]*M[3][3] );
IM[1][1] = det * ( M[0][2]*M[2][3]*M[3][0] - M[0][3]*M[2][2]*M[3][0] + M[0][3]*M[2][0]*M[3][2] - M[0][0]*M[2][3]*M[3][2] - M[0][2]*M[2][0]*M[3][3] + M[0][0]*M[2][2]*M[3][3] );
IM[1][2] = det * ( M[0][3]*M[1][2]*M[3][0] - M[0][2]*M[1][3]*M[3][0] - M[0][3]*M[1][0]*M[3][2] + M[0][0]*M[1][3]*M[3][2] + M[0][2]*M[1][0]*M[3][3] - M[0][0]*M[1][2]*M[3][3] );
IM[1][3] = det * ( M[0][2]*M[1][3]*M[2][0] - M[0][3]*M[1][2]*M[2][0] + M[0][3]*M[1][0]*M[2][2] - M[0][0]*M[1][3]*M[2][2] - M[0][2]*M[1][0]*M[2][3] + M[0][0]*M[1][2]*M[2][3] );
IM[2][0] = det * ( M[1][1]*M[2][3]*M[3][0] - M[1][3]*M[2][1]*M[3][0] + M[1][3]*M[2][0]*M[3][1] - M[1][0]*M[2][3]*M[3][1] - M[1][1]*M[2][0]*M[3][3] + M[1][0]*M[2][1]*M[3][3] );
IM[2][1] = det * ( M[0][3]*M[2][1]*M[3][0] - M[0][1]*M[2][3]*M[3][0] - M[0][3]*M[2][0]*M[3][1] + M[0][0]*M[2][3]*M[3][1] + M[0][1]*M[2][0]*M[3][3] - M[0][0]*M[2][1]*M[3][3] );
IM[2][2] = det * ( M[0][1]*M[1][3]*M[3][0] - M[0][3]*M[1][1]*M[3][0] + M[0][3]*M[1][0]*M[3][1] - M[0][0]*M[1][3]*M[3][1] - M[0][1]*M[1][0]*M[3][3] + M[0][0]*M[1][1]*M[3][3] );
IM[2][3] = det * ( M[0][3]*M[1][1]*M[2][0] - M[0][1]*M[1][3]*M[2][0] - M[0][3]*M[1][0]*M[2][1] + M[0][0]*M[1][3]*M[2][1] + M[0][1]*M[1][0]*M[2][3] - M[0][0]*M[1][1]*M[2][3] );
IM[3][0] = det * ( M[1][2]*M[2][1]*M[3][0] - M[1][1]*M[2][2]*M[3][0] - M[1][2]*M[2][0]*M[3][1] + M[1][0]*M[2][2]*M[3][1] + M[1][1]*M[2][0]*M[3][2] - M[1][0]*M[2][1]*M[3][2] );
IM[3][1] = det * ( M[0][1]*M[2][2]*M[3][0] - M[0][2]*M[2][1]*M[3][0] + M[0][2]*M[2][0]*M[3][1] - M[0][0]*M[2][2]*M[3][1] - M[0][1]*M[2][0]*M[3][2] + M[0][0]*M[2][1]*M[3][2] );
IM[3][2] = det * ( M[0][2]*M[1][1]*M[3][0] - M[0][1]*M[1][2]*M[3][0] - M[0][2]*M[1][0]*M[3][1] + M[0][0]*M[1][2]*M[3][1] + M[0][1]*M[1][0]*M[3][2] - M[0][0]*M[1][1]*M[3][2] );
IM[3][3] = det * ( M[0][1]*M[1][2]*M[2][0] - M[0][2]*M[1][1]*M[2][0] + M[0][2]*M[1][0]*M[2][1] - M[0][0]*M[1][2]*M[2][1] - M[0][1]*M[1][0]*M[2][2] + M[0][0]*M[1][1]*M[2][2] );
return IM;
#endif
}
float
lengthSquared( vec3 lInVec3 )
{
return dot( lInVec3, lInVec3 );
}
#endif
////////////////////////////////////////////////////////////////////////////////
///
/// @file CommonDepth.h
/// @author User
/// @date
///
/// @brief CommonDepth
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Compilation defines
#ifndef D_COMMONDEPTH_H
#define D_COMMONDEPTH_H
//-----------------------------------------------------------------------------
// Include files
//#include "Common/CommonUniforms.shader.h"
//-----------------------------------------------------------------------------
// Global Data
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
///
/// LinearToLogDepth
///
/// @brief LinearToLogDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
#ifdef D_USING_LOGDEPTH
vec4
LinearToLogDepth_Vertex(
in vec4 lClipPlanes,
in vec4 lScreenPos )
{
vec4 lLogScreenPos = lScreenPos;
float kfFarPlane = lClipPlanes.y;
float FC = lClipPlanes.z; // 2.0 / log2(farplane + 1.0)
float lfLogz = log2( max( 1e-6, lScreenPos.w + 1 ) ) * FC - 1.0;
lLogScreenPos.z = ( lfLogz ) * lScreenPos.w;
return lLogScreenPos;
}
//-----------------------------------------------------------------------------
///
/// LinearToLogDepth_Pixel
///
/// @brief LinearToLogDepth_Pixel
///
/// @param in float lfLogZ
/// @param in vec4 lClipPlanes
/// @return float
///
//-----------------------------------------------------------------------------
float
LinearToLogDepth_Pixel(
in float lfLogZ,
in vec4 lClipPlanes )
{
return log2( lfLogZ ) * lClipPlanes.w; // 1.0 / log2(farplane + 1.0)
}
//-----------------------------------------------------------------------------
///
/// LogToLinearDepth
///
/// @brief LogToLinearDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
LogToLinearDepth2(
in vec4 lClipPlanes,
float lfLogDepth )
{
return exp2( lfLogDepth / lClipPlanes.w ); // 1.0 / log2(farplane + 1.0)
}
//-----------------------------------------------------------------------------
///
/// LogToLinearDepth
///
/// @brief LogToLinearDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
#if 0
float
LogToLinearDepth(
in vec4 lClipPlanes,
float lfLogDepth )
{
float kfNearClip = lClipPlanes.x;
float kfFar = lClipPlanes.y;
float kfFarClip = 1.0 / log( kfFar*kfNearClip + 1.0 );
float lfLinearDepth = ( exp( lfLogDepth/kfFarClip ) - 1.0 ) / kfNearClip;
return lfLinearDepth;
}
#else
float
LogToLinearDepth(
in vec4 lClipPlanesR,
float lfLogDepth )
{
float lfLinearDepth = ( exp2( lfLogDepth*lClipPlanesR.z ) - 1.0 ) * lClipPlanesR.x;
return lfLinearDepth;
}
#endif
#else
vec4
LinearToLogDepth_Vertex(
in vec4 lClipPlanes,
in vec4 lScreenPos)
{
// This is a NOP with ReverseZ
return lScreenPos;
}
float
ReverseZToLinearDepth(
in vec4 lClipPlanes,
float lfDepth)
{
float zNear = lClipPlanes.x;
float zFar = lClipPlanes.y;
return zNear * zFar / ( zNear + lfDepth * (zFar - zNear));
}
float
ReverseZToLinearDepthNorm(
in vec4 lClipPlanes,
float lfDepth)
{
float zNear = lClipPlanes.x;
float zFar = lClipPlanes.y;
return zNear / (zNear + lfDepth * (zFar - zNear));
}
float
LinearToReverseZDepth(
in vec4 lClipPlanes,
float lfDepth)
{
float zNear = lClipPlanes.x;
float zFar = lClipPlanes.y;
return ( zNear * zFar / lfDepth - zNear ) / ( zFar - zNear );
}
#endif
#if 0
// These are no longer used
//-----------------------------------------------------------------------------
///
/// NormaliseDepth
///
/// @brief LogToLinearDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
NormaliseDepth(
in vec4 lClipPlanes,
float lfDepth )
{
float kfNearClip = lClipPlanes.x;
float kfFar = lClipPlanes.y;
return (lfDepth - kfNearClip) / (kfFar-kfNearClip);
}
//-----------------------------------------------------------------------------
///
/// NormaliseDepth
///
/// @brief LogToLinearDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
DenormaliseDepth(
in vec4 lClipPlanes,
float lfDepth )
{
float kfNearClip = lClipPlanes.x;
float kfFar = lClipPlanes.y;
return lfDepth * ( kfFar-kfNearClip ) + kfNearClip;
}
#endif
//-----------------------------------------------------------------------------
///
/// FastNormaliseDepth
///
/// @brief FastNormaliseDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
FastNormaliseDepth(
in vec4 lClipPlanesR,
float lfDepth )
{
float kfRecip_Far = lClipPlanesR.y;
return (lfDepth * kfRecip_Far);
}
//-----------------------------------------------------------------------------
///
/// FastDenormaliseDepth
///
/// @brief FastDenormaliseDepth
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
FastDenormaliseDepth(
in vec4 lClipPlanes,
float lfDepth )
{
float kfFar = lClipPlanes.y;
return lfDepth * kfFar;
}
//-----------------------------------------------------------------------------
///
/// EncodeDepthToColour
///
/// @brief EncodeDepthToColour
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
vec4
EncodeDepthToColour(
float lDepth )
{
#if 0
vec4 enc = vec4( 1.0, 255.0, 65025.0, 16581375.0 ) * vec4(lDepth);
enc = fract(enc);
enc.xyz -= enc.yzw * vec3( 1.0f/255.0, 1.0f/255.0, 1.0f/255.0 );
return enc;
#else
return vec4(lDepth,0.0,0.0,0.0);
#endif
}
//-----------------------------------------------------------------------------
///
/// DecodeDepthFromColour
///
/// @brief DecodeDepthFromColour
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
DecodeDepthFromColour(
vec4 lColour )
{
#if 0
return dot( lColour, vec4( 1.0, 1.0f/255.0, 1.0f/65025.0, 1.0 / 16581375.0 ) );
#else
return lColour.x;
#endif
}
vec3
RecreatePositionFromDepthWithIVP(
in float lfDepth,
in vec2 lFragCoordsVec2,
in vec3 lViewPosition,
in mat4 lInverseViewProjectionMatrix,
in vec4 lClipPlanes)
{
vec4 lPositionVec4;
lPositionVec4.x = lFragCoordsVec2.x * 2.0 - 1.0;
#ifdef D_PLATFORM_ORBIS
lPositionVec4.y = (1.0f - lFragCoordsVec2.y) * 2.0 - 1.0;
#else
lPositionVec4.y = lFragCoordsVec2.y * 2.0 - 1.0;
#endif
lPositionVec4.z = LinearToReverseZDepth( lClipPlanes, lfDepth );
lPositionVec4.w = 1.0;
lPositionVec4 = MUL(lInverseViewProjectionMatrix, lPositionVec4);
lPositionVec4.xyz = lPositionVec4.xyz / lPositionVec4.w;
lPositionVec4.xyz += lViewPosition;
return lPositionVec4.xyz;
}
vec3
RecreatePositionFromDepth(
in float lfDepth,
in vec2 lFragCoordsVec2,
in vec3 lViewPosition,
in mat4 lInverseProjectionMatrix,
in mat4 lInverseViewMatrix )
{
vec4 lPositionVec4;
lPositionVec4.x = lFragCoordsVec2.x * 2.0 - 1.0;
#ifdef D_PLATFORM_ORBIS
lPositionVec4.y = ( 1.0f-lFragCoordsVec2.y ) * 2.0 - 1.0;
#else
lPositionVec4.y = lFragCoordsVec2.y * 2.0 - 1.0;
#endif
lPositionVec4.z = 0.0;
lPositionVec4.w = 1.0;
// Inverse projection
lPositionVec4 = MUL( lInverseProjectionMatrix, lPositionVec4 );
//lPositionVec4 = lPositionVec4 / lPositionVec4.w;
lPositionVec4 = lPositionVec4 / abs(lPositionVec4.z);
lPositionVec4 *= lfDepth;
// Inverse view
mat4 lViewMat = lInverseViewMatrix;
MAT4_SET_POS( lViewMat, vec4( 0.0, 0.0, 0.0, 1.0 ) );
lPositionVec4 = MUL( lViewMat, lPositionVec4 );
//lPositionVec4 = lPositionVec4 / lPositionVec4.w;
//lPositionVec4.xyz -= lViewPosition;
lPositionVec4.xyz = lPositionVec4.xyz + lViewPosition;
return lPositionVec4.xyz;
}
vec4
GetDepthColour(
in float lfDepth )
{
vec4 lColourVec4;
if( lfDepth < 1.0 )
{
lColourVec4 = vec4( 0.0, 0.0, 1.0, 1.0 );
}
else if( lfDepth < 10.0 )
{
lColourVec4 = vec4( 1.0, 0.0, 0.0, 1.0 );
}
else if( lfDepth < 20.0 )
{
lColourVec4 = vec4( 1.0, 1.0, 0.0, 1.0 );
}
else if( lfDepth < 40.0 )
{
lColourVec4 = vec4( 0.0, 1.0, 0.0, 1.0 );
}
else if( lfDepth < 80.0 )
{
lColourVec4 = vec4( 0.0, 1.0, 1.0, 1.0 );
}
else if( lfDepth < 160.0 )
{
lColourVec4 = vec4( 1.0, 0.0, 1.0, 1.0 );
}
else if( lfDepth < 320.0 )
{
lColourVec4 = vec4( 1.0, 0.5, 0.0, 1.0 );
}
else if( lfDepth < 640.0 )
{
lColourVec4 = vec4( 0.5, 1.0, 0.0, 1.0 );
}
else if( lfDepth < 1280.0 )
{
lColourVec4 = vec4( 0.0, 1.0, 0.5, 1.0 );
}
else if( lfDepth < 2560.0 )
{
lColourVec4 = vec4( 0.5, 0.0, 1.0, 1.0 );
}
else
{
lColourVec4 = vec4( 1.0, 0.0, 0.5, 1.0 );
}
return lColourVec4;
}
#endif
float
EncodeUnitScalars(
in float lfUnitScalarA,
in float lfUnitScalarB )
{
int liUpper = int( saturate( lfUnitScalarB ) * 255.0 ) << 8;
int liLower = int( saturate( lfUnitScalarA ) * 255.0 );
return float( liUpper | liLower );
//return lfUnitScalarA;
}
void
DecodeUnitScalars(
in float lfEncodedFloat,
out float lfUnitScalarA,
out float lfUnitScalarB )
{
lfUnitScalarA = float( int( lfEncodedFloat ) & 0xFF ) / 255.0;
lfUnitScalarB = float( ( int( lfEncodedFloat ) >> 8 ) & 0xFF ) / 255.0;
}
float
EncodeUnitScalars(
in int liUnitScalarA,
in float lfUnitScalarB )
{
int liUpper = int( saturate( lfUnitScalarB ) * 255.0 ) << 8;
int liLower = liUnitScalarA & 0xFF;
return float( liUpper | liLower );
//return lfUnitScalarA;
}
void
DecodeUnitScalars(
in float lfEncodedFloat,
out int liUnitScalarA,
out float lfUnitScalarB )
{
liUnitScalarA = int( lfEncodedFloat ) & 0xFF;
lfUnitScalarB = float( ( int( lfEncodedFloat ) >> 8 ) & 0xFF ) / 255.0;
}
// 4bit
float
Encode4BitUnitScalars(
in float lfUnitScalarA,
in float lfUnitScalarB )
{
int liUpper = int( saturate( lfUnitScalarB ) * 15.0 ) << 4;
int liLower = int( saturate( lfUnitScalarA ) * 15.0 );
return float( liUpper | liLower ) / 255.0;
//return lfUnitScalarA;
}
void
Decode4BitUnitScalars(
in float lfEncodedFloat,
out float lfUnitScalarA,
out float lfUnitScalarB )
{
lfEncodedFloat *= 255.0;
lfUnitScalarA = float( int( lfEncodedFloat ) & 0xF ) / 15.0;
lfUnitScalarB = float( ( int( lfEncodedFloat ) >> 4 ) & 0xF ) / 15.0;
}
float
Encode4BitUnitScalars(
in int liUnitScalarA,
in float lfUnitScalarB )
{
int liUpper = int( saturate( lfUnitScalarB ) * 15.0 ) << 4;
int liLower = liUnitScalarA & 0xF;
return float( liUpper | liLower ) / 255.0;
//return lfUnitScalarA;
}
void
Decode4BitUnitScalars(
in float lfEncodedFloat,
out int liUnitScalarA,
out float lfUnitScalarB )
{
lfEncodedFloat *= 255.0;
liUnitScalarA = int( lfEncodedFloat ) & 0xF;
lfUnitScalarB = float( ( int( lfEncodedFloat ) >> 4 ) & 0xF ) / 15.0;
}
//-----------------------------------------------------------------------------
///
/// EncodeScalarAsVector
///
//-----------------------------------------------------------------------------
vec4
EncodeScalarAsVector(
in float lfScalar )
{
vec4 lEncoded;
float lfScaled = lfScalar * 2048.0;
lEncoded = vec4( floor( lfScaled ), fract( lfScaled ), 0.0, 0.0 );
return lEncoded;
}
//-----------------------------------------------------------------------------
///
/// EncodeScalarAsVector
///
//-----------------------------------------------------------------------------
float
DecodeScalarAsVector(
in vec4 lEncoded )
{
return dot( lEncoded, vec4( 1.0 / 2048.0 ) );
}
//-----------------------------------------------------------------------------
///
/// EncodeNormal
///
//-----------------------------------------------------------------------------
void
EncodeNormal(
in vec3 lNormal,
out vec3 lBuffer )
{
lBuffer = lNormal * 0.5 + vec3( 0.5 );
}
//-----------------------------------------------------------------------------
///
/// DecodeNormal
///
//-----------------------------------------------------------------------------
vec3
DecodeNormal(
in vec3 lBuffer )
{
return lBuffer * 2.0 - 1.0;
}
//-----------------------------------------------------------------------------
///
/// EncodeMotion
///
//-----------------------------------------------------------------------------
vec2
EncodeMotion(
in vec2 lMotion )
{
// gamma 2.0 encoding to pack a reasonable value into RG8 targets
// corresponding decode is in CommonPostProcess to save rebuilds
vec2 lMotionScaled = lMotion * 16.0;
#ifdef D_PLATFORM_ORBIS
lMotionScaled.y = -lMotionScaled.y;
#endif
//float lLength = length( lMotionScaled * vec2( 9.0 / 16.0, 1.0 ) );
float lLength = length( lMotionScaled );
lMotionScaled /= max( 1.0, lLength );
if( lLength > 0.0 )
{
// set length to sqrt( the clamped length )
lMotionScaled /= sqrt( length( lMotionScaled ) );
}
// reserve 1.0 for signaling values`
vec2 lMaxRealValue = vec2( 254.0 / 255.0 );
return min( lMaxRealValue, lMotionScaled * ( 127.0 / 255.0 ) + 0.5 );
}
//-----------------------------------------------------------------------------
///
/// DecodeGBufferPosition
///
//-----------------------------------------------------------------------------
vec3
DecodeGBufferPosition(
in vec2 lScreenPosVec2,
in vec4 lClipPlanes,
in mat4 lInverseProjectionMat4,
in mat4 lInverseViewMat4,
in vec3 lViewPositionVec3,
in vec4 lBuffer1_Vec4,
in bool lbWithIVP
)
{
float lfDepth = FastDenormaliseDepth(lClipPlanes, DecodeDepthFromColour(lBuffer1_Vec4));
if (lbWithIVP)
{
// fast path with lInverseProjectionMat4 as invView(zero position) * invProj
return RecreatePositionFromDepthWithIVP(lfDepth, lScreenPosVec2, lViewPositionVec3, lInverseProjectionMat4, lClipPlanes);
}
else
{
return RecreatePositionFromDepth(lfDepth, lScreenPosVec2, lViewPositionVec3, lInverseProjectionMat4, lInverseViewMat4);
}
}
//-----------------------------------------------------------------------------
///
/// DecodeGBuffer
///
//-----------------------------------------------------------------------------
void
DecodeGBuffer(
in vec2 lScreenPosVec2,
in vec4 lClipPlanes,
in mat4 lInverseProjectionMat4,
in mat4 lInverseViewMat4,
in vec3 lViewPositionVec3,
in vec4 lBuffer0_Vec4,
in vec4 lBuffer1_Vec4,
in vec4 lBuffer2_Vec4,
in vec4 lBuffer3_Vec4,
in bool lbDecodePosition,
in bool lbWithIVP,
out vec3 lColourVec3,
inout vec3 lPositionVec3,
out vec3 lNormalVec3,
out int liMaterialID,
out float lfRoughness,
out float lfMetallic,
out float lfSubsurface,
out float lfGlow )
{
if (lbDecodePosition)
{
lPositionVec3 = DecodeGBufferPosition(lScreenPosVec2, lClipPlanes, lInverseProjectionMat4, lInverseViewMat4, lViewPositionVec3, lBuffer1_Vec4, lbWithIVP);
}
lColourVec3 = lBuffer0_Vec4.rgb;
lfGlow = lBuffer0_Vec4.a;
lNormalVec3 = DecodeNormal( lBuffer2_Vec4.xyz );
liMaterialID = int(lBuffer3_Vec4.r * 255.0 );
lfRoughness = ( lBuffer3_Vec4.g * lBuffer3_Vec4.g * 2.0 );
lfMetallic = lBuffer3_Vec4.b;
lfSubsurface = lBuffer3_Vec4.a;
}
//-----------------------------------------------------------------------------
///
/// EncodeGBuffer
///
//-----------------------------------------------------------------------------
void
EncodeGBuffer(
in vec4 lClipPlanes,
in vec4 lClipPlanesR,
in vec3 lViewPositionVec3,
in mat4 lViewMat4,
out vec4 lBuffer0_Vec4,
out vec4 lBuffer1_Vec4,
out vec4 lBuffer2_Vec4,
out vec4 lBuffer3_Vec4,
out vec4 lBuffer4_Vec4,
in vec3 lColourVec3,
in vec3 lPositionVec3,
in vec3 lNormalVec3,
in int liMaterialID,
in float lfRoughness,
in float lfMetallic,
in float lfSubsurface,
in float lfGlow,
in vec2 lScreenSpaceMotionVec2 )
{
lBuffer0_Vec4.xyz = lColourVec3;
lBuffer0_Vec4.a = saturate(lfGlow);
//float lDepth = FastNormaliseDepth( lClipPlanesR, length( lPositionVec3 - lViewPositionVec3 ) );
//lBuffer4_Vec4 = EncodeDepthToColour( lDepth );
EncodeNormal( lNormalVec3, lBuffer2_Vec4.xyz );
lBuffer2_Vec4.w = 0.0;
float lfRoughnessEncoded = sqrt( lfRoughness * ( 1.0 / 2.0 ) );
lBuffer3_Vec4.r = float(liMaterialID) / 255.0;
lBuffer3_Vec4.g = lfRoughnessEncoded;
lBuffer3_Vec4.b = saturate(lfMetallic);
lBuffer3_Vec4.a = saturate(lfSubsurface);
#ifdef D_OUTPUT_MOTION_VECTORS
lBuffer1_Vec4 = vec4( EncodeMotion( lScreenSpaceMotionVec2 * 0.5 ), 0.0, 0.0 );
#else
lBuffer1_Vec4 = vec4( lScreenSpaceMotionVec2, 0.0, 0.0 );
#endif
}
#endif
//-----------------------------------------------------------------------------
// Global Data
STATIC_CONST float kfSHCubemapBrightnessScale = 0.45;
STATIC_CONST float kfMaxShadowIntensity = 0.5;
STATIC_CONST vec4 kShadowPoissonTapsVec4[] =
{
vec4( 0.000000f, 0.000000f, 0.0, 0.0 ),
vec4( 0.527837f,-0.085868f, 0.0, 0.0 ),
vec4(-0.040088f, 0.536087f, 0.0, 0.0 ),
vec4(-0.670445f,-0.179949f, 0.0, 0.0 ),
vec4(-0.419418f,-0.616039f, 0.0, 0.0 ),
vec4( 0.440453f,-0.639399f, 0.0, 0.0 ),
vec4(-0.757088f, 0.349334f, 0.0, 0.0 ),
vec4( 0.574619f, 0.685879f, 0.0, 0.0 )
} ;
#define D_NUMBER_OF_CASCADES (3.0)
#define D_CASCADE_SIZE (1.0 / D_NUMBER_OF_CASCADES)
#define D_INSIDE_SM_BOUNDS1( V, TEXEL_SIZE ) ( ( max(V.x,V.y) < (1.0-(TEXEL_SIZE*1.0)) ) && ( min(V.x,V.y) > (TEXEL_SIZE*1.0) ) && ( V.z < 1.0 ) && ( V.z >= 0.0 ) )
#define D_INSIDE_SM_BOUNDS2( V, TEXEL_SIZE ) ( ( max(V.x,V.y) < (1.0-(TEXEL_SIZE*1.0)) ) && ( min(V.x,V.y) > (TEXEL_SIZE*1.0) ) && ( V.z < 1.0 ) && ( V.z >= 0.0 ) )
#define D_INSIDE_SM_BOUNDS3( V, TEXEL_SIZE ) ( ( max(V.x,V.y) < (1.0-(TEXEL_SIZE*1.0)) ) && ( min(V.x,V.y) > (TEXEL_SIZE*1.0) ) && ( V.z < 1.0 ) && ( V.z >= 0.0 ) )
//-----------------------------------------------------------------------------
// Typedefs and Classes
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
///
/// SampleShadowMap_RPDB
///
/// @brief SampleShadowMap_RPDB
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
// This method is used in the Witness
float
SampleShadowMap_RPDB(CustomPerMaterialUniforms lPerMaterialUniforms, in vec2 base_uv, in float u, in float v, in vec2 shadowMapSizeInv, in float depth, in vec2 receiverPlaneDepthBias, in float lfCascade)
{
vec2 uv = base_uv + vec2(u, v) * shadowMapSizeInv;
float z = depth + dot(vec2(u, v) * shadowMapSizeInv, receiverPlaneDepthBias);
z = clamp(z, 0.0, 1.0);
uv.x = (uv.x + lfCascade) * D_CASCADE_SIZE;
return shadow2D( lPerMaterialUniforms.gShadowMap, vec3(uv, z) ).x;
}
float
PCF_RPDB2(
in CustomPerMaterialUniforms lPerMaterialUniforms,
in CommonPerMeshUniforms lUniforms,
vec3 lTexCoordVec3,
in vec2 lReceiverPlaneDepthBiasVec2,
in vec4 lShadowMapSize,
in float lfCascade,
in bool lbHQ)
{
vec2 base_uv;
vec2 uv;
uv.x = lTexCoordVec3.x * lShadowMapSize.x;
uv.y = lTexCoordVec3.y * lShadowMapSize.y;
vec2 shadowMapSizeInv;
shadowMapSizeInv.x = lShadowMapSize.z;
shadowMapSizeInv.y = lShadowMapSize.w;
base_uv.x = floor(uv.x + 0.5);
base_uv.y = floor(uv.y + 0.5);
float s = (uv.x + 0.5 - base_uv.x);
float t = (uv.y + 0.5 - base_uv.y);
base_uv -= vec2(0.5, 0.5);
base_uv *= shadowMapSizeInv;
float lightDepth = lTexCoordVec3.z;
float sum = 0.0;
if (lfCascade == 0.0 && lbHQ)
{
float uw0 = (5 * s - 6);
float uw1 = (11 * s - 28);
float uw2 = -(11 * s + 17);
float uw3 = -(5 * s + 1);
float u0 = (4 * s - 5) / uw0 - 3;
float u1 = (4 * s - 16) / uw1 - 1;
float u2 = -(7 * s + 5) / uw2 + 1;
float u3 = -s / uw3 + 3;
float vw0 = (5 * t - 6);
float vw1 = (11 * t - 28);
float vw2 = -(11 * t + 17);
float vw3 = -(5 * t + 1);
float v0 = (4 * t - 5) / vw0 - 3;
float v1 = (4 * t - 16) / vw1 - 1;
float v2 = -(7 * t + 5) / vw2 + 1;
float v3 = -t / vw3 + 3;
sum += uw0 * vw0 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u0, v0, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw1 * vw0 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u1, v0, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw2 * vw0 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u2, v0, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw3 * vw0 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u3, v0, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw0 * vw1 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u0, v1, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw1 * vw1 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u1, v1, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw2 * vw1 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u2, v1, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw3 * vw1 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u3, v1, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw0 * vw2 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u0, v2, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw1 * vw2 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u1, v2, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw2 * vw2 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u2, v2, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw3 * vw2 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u3, v2, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw0 * vw3 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u0, v3, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw1 * vw3 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u1, v3, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw2 * vw3 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u2, v3, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw3 * vw3 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u3, v3, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
return sum * 1.0 / 2704.0;
}
else if (lfCascade == 1.0 && lbHQ)
{
float uw0 = (4 - 3 * s);
float uw1 = 7;
float uw2 = (1 + 3 * s);
float u0 = (3 - 2 * s) / uw0 - 2;
float u1 = (3 + s) / uw1;
float u2 = s / uw2 + 2;
float vw0 = (4 - 3 * t);
float vw1 = 7;
float vw2 = (1 + 3 * t);
float v0 = (3 - 2 * t) / vw0 - 2;
float v1 = (3 + t) / vw1;
float v2 = t / vw2 + 2;
sum += uw0 * vw0 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u0, v0, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw1 * vw0 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u1, v0, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw2 * vw0 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u2, v0, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw0 * vw1 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u0, v1, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw1 * vw1 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u1, v1, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw2 * vw1 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u2, v1, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw0 * vw2 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u0, v2, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw1 * vw2 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u1, v2, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw2 * vw2 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u2, v2, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
return sum * 1.0 / 144.0;
}
else
{
float uw0 = (3 - 2 * s);
float uw1 = (1 + 2 * s);
float u0 = (2 - s) / uw0 - 1;
float u1 = s / uw1 + 1;
float vw0 = (3 - 2 * t);
float vw1 = (1 + 2 * t);
float v0 = (2 - t) / vw0 - 1;
float v1 = t / vw1 + 1;
shadowMapSizeInv *= 0.5f; //
sum += uw0 * vw0 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u0, v0, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw1 * vw0 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u1, v0, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw0 * vw1 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u0, v1, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
sum += uw1 * vw1 * SampleShadowMap_RPDB(lPerMaterialUniforms, base_uv, u1, v1, shadowMapSizeInv, lightDepth, lReceiverPlaneDepthBiasVec2, lfCascade);
return sum * 1.0 / 16.0;
}
}
//-----------------------------------------------------------------------------
///
/// ComputeShadowIntensity
///
/// @brief ComputeShadowIntensity
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
vec2 ComputeReceiverPlaneDepthBias(vec3 texCoordDX, vec3 texCoordDY)
{
vec2 biasUV;
biasUV.x = texCoordDY.y * texCoordDX.z - texCoordDX.y * texCoordDY.z;
biasUV.y = texCoordDX.x * texCoordDY.z - texCoordDY.x * texCoordDX.z;
float Det =(texCoordDX.x * texCoordDY.y) - (texCoordDX.y * texCoordDY.x);
#ifdef D_PLATFORM_PC
if (Det == 0.0)
{
return vec2(0.0);
}
#endif
biasUV *= 1.0 / ( sign(Det) * max(abs(Det), 1e-8) );
return biasUV;
}
float
ComputeShadowIntensity(
in CustomPerMaterialUniforms lPerMaterialUniforms,
in PerFrameUniforms lRenderTargetUniforms,
in CommonPerMeshUniforms lUniforms,
in vec3 lPositionVec3,
in vec3 lNormalVec3,
in vec2 lScreenPositionVec2,
in bool lbHQ )
{
vec3 lProjectedPos;
float lfDepth = 1.0;
float lfTexelSize = lRenderTargetUniforms.gShadowSizeVec4.w; // 1.0 / lRenderTargetUniforms.gShadowSizeVec4.y;
float lfCascade = 0.0;
float lfShadowFade = 0.0;
float lfAutoBias = lUniforms.gShadowProjScaleVec4[0].z;
float lfAutoBiasBase = 0.08;
lProjectedPos = MUL( lUniforms.gaShadowMat4[ 0 ], vec4( lPositionVec3, 1.0 ) ).xyz;
// Check if you are outside the high detail shadow cascade
if( !D_INSIDE_SM_BOUNDS1( ( lProjectedPos.xyz ), lfTexelSize ) )
{
lProjectedPos = MUL( lUniforms.gaShadowMat4[ 1 ], vec4( lPositionVec3, 1.0 ) ).xyz;
if (!D_INSIDE_SM_BOUNDS2( (lProjectedPos.xyz), lfTexelSize) )
{
lProjectedPos = MUL( lUniforms.gaShadowMat4[ 2 ], vec4(lPositionVec3, 1.0) ).xyz;
if (!D_INSIDE_SM_BOUNDS3( (lProjectedPos.xyz), lfTexelSize) )
{
// outside all cascades
return 1.0;
}
else
{ // inside cascade 2
lfCascade = 2.0;
lfAutoBias = lUniforms.gShadowProjScaleVec4[2].z;
lfAutoBiasBase = 0.004;
lfShadowFade = clamp( (length(lRenderTargetUniforms.gViewPositionVec3-lPositionVec3)-lRenderTargetUniforms.gShadowFadeParamVec4.x ) * lRenderTargetUniforms.gShadowFadeParamVec4.y , 0.0, 1.0);
}
}
else
{
// inside cascade 1
lfCascade = 1.0;
lfAutoBias = lUniforms.gShadowProjScaleVec4[1].z;
lfAutoBiasBase = 0.0032;
}
}
//inside cascade 0 (or cascade 1,2 fall through)
vec3 lProjectedPosS = lProjectedPos;
vec3 lShadowPosDDXVec3 = dFdxFine(lProjectedPosS);
vec3 lShadowPosDDYVec3 = dFdyFine(lProjectedPosS);
vec2 lReceiverPlaneDepthBiasVec2 = ComputeReceiverPlaneDepthBias(lShadowPosDDXVec3, lShadowPosDDYVec3);
lReceiverPlaneDepthBiasVec2 *= vec2(lRenderTargetUniforms.gShadowSizeVec4.z, lRenderTargetUniforms.gShadowSizeVec4.w);
// Static depth biasing to make up for incorrect fractional sampling on the shadow map grid
float fractionalSamplingError = dot(vec2(2.0, 2.0), abs(lReceiverPlaneDepthBiasVec2));
// dynamic bias, based off Z view space range
fractionalSamplingError += lfAutoBiasBase / lfAutoBias;
lProjectedPos.z -= fractionalSamplingError;
float lfShadow = PCF_RPDB2(lPerMaterialUniforms, lUniforms, lProjectedPos, lReceiverPlaneDepthBiasVec2, lRenderTargetUniforms.gShadowSizeVec4, lfCascade, lbHQ);
return mix( lfShadow, 1.0, lfShadowFade );
}
//-----------------------------------------------------------------------------
///
/// EnvBRDFApprox
///
/// @brief EnvBRDFApprox
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
vec3 EnvBRDFApprox( vec3 SpecularColor, float Roughness, float NoV )
{
// [ Lazarov 2013, "Getting More Physical in Call of Duty: Black Ops II" ]
// Adaptation to fit our G term.
const vec4 c0 = vec4( -1, -0.0275, -0.572, 0.022 );
const vec4 c1 = vec4( 1, 0.0425, 1.04, -0.04 );
vec4 r = Roughness * c0 + c1;
float a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y;
vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;
return SpecularColor * AB.x + AB.y;
}
//-----------------------------------------------------------------------------
///
/// PhongApprox
///
/// @brief PhongApprox
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
PhongApprox(
float Roughness,
float RoL )
{
//float a = Roughness * Roughness; // 1 mul
//float a2 = a * a; // 1 mul
//float rcp_a2 = rcp(a2); // 1 rcp
float rcp_a2 = exp2( -6.88886882 * Roughness + 6.88886882 );
//float rcp_a2 = 1.0 / a2; // 1 rcp
// Spherical Gaussian approximation: pow( x, n ) ~= exp( (n + 0.775) * (x - 1) )
// Phong: n = 0.5 / a2 - 0.5
// 0.5 / ln(2), 0.275 / ln(2)
vec2 c = vec2( 0.72134752, 0.25 ) * rcp_a2 + vec2( 0.39674113, 0.75 ); // 1 mad
return c.y * exp2( c.x * RoL - c.x ); // 2 mad, 1 exp2, 1 mul
// Total 7 instr
}
//-----------------------------------------------------------------------------
///
/// GetImageBasedReflectionLighting
///
/// @brief GetImageBasedReflectionLighting
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
vec3 GetImageBasedReflectionLighting(
SAMPLER2DARG( lDualPMapBack ) ,
SAMPLER2DARG( lDualPMapFront ) ,
vec3 lReflectionVec3,
float Roughness)
{
vec3 ProjectedCaptureVector = lReflectionVec3;
// Compute fractional mip from roughness
//float AbsoluteSpecularMip = ComputeReflectionCaptureMipFromRoughness(Roughness);
// Fetch from cubemap and convert to linear HDR
vec3 SpecularIBL = ReadDualParaboloidMap( SAMPLER2DPARAM( lDualPMapBack ),
SAMPLER2DPARAM( lDualPMapFront ),
ProjectedCaptureVector,
int (min(Roughness, 0.99) * 7.0) );
return SpecularIBL;
}
STATIC_CONST float fLTDistortion = 0.200000; // Translucency Distortion Scale Factor
STATIC_CONST float fLTScale = 1.000000; // Scale Factor
STATIC_CONST float fLTPower = 4.000000; // Power Factor
STATIC_CONST float fLTAmbient = 0.000000; // Minimum front and back translucency
//-----------------------------------------------------------------------------
///
/// SubsurfaceScatter
///
/// @brief SubsurfaceScatter
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
float
SubsurfaceScatter(
vec3 lViewDirVec3,
vec3 lNormalVec3,
vec3 lLightDirectionVec3,
float lfSubsurfaceFactor )
{
//float dot = pow( saturate( dot( lViewDirVec3, -lLightDirectionVec3 ) ), fLTPower ) * fLTScale;
float lfTest = saturate( dot( lViewDirVec3, -lLightDirectionVec3 ) );
float lfDot = pow( lfTest, fLTPower ) * fLTScale;
float lt = (lfDot + fLTAmbient) * lfSubsurfaceFactor;
return lt;
}
STATIC_CONST float kfRimFactor = 0.5;
//-----------------------------------------------------------------------------
///
/// ComputeLightColour
///
/// @brief ComputeLightColour
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
vec3
ComputeLightColour(
in CustomPerMaterialUniforms lPerMaterialUniforms,
in PerFrameUniforms lPerFrameUniforms,
in CommonPerMeshUniforms lMeshUniforms,
in vec3 lLightDirectionVec3,
in vec3 lPositionVec3,
in vec2 lScreenPositionVec2,
in vec3 lNormalVec3,
in vec3 lInputColourVec3,
in mat3 lUpMatrix,
in int liMaterialID,
in float lfMetallic,
in float lfRoughness,
in float lfSubsurfaceFactor,
in float lfNonMetalSpecularScale)
{
vec3 lFinalColour = vec3(0.0);
vec3 lDiffuseColourVec3;
vec3 lSpecularColourVec3;
vec3 lViewDirVec3;
float lfShadow = 1.0;
float lfNoV;
float lfNoL;
vec3 lColourVec3 = lInputColourVec3;
vec3 lWorldUpVec3 = GetWorldUp( lPositionVec3, lMeshUniforms.gPlanetPositionVec4 );
float lfHeight = dot( lWorldUpVec3, lNormalVec3 );
lViewDirVec3 = normalize( lPerFrameUniforms.gViewPositionVec3 - lPositionVec3.xyz );
lfNoV = max( 0.0, dot( lNormalVec3, lViewDirVec3 ) );
lfNoL = max( 0.0, dot( lNormalVec3, lLightDirectionVec3 ) );
#ifdef _F48_
lfNoL = max( 0.0, (dot( lNormalVec3, lLightDirectionVec3 ) + 1.0)*0.5 );
#endif
vec3 lUp = GetWorldUp( lPerFrameUniforms.gViewPositionVec3, lMeshUniforms.gPlanetPositionVec4 );
vec3 lCross1 = normalize( cross( lUp, vec3( 0.0, 0.0, 1.0 ) ) );
vec3 lCross2 = normalize( cross( lUp, lCross1 ) );
lCross1 = normalize( cross( lUp, lCross2 ) );
vec3 lDir = lWorldUpVec3 - lUp;
vec2 lCloudTexCoords = vec2( dot( lDir, lCross1 ), dot( lDir, lCross2 ) ) * 0.5 * 0.005 * lMeshUniforms.gPlanetPositionVec4.w;
lCloudTexCoords += vec2( 0.5, 0.5 );
vec4 lOverlayValue = texture2D( lPerMaterialUniforms.gCloudShadowMap, lCloudTexCoords );
if ( (liMaterialID & D_NORECEIVESHADOW) == 0 )
{
if ( (liMaterialID & D_EMBEDDED_SHADOW) != 0 )
{
lfShadow = lfSubsurfaceFactor;
lfSubsurfaceFactor = 0.0;
} else
{
lfShadow = ComputeShadowIntensity( lPerMaterialUniforms, lPerFrameUniforms, lMeshUniforms, lPositionVec3, lNormalVec3, lScreenPositionVec2, true );
}
lfShadow *= 1.0 - lOverlayValue.a * 0.75;
//lfShadow *= 1.0 - lOverlayValue.a;
}
if ( (liMaterialID & D_HUESHIFT) != 0 )
{
lColourVec3 = RGBToHSV( lColourVec3 );
lColourVec3.r = lColourVec3.r - lOverlayValue.r;
lColourVec3.r = fract( lColourVec3.r );
lColourVec3.g = saturate( lColourVec3.g * ( 1.0 - lOverlayValue.g ) );
lColourVec3.b = saturate( lColourVec3.b * ( 1.0 - lOverlayValue.b ) );
lColourVec3 = HSVToRGB( lColourVec3 );
}
{
float DielectricSpecular = 0.08 * lfNonMetalSpecularScale;
lDiffuseColourVec3 = lColourVec3 - (lColourVec3 * lfMetallic); // 1 mad
lSpecularColourVec3 = (DielectricSpecular - (DielectricSpecular * lfMetallic)) + (lColourVec3 * lfMetallic); // 2 mad
}
{
lSpecularColourVec3 = EnvBRDFApprox( lSpecularColourVec3, lfRoughness, lfNoV );
}
{
vec3 lLightColourVec3 = /*GammaCorrectInput*/ ( lMeshUniforms.gLightColourVec4.xyz ) * lMeshUniforms.gLightColourVec4.w;
vec3 lReflectionVec3 = reflect( -lViewDirVec3, lNormalVec3 );
float lfRoL = max( 0.0, dot( lReflectionVec3, lLightDirectionVec3 ) );
float lfSubSurface = 0.0;
#ifdef _F40_
{
lfSubSurface = SubsurfaceScatter( lViewDirVec3, lNormalVec3, lLightDirectionVec3, lfSubsurfaceFactor );
lfSubSurface *= 0.2 + (lfShadow * 0.8);
}
#endif
lFinalColour += ((lfShadow * lfNoL ) + lfSubSurface) * lLightColourVec3 * (lDiffuseColourVec3 + lSpecularColourVec3 * PhongApprox( lfRoughness, lfRoL ) );
#ifdef D_DEBUG_AMBIENT_ONLY
{
lFinalColour = vec3( 0.0 );
}
#endif
#ifndef D_SPOTLIGHT
{
vec3 lTransformedRelectionVec3 = MUL( lUpMatrix, lReflectionVec3 );
vec3 lTransformedNormalVec3 = MUL( lUpMatrix, lNormalVec3 );
#ifndef D_PLATFORM_ORBIS
lTransformedRelectionVec3 = -lTransformedRelectionVec3;
lTransformedNormalVec3 = -lTransformedNormalVec3;
#endif
vec3 SpecularIBL = GetImageBasedReflectionLighting( SAMPLER2DPARAM( lPerMaterialUniforms.gDualPMapBack ),
SAMPLER2DPARAM( lPerMaterialUniforms.gDualPMapFront ),
lTransformedRelectionVec3,
lfRoughness);
lFinalColour += lfShadow * SpecularIBL * lSpecularColourVec3;
vec3 AmbientIBL = GetImageBasedReflectionLighting( SAMPLER2DPARAM( lPerMaterialUniforms.gDualPMapBack ),
SAMPLER2DPARAM( lPerMaterialUniforms.gDualPMapFront ),
lTransformedNormalVec3,
0.5 );
// Ambient
if ( ( liMaterialID & D_DISBALE_AMBIENT ) != 0 )
{
// branching around the whole ambient section, lowers PS4 shader occupancy
AmbientIBL = vec3(0.0);
}
float lfBounceLight;
float lfSkyLight;
lfBounceLight = max( (-lfHeight) + 0.5, 0.0 ) / ( 1.0 + 0.5 ); //saturate( ((-lfHeight)+ 1.0) * 0.5 );
lfBounceLight = pow( lfBounceLight, 5.0 ) * 1.0;
lfSkyLight = max( (lfHeight) + 0.0, 0.0 ) / ( 1.0 + 0.0 ); //saturate( (lfHeight + 1.0) * 0.5 );
lfSkyLight = pow( lfSkyLight, 10.0 ) * 1.0;
lFinalColour += AmbientIBL * lColourVec3 * ( lfBounceLight + lfSkyLight );
#ifdef D_DEBUG_NO_COLOUR
{
lFinalColour = AmbientIBL * ( lfBounceLight + lfSkyLight );
}
#endif
// Rim
{
float lfNormalDotCamera;
lfNormalDotCamera = dot( lNormalVec3, -lViewDirVec3 );
lfNormalDotCamera = max( lfNormalDotCamera + 0.8, 0.0 ) / ( 1.0 + 0.8 );
float lfSideRim = lfNormalDotCamera;
lfSideRim *= 1.0 - (max( lfHeight, 0.0 ) + max( -lfHeight, 0.0 ));
vec3 lRimColour = mix(lColourVec3, SpecularIBL, 0.3) * (lfSideRim * 0.088);
float lfTopRim = max( lfHeight + 1.0, 0.0 ) / ( 1.0 + 1.0 );
lfTopRim = pow( lfTopRim, 30.0 ) * 0.3;
lRimColour += mix(lColourVec3, SpecularIBL, 0.0) * lfTopRim * lfShadow;
#ifdef D_DEBUG_NO_AMBIENT
{
return lRimColour;
//return gLightingHackParamsVec4.xyz;
}
#endif
lFinalColour += lRimColour;
}
//lFinalColour = AmbientIBL;
}
#endif
}
return lFinalColour;
//return AmbientIBL;
}
#endif
////////////////////////////////////////////////////////////////////////////////
///
/// @file CommonPlanet.h
/// @author User
/// @date
///
/// @brief CommonPlanetShader
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Compilation defines
#ifndef D_COMMONPLANET_H
#define D_COMMONPLANET_H
//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------
// Global Data
STATIC_CONST vec3 kUp = vec3( 0.0, 1.0, 0.0 );
STATIC_CONST float kfPi = 3.14159;
STATIC_CONST float kfAccuracy = 0.001;
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
///
/// GetHeight
///
/// @brief GetHeight
///
/// @param in vec3 lWorldPosition
/// @return float
///
//-----------------------------------------------------------------------------
float
GetHeight(
in vec3 lWorldPosition,
in vec4 lPlanetPosition )
{
vec3 lOffset = lWorldPosition - lPlanetPosition.xyz;
return length(lOffset) - lPlanetPosition.w;
}
//-----------------------------------------------------------------------------
///
/// GetHeight
///
/// @brief GetHeight
///
/// @param in vec3 lWorldPosition
/// @return float
///
//-----------------------------------------------------------------------------
float
GetDistanceFromCenter(
in vec3 lWorldPosition,
in vec4 lPlanetPosition )
{
vec3 lOffset = lWorldPosition - lPlanetPosition.xyz;
return length(lOffset);
}
//-----------------------------------------------------------------------------
///
/// GetWorldUp
///
/// @brief GetWorldUp
///
/// @param in vec3 lWorldPosition
/// @return vec3
///
//-----------------------------------------------------------------------------
vec3
GetWorldUp(
in vec3 lWorldPosition,
in vec4 lPlanetPosition )
{
#ifdef D_ASTEROID
return kUp;
#else
return normalize(lWorldPosition / lPlanetPosition.w - lPlanetPosition.xyz / lPlanetPosition.w);
#endif
}
//-----------------------------------------------------------------------------
///
/// GetWorldUp
///
/// @brief GetWorldUp
///
/// @param in vec3 lWorldPosition
/// @param out float lfHeight
/// @return vec3
///
//-----------------------------------------------------------------------------
vec3
GetWorldUp(
in vec3 lWorldPosition,
in vec4 lPlanetPosition,
out float lfHeight )
{
vec3 lOffset;
// Get the offset from planet centre
lOffset = (lWorldPosition - lPlanetPosition.xyz);
// Get the length of the offset
lfHeight = length(lOffset);
// Normalise the offset to get the world up
lOffset /= lfHeight;
// Remove the planet radius to get the height
lfHeight -= lPlanetPosition.w;
return lOffset;
}
//-----------------------------------------------------------------------------
///
/// GetWorldUpTransform
///
/// @brief GetWorldUpTransform
///
/// @param in vec3 lViewPosition
/// @return mat3
///
//-----------------------------------------------------------------------------
mat3
GetRotation(
in vec3 lFromVec3,
in vec3 lToVec3 )
{
mat3 lMatrix;
vec3 lAxisVec3 = cross( lFromVec3, lToVec3 );
float lfDot = dot( lFromVec3, lToVec3 );
float lfAngle = length( lAxisVec3 );
if( lfAngle > kfAccuracy && lfDot < ( 1.0 - kfAccuracy ) && lfDot > -( 1.0 - kfAccuracy ) )
{
lfAngle = length( lAxisVec3 );
lAxisVec3 = normalize( lAxisVec3 );
}
else
{
return mat3( vec3( 1.0, 0.0, 0.0 ), vec3( 0.0, 1.0, 0.0 ), vec3( 0.0, 0.0, 1.0 ) );
}
lfAngle = clamp( lfAngle, -1.0, 1.0 );
lfAngle = asin( lfAngle );
if( lfDot < 0.0 )
{
lfAngle = kfPi - lfAngle;
}
float lfCos = cos( lfAngle );
float lfInv = 1.0 - lfCos;
float lfSin = sin( lfAngle );
MAT3_SET_COLUMN( lMatrix, 0, vec3( lfCos + lAxisVec3.x * lAxisVec3.x * lfInv, lAxisVec3.y * lAxisVec3.z * lfInv + lAxisVec3.z * lfSin, lAxisVec3.z * lAxisVec3.x * lfInv - lAxisVec3.y * lfSin ) );
MAT3_SET_COLUMN( lMatrix, 1, vec3( lAxisVec3.x * lAxisVec3.y * lfInv - lAxisVec3.z * lfSin, lfCos + lAxisVec3.y * lAxisVec3.y * lfInv, lAxisVec3.z * lAxisVec3.y * lfInv + lAxisVec3.x * lfSin ) );
MAT3_SET_COLUMN( lMatrix, 2, vec3( lAxisVec3.x * lAxisVec3.z * lfInv + lAxisVec3.y * lfSin, lAxisVec3.y * lAxisVec3.z * lfInv - lAxisVec3.x * lfSin, lfCos + lAxisVec3.z * lAxisVec3.z * lfInv ) );
return lMatrix;
}
//-----------------------------------------------------------------------------
///
/// GetWorldUpTransform
///
/// @brief GetWorldUpTransform
///
/// @param in vec3 lViewPosition
/// @return mat3
///
//-----------------------------------------------------------------------------
mat3
GetWorldUpTransform(
in vec3 lViewPosition,
in vec4 lPlanetPosition )
{
vec3 lUp = vec3( 0.0, 1.0, 0.0);
vec3 lWorldUp = GetWorldUp( lViewPosition, lPlanetPosition );
return GetRotation( lUp, lWorldUp );
}
//-----------------------------------------------------------------------------
///
/// GetWorldUpTransform
///
/// @brief GetWorldUpTransform
///
/// @param in vec3 lViewPosition
/// @return mat3
///
//-----------------------------------------------------------------------------
mat3
GetInverseWorldUpTransform(
in vec3 lViewPosition,
in vec4 lPlanetPosition )
{
vec3 lUp = vec3( 0.0, 1.0, 0.0 );
vec3 lWorldUp = GetWorldUp( lViewPosition, lPlanetPosition );
return GetRotation( lWorldUp, lUp );
}
#endif
#endif
//-----------------------------------------------------------------------------
// Global Data
//-----------------------------------------------------------------------------
// Typedefs and Classes
//-----------------------------------------------------------------------------
///
/// Input
///
/// @brief Input
///
//-----------------------------------------------------------------------------
DECLARE_INPUT
IN_SCREEN_POSITION
INPUT( vec4, mTexCoordsVec4, TEXCOORD0 )
#ifdef _F21_
INPUT( vec4, mColourVec4, TEXCOORD1 )
#endif
#ifdef _F30_
INPUT( vec4, mProjectedTexCoordsVec4, TEXCOORD2 )
#endif
//#ifdef D_USES_WORLD_POSITION
INPUT( vec4, mWorldPositionVec3_mfSpare, TEXCOORD3 )
//#endif
#if !defined( _F01_ ) || defined( _F22_ )
INPUT( vec4, mMaterialVec4, TEXCOORD4 )
#endif
#ifdef D_USES_VERTEX_NORMAL
INPUT( vec3, mTangentSpaceNormalVec3, TEXCOORD6 )
#endif
#ifdef _F20_
INPUT( vec3, mTangentSpaceEyeVec3, TEXCOORD5 )
#endif
#if defined( _F03_ ) || defined( _F42_ )
INPUT( vec3, mTangentMatRow1Vec3, TEXCOORD18 )
INPUT( vec3, mTangentMatRow2Vec3, TEXCOORD19 )
INPUT( vec3, mTangentMatRow3Vec3, TEXCOORD20 )
#endif
#if defined( _F47_ ) && defined( D_USING_LOGDEPTH )
INPUT( float, mfLogZ, TEXCOORD11 )
#endif
#if defined( _F58_ )
INPUT( vec3, mCenteralNormalVec3, TEXCOORD14 )
INPUT( vec3, mCenterPositionVec3, TEXCOORD16 )
#endif
#ifdef D_USE_SCREEN_POSITION
INPUT( vec4, mScreenSpacePositionVec4, TEXCOORD15 )
#endif
#ifdef D_OUTPUT_MOTION_VECTORS
INPUT( vec4, mPrevScreenPosition, TEXCOORD21 )
#endif
#ifdef _F37_
INPUT( vec4, mPaletteColour1Vec4, TEXCOORD16 )
INPUT( vec4, mPaletteColour2Vec4, TEXCOORD17 )
#endif
DECLARE_END
#ifdef D_DEFER
////////////////////////////////////////////////////////////////////////////////
///
/// @file UberFragmentShader.h
/// @author User
/// @date
///
/// @brief UberFragmentShader
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Compilation defines
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
///
/// WriteOutput
///
/// @brief WriteOutput
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
void
WriteOutput(
out vec4 lOutColours0Vec4,
out vec4 lOutColours1Vec4,
out vec4 lOutColours2Vec4,
out vec4 lOutColours3Vec4,
out vec4 lOutColours4Vec4,
in PerFrameUniforms lPerFrameUniforms,
in CommonPerMeshUniforms lMeshUniforms,
in CustomPerMaterialUniforms lCustomUniforms,
in vec4 lColourVec4,
in vec3 lPositionVec3,
in vec3 lNormalVec3,
in int liMaterialID,
in float lfMetallic,
in float lfRoughness,
in float lfSubsurface,
in float lfGlow,
in vec4 lScreenSpacePositionVec4,
in vec4 lPrevScreenPositionVec4,
in float lfPixelDepth,
in bool lbFrontFacing)
{
//-----------------------------------------------------------------------------
///
/// Output
///
//-----------------------------------------------------------------------------
#if defined( D_IMPOSTER_COLOUR )
{
lOutColours0Vec4 = vec4(lColourVec4.x, lColourVec4.y, lColourVec4.z ,1.0);
}
#elif defined( D_IMPOSTER_NORMAL )
{
vec3 lEncodedNormal;
// [peter] the engine expects the normal maps to be in a coordinate space that
// has a flipped y axis with regard to the one we are currently using
lEncodedNormal = vec3(-lNormalVec3.x, -lNormalVec3.y, -lNormalVec3.z);
#ifdef _F11_
// [Griff] why is this needed?! we will NEVER NEVER know.
#if defined( _F12_ ) || defined( _F36_ )
if (true)
#else
if ( !lbFrontFacing )
#endif
{
lEncodedNormal.x = -lEncodedNormal.x;
lEncodedNormal.z = -lEncodedNormal.z;
}
else
{
lEncodedNormal.y = -lEncodedNormal.y;
}
#endif
lEncodedNormal = ( lEncodedNormal + 1.0 ) * 0.5;
lOutColours0Vec4 = vec4( lEncodedNormal.x, lEncodedNormal.y, lEncodedNormal.z, 1.0 );
}
#elif defined( D_IMPOSTER_MASK )
{
lOutColours0Vec4 = vec4( lfSubsurface, 1.0, 1.0, 1.0 );
}
#else
{
#if !defined( D_ATTRIBUTES )
lOutColours0Vec4 = vec4( lColourVec4.xyz, lfGlow );
#else
#if defined( D_OUTPUT_MOTION_VECTORS )
vec2 lScreenSpaceMotionVec2 = lScreenSpacePositionVec4.xy / lScreenSpacePositionVec4.w - lPrevScreenPositionVec4.xy / lPrevScreenPositionVec4.w;
#ifdef D_PLATFORM_PC
lScreenSpaceMotionVec2 = -lScreenSpaceMotionVec2;
#endif
#else
vec2 lScreenSpaceMotionVec2 = vec2( 1.0, 0.0 );
#endif
vec4 lBuffer0_Vec4;
vec4 lBuffer1_Vec4;
vec4 lBuffer2_Vec4;
vec4 lBuffer3_Vec4;
vec4 lBuffer4_Vec4;
EncodeGBuffer(
lPerFrameUniforms.gClipPlanesVec4,
lPerFrameUniforms.gClipPlanesRVec4,
lPerFrameUniforms.gViewPositionVec3,
lPerFrameUniforms.gViewMat4,
lBuffer0_Vec4,
lBuffer1_Vec4,
lBuffer2_Vec4,
lBuffer3_Vec4,
lBuffer4_Vec4,
lColourVec4.xyz,
lPositionVec3,
lNormalVec3,
liMaterialID,
lfRoughness,
lfMetallic,
lfSubsurface,
lfGlow,
lScreenSpaceMotionVec2 );
lOutColours0Vec4 = lBuffer0_Vec4;
lOutColours1Vec4 = lBuffer1_Vec4;
lOutColours2Vec4 = lBuffer2_Vec4;
lOutColours3Vec4 = lBuffer3_Vec4;
lOutColours4Vec4 = lBuffer4_Vec4;
#endif
}
#endif
}
#else
#if !defined( _F50_ ) && !defined( D_NO_POSTPROCESS )
////////////////////////////////////////////////////////////////////////////////
///
/// @file CommonDepth.h
/// @author User
/// @date
///
/// @brief CommonDepth
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Compilation defines
#ifndef D_COMMONSCATTERING_H
#define D_COMMONSCATTERING_H
//-----------------------------------------------------------------------------
// Include files
////////////////////////////////////////////////////////////////////////////////
///
/// @file Common.h
/// @author User
/// @date
///
/// @brief Common
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
#ifndef D_COMMON_H
#define D_COMMON_H
#define D_TERRAINCOLOURARRAY_SIZE 23
STATIC_CONST vec3 kGammaOutVec3 = vec3( 1.0 / 2.2 );
STATIC_CONST vec3 kGammaInVec3 = vec3( 2.2 );
STATIC_CONST vec4 RGBToHSV_K = vec4( 0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0 );
STATIC_CONST vec4 HSVToRGB_K = vec4( 1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0 );
#ifdef D_PLATFORM_ORBIS
STATIC_CONST float3x3 BT709_TO_BT2020 = float3x3( //ref: ARIB STD-B62 and BT.2087
#else
STATIC_CONST mat3 BT709_TO_BT2020 = mat3( //ref: ARIB STD-B62 and BT.2087
#endif
0.6274, 0.3293, 0.0433,
0.0691, 0.9195, 0.0114,
0.0164, 0.0880, 0.8956
);
#ifdef D_PLATFORM_ORBIS
STATIC_CONST float3x3 BT2020_TO_BT709 = float3x3(
#else
STATIC_CONST mat3 BT2020_TO_BT709 = mat3(
#endif
1.6605, -0.5877, -0.0728,
-0.1246, 1.1330, -0.0084,
-0.0182, -0.1006, 1.1187
);
//-----------------------------------------------------------------------------
///
/// GammaCorrect
///
//-----------------------------------------------------------------------------
vec3
GammaCorrectInput(
in vec3 lColourVec3 )
{
vec3 lCorrectColourVec3;
lCorrectColourVec3 = lColourVec3 * ( lColourVec3 * ( lColourVec3 * vec3( 0.305306011 ) + vec3( 0.682171111 ) ) + vec3( 0.012522878 ) );
return lCorrectColourVec3;
}
//-----------------------------------------------------------------------------
///
/// GammaCorrect
///
//-----------------------------------------------------------------------------
vec3
GammaCorrectOutput(
in vec3 lColourVec3 )
{
vec3 lCorrectColourVec3;
lCorrectColourVec3 = pow( lColourVec3, kGammaOutVec3 );
return lCorrectColourVec3;
}
//-----------------------------------------------------------------------------
///
/// RGBToHSV
///
//-----------------------------------------------------------------------------
vec3
RGBToHSV(
vec3 lRGB )
{
//vec4 p = mix( vec4(lRGB.bg, RGBToHSV_K.wz), vec4(lRGB.gb, RGBToHSV_K.xy), step(lRGB.b, lRGB.g) );
//vec4 q = mix( vec4(p.xyw, lRGB.r), vec4(lRGB.r, p.yzx), step(p.x, lRGB.r) );
// This variant is faster, since it generates conditional moves
vec4 p = lRGB.g < lRGB.b ? vec4(lRGB.bg, RGBToHSV_K.wz) : vec4(lRGB.gb, RGBToHSV_K.xy);
vec4 q = lRGB.r < p.x ? vec4(p.xyw, lRGB.r) : vec4(lRGB.r, p.yzx);
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
//-----------------------------------------------------------------------------
///
/// HSVToRGB
///
/// @brief http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
///
//-----------------------------------------------------------------------------
vec3
HSVToRGB(
vec3 lHSV )
{
vec3 p = abs(fract(lHSV.xxx + HSVToRGB_K.xyz) * 6.0 - HSVToRGB_K.www);
return lHSV.z * mix(HSVToRGB_K.xxx, saturate(p - HSVToRGB_K.xxx), lHSV.y);
}
//-----------------------------------------------------------------------------
///
/// HDR ( Perceptual Quantizer(PQ), Rec. 2020 color space. ) helpers
///
//------------------------------------------------------------------------------
#ifdef D_PLATFORM_PC
float CndMask(bool cnd, float src0, float src1)
{
return cnd ? src0 : src1;
}
#endif
STATIC_CONST float kRefWhiteLevel = 100.0;
vec4 SRGB_OETF(vec4 L)
{
vec3 dark = L.xyz * 12.92;
vec3 light = 1.055 * pow(L.xyz, vec3(1.0 / 2.4)) - 0.055;
vec4 r;
r.x = CndMask(L.x <= 0.0031308, dark.x, light.x);
r.y = CndMask(L.y <= 0.0031308, dark.y, light.y);
r.z = CndMask(L.z <= 0.0031308, dark.z, light.z);
r.w = L.w;
return r;
}
vec4 SRGB_EOTF(vec4 E)
{
vec3 dark = E.xyz / 12.92;
vec3 light = pow((E.xyz + 0.055) / (1 + 0.055), vec3(2.4));
vec4 r;
r.x = CndMask(E.x <= 0.04045, dark.x, light.x);
r.y = CndMask(E.y <= 0.04045, dark.y, light.y);
r.z = CndMask(E.z <= 0.04045, dark.z, light.z);
r.w = E.w;
return r;
}
//apply gamma adjustment to (minL, maxL).
vec4 GammaAdjOOTF(vec4 L, float minLNits, float maxLNits, float gamma, bool inverse)
{
vec3 nits = L.xyz * kRefWhiteLevel;
vec4 i = vec4((nits - minLNits) / (maxLNits - minLNits), 1.0);
vec3 j;
if (inverse){
j = SRGB_EOTF(pow(i, vec4(1 / gamma))).xyz;
}
else{
j = pow(SRGB_OETF(i).xyz,vec3(gamma));
}
vec3 adj = (minLNits + (maxLNits - minLNits) * j) / kRefWhiteLevel;
vec4 ret;
ret.x = CndMask(nits.x >= minLNits && nits.x < maxLNits, adj.x, L.x);
ret.y = CndMask(nits.y >= minLNits && nits.y < maxLNits, adj.y, L.y);
ret.z = CndMask(nits.z >= minLNits && nits.z < maxLNits, adj.z, L.z);
ret.w = L.w;
return ret;
}
//input: normalized L in units of RefWhite (1.0=100nits), output: normalized E
vec4 PQ_OETF(vec4 L, uint gamma_adj, float gamma)
{
if (gamma_adj != 0)
L = GammaAdjOOTF(L, 0.0, 300.0, gamma, false);
const float c1 = 0.8359375;//3424.f/4096.f;
const float c2 = 18.8515625;//2413.f/4096.f*32.f;
const float c3 = 18.6875; //2392.f/4096.f*32.f;
const float m1 = 0.159301758125; //2610.f / 4096.f / 4;
const float m2 = 78.84375;// 2523.f / 4096.f * 128.f;
L = L * kRefWhiteLevel / 10000.0;
vec3 Lm1 = pow(L.xyz, vec3(m1));
vec3 X = (c1 + c2 * Lm1) / (1 + c3 * Lm1);
vec4 res = vec4(pow(X, vec3(m2)), L.w);
return res;
}
//input: normalized E (0.0, 1.0), output: normalized L in units of RefWhite
vec4 PQ_EOTF(vec4 E, uint gamma_adj, float gamma)
{
const float c1 = 0.8359375;//3424.f/4096.f;
const float c2 = 18.8515625;//2413.f/4096.f*32.f;
const float c3 = 18.6875; //2392.f/4096.f*32.f;
const float m1 = 0.159301758125; //2610.f / 4096.f / 4;
const float m2 = 78.84375;// 2523.f / 4096.f * 128.f;
vec3 M = c2 - c3 * pow(E.xyz, vec3(1 / m2));
vec3 N = max(pow(E.xyz, vec3(1 / m2)) - c1, 0);
vec3 L = pow(N / M, vec3(1 / m1)); //normalized nits (1.0 = 10000nits)
L = L * 10000.0 / kRefWhiteLevel; //convert to normalized L in units of RefWhite
return (gamma_adj !=0) ? GammaAdjOOTF(vec4(L, E.w), 0.0, 300.0, gamma, true) : vec4(L, E.w);
}
// PQ OETF fast approximation
// http://www.glowybits.com/blog/2017/01/04/ifl_iss_hdr_2/
vec3 PQ_OETF_Fast(vec3 x)
{
x = (x * (x * (x * (x * (x * 533095.76 + 47438306.2) + 29063622.1) + 575216.76) + 383.09104) + 0.000487781) /
(x * (x * (x * (x * 66391357.4 + 81884528.2) + 4182885.1) + 10668.404) + 1.0);
return x;
}
//-----------------------------------------------------------------------------
///
/// BrightnessVibranceContrast
///
//-----------------------------------------------------------------------------
vec3 BrightnessVibranceContrast(
vec3 lInputColour,
float lfBrightness,
float lfVibrance,
float lfContrast)
{
vec3 lBrtResult = lInputColour * lfBrightness;
// get lum
vec3 lLuma = vec3( dot(lBrtResult, vec3( 0.2125, 0.7154, 0.0721 )) );
// get saturation
float lfMaxCol = max( lBrtResult.r, max(lBrtResult.g, lBrtResult.b) );
float lfMinCol = min( lBrtResult.r, min(lBrtResult.g, lBrtResult.b) );
float lfCurSatV = lfMaxCol - lfMinCol;
// lerp by 1 + (1 - vibrance) - current saturation
float lfVibranceMix = (1.0 + (lfVibrance * (1.0 - (sign(lfVibrance) * lfCurSatV))));
vec3 lVibResult = mix( lLuma, lBrtResult, lfVibranceMix );
// lerp from mid gray for contrast
vec3 lContrastBase = vec3( 0.5, 0.5, 0.5 );
vec3 lConResult = mix( lContrastBase , lVibResult, lfContrast );
return lConResult;
}
//-----------------------------------------------------------------------------
///
/// Desaturate
///
//-----------------------------------------------------------------------------
vec3 Desaturate( vec3 color, float lfAmount )
{
vec3 gray = vec3( dot( vec3( 0.299, 0.587, 0.114 ), color) );
return mix( color, gray, lfAmount );
}
// improved rgb lerp by @stormoid
// https://www.shadertoy.com/view/lsdGzN
//---------------Improved RGB--------------
/*
The idea behind this function is to avoid the low saturation area in the
rgb color space. This is done by getting the direction to that diagonal
and displacing the interpolated color by it's inverse while scaling it
by saturation error and desired lightness.
I find it behaves very well under most circumstances, the only instance
where it doesn't behave ideally is when the hues are very close to 180
degrees apart, since the method I am using to find the displacement vector
does not compensate for non-curving motion. I tried a few things to
circumvent this problem but none were cheap and effective enough..
*/
//Changes the strength of the displacement
#define DSP_STR 1.5
//-----------------------------------------------------------------------------
float _getsat( vec3 lColour )
{
float mi = min(min(lColour.x, lColour.y), lColour.z);
float ma = max(max(lColour.x, lColour.y), lColour.z);
return (ma - mi) / (ma + 1e-7);
}
vec3 NmzRgbLerp( vec3 a, vec3 b, float x )
{
// interpolated base color (with singularity fix)
vec3 ic = mix( a, b, x ) + vec3( 1e-6, 0.0, 0.0 );
// saturation difference from ideal scenario
float sd = abs( _getsat( ic ) - mix( _getsat( a ), _getsat( b ), x ) );
// displacement direction
vec3 dir = normalize(
vec3( 2.0 * ic.x - ic.y - ic.z,
2.0 * ic.y - ic.x - ic.z,
2.0 * ic.z - ic.y - ic.x )
);
// simple Lighntess
float lgt = dot( vec3( 1.0 ), ic );
// extra scaling factor for the displacement
float ff = dot( dir, normalize( ic ) );
// displace the color
ic += DSP_STR * dir * sd * ff * lgt;
return clamp( ic, 0.0, 1.0 );
}
//-----------------------------------------------------------------------------
///
/// Inverse
///
//-----------------------------------------------------------------------------
mat4
Inverse(
const mat4 lInMat4 )
{
#ifdef D_PLATFORM_PC
return inverse( lInMat4 );
#else
float det = determinant( lInMat4 );
det = 1.0f / det;
mat4 M = lInMat4;
mat4 IM;
IM[0][0] = det * ( M[1][2]*M[2][3]*M[3][1] - M[1][3]*M[2][2]*M[3][1] + M[1][3]*M[2][1]*M[3][2] - M[1][1]*M[2][3]*M[3][2] - M[1][2]*M[2][1]*M[3][3] + M[1][1]*M[2][2]*M[3][3] );
IM[0][1] = det * ( M[0][3]*M[2][2]*M[3][1] - M[0][2]*M[2][3]*M[3][1] - M[0][3]*M[2][1]*M[3][2] + M[0][1]*M[2][3]*M[3][2] + M[0][2]*M[2][1]*M[3][3] - M[0][1]*M[2][2]*M[3][3] );
IM[0][2] = det * ( M[0][2]*M[1][3]*M[3][1] - M[0][3]*M[1][2]*M[3][1] + M[0][3]*M[1][1]*M[3][2] - M[0][1]*M[1][3]*M[3][2] - M[0][2]*M[1][1]*M[3][3] + M[0][1]*M[1][2]*M[3][3] );
IM[0][3] = det * ( M[0][3]*M[1][2]*M[2][1] - M[0][2]*M[1][3]*M[2][1] - M[0][3]*M[1][1]*M[2][2] + M[0][1]*M[1][3]*M[2][2] + M[0][2]*M[1][1]*M[2][3] - M[0][1]*M[1][2]*M[2][3] );
IM[1][0] = det * ( M[1][3]*M[2][2]*M[3][0] - M[1][2]*M[2][3]*M[3][0] - M[1][3]*M[2][0]*M[3][2] + M[1][0]*M[2][3]*M[3][2] + M[1][2]*M[2][0]*M[3][3] - M[1][0]*M[2][2]*M[3][3] );
IM[1][1] = det * ( M[0][2]*M[2][3]*M[3][0] - M[0][3]*M[2][2]*M[3][0] + M[0][3]*M[2][0]*M[3][2] - M[0][0]*M[2][3]*M[3][2] - M[0][2]*M[2][0]*M[3][3] + M[0][0]*M[2][2]*M[3][3] );
IM[1][2] = det * ( M[0][3]*M[1][2]*M[3][0] - M[0][2]*M[1][3]*M[3][0] - M[0][3]*M[1][0]*M[3][2] + M[0][0]*M[1][3]*M[3][2] + M[0][2]*M[1][0]*M[3][3] - M[0][0]*M[1][2]*M[3][3] );
IM[1][3] = det * ( M[0][2]*M[1][3]*M[2][0] - M[0][3]*M[1][2]*M[2][0] + M[0][3]*M[1][0]*M[2][2] - M[0][0]*M[1][3]*M[2][2] - M[0][2]*M[1][0]*M[2][3] + M[0][0]*M[1][2]*M[2][3] );
IM[2][0] = det * ( M[1][1]*M[2][3]*M[3][0] - M[1][3]*M[2][1]*M[3][0] + M[1][3]*M[2][0]*M[3][1] - M[1][0]*M[2][3]*M[3][1] - M[1][1]*M[2][0]*M[3][3] + M[1][0]*M[2][1]*M[3][3] );
IM[2][1] = det * ( M[0][3]*M[2][1]*M[3][0] - M[0][1]*M[2][3]*M[3][0] - M[0][3]*M[2][0]*M[3][1] + M[0][0]*M[2][3]*M[3][1] + M[0][1]*M[2][0]*M[3][3] - M[0][0]*M[2][1]*M[3][3] );
IM[2][2] = det * ( M[0][1]*M[1][3]*M[3][0] - M[0][3]*M[1][1]*M[3][0] + M[0][3]*M[1][0]*M[3][1] - M[0][0]*M[1][3]*M[3][1] - M[0][1]*M[1][0]*M[3][3] + M[0][0]*M[1][1]*M[3][3] );
IM[2][3] = det * ( M[0][3]*M[1][1]*M[2][0] - M[0][1]*M[1][3]*M[2][0] - M[0][3]*M[1][0]*M[2][1] + M[0][0]*M[1][3]*M[2][1] + M[0][1]*M[1][0]*M[2][3] - M[0][0]*M[1][1]*M[2][3] );
IM[3][0] = det * ( M[1][2]*M[2][1]*M[3][0] - M[1][1]*M[2][2]*M[3][0] - M[1][2]*M[2][0]*M[3][1] + M[1][0]*M[2][2]*M[3][1] + M[1][1]*M[2][0]*M[3][2] - M[1][0]*M[2][1]*M[3][2] );
IM[3][1] = det * ( M[0][1]*M[2][2]*M[3][0] - M[0][2]*M[2][1]*M[3][0] + M[0][2]*M[2][0]*M[3][1] - M[0][0]*M[2][2]*M[3][1] - M[0][1]*M[2][0]*M[3][2] + M[0][0]*M[2][1]*M[3][2] );
IM[3][2] = det * ( M[0][2]*M[1][1]*M[3][0] - M[0][1]*M[1][2]*M[3][0] - M[0][2]*M[1][0]*M[3][1] + M[0][0]*M[1][2]*M[3][1] + M[0][1]*M[1][0]*M[3][2] - M[0][0]*M[1][1]*M[3][2] );
IM[3][3] = det * ( M[0][1]*M[1][2]*M[2][0] - M[0][2]*M[1][1]*M[2][0] + M[0][2]*M[1][0]*M[2][1] - M[0][0]*M[1][2]*M[2][1] - M[0][1]*M[1][0]*M[2][2] + M[0][0]*M[1][1]*M[2][2] );
return IM;
#endif
}
float
lengthSquared( vec3 lInVec3 )
{
return dot( lInVec3, lInVec3 );
}
#endif
#ifndef D_NOISE3D
#define D_NOISE3D
STATIC_CONST vec2 lCVec4 = vec2( 1.0/6.0, 1.0/3.0 );
STATIC_CONST vec4 lDVec4 = vec4( 0.0, 0.5, 1.0, 2.0 );
vec3 mod289(vec3 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}
vec4 mod289(vec4 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}
vec4 permute(vec4 x) {
return mod289(((x*34.0)+1.0)*x);
}
vec4 taylorInvSqrt(vec4 r)
{
return 1.79284291400159 - 0.85373472095314 * r;
}
float snoise(vec3 v)
{
// First corner
vec3 i = floor(v + dot(v, lCVec4.yyy) );
vec3 x0 = v - i + dot(i, lCVec4.xxx) ;
// Other corners
vec3 g = step(x0.yzx, x0.xyz);
vec3 l = 1.0 - g;
vec3 i1 = min( g.xyz, l.zxy );
vec3 i2 = max( g.xyz, l.zxy );
// x0 = x0 - 0.0 + 0.0 * C.xxx;
// x1 = x0 - i1 + 1.0 * C.xxx;
// x2 = x0 - i2 + 2.0 * C.xxx;
// x3 = x0 - 1.0 + 3.0 * C.xxx;
vec3 x1 = x0 - i1 + lCVec4.xxx;
vec3 x2 = x0 - i2 + lCVec4.yyy; // 2.0*C.x = 1/3 = C.y
vec3 x3 = x0 - lDVec4.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
// Permutations
i = mod289(i);
vec4 p = permute( permute( permute(
i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
+ i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
+ i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
// Gradients: 7x7 points over a square, mapped onto an octahedron.
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
float n_ = 0.142857142857; // 1.0/7.0
vec3 ns = n_ * lDVec4.wyz - lDVec4.xzx;
vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)
vec4 x_ = floor(j * ns.z);
vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)
vec4 x = x_ *ns.x + ns.yyyy;
vec4 y = y_ *ns.x + ns.yyyy;
vec4 h = 1.0 - abs(x) - abs(y);
vec4 b0 = vec4( x.xy, y.xy );
vec4 b1 = vec4( x.zw, y.zw );
//vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
vec4 s0 = floor(b0)*2.0 + 1.0;
vec4 s1 = floor(b1)*2.0 + 1.0;
vec4 sh = -step(h, vec4(0.0));
vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
vec3 p0 = vec3(a0.xy,h.x);
vec3 p1 = vec3(a0.zw,h.y);
vec3 p2 = vec3(a1.xy,h.z);
vec3 p3 = vec3(a1.zw,h.w);
//Normalise gradients
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;
// Mix final noise value
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
m = m * m;
return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
dot(p2,x2), dot(p3,x3) ) );
}
#endif
//-----------------------------------------------------------------------------
// Global Data
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
// Global Data
STATIC_CONST float lf4Pi = 3.14159265358979323846 * 4.0;
//-----------------------------------------------------------------------------
// Functions
vec3
GetFarRayIntersectionPoint(
vec3 lStartPointVec3,
vec3 lDirection,
float lfRadius )
{
float lfB = 2.0 * dot( lStartPointVec3, lDirection );
float lfC = dot( lStartPointVec3, lStartPointVec3 ) - ( lfRadius * lfRadius );
float lfDet = lfB*lfB - 4.0 * lfC;
if( lfDet >= 0.0 )
{
float lfSqrt = sqrt( lfDet );
float lfFar = 0.5 * ( -lfB + lfSqrt );
return lStartPointVec3 + lDirection * lfFar;
}
else
{
return vec3( 0.0 );
}
}
vec3
GetNearRayIntersectionPoint(
vec3 lStartPointVec3,
vec3 lDirection,
float lfRadius )
{
float lfB = 2.0 * dot( lStartPointVec3, lDirection );
float lfC = dot( lStartPointVec3, lStartPointVec3 ) - ( lfRadius * lfRadius );
float lfDet = lfB*lfB - 4.0 * lfC;
if( lfDet >= 0.0 )
{
float lfSqrt = sqrt( lfDet );
float lfNear = 0.5 * ( -lfB - lfSqrt );
return normalize( lStartPointVec3 + lDirection * lfNear ) * lfRadius;
}
else
{
return vec3( 0.0 );
}
}
float
GetRayIntersectionPoint(
in vec3 lStartPointVec3,
in vec3 lEndPointVec3,
in float lfRadius,
out vec3 lOutNearPointVec3,
out vec3 lOutFarPointVec3 )
{
lOutNearPointVec3 = lStartPointVec3;
lOutFarPointVec3 = lEndPointVec3;
float lfLength = length( lStartPointVec3 - lEndPointVec3 );
vec3 lNormalisedRayVec3 = normalize( lStartPointVec3 - lEndPointVec3 );
float lfB = 2.0 * dot( lStartPointVec3, lNormalisedRayVec3 );
float lfC = dot( lStartPointVec3, lStartPointVec3 ) - ( lfRadius * lfRadius );
float lfDet = lfB * lfB - 4.0 * lfC;
if( lfDet >= 0.0 && lfLength != 0.0 )
{
float lfSqrt = sqrt( lfDet );
float lfNear = 0.5 * ( -lfB + lfSqrt );
float lfFar = 0.5 * ( -lfB - lfSqrt );
lOutFarPointVec3 = lStartPointVec3 + lNormalisedRayVec3 * lfFar;
lOutNearPointVec3 = lStartPointVec3 + lNormalisedRayVec3 * lfNear;
lfDet = 1.0;
if( max( length( lOutNearPointVec3 - lEndPointVec3 ), length( lOutNearPointVec3 - lStartPointVec3 ) ) > lfLength )
{
lOutNearPointVec3 = lStartPointVec3;
lfDet += 1.0;
}
if( max( length( lOutFarPointVec3 - lEndPointVec3 ), length( lOutFarPointVec3 - lStartPointVec3 ) ) > lfLength )
{
lOutFarPointVec3 = lEndPointVec3;
lfDet += 2.0;
}
return lfDet;
}
return 0.0;
}
float
GetAtmosphereDensity(
vec3 lSamplePointVec3,
float lfInvAtmosphereSize,
float lfScaleDepth )
{
float lfDensity;
// Distances from planet
float lfHeight = length( lSamplePointVec3 );
float lfHeightAbovePlanet = lfHeight - 1.0; // Inner radius size
// Scale based on average depth of scattering particles
lfDensity = ( lfHeightAbovePlanet * lfInvAtmosphereSize );
lfDensity = lfDensity / lfScaleDepth;
// Exponential curve out from planet
return exp( -lfDensity );
}
float
OutScattering(
vec3 lStartPointVec3,
vec3 lStartPoint,
float lfInvAtmosphereSize,
float lScatteringRatio,
float lfScaleDepth )
{
float lScattering;
float lfSegments = float( 20 );
vec3 lSamplePointVec3 = lStartPointVec3;
vec3 lRayStepVec3 = ( lStartPoint - lStartPointVec3 ) / lfSegments;
float lfIntegrationFactor = 1.0 / (2.0 * lfSegments);
#if 0
float lfInvAtmosphereSizeSN = lfInvAtmosphereSize / -lfScaleDepth ;
lScattering= exp( (length(lSamplePointVec3 + 0.0 * lRayStepVec3)-1.0) * lfInvAtmosphereSizeSN );
lScattering+= exp( (length(lSamplePointVec3 + 1.0 * lRayStepVec3)-1.0) * lfInvAtmosphereSizeSN );
lScattering+= exp( (length(lSamplePointVec3 + 2.0 * lRayStepVec3)-1.0) * lfInvAtmosphereSizeSN );
lScattering+= exp( (length(lSamplePointVec3 + 3.0 * lRayStepVec3)-1.0) * lfInvAtmosphereSizeSN );
lScattering+= exp( (length(lSamplePointVec3 + 5.0 * lRayStepVec3)-1.0) * lfInvAtmosphereSizeSN );
lScattering+= exp( (length(lSamplePointVec3 + 7.0 * lRayStepVec3)-1.0) * lfInvAtmosphereSizeSN );
lScattering+= exp( (length(lSamplePointVec3 + 11.0 * lRayStepVec3)-1.0) * lfInvAtmosphereSizeSN );
lScattering+= exp( (length(lSamplePointVec3 + 15.0 * lRayStepVec3)-1.0) * lfInvAtmosphereSizeSN );
lScattering+= exp( (length(lSamplePointVec3 + 20.0 * lRayStepVec3)-1.0) * lfInvAtmosphereSizeSN );
return lScattering*lfIntegrationFactor*lf4Pi*lScatteringRatio;
#else
// Optimised version:
// 1. exp2 is a native GCN instruction - so convert the original natural exp with a log identity
// 2. re-arrange inner exp2 maths to allow for efficient MAC code gen.
float lScattering2;
float lfInvAtmosphereSizeSN_L2 = (lfInvAtmosphereSize / lfScaleDepth) / log(2);
//float lfInvAtmosphereSizeSN_L2E = exp2(lfInvAtmosphereSizeSN_L2);
lScattering2 = exp2(lfInvAtmosphereSizeSN_L2 - length(lSamplePointVec3 + 0.0 * lRayStepVec3) * lfInvAtmosphereSizeSN_L2);
lScattering2 += exp2(lfInvAtmosphereSizeSN_L2 - length(lSamplePointVec3 + 1.0 * lRayStepVec3) * lfInvAtmosphereSizeSN_L2);
lScattering2 += exp2(lfInvAtmosphereSizeSN_L2 - length(lSamplePointVec3 + 2.0 * lRayStepVec3) * lfInvAtmosphereSizeSN_L2);
lScattering2 += exp2(lfInvAtmosphereSizeSN_L2 - length(lSamplePointVec3 + 3.0 * lRayStepVec3) * lfInvAtmosphereSizeSN_L2);
lScattering2 += exp2(lfInvAtmosphereSizeSN_L2 - length(lSamplePointVec3 + 5.0 * lRayStepVec3) * lfInvAtmosphereSizeSN_L2);
lScattering2 += exp2(lfInvAtmosphereSizeSN_L2 - length(lSamplePointVec3 + 7.0 * lRayStepVec3) * lfInvAtmosphereSizeSN_L2);
lScattering2 += exp2(lfInvAtmosphereSizeSN_L2 - length(lSamplePointVec3 + 11.0 * lRayStepVec3) * lfInvAtmosphereSizeSN_L2);
lScattering2 += exp2(lfInvAtmosphereSizeSN_L2 - length(lSamplePointVec3 + 15.0 * lRayStepVec3) * lfInvAtmosphereSizeSN_L2);
lScattering2 += exp2(lfInvAtmosphereSizeSN_L2 - length(lSamplePointVec3 + 20.0 * lRayStepVec3) * lfInvAtmosphereSizeSN_L2);
return lScattering2*lfIntegrationFactor*lf4Pi*lScatteringRatio;
#endif
}
vec3
OutScatteringReference(
vec3 lStartPointVec3,
vec3 lStartPoint,
float lfInvAtmosphereSize,
float lScatteringRatio,
float lfScaleDepth )
{
// Atmosphere Scattering
vec3 lScatteringVec3 = vec3( 0.0 );
int liSegments = 20;
float lfSegments = float( liSegments );
vec3 lSamplePointVec3 = lStartPointVec3;
vec3 lRayStepVec3 = ( lStartPoint - lStartPointVec3 ) / lfSegments;
float lfIntegrationFactor = length( lStartPoint - lStartPointVec3 ) / ( 2.0 * lfSegments );
// Sample density at points along the ray
for( int i = 0; i < liSegments + 1; i++ )
{
float lfDensity = 0.0;
lfDensity = GetAtmosphereDensity(
lSamplePointVec3,
lfInvAtmosphereSize,
lfScaleDepth );
// Accumulate and move along ray
lScatteringVec3 += vec3( lfDensity );
lSamplePointVec3 += lRayStepVec3;
}
lScatteringVec3 *= lfIntegrationFactor;
// Combine out scattering factors
lScatteringVec3 *= vec3( lf4Pi * lScatteringRatio );
return lScatteringVec3;
}
vec3
InScattering(
vec3 lStartPointVec3,
vec3 lSunPositionVec3,
vec3 lCameraPositionVec3,
float lfOuterRadius,
float lScatteringRatio,
float lfScaleDepth,
bool lbLowQuality,
bool lbNoTest )
{
float lfInvAtmosphereSize = 1.0 / ( lfOuterRadius - 1.0 );
int liSegments = lbLowQuality ? 4 : 8;
float lfSegments = float( liSegments );
float lfCameraScattering = 0.0;
float lfTotalScattering = 0.0;
// Space
vec3 lAtmosphereHitPointNear = lStartPointVec3;
vec3 lAtmosphereHitPointFar = lCameraPositionVec3 ;
if (lfScaleDepth != 0.0)
{
vec3 lSamplePointVec3 = lAtmosphereHitPointFar;
vec3 lRayStepVec3 = ( lAtmosphereHitPointNear - lAtmosphereHitPointFar ) / lfSegments;
float lfSunIntegrationFactor = length( lAtmosphereHitPointNear - lAtmosphereHitPointFar ) / ( 2.0 * lfSegments );
// Sum samples along ray from camera to world position
for( int i = 0; i < liSegments + 1; i++ )
{
float lfDensity = GetAtmosphereDensity( lSamplePointVec3, lfInvAtmosphereSize, lfScaleDepth );
lfCameraScattering += lfDensity;
if (abs(lfDensity) > 0.0003)
{
// At each step, calculate out scattering back to the camera
float lfCurrentCameraScattering = lfCameraScattering;
if( i > 0 )
{
float lfCameraIntegrationFactor = length( lSamplePointVec3 - lAtmosphereHitPointFar ) / ( 2.0 * float(i) );
lfCurrentCameraScattering *= lfCameraIntegrationFactor;
lfCurrentCameraScattering *= lf4Pi * lScatteringRatio ;
}
float lfCurrentCameraSunDensity = exp(-lfCurrentCameraScattering) * lfDensity;
if (abs(lfCurrentCameraSunDensity) > 0.0002)
{
// Out scattering between the lightsource and the sample point
float lfSunScattering = OutScattering(
lSamplePointVec3, lSamplePointVec3 + lSunPositionVec3,
lfInvAtmosphereSize,
lScatteringRatio, lfScaleDepth );
float lfSunDensity = exp( -( lfSunScattering + lfCurrentCameraScattering ) );
/*
vec3 lSunScatteringVec3Old = OutScatteringReference(
lSamplePointVec3, lSamplePointVec3 + lSunPositionVec3,
lfInvAtmosphereSize,
lScatteringRatio, lfScaleDepth );
vec3 lSunDensityOldVec3 = exp( -( lSunScatteringVec3Old + lCurrentCameraScatteringVec3 ) );
vec3 diff = abs(lSunDensityOldVec3 - lSunDensityVec3);
if ( (diff.x > 0.03) || (diff.y > 0.03) || (diff.z > 0.03) )
{
_SCE_BREAK();
}*/
// Accumulate
lfTotalScattering += lfDensity * lfSunDensity ;
}
}
lSamplePointVec3 += lRayStepVec3;
}
lfTotalScattering *= lfSunIntegrationFactor;
}
return vec3(isnan(lfTotalScattering) ? 0.0 : lfTotalScattering);
}
float
MiePhase(
vec3 lSunPositionVec3,
vec3 lRayDirectionVec3,
float lfSunScale )
{
float lfCos = dot( normalize( lSunPositionVec3 ), lRayDirectionVec3 ) / length( lRayDirectionVec3 );
float lfSunScale2 = lfSunScale * lfSunScale;
return 1.5 * ( ( 1.0 - lfSunScale2 ) / ( 2.0 + lfSunScale2 ) ) * ( 1.0 + lfCos*lfCos ) / pow( 1.0 + lfSunScale2 - 2.0*lfSunScale*lfCos, 1.5 );
}
// MiePhase with pre-normalised inputs assumed.
float
MiePhasePN(
vec3 lSunPositionVec3,
vec3 lRayDirectionVec3,
float lfSunScale)
{
float lfCos = dot(lSunPositionVec3, lRayDirectionVec3);
float lfSunScale2 = lfSunScale * lfSunScale;
return 1.5 * ((1.0 - lfSunScale2) / (2.0 + lfSunScale2)) * (1.0 + lfCos*lfCos) / pow(max(1.0 + lfSunScale2 - 2.0*lfSunScale*lfCos, 0.0000001), 1.5);
}
float
RayleighPhase(
vec3 lSunPositionVec3,
vec3 lRayDirectionVec3 )
{
float lfCos = dot( normalize( lSunPositionVec3 ), lRayDirectionVec3 ) / length( lRayDirectionVec3 );
return 0.75 * ( 1.0 + lfCos*lfCos );
}
vec3
InScatteringPhase(
vec3 lInScatteringVec3,
vec3 lSunColour,
float lfSunFactor,
float lScatteringRatio,
float lfPhase )
{
vec3 lSunStrengthVec3 = lSunColour * lfSunFactor;
float lScatterStrengthVec3 = lScatteringRatio * lfPhase;
return lSunStrengthVec3 * lScatterStrengthVec3 * lInScatteringVec3;
}
vec3
GetSpaceColour(
vec3 lWorldPositionVec3,
vec3 lCameraPositionVec3,
vec3 lSunPositionVec3,
vec3 lColour1Vec3,
vec3 lColour2Vec3,
vec3 lColour3Vec3,
float lfPower )
{
vec3 lCircumSolar0Vec3;
vec3 lCircumSolar1Vec3;
vec3 lCircumSolar2Vec3;
lCircumSolar0Vec3 = /*GammaCorrectInput*/ ( lColour1Vec3 );
lCircumSolar1Vec3 = /*GammaCorrectInput*/ (lColour2Vec3)-lCircumSolar0Vec3;
lCircumSolar2Vec3 = /*GammaCorrectInput*/ (lColour3Vec3)-lCircumSolar0Vec3;
float lfVS = dot( normalize( lWorldPositionVec3 - lCameraPositionVec3 ), normalize( lSunPositionVec3 - lCameraPositionVec3 ) );
if( lfVS > 0.0 )
{
lfVS = pow( lfVS, lfPower );
return (lCircumSolar0Vec3)+( lCircumSolar1Vec3 * lfVS );
}
else
{
lfVS = pow( abs( lfVS ), lfPower );
return (lCircumSolar0Vec3)+( lCircumSolar2Vec3 * lfVS );
}
}
#endif
////////////////////////////////////////////////////////////////////////////////
///
/// @file CommonFog.h
/// @author User
/// @date
///
/// @brief CommonFogShader
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Compilation defines
#ifndef D_COMMONFOG_H
#define D_COMMONFOG_H
//-----------------------------------------------------------------------------
// Include files
////////////////////////////////////////////////////////////////////////////////
///
/// @file CommonUniforms.h
/// @author User
/// @date
///
/// @brief CommonUniforms
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
#ifndef D_COMMONUNIFORMS2_H
#define D_COMMONUNIFORMS2_H
// =================================================================================================
#ifndef D_DEFINES
#define D_DEFINES
// =================================================================================================
// Platform defines
// =================================================================================================
#ifdef D_PLATFORM_PC
#define D_ENABLE_REVERSEZ_PROJECTION (1)
#pragma optionNV(strict on)
#extension GL_ARB_gpu_shader5 : enable
#extension GL_ARB_fragment_coord_conventions : enable
#extension GL_ARB_derivative_control : enable
#if defined( D_FRAGMENT ) && defined( _F64_ )
layout(early_fragment_tests) in;
#endif
#elif defined(D_PLATFORM_ORBIS)
#define D_ENABLE_REVERSEZ_PROJECTION (1)
// use this with sdk 2.0 compiler
// #pragma argument (allow-scratch-buffer-spill)
//define these flags so they don't get ignored in build process and in the comb mask
//this is because materials, vertex layouts and shaders need to be synced on 360 to avoid patching
#ifdef _F27_
#endif
#ifdef _F28_
#endif
#ifdef _F29_
#endif
#ifdef _F21_
#endif
#ifdef _F02_
#endif
#ifdef _F03_
#endif
#if defined( _F01_ ) || defined( D_LOD0 ) || defined( D_LOD1 ) || defined( D_LOD2 ) || defined( D_LOD3) || defined( D_LOD4 )
#endif
#ifdef _F01_
#endif
#ifdef _F09_
#endif
#ifdef _F10_
#endif
// disable warnings for unused parameters. This happens a lot because of defining different things.
#pragma warning (disable: 5203)
// temp thing to know what things are still required on ps4.
#define D_PLATFORM_ORBIS_FIX
#ifdef __PSSL_CS__
#define D_PLATFORM_ORBIS_COMPUTE
#endif
#ifdef __PSSL_HS__
#define D_HULL
#endif
#ifdef __PSSL_DS__
#define D_DOMAIN
#endif
#ifdef __PSSL_VS__
#define D_VERTEX
#endif
#ifdef __PSSL_GS__
#define D_GEOMETRY
#endif
#endif
#if !D_ENABLE_REVERSEZ_PROJECTION
#define D_USING_LOGDEPTH
#endif
// =================================================================================================
// Basic Types
// =================================================================================================
#ifdef D_PLATFORM_PC
#define JOINT_TYPE vec4
//#define CONST const
#define STATIC_CONST const
#elif defined(D_PLATFORM_ORBIS)
#define JOINT_TYPE int4
#define float float
#define vec2 float2
#define vec3 float3
#define vec4 float4
#define ivec2 int2
#define ivec3 int3
#define ivec4 int4
#define uvec2 uint2
#define uvec3 uint3
#define uvec4 uint4
// NOTE:
// operator[] accesses rows, not columns
// matrix constructors interpret the passed vectors as row vectors, not column vectors
#define mat2 row_major float2x2
#define mat3 row_major float3x3
#define mat4 row_major float4x4
//#define CONST
#define STATIC_CONST static const
// #define const ERROR, DON'T USE CONST FOR PS4. USE STATIC_CONST INSTEAD FOR A COMPILED IN CONSTANT. OTHERWISE IT TRIES TO PUT IT IN A CONSTANT BUFFER AND FOR SOME REASON IT DOESN'T WORK.
#endif
// =================================================================================================
// Functions
// =================================================================================================
#ifdef D_PLATFORM_PC
#define saturate( V ) min( max( V, 0.0) , 1.0)
#define atan2( Y, X ) atan( Y, X )
#define invsqrt( X ) inversesqrt( X )
#ifdef D_COMPUTE
#define groupID gl_WorkGroupID
#define groupThreadID gl_LocalInvocationID
#define dispatchThreadID gl_GlobalInvocationID
#endif
#elif defined(D_PLATFORM_ORBIS)
#if defined(D_PLATFORM_ORBIS_COMPUTE)
float dFdx( float var ) { float delta = var - LaneSwizzle( var, 0x1f, 0, 1 ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
float dFdy( float var ) { float delta = var - LaneSwizzle( var, 0x1f, 0, 8 ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec2 dFdx( vec2 var ) { vec2 delta = vec2( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec2 dFdy( vec2 var ) { vec2 delta = vec2( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec3 dFdx( vec3 var ) { vec3 delta = vec3( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec3 dFdy( vec3 var ) { vec3 delta = vec3( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec4 dFdx( vec4 var ) { vec4 delta = vec4( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.w, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec4 dFdy( vec4 var ) { vec4 delta = vec4( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.w, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
#define dFdxFine dFdx
#define dFdyFine dFdy
#else
#define dFdx ddx
#define dFdy ddy
#define dFdxFine ddx_fine
#define dFdyFine ddy_fine
#endif
#define mix lerp
#define fract frac
#define mod fmod
#define saturate( V ) ( min( max( V, 0.0) , 1.0) )
#define invsqrt( X ) rsqrt( X )
#endif
// =================================================================================================
// Samplers and textures
// =================================================================================================
#ifdef D_PLATFORM_PC
#define shadow2D( S, UV ) texture( S, UV )
#define SAMPLER2DSHADOW( NAME, REG ) uniform sampler2DShadow NAME
#define SAMPLERCUBE( NAME ) samplerCube NAME
#define SAMPLERCUBEARG( NAME ) in samplerCube NAME
#define SAMPLERCUBEPARAM( NAME ) NAME
#define imageAtomicAddOut( T, C, V, O ) O = imageAtomicAdd( T, C, V )
#if defined( D_TEXTURE_FEEDBACK )
#define texture2D( T, C ) Tex2dFeedback( T, T##FB, C )
#define texture2DLod( T, C, N ) Tex2dLodFeedback( T, T##FB, C, N )
#define texture2DArray( T, C ) Tex2dArrayFeedback( T, T##FB, C )
#define texture3D( S, UV ) Tex3dFeedback( S, S##FB, UV )
#define texture3DLod( S, UV, LOD ) Tex3dLodFeedback( S, S##FB, UV, LOD )
#define SAMPLER2DARG( NAME ) in sampler2D NAME, in int NAME##FB
#define SAMPLER2DPARAM( NAME ) NAME, NAME##FB
#define SAMPLER2DARRAYARG( NAME ) in sampler2DArray NAME, in int NAME##FB
#define SAMPLER2DARRAYPARAM( NAME ) NAME, NAME##FB
#define SAMPLER2D( NAME ) sampler2D NAME; int NAME##FB
#define SAMPLER2DARRAY( NAME ) sampler2DArray NAME; int NAME##FB
#define SAMPLER3D( NAME ) sampler3D NAME; int NAME##FB
#define SAMPLER2DSHADOW_SRT( NAME ) sampler2DShadow NAME; int NAME##FB
#else
#define texture2DLod( S, UV, LOD ) textureLod( S, UV, LOD )
#define texture3DLod( S, UV, LOD ) textureLod( S, UV, LOD )
#define SAMPLER2DARG( NAME ) in sampler2D NAME
#define SAMPLER2DPARAM( NAME ) NAME
#define SAMPLER2DARRAYARG( NAME ) in sampler2DArray NAME
#define SAMPLER2DARRAYPARAM( NAME ) NAME
#define SAMPLER2D( NAME ) sampler2D NAME
#define SAMPLER2DARRAY( NAME ) sampler2DArray NAME
#define SAMPLER3D( NAME ) sampler3D NAME
#define SAMPLER2DSHADOW_SRT( NAME ) sampler2DShadow NAME
#endif
#define textureGatherRed( lTex, lSamp ) textureGather( lTex, lSamp, 0 )
#define textureGatherGreen( lTex, lSamp ) textureGather( lTex, lSamp, 1 )
#define textureGatherBlue( lTex, lSamp ) textureGather( lTex, lSamp, 2 )
#define textureGatherAlpha( lTex, lSamp ) textureGather( lTex, lSamp, 3 )
#define texture2DComputeGrad( T, C ) texture2D( T, C )
#elif defined(D_PLATFORM_ORBIS)
#define SAMPLERCUBE( NAME, REG ) SamplerState NAME##SS : register( s##REG ); TextureCube NAME##TU : register( t##REG )
#define SAMPLER2D( NAME ) Texture2D NAME; SamplerState NAME##SS
#define SAMPLER2DSHADOW_SRT( NAME ) Texture2D NAME; SamplerComparisonState NAME##SS //SAMPLER2D( NAME )
#define SAMPLER3D( NAME ) Texture3D NAME; SamplerState NAME##SS
#define SAMPLER2DARRAY( NAME ) Texture2D_Array NAME; SamplerState NAME##SS
#define SAMPLER2DARRAYARG( NAME ) Texture2D_Array NAME, SamplerState NAME##SS
#define SAMPLER2DARRAYPARAM( NAME ) NAME, NAME##SS
#define SAMPLER2DPARAM( NAME ) NAME, NAME##SS
#define SAMPLER2DARG( NAME ) Texture2D NAME, SamplerState NAME##SS
#define texture2D( T, C ) T.Sample( T##SS, C )
#if defined(D_PLATFORM_ORBIS_COMPUTE)
#define texture2DComputeGrad( T, C ) T.SampleGradient( T##SS, C, vec2( dFdx( C ) ), vec2( dFdy( C ) ) )
#define shadow2D( T, C ) T.SampleCmpLOD0( T##SS, C.xy, C.z )
#else
#define texture2DComputeGrad( T, C ) T.Sample( T##SS, C )
#define shadow2D( T, C ) T.SampleCmp( T##SS, C.xy, C.z )
#endif
#define texture2DLod( T, C, N ) T.SampleLOD( T##SS, C, N )
#define texture2DArray( T, C ) T.Sample( T##SS, C )
#define texture3DLod( T, C, N ) T.SampleLOD( T##SS, C, N )
//#define shadow2D( T, C ) vec3( C.z > T.Sample( T##SS, C.xy ).x ? 1.0 : 0.0 )
//#define shadow2D( T, C ) T.GatherCmp( T##SS, C.xy, C.z )
//#define shadow2D( T, C ) T.SampleCmpLOD0( T##SS, C.xy, C.z )
#define textureCube( T, C ) T##TU.Sample( T##SS, C )
#define textureCubeLod( T, C, N ) T##TU.Sample( T##SS, C, N )
#define textureGrad( T, C, DDX, DDY ) T.SampleGradient( T##SS, C, DDX, DDY )
#define imageAtomicAdd( T, C, V ) AtomicAdd( T[ C ], V )
#define imageAtomicAddOut( T, C, V, O ) AtomicAdd( T[ C ], V, O )
#define imageStore( T, C, V ) ( T[C] = V )
#define textureGatherRed( lTex, lSamp ) lTex.GatherRed ( lTex##SS, lSamp )
#define textureGatherGreen( lTex, lSamp ) lTex.GatherGreen( lTex##SS, lSamp )
#define textureGatherBlue( lTex, lSamp ) lTex.GatherBlue ( lTex##SS, lSamp )
#define textureGatherAlpha( lTex, lSamp ) lTex.GatherAlpha( lTex##SS, lSamp )
#define texelFetch( lTex, lSamp, lLod ) lTex.MipMaps((lLod), (lSamp))
#endif
#if defined(D_PLATFORM_ORBIS_COMPUTE)
#define THREADGROUP_LOCAL thread_group_memory
#define THREADGROUP_BARRIER ThreadGroupMemoryBarrier()
#elif defined(D_PLATFORM_PC_COMPUTE)
#define THREADGROUP_LOCAL layout( shared )
#define THREADGROUP_BARRIER groupMemoryBarrier()
#endif
// =================================================================================================
// Matrices
// =================================================================================================
#ifdef D_PLATFORM_PC
#define MUL( INPUT_A, INPUT_B ) (INPUT_A * INPUT_B)
#define PLATFORM_TRANSPOSE
#define MAT4_SET_POS( M, P ) M[ 3 ] = P
#define MAT4_SET_TRANSLATION( M, T ) M[ 3 ].xyz = T
#define MAT4_GET_COLUMN( M, C ) M[ C ].xyz
#define MAT3_GET_COLUMN( M, C ) M[ C ]
#define MAT4_GET_COLUMN_VEC4( M, C ) M[ C ]
#define MAT3_SET_COLUMN( M, C, V ) M[ C ] = V;
#define MAT4_SET_COLUMN( M, C, V ) M[ C ] = V;
#elif defined(D_PLATFORM_ORBIS)
#define MUL( INPUT_A, INPUT_B ) mul( INPUT_B, INPUT_A )
#define PLATFORM_TRANSPOSE
#define MAT4_SET_POS( M, P ) M[ 3 ] = P
#define MAT4_SET_TRANSLATION( M, T ) M[ 3 ].xyz = T
#define MAT4_GET_COLUMN( M, C ) M[ C ].xyz
#define MAT3_GET_COLUMN( M, C ) M[ C ]
#define MAT4_GET_COLUMN_VEC4( M, C ) M[ C ]
#define MAT3_SET_COLUMN( M, C, V ) M[ C ] = V;
#define MAT4_SET_COLUMN( M, C, V ) M[ C ] = V;
#endif
// =================================================================================================
// Arrays (workaround AMD shader compiler issues by making arrays have global scope)
// =================================================================================================
#if defined(D_PLATFORM_ORBIS)
#define ARRAY_LOOKUP_FS( _UNIFORMS, _ELEMENT, _INDEX) _UNIFORMS._ELEMENT[_INDEX]
#define ARRAY_LOOKUP_FP( _UNIFORMS, _ELEMENT, _INDEX) _UNIFORMS._ELEMENT[_INDEX]
#else
#define ARRAY_LOOKUP_FS( _UNIFORMS, _ELEMENT, _INDEX) _ELEMENT[_INDEX]
#define ARRAY_LOOKUP_FP( _UNIFORMS, _ELEMENT, _INDEX) _ELEMENT[_INDEX]
#endif
// =================================================================================================
// Input and Output
// =================================================================================================
#ifdef D_PLATFORM_PC
#define UNIFORM( TYPE, NAME ) uniform TYPE NAME
#define UNIFORM_SRT( TYPE, NAME ) uniform TYPE NAME
#define DECLARE_INPUT
#define DECLARE_OUTPUT
#define DECLARE_END
#define DECLARE_PTR( TYPE, NAME ) TYPE NAME;
#define DECLARE_PATCH_INPUT_TRI
#define DECLARE_PATCH_OUTPUT_TRI
#define IN_PATCH_TRI_TESS_CONSTANTS
#define OUT_PATCH_TRI_TESS_CONSTANTS
#define DECLARE_PATCH_INPUT_QUAD
#define DECLARE_PATCH_OUTPUT_QUAD
#define IN_PATCH_QUAD_TESS_CONSTANTS
#define OUT_PATCH_QUAD_TESS_CONSTANTS
#if defined( D_HULL )
#define INPUT( TYPE, NAME, REG ) in TYPE NAME [];
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME [];
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME [];
#define PATCH_OUTPUT( TYPE, NAME, REG ) patch out TYPE NAME;
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME [];
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME [];
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME [];
#elif defined( D_DOMAIN )
#define PATCH_INPUT( TYPE, NAME, REG ) patch in TYPE NAME;
#define INPUT( TYPE, NAME, REG ) in TYPE NAME [];
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME [];
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME [];
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME;
#else
#define INPUT( TYPE, NAME, REG ) in TYPE NAME;
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME;
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME;
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME;
#endif
#define FRAGMENT_COLOUR_UVEC4_DEFINE layout(location = 0) out uvec4 outu_color0;
#define FRAGMENT_COLOUR_UVEC4 outu_color0
#define FRAGMENT_COLOUR out_color0
#define FRAGMENT_COLOUR0 out_color0
#define FRAGMENT_COLOUR1 out_color1
#define FRAGMENT_COLOUR2 out_color2
#define FRAGMENT_COLOUR3 out_color3
#define FRAGMENT_COLOUR4 out_color4
#if defined( D_TAA_RENDER_TARGETS )
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1; layout(location = 2) out vec4 out_color2;
#elif !defined(D_ATTRIBUTES)
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0;
#else
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1; layout(location = 2) out vec4 out_color2; layout(location = 3) out vec4 out_color3; layout(location = 4) out vec4 out_color4;
#endif
#define FRAGMENT_COLOUR01_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1;
#define FRAGMENT_DEPTH gl_FragDepth
#define FRAGMENT_FRONTFACE gl_FrontFacing
#define INPUT_FRONTFACING
#define DEREF_PTR( VAR ) VAR
#if defined( D_HULL )
#define IN( VAR ) VAR[ gl_InvocationID ]
#define OUT( VAR ) VAR[ gl_InvocationID ]
#define PATCH_OUT( VAR ) VAR
#define OUTPUT_VERTEX_SCREEN_POSITION gl_out[ gl_InvocationID ].gl_Position
#define INPUT_VERTEX_SCREEN_POSITION gl_in [ gl_InvocationID ].gl_Position
#define TESS_LEVEL_EDGE( IND ) gl_TessLevelOuter[ IND ]
#define TESS_LEVEL_INNER( IND ) gl_TessLevelInner[ IND ]
#elif defined( D_DOMAIN )
#define PATCH_IN( VAR, IND ) VAR[ IND ]
#define IN( VAR, IND ) VAR[ IND ]
#define OUT( VAR ) VAR
#define INPUT_VERTEX_SCREEN_POSITION( IND ) gl_in [ IND ].gl_Position
#define DOMAIN_COORDS gl_TessCoord
#elif defined( D_GEOMETRY )
#define OUTPUT_VERTEX_SCREEN_POSITION gl_Position
#define INPUT_VERTEX_SCREEN_POSITION( IND ) gl_in [ IND ].gl_Position
#define IN( VAR, IND ) VAR[ IND ]
#define OUT( VAR ) VAR
#else
#define IN( VAR ) VAR
#define OUT( VAR ) VAR
#endif
#define OUT_VERTEX_SCREEN_POSITION
#define IN_SCREEN_POSITION
#define VERTEX_SCREEN_POSITION gl_Position
#elif defined(D_PLATFORM_ORBIS_COMPUTE)
#define DECLARE_INPUT struct cInput {
#define DECLARE_END };
#define DECLARE_PTR( TYPE, NAME ) TYPE* NAME;
#define INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define INPUT_NOINTERP( TYPE, NAME, REG ) TYPE NAME : REG;
#define IN_SCREEN_POSITION
#define FRAGMENT_COLOUR lUniforms.mpCmpOutPerMesh.gOutTexture0[dispatchThreadID.xy]
#define FRAGMENT_COLOUR0 lUniforms.mpCmpOutPerMesh.gOutTexture0[dispatchThreadID.xy]
#define FRAGMENT_COLOUR1 lUniforms.mpCmpOutPerMesh.gOutTexture1[dispatchThreadID.xy]
#define FRAGMENT_COLOUR2 lUniforms.mpCmpOutPerMesh.gOutTexture2[dispatchThreadID.xy]
#define FRAGMENT_COLOUR3 lUniforms.mpCmpOutPerMesh.gOutTexture3[dispatchThreadID.xy]
#define FRAGMENT_COLOUR4 lUniforms.mpCmpOutPerMesh.gOutTexture4[dispatchThreadID.xy]
#define FRAGMENT_DEPTH lUniforms.mpCmpOutPerMesh.gOutTextureDepth[dispatchThreadID.xy]
#define DEREF_PTR( VAR ) *VAR
#elif defined(D_PLATFORM_ORBIS)
#define UNIFORM( TYPE, NAME ) ConstantBuffer NAME##CB{ TYPE NAME; };
#define UNIFORM_SRT( TYPE, NAME ) ConstantBuffer NAME##CB{ TYPE NAME : S_SRT_DATA; };
#define DECLARE_OUTPUT struct cOutput {
#define DECLARE_INPUT struct cInput {
#define DECLARE_END };
#define DECLARE_PTR( TYPE, NAME ) TYPE* NAME;
#define INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define INPUT_NOINTERP( TYPE, NAME, REG ) nointerp TYPE NAME : REG;
#define INPUT_NOPERSP( TYPE, NAME, REG ) nopersp TYPE NAME : REG;
#define OUTPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) nointerp TYPE NAME : REG;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) nopersp TYPE NAME : REG;
#define FRAGMENT_COLOUR_UVEC4_DEFINE
#define FRAGMENT_COLOUR_UVEC4 Out.mColour
#define FRAGMENT_COLOUR Out.mColour
#define FRAGMENT_COLOUR0 Out.mColour0
#define FRAGMENT_COLOUR1 Out.mColour1
#define FRAGMENT_COLOUR2 Out.mColour2
#define FRAGMENT_COLOUR3 Out.mColour3
#define FRAGMENT_COLOUR4 Out.mColour4
#define FRAGMENT_DEPTH Out.mDepth
#define FRAGMENT_FRONTFACE In.mbFrontFacing
#define INPUT_FRONTFACING bool mbFrontFacing : S_FRONT_FACE;
#if defined( D_HULL )
#define IN( VAR ) In[ uCPID ].VAR
#define OUT( VAR ) Out.VAR
#define PATCH_OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION IN( mScreenPositionVec4 )
#define TESS_LEVEL_EDGE( IND ) Out.edge_ts[ IND ]
#define TESS_LEVEL_INNER( IND ) Out.insi_ts[ IND ]
#define DECLARE_PATCH_OUTPUT_TRI [DOMAIN_PATCH_TYPE("tri")] struct HSConstantOutputData {
#define OUT_PATCH_TRI_TESS_CONSTANTS float edge_ts[3] : S_EDGE_TESS_FACTOR; \
float insi_ts[1] : S_INSIDE_TESS_FACTOR;
#define DECLARE_PATCH_OUTPUT_QUAD [DOMAIN_PATCH_TYPE("quad")] struct HSConstantOutputData (
#define OUT_PATCH_QUAD_TESS_CONSTANTS float edge_ts[4] : S_EDGE_TESS_FACTOR; \
float insi_ts[2] : S_INSIDE_TESS_FACTOR;
#define PATCH_OUTPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#elif defined( D_DOMAIN )
#define PATCH_IN( VAR, IND ) patchIn.VAR
#define IN( VAR, IND ) In[ IND ].VAR
#define OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION( IND ) IN( mScreenPositionVec4, IND )
#define DOMAIN_COORDS domainCoordinates
#define DECLARE_PATCH_INPUT_TRI [DOMAIN_PATCH_TYPE("tri")] struct HSConstantOutputData {
#define IN_PATCH_TRI_TESS_CONSTANTS float edge_ts[3] : S_EDGE_TESS_FACTOR; \
float insi_ts[1] : S_INSIDE_TESS_FACTOR;
#define DECLARE_PATCH_INPUT_QUAD [DOMAIN_PATCH_TYPE("quad")] struct HSConstantOutputData {
#define IN_PATCH_QUAD_TESS_CONSTANTS float edge_ts[4] : S_EDGE_TESS_FACTOR; \
float insi_ts[2] : S_INSIDE_TESS_FACTOR;
#define PATCH_INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#elif defined( D_GEOMETRY )
#define IN( VAR, IND ) In[ IND ].VAR
#define OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION( IND ) IN( mScreenPositionVec4, IND )
#define EMIT_VERTEX TriStream.Append( Out )
#define END_PRIMITIVE TriStream.RestartStrip()
#else
#define IN( VAR ) In.VAR
#define OUT( VAR ) Out.VAR
#endif
// TODO get rid of this - don't pass struct through functinos, pass members.
#define DEREF_PTR( VAR ) *VAR
#define OUT_VERTEX_SCREEN_POSITION OUTPUT( vec4, mScreenPositionVec4, S_POSITION )
#define IN_SCREEN_POSITION INPUT ( vec4, mScreenPositionVec4, S_POSITION )
#define VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#endif
// =================================================================================================
// Main
// =================================================================================================
#ifdef D_PLATFORM_PC
#define VERTEX_MAIN void main( void )
#define VERTEX_MAIN_SRT uniform UniformBuffer lUniforms; void main( void )
#define HULL_TRI_MAIN_SRT layout( vertices = 3 ) out; uniform UniformBuffer lUniforms; void main( void )
#define HULL_QUAD_MAIN_SRT layout( vertices = 4 ) out; uniform UniformBuffer lUniforms; void main( void )
#define DOMAIN_TRI_MAIN_SRT layout( triangles, fractional_even_spacing ) in; uniform UniformBuffer lUniforms; void main( void )
#define DOMAIN_QUAD_MAIN_SRT layout( quads, fractional_even_spacing ) in; uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define VOID_MAIN_COLOUR FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_GE_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_LE_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_EARLYZ_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_UICOLOUR_SRT FRAGMENT_COLOUR_UVEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define VOID_MAIN_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define VOID_MAIN_DEPTH_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR01_SRT FRAGMENT_COLOUR01_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR01_DEPTH_SRT FRAGMENT_COLOUR01_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#elif defined( D_PLATFORM_PC_COMPUTE )
#define COMPUTE_MAIN_SRT( X, Y, Z ) layout (local_size_x = X, local_size_y = Y, local_size_z = Z) in; void main( void )
#define FRAGMENT_MAIN_COLOUR_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR01_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#elif defined( D_PLATFORM_ORBIS_COMPUTE )
#define COMPUTE_MAIN_SRT( X, Y, Z ) [NUM_THREADS(X, Y, Z)] void main(uint3 groupID : S_GROUP_ID, uint3 groupThreadID : S_GROUP_THREAD_ID, uint3 dispatchThreadID : S_DISPATCH_THREAD_ID, UniformBuffer lUniforms : S_SRT_DATA)
#define FRAGMENT_MAIN_COLOUR_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR01_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#elif defined( D_PLATFORM_ORBIS )
#define VERTEX_MAIN void main( cInput In, out cOutput Out )
#define VERTEX_MAIN_SRT void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define HULL_TRI_MAIN_SRT [DOMAIN_PATCH_TYPE("tri")] \
[PARTITIONING_TYPE("integer")] \
[OUTPUT_TOPOLOGY_TYPE("triangle_cw")] \
[OUTPUT_CONTROL_POINTS(3)] \
[PATCH_CONSTANT_FUNC("ConstantsHS")] \
[MAX_TESS_FACTOR(16.0)] \
void main( \
InputPatch<cInput, 3> In, \
uint uCPID : S_OUTPUT_CONTROL_POINT_ID, \
UniformBuffer lUniforms : S_SRT_DATA, \
out cOutput Out )
#define HULL_QUAD_MAIN_SRT [DOMAIN_PATCH_TYPE("quad")] \
[PARTITIONING_TYPE("integer")] \
[OUTPUT_TOPOLOGY_TYPE("triangle_cw")] \
[OUTPUT_CONTROL_POINTS(4)] \
[PATCH_CONSTANT_FUNC("ConstantsHS")] \
[MAX_TESS_FACTOR(16.0)] \
void main( \
InputPatch<cInput, 4> In, \
uint uCPID : S_OUTPUT_CONTROL_POINT_ID, \
UniformBuffer lUniforms : S_SRT_DATA, \
out cOutput Out )
#define DOMAIN_TRI_MAIN_SRT [DOMAIN_PATCH_TYPE("tri")] \
void main( \
HSConstantOutputData patchIn, \
const OutputPatch<cInput, 3> In, \
out cOutput Out, \
UniformBuffer lUniforms : S_SRT_DATA, \
float3 domainCoordinates : S_DOMAIN_LOCATION )
#define DOMAIN_QUAD_MAIN_SRT [DOMAIN_PATCH_TYPE("quad")] \
void main( \
HSConstantOutputData patchIn, \
const OutputPatch<cInput, 4> In, \
out cOutput Out, \
UniformBuffer lUniforms : S_SRT_DATA, \
float2 domainCoordinates : S_DOMAIN_LOCATION )
#define GEOMETRY_MAIN_SRT( MAX_VERTS ) cOutput Out; [MAX_VERTEX_COUNT(MAX_VERTS)] void main( inout TriangleBuffer<cOutput> TriStream, Triangle cInput In[3], UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out )
#define VOID_MAIN_COLOUR struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; void main( cInput In, out cOutput Out )
#define FRAGMENT_MAIN_COLOUR_DEPTH struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out )
#define VOID_MAIN_SRT void main( cInput In, UniformBuffer lUniforms : S_SRT_DATA )
#if defined( D_TAA_RENDER_TARGETS )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#elif !defined( D_ATTRIBUTES )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_DEPTH_GE_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_GE_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_DEPTH_LE_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_LE_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define VOID_MAIN_DEPTH_SRT struct cOutput { float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define VOID_MAIN_COLOUR_EARLYZ_SRT [FORCE_EARLY_DEPTH_STENCIL] void main( cInput In, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR01_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR01_DEPTH_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
float mDepth : S_DEPTH_OUTPUT; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#else
// #pragma PSSL_target_output_format(target 1 FMT_32_AR)
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; \
float mDepth : S_DEPTH_OUTPUT; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_EARLYZ_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; }; \
[FORCE_EARLY_DEPTH_STENCIL] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#endif
#endif
// =================================================================================================
// Texture resolution
// =================================================================================================
#ifdef D_PLATFORM_ORBIS
uvec2 GetResolution( Texture2D lTexture )
{
uvec2 lResolution;
lTexture.GetDimensionsFast(lResolution.x, lResolution.y);
return lResolution;
}
uvec2 GetResolution( RW_Texture2D<float4> lTexture )
{
uvec2 lResolution;
lTexture.GetDimensionsFast(lResolution.x, lResolution.y);
return lResolution;
}
#else
uvec2 GetResolution( sampler2D lTexture )
{
return textureSize( lTexture, 0 );
}
#endif
// =================================================================================================
// Viewport
// =================================================================================================
#ifdef D_PLATFORM_PC
#define SCREENSPACE_AS_RENDERTARGET_UVS( A ) A.xy
#elif defined(D_PLATFORM_ORBIS)
#define SCREENSPACE_AS_RENDERTARGET_UVS( A ) ( float2( A.x, 1.0 - A.y ) )
#endif
#ifdef D_USING_LOGDEPTH
#define D_DEPTH_CLEARVALUE (1.0)
#else
#define D_DEPTH_CLEARVALUE (0.0)
#endif
// =================================================================================================
// Texture usage feedback
// =================================================================================================
#if defined( D_TEXTURE_FEEDBACK ) && defined( D_PLATFORM_PC )
layout(r32i) uniform iimage2D gTexFeedbackImg;
void WriteTexFeedback( in int liCounter, in float liMip )
{
if( liCounter != 0 )
{
#if defined( GL_ARB_shader_ballot ) && ( GL_ARB_shader_ballot == 1 )
if( readFirstInvocationARB( gl_SubGroupInvocationARB ) == gl_SubGroupInvocationARB )
#endif
{
int liIntMip = int(floor(liMip));
//imageStore( gTexFeedbackImg, ivec2( liCounter, liIntMip ), ivec4(1,0,0,0) );
imageAtomicAdd( gTexFeedbackImg, ivec2( liCounter, liIntMip ), int(1) );
}
}
}
vec4 Tex2dFeedback( in sampler2D lSamp, in int liCounter, in vec2 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex2dLodFeedback( in sampler2D lSamp, in int liCounter, in vec2 lCoords, in float liLod )
{
WriteTexFeedback( liCounter, liLod );
return textureLod( lSamp, lCoords, liLod );
}
vec4 Tex2dArrayFeedback( in sampler2DArray lSamp, in int liCounter, in vec3 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords.xy ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex3dFeedback( in sampler3D lSamp, in int liCounter, in vec3 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex3dLodFeedback( in sampler3D lSamp, in int liCounter, in vec3 lCoords, in float liLod )
{
WriteTexFeedback( liCounter, liLod );
return textureLod( lSamp, lCoords, liLod );
}
#endif
#endif
struct PerFrameUniforms
{
vec4 gLightPositionVec4; // EShaderConst_LightPositionVec4
vec4 gLightDirectionVec4; // EShaderConst_LightDirectionVec4
vec3 gViewPositionVec3; // EShaderConst_ViewPositionVec3
float gfTime; // EShaderConst_Time
float gfPrevTime; // EShaderConst_PrevTime
vec4 gClipPlanesVec4; // EShaderConst_ClipPlanesVec4
vec4 gClipPlanesRVec4; // EShaderConst_ClipPlanesRVec4
mat4 gCameraMat4; // EShaderConst_CameraMat4
mat4 gCameraDeltaMat4; // EShaderConst_CameraDeltaMat4
mat4 gPrevViewProjectionMat4; // EShaderConst_PrevViewProjectionMat4
vec4 gMBlurSettingsVec4; // EShaderConst_BlurSettingsVec4
vec4 gDeJitterVec4; // EShaderConst_DeJitterVec4
vec4 gTaaSettingsVec4; // EShaderConst_TaaSettingsVec4
vec4 gFrameBufferSizeVec4;
vec4 gFoVValuesVec4; // EShaderConst_FoVValuesVec4
vec4 gShadowSizeVec4;
vec4 gShadowFadeParamVec4;
vec4 gShadowProjScaleVec4[3]; // EShaderConst_ShadowProjScaleVec4
mat4 gViewMat4; // EShaderConst_ViewMat4
};
struct CommonPerMeshUniforms
{
// These are planet specific. Should they be here?
vec4 gPlanetPositionVec4;
vec4 gLightOriginVec4;
mat4 gWorldMat4; // EShaderConst_WorldMat4
mat4 gWorldMotionMat4; // EShaderConst_WorldMotionMat4
mat4 gWorldViewProjectionMat4; // EShaderConst_WorldViewProjectionMat4
mat4 gWorldNormalMat4; // EShaderConst_WorldNormalMat4
#if defined( D_FADE ) && !defined( D_INSTANCE )
float gfFadeValue; // EShaderConst_FadeTime
#else
float fdFadeValueDummy;
#endif
#if defined( D_SKINNING_UNIFORMS ) && defined( D_PLATFORM_ORBIS )
vec4 gaSkinMatrixRowsVec4[ 75 * 3 ];
vec4 gaPrevSkinMatrixRowsVec4[ 75 * 3 ];
#endif
//float gfShadowBias; // EShaderConst_ShadowBias
// have particle shader use a particlecommon instead of uber, and put these into it.
#if defined( D_PARTICLE_UNIFORMS ) && defined( D_PLATFORM_ORBIS )
vec4 gaParticleCornersVec4[ 4 ]; // EShaderConst_ParticleCornersVec4
vec4 gaParticlePositionsVec4[ 32 ]; // EShaderConst_ParticlePositionsVec4
vec4 gaParticleSizeAndRotationsVec4[ 32 ]; // EShaderConst_ParticleSizeAndRotationsVec4
vec4 gaParticleNormalsVec4[ 32 ]; // EShaderConst_ParticleNormalsVec4
vec4 gaParticleColoursVec4[ 32 ]; // EShaderConst_ParticleColoursVec4
#endif
// This stuff is here atm because of shadows. The shadow shader is one thing, but renders twice, with these needing to be set differently.
// ideally we don't want them set per mesh though, probably a SRT for 'percamera' or something
//
//
mat4 gProjectionMat4; // EShaderConst_ProjectionMat4
mat4 gViewProjectionMat4; // EShaderConst_ViewProjectionMat4
#if !defined( D_DEPTHONLY )
mat4 gInverseWorldUpMat4;
// Stop these being compiled in when recolouring as the recolour shader needs ALL tex units.
#if defined( D_DEFERRED_DECAL )
mat4 gInverseModelMat4; // EShaderConst_InverseModelMat4 = 0
#else
mat4 gInverseProjectionSCMat4; // EShaderConst_InverseProjectionSCMat4
#endif
mat4 gInverseViewMat4; // EShaderConst_InverseViewMat4
mat4 gInverseProjectionMat4; // EShaderConst_InverseProjectionMat4
//mat4 gInverseViewProjectionMat4; // EShaderConst_InverseViewProjectionMat4
mat4 gaShadowMat4[ 3 ]; // EShaderConst_ShadowMat4
vec4 gLightColourVec4; // EShaderConst_LightColourVec4
#ifdef D_IBL
vec4 gGenericParam0Vec4; // EShaderConst_GenericParam0Vec4
#else
vec4 gGenericParam0DummyVec4;
#endif
// These shouldn't be per mesh, the should be per rendertarget. BUT we need to add them to the enum
// in egShader and SetPErRenderTargetUniforms for that to work and we're trying to do a build for sony
// so that will have to wait. (also probably need a way of setting per RT uniforms from Game).
vec4 gScanParamsPosVec4;
vec4 gScanParamsCfg1Vec4;
vec4 gScanParamsCfg2Vec4;
vec4 gScanParamsCfg3Vec4;
vec4 gScanColourVec4;
vec4 gSpotlightPositionVec4;
vec4 gSpotlightDirectionVec4;
#endif
vec4 gUserDataVec4;
};
#if defined( D_PARTICLE_UNIFORMS ) && defined( D_PLATFORM_PC )
uniform vec4 gaParticleCornersVec4[4]; // EShaderConst_ParticleCornersVec4
uniform vec4 gaParticlePositionsVec4[32]; // EShaderConst_ParticlePositionsVec4
uniform vec4 gaParticleSizeAndRotationsVec4[32]; // EShaderConst_ParticleSizeAndRotationsVec4
uniform vec4 gaParticleNormalsVec4[32]; // EShaderConst_ParticleNormalsVec4
uniform vec4 gaParticleColoursVec4[32]; // EShaderConst_ParticleColoursVec4
#endif
#endif
////////////////////////////////////////////////////////////////////////////////
///
/// @file CommonTriplanarTexturing.h
/// @author User
/// @date
///
/// @brief CommonTriplanarTexturing
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Compilation defines
//-----------------------------------------------------------------------------
// Include files
#ifndef D_COMMONTRIPLANARTEXTURING
#define D_COMMONTRIPLANARTEXTURING
////////////////////////////////////////////////////////////////////////////////
///
/// @file CommonFragment.h
/// @author User
/// @date
///
/// @brief CommonFogShader
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Compilation defines
#ifndef D_COMMONFRAGMENT_H
#define D_COMMONFRAGMENT_H
// =================================================================================================
#ifndef D_DEFINES
#define D_DEFINES
// =================================================================================================
// Platform defines
// =================================================================================================
#ifdef D_PLATFORM_PC
#define D_ENABLE_REVERSEZ_PROJECTION (1)
#pragma optionNV(strict on)
#extension GL_ARB_gpu_shader5 : enable
#extension GL_ARB_fragment_coord_conventions : enable
#extension GL_ARB_derivative_control : enable
#if defined( D_FRAGMENT ) && defined( _F64_ )
layout(early_fragment_tests) in;
#endif
#elif defined(D_PLATFORM_ORBIS)
#define D_ENABLE_REVERSEZ_PROJECTION (1)
// use this with sdk 2.0 compiler
// #pragma argument (allow-scratch-buffer-spill)
//define these flags so they don't get ignored in build process and in the comb mask
//this is because materials, vertex layouts and shaders need to be synced on 360 to avoid patching
#ifdef _F27_
#endif
#ifdef _F28_
#endif
#ifdef _F29_
#endif
#ifdef _F21_
#endif
#ifdef _F02_
#endif
#ifdef _F03_
#endif
#if defined( _F01_ ) || defined( D_LOD0 ) || defined( D_LOD1 ) || defined( D_LOD2 ) || defined( D_LOD3) || defined( D_LOD4 )
#endif
#ifdef _F01_
#endif
#ifdef _F09_
#endif
#ifdef _F10_
#endif
// disable warnings for unused parameters. This happens a lot because of defining different things.
#pragma warning (disable: 5203)
// temp thing to know what things are still required on ps4.
#define D_PLATFORM_ORBIS_FIX
#ifdef __PSSL_CS__
#define D_PLATFORM_ORBIS_COMPUTE
#endif
#ifdef __PSSL_HS__
#define D_HULL
#endif
#ifdef __PSSL_DS__
#define D_DOMAIN
#endif
#ifdef __PSSL_VS__
#define D_VERTEX
#endif
#ifdef __PSSL_GS__
#define D_GEOMETRY
#endif
#endif
#if !D_ENABLE_REVERSEZ_PROJECTION
#define D_USING_LOGDEPTH
#endif
// =================================================================================================
// Basic Types
// =================================================================================================
#ifdef D_PLATFORM_PC
#define JOINT_TYPE vec4
//#define CONST const
#define STATIC_CONST const
#elif defined(D_PLATFORM_ORBIS)
#define JOINT_TYPE int4
#define float float
#define vec2 float2
#define vec3 float3
#define vec4 float4
#define ivec2 int2
#define ivec3 int3
#define ivec4 int4
#define uvec2 uint2
#define uvec3 uint3
#define uvec4 uint4
// NOTE:
// operator[] accesses rows, not columns
// matrix constructors interpret the passed vectors as row vectors, not column vectors
#define mat2 row_major float2x2
#define mat3 row_major float3x3
#define mat4 row_major float4x4
//#define CONST
#define STATIC_CONST static const
// #define const ERROR, DON'T USE CONST FOR PS4. USE STATIC_CONST INSTEAD FOR A COMPILED IN CONSTANT. OTHERWISE IT TRIES TO PUT IT IN A CONSTANT BUFFER AND FOR SOME REASON IT DOESN'T WORK.
#endif
// =================================================================================================
// Functions
// =================================================================================================
#ifdef D_PLATFORM_PC
#define saturate( V ) min( max( V, 0.0) , 1.0)
#define atan2( Y, X ) atan( Y, X )
#define invsqrt( X ) inversesqrt( X )
#ifdef D_COMPUTE
#define groupID gl_WorkGroupID
#define groupThreadID gl_LocalInvocationID
#define dispatchThreadID gl_GlobalInvocationID
#endif
#elif defined(D_PLATFORM_ORBIS)
#if defined(D_PLATFORM_ORBIS_COMPUTE)
float dFdx( float var ) { float delta = var - LaneSwizzle( var, 0x1f, 0, 1 ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
float dFdy( float var ) { float delta = var - LaneSwizzle( var, 0x1f, 0, 8 ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec2 dFdx( vec2 var ) { vec2 delta = vec2( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec2 dFdy( vec2 var ) { vec2 delta = vec2( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec3 dFdx( vec3 var ) { vec3 delta = vec3( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec3 dFdy( vec3 var ) { vec3 delta = vec3( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
vec4 dFdx( vec4 var ) { vec4 delta = vec4( var.x - LaneSwizzle( var.x, 0x1f, 0, 1 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 1 ), var.z - LaneSwizzle( var.w, 0x1f, 0, 1 ) ); return __v_cndmask_b32(0, 1, 0xAAAAAAAAAAAAAAAA ) ? delta : -delta; }
vec4 dFdy( vec4 var ) { vec4 delta = vec4( var.x - LaneSwizzle( var.x, 0x1f, 0, 8 ), var.y - LaneSwizzle( var.y, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.z, 0x1f, 0, 8 ), var.z - LaneSwizzle( var.w, 0x1f, 0, 8 ) ); return __v_cndmask_b32(0, 1, 0xFF00FF00FF00FF00 ) ? delta : -delta; }
#define dFdxFine dFdx
#define dFdyFine dFdy
#else
#define dFdx ddx
#define dFdy ddy
#define dFdxFine ddx_fine
#define dFdyFine ddy_fine
#endif
#define mix lerp
#define fract frac
#define mod fmod
#define saturate( V ) ( min( max( V, 0.0) , 1.0) )
#define invsqrt( X ) rsqrt( X )
#endif
// =================================================================================================
// Samplers and textures
// =================================================================================================
#ifdef D_PLATFORM_PC
#define shadow2D( S, UV ) texture( S, UV )
#define SAMPLER2DSHADOW( NAME, REG ) uniform sampler2DShadow NAME
#define SAMPLERCUBE( NAME ) samplerCube NAME
#define SAMPLERCUBEARG( NAME ) in samplerCube NAME
#define SAMPLERCUBEPARAM( NAME ) NAME
#define imageAtomicAddOut( T, C, V, O ) O = imageAtomicAdd( T, C, V )
#if defined( D_TEXTURE_FEEDBACK )
#define texture2D( T, C ) Tex2dFeedback( T, T##FB, C )
#define texture2DLod( T, C, N ) Tex2dLodFeedback( T, T##FB, C, N )
#define texture2DArray( T, C ) Tex2dArrayFeedback( T, T##FB, C )
#define texture3D( S, UV ) Tex3dFeedback( S, S##FB, UV )
#define texture3DLod( S, UV, LOD ) Tex3dLodFeedback( S, S##FB, UV, LOD )
#define SAMPLER2DARG( NAME ) in sampler2D NAME, in int NAME##FB
#define SAMPLER2DPARAM( NAME ) NAME, NAME##FB
#define SAMPLER2DARRAYARG( NAME ) in sampler2DArray NAME, in int NAME##FB
#define SAMPLER2DARRAYPARAM( NAME ) NAME, NAME##FB
#define SAMPLER2D( NAME ) sampler2D NAME; int NAME##FB
#define SAMPLER2DARRAY( NAME ) sampler2DArray NAME; int NAME##FB
#define SAMPLER3D( NAME ) sampler3D NAME; int NAME##FB
#define SAMPLER2DSHADOW_SRT( NAME ) sampler2DShadow NAME; int NAME##FB
#else
#define texture2DLod( S, UV, LOD ) textureLod( S, UV, LOD )
#define texture3DLod( S, UV, LOD ) textureLod( S, UV, LOD )
#define SAMPLER2DARG( NAME ) in sampler2D NAME
#define SAMPLER2DPARAM( NAME ) NAME
#define SAMPLER2DARRAYARG( NAME ) in sampler2DArray NAME
#define SAMPLER2DARRAYPARAM( NAME ) NAME
#define SAMPLER2D( NAME ) sampler2D NAME
#define SAMPLER2DARRAY( NAME ) sampler2DArray NAME
#define SAMPLER3D( NAME ) sampler3D NAME
#define SAMPLER2DSHADOW_SRT( NAME ) sampler2DShadow NAME
#endif
#define textureGatherRed( lTex, lSamp ) textureGather( lTex, lSamp, 0 )
#define textureGatherGreen( lTex, lSamp ) textureGather( lTex, lSamp, 1 )
#define textureGatherBlue( lTex, lSamp ) textureGather( lTex, lSamp, 2 )
#define textureGatherAlpha( lTex, lSamp ) textureGather( lTex, lSamp, 3 )
#define texture2DComputeGrad( T, C ) texture2D( T, C )
#elif defined(D_PLATFORM_ORBIS)
#define SAMPLERCUBE( NAME, REG ) SamplerState NAME##SS : register( s##REG ); TextureCube NAME##TU : register( t##REG )
#define SAMPLER2D( NAME ) Texture2D NAME; SamplerState NAME##SS
#define SAMPLER2DSHADOW_SRT( NAME ) Texture2D NAME; SamplerComparisonState NAME##SS //SAMPLER2D( NAME )
#define SAMPLER3D( NAME ) Texture3D NAME; SamplerState NAME##SS
#define SAMPLER2DARRAY( NAME ) Texture2D_Array NAME; SamplerState NAME##SS
#define SAMPLER2DARRAYARG( NAME ) Texture2D_Array NAME, SamplerState NAME##SS
#define SAMPLER2DARRAYPARAM( NAME ) NAME, NAME##SS
#define SAMPLER2DPARAM( NAME ) NAME, NAME##SS
#define SAMPLER2DARG( NAME ) Texture2D NAME, SamplerState NAME##SS
#define texture2D( T, C ) T.Sample( T##SS, C )
#if defined(D_PLATFORM_ORBIS_COMPUTE)
#define texture2DComputeGrad( T, C ) T.SampleGradient( T##SS, C, vec2( dFdx( C ) ), vec2( dFdy( C ) ) )
#define shadow2D( T, C ) T.SampleCmpLOD0( T##SS, C.xy, C.z )
#else
#define texture2DComputeGrad( T, C ) T.Sample( T##SS, C )
#define shadow2D( T, C ) T.SampleCmp( T##SS, C.xy, C.z )
#endif
#define texture2DLod( T, C, N ) T.SampleLOD( T##SS, C, N )
#define texture2DArray( T, C ) T.Sample( T##SS, C )
#define texture3DLod( T, C, N ) T.SampleLOD( T##SS, C, N )
//#define shadow2D( T, C ) vec3( C.z > T.Sample( T##SS, C.xy ).x ? 1.0 : 0.0 )
//#define shadow2D( T, C ) T.GatherCmp( T##SS, C.xy, C.z )
//#define shadow2D( T, C ) T.SampleCmpLOD0( T##SS, C.xy, C.z )
#define textureCube( T, C ) T##TU.Sample( T##SS, C )
#define textureCubeLod( T, C, N ) T##TU.Sample( T##SS, C, N )
#define textureGrad( T, C, DDX, DDY ) T.SampleGradient( T##SS, C, DDX, DDY )
#define imageAtomicAdd( T, C, V ) AtomicAdd( T[ C ], V )
#define imageAtomicAddOut( T, C, V, O ) AtomicAdd( T[ C ], V, O )
#define imageStore( T, C, V ) ( T[C] = V )
#define textureGatherRed( lTex, lSamp ) lTex.GatherRed ( lTex##SS, lSamp )
#define textureGatherGreen( lTex, lSamp ) lTex.GatherGreen( lTex##SS, lSamp )
#define textureGatherBlue( lTex, lSamp ) lTex.GatherBlue ( lTex##SS, lSamp )
#define textureGatherAlpha( lTex, lSamp ) lTex.GatherAlpha( lTex##SS, lSamp )
#define texelFetch( lTex, lSamp, lLod ) lTex.MipMaps((lLod), (lSamp))
#endif
#if defined(D_PLATFORM_ORBIS_COMPUTE)
#define THREADGROUP_LOCAL thread_group_memory
#define THREADGROUP_BARRIER ThreadGroupMemoryBarrier()
#elif defined(D_PLATFORM_PC_COMPUTE)
#define THREADGROUP_LOCAL layout( shared )
#define THREADGROUP_BARRIER groupMemoryBarrier()
#endif
// =================================================================================================
// Matrices
// =================================================================================================
#ifdef D_PLATFORM_PC
#define MUL( INPUT_A, INPUT_B ) (INPUT_A * INPUT_B)
#define PLATFORM_TRANSPOSE
#define MAT4_SET_POS( M, P ) M[ 3 ] = P
#define MAT4_SET_TRANSLATION( M, T ) M[ 3 ].xyz = T
#define MAT4_GET_COLUMN( M, C ) M[ C ].xyz
#define MAT3_GET_COLUMN( M, C ) M[ C ]
#define MAT4_GET_COLUMN_VEC4( M, C ) M[ C ]
#define MAT3_SET_COLUMN( M, C, V ) M[ C ] = V;
#define MAT4_SET_COLUMN( M, C, V ) M[ C ] = V;
#elif defined(D_PLATFORM_ORBIS)
#define MUL( INPUT_A, INPUT_B ) mul( INPUT_B, INPUT_A )
#define PLATFORM_TRANSPOSE
#define MAT4_SET_POS( M, P ) M[ 3 ] = P
#define MAT4_SET_TRANSLATION( M, T ) M[ 3 ].xyz = T
#define MAT4_GET_COLUMN( M, C ) M[ C ].xyz
#define MAT3_GET_COLUMN( M, C ) M[ C ]
#define MAT4_GET_COLUMN_VEC4( M, C ) M[ C ]
#define MAT3_SET_COLUMN( M, C, V ) M[ C ] = V;
#define MAT4_SET_COLUMN( M, C, V ) M[ C ] = V;
#endif
// =================================================================================================
// Arrays (workaround AMD shader compiler issues by making arrays have global scope)
// =================================================================================================
#if defined(D_PLATFORM_ORBIS)
#define ARRAY_LOOKUP_FS( _UNIFORMS, _ELEMENT, _INDEX) _UNIFORMS._ELEMENT[_INDEX]
#define ARRAY_LOOKUP_FP( _UNIFORMS, _ELEMENT, _INDEX) _UNIFORMS._ELEMENT[_INDEX]
#else
#define ARRAY_LOOKUP_FS( _UNIFORMS, _ELEMENT, _INDEX) _ELEMENT[_INDEX]
#define ARRAY_LOOKUP_FP( _UNIFORMS, _ELEMENT, _INDEX) _ELEMENT[_INDEX]
#endif
// =================================================================================================
// Input and Output
// =================================================================================================
#ifdef D_PLATFORM_PC
#define UNIFORM( TYPE, NAME ) uniform TYPE NAME
#define UNIFORM_SRT( TYPE, NAME ) uniform TYPE NAME
#define DECLARE_INPUT
#define DECLARE_OUTPUT
#define DECLARE_END
#define DECLARE_PTR( TYPE, NAME ) TYPE NAME;
#define DECLARE_PATCH_INPUT_TRI
#define DECLARE_PATCH_OUTPUT_TRI
#define IN_PATCH_TRI_TESS_CONSTANTS
#define OUT_PATCH_TRI_TESS_CONSTANTS
#define DECLARE_PATCH_INPUT_QUAD
#define DECLARE_PATCH_OUTPUT_QUAD
#define IN_PATCH_QUAD_TESS_CONSTANTS
#define OUT_PATCH_QUAD_TESS_CONSTANTS
#if defined( D_HULL )
#define INPUT( TYPE, NAME, REG ) in TYPE NAME [];
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME [];
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME [];
#define PATCH_OUTPUT( TYPE, NAME, REG ) patch out TYPE NAME;
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME [];
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME [];
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME [];
#elif defined( D_DOMAIN )
#define PATCH_INPUT( TYPE, NAME, REG ) patch in TYPE NAME;
#define INPUT( TYPE, NAME, REG ) in TYPE NAME [];
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME [];
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME [];
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME;
#else
#define INPUT( TYPE, NAME, REG ) in TYPE NAME;
#define INPUT_NOINTERP( TYPE, NAME, REG ) flat in TYPE NAME;
#define INPUT_NOPERSP( TYPE, NAME, REG ) in TYPE NAME;
#define OUTPUT( TYPE, NAME, REG ) out TYPE NAME;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) flat out TYPE NAME;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) out TYPE NAME;
#endif
#define FRAGMENT_COLOUR_UVEC4_DEFINE layout(location = 0) out uvec4 outu_color0;
#define FRAGMENT_COLOUR_UVEC4 outu_color0
#define FRAGMENT_COLOUR out_color0
#define FRAGMENT_COLOUR0 out_color0
#define FRAGMENT_COLOUR1 out_color1
#define FRAGMENT_COLOUR2 out_color2
#define FRAGMENT_COLOUR3 out_color3
#define FRAGMENT_COLOUR4 out_color4
#if defined( D_TAA_RENDER_TARGETS )
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1; layout(location = 2) out vec4 out_color2;
#elif !defined(D_ATTRIBUTES)
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0;
#else
#define FRAGMENT_COLOUR_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1; layout(location = 2) out vec4 out_color2; layout(location = 3) out vec4 out_color3; layout(location = 4) out vec4 out_color4;
#endif
#define FRAGMENT_COLOUR01_VEC4_DEFINE layout(location = 0) out vec4 out_color0; layout(location = 1) out vec4 out_color1;
#define FRAGMENT_DEPTH gl_FragDepth
#define FRAGMENT_FRONTFACE gl_FrontFacing
#define INPUT_FRONTFACING
#define DEREF_PTR( VAR ) VAR
#if defined( D_HULL )
#define IN( VAR ) VAR[ gl_InvocationID ]
#define OUT( VAR ) VAR[ gl_InvocationID ]
#define PATCH_OUT( VAR ) VAR
#define OUTPUT_VERTEX_SCREEN_POSITION gl_out[ gl_InvocationID ].gl_Position
#define INPUT_VERTEX_SCREEN_POSITION gl_in [ gl_InvocationID ].gl_Position
#define TESS_LEVEL_EDGE( IND ) gl_TessLevelOuter[ IND ]
#define TESS_LEVEL_INNER( IND ) gl_TessLevelInner[ IND ]
#elif defined( D_DOMAIN )
#define PATCH_IN( VAR, IND ) VAR[ IND ]
#define IN( VAR, IND ) VAR[ IND ]
#define OUT( VAR ) VAR
#define INPUT_VERTEX_SCREEN_POSITION( IND ) gl_in [ IND ].gl_Position
#define DOMAIN_COORDS gl_TessCoord
#elif defined( D_GEOMETRY )
#define OUTPUT_VERTEX_SCREEN_POSITION gl_Position
#define INPUT_VERTEX_SCREEN_POSITION( IND ) gl_in [ IND ].gl_Position
#define IN( VAR, IND ) VAR[ IND ]
#define OUT( VAR ) VAR
#else
#define IN( VAR ) VAR
#define OUT( VAR ) VAR
#endif
#define OUT_VERTEX_SCREEN_POSITION
#define IN_SCREEN_POSITION
#define VERTEX_SCREEN_POSITION gl_Position
#elif defined(D_PLATFORM_ORBIS_COMPUTE)
#define DECLARE_INPUT struct cInput {
#define DECLARE_END };
#define DECLARE_PTR( TYPE, NAME ) TYPE* NAME;
#define INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define INPUT_NOINTERP( TYPE, NAME, REG ) TYPE NAME : REG;
#define IN_SCREEN_POSITION
#define FRAGMENT_COLOUR lUniforms.mpCmpOutPerMesh.gOutTexture0[dispatchThreadID.xy]
#define FRAGMENT_COLOUR0 lUniforms.mpCmpOutPerMesh.gOutTexture0[dispatchThreadID.xy]
#define FRAGMENT_COLOUR1 lUniforms.mpCmpOutPerMesh.gOutTexture1[dispatchThreadID.xy]
#define FRAGMENT_COLOUR2 lUniforms.mpCmpOutPerMesh.gOutTexture2[dispatchThreadID.xy]
#define FRAGMENT_COLOUR3 lUniforms.mpCmpOutPerMesh.gOutTexture3[dispatchThreadID.xy]
#define FRAGMENT_COLOUR4 lUniforms.mpCmpOutPerMesh.gOutTexture4[dispatchThreadID.xy]
#define FRAGMENT_DEPTH lUniforms.mpCmpOutPerMesh.gOutTextureDepth[dispatchThreadID.xy]
#define DEREF_PTR( VAR ) *VAR
#elif defined(D_PLATFORM_ORBIS)
#define UNIFORM( TYPE, NAME ) ConstantBuffer NAME##CB{ TYPE NAME; };
#define UNIFORM_SRT( TYPE, NAME ) ConstantBuffer NAME##CB{ TYPE NAME : S_SRT_DATA; };
#define DECLARE_OUTPUT struct cOutput {
#define DECLARE_INPUT struct cInput {
#define DECLARE_END };
#define DECLARE_PTR( TYPE, NAME ) TYPE* NAME;
#define INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define INPUT_NOINTERP( TYPE, NAME, REG ) nointerp TYPE NAME : REG;
#define INPUT_NOPERSP( TYPE, NAME, REG ) nopersp TYPE NAME : REG;
#define OUTPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#define OUTPUT_NOINTERP( TYPE, NAME, REG ) nointerp TYPE NAME : REG;
#define OUTPUT_NOPERSP( TYPE, NAME, REG ) nopersp TYPE NAME : REG;
#define FRAGMENT_COLOUR_UVEC4_DEFINE
#define FRAGMENT_COLOUR_UVEC4 Out.mColour
#define FRAGMENT_COLOUR Out.mColour
#define FRAGMENT_COLOUR0 Out.mColour0
#define FRAGMENT_COLOUR1 Out.mColour1
#define FRAGMENT_COLOUR2 Out.mColour2
#define FRAGMENT_COLOUR3 Out.mColour3
#define FRAGMENT_COLOUR4 Out.mColour4
#define FRAGMENT_DEPTH Out.mDepth
#define FRAGMENT_FRONTFACE In.mbFrontFacing
#define INPUT_FRONTFACING bool mbFrontFacing : S_FRONT_FACE;
#if defined( D_HULL )
#define IN( VAR ) In[ uCPID ].VAR
#define OUT( VAR ) Out.VAR
#define PATCH_OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION IN( mScreenPositionVec4 )
#define TESS_LEVEL_EDGE( IND ) Out.edge_ts[ IND ]
#define TESS_LEVEL_INNER( IND ) Out.insi_ts[ IND ]
#define DECLARE_PATCH_OUTPUT_TRI [DOMAIN_PATCH_TYPE("tri")] struct HSConstantOutputData {
#define OUT_PATCH_TRI_TESS_CONSTANTS float edge_ts[3] : S_EDGE_TESS_FACTOR; \
float insi_ts[1] : S_INSIDE_TESS_FACTOR;
#define DECLARE_PATCH_OUTPUT_QUAD [DOMAIN_PATCH_TYPE("quad")] struct HSConstantOutputData (
#define OUT_PATCH_QUAD_TESS_CONSTANTS float edge_ts[4] : S_EDGE_TESS_FACTOR; \
float insi_ts[2] : S_INSIDE_TESS_FACTOR;
#define PATCH_OUTPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#elif defined( D_DOMAIN )
#define PATCH_IN( VAR, IND ) patchIn.VAR
#define IN( VAR, IND ) In[ IND ].VAR
#define OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION( IND ) IN( mScreenPositionVec4, IND )
#define DOMAIN_COORDS domainCoordinates
#define DECLARE_PATCH_INPUT_TRI [DOMAIN_PATCH_TYPE("tri")] struct HSConstantOutputData {
#define IN_PATCH_TRI_TESS_CONSTANTS float edge_ts[3] : S_EDGE_TESS_FACTOR; \
float insi_ts[1] : S_INSIDE_TESS_FACTOR;
#define DECLARE_PATCH_INPUT_QUAD [DOMAIN_PATCH_TYPE("quad")] struct HSConstantOutputData {
#define IN_PATCH_QUAD_TESS_CONSTANTS float edge_ts[4] : S_EDGE_TESS_FACTOR; \
float insi_ts[2] : S_INSIDE_TESS_FACTOR;
#define PATCH_INPUT( TYPE, NAME, REG ) TYPE NAME : REG;
#elif defined( D_GEOMETRY )
#define IN( VAR, IND ) In[ IND ].VAR
#define OUT( VAR ) Out.VAR
#define OUTPUT_VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#define INPUT_VERTEX_SCREEN_POSITION( IND ) IN( mScreenPositionVec4, IND )
#define EMIT_VERTEX TriStream.Append( Out )
#define END_PRIMITIVE TriStream.RestartStrip()
#else
#define IN( VAR ) In.VAR
#define OUT( VAR ) Out.VAR
#endif
// TODO get rid of this - don't pass struct through functinos, pass members.
#define DEREF_PTR( VAR ) *VAR
#define OUT_VERTEX_SCREEN_POSITION OUTPUT( vec4, mScreenPositionVec4, S_POSITION )
#define IN_SCREEN_POSITION INPUT ( vec4, mScreenPositionVec4, S_POSITION )
#define VERTEX_SCREEN_POSITION OUT( mScreenPositionVec4 )
#endif
// =================================================================================================
// Main
// =================================================================================================
#ifdef D_PLATFORM_PC
#define VERTEX_MAIN void main( void )
#define VERTEX_MAIN_SRT uniform UniformBuffer lUniforms; void main( void )
#define HULL_TRI_MAIN_SRT layout( vertices = 3 ) out; uniform UniformBuffer lUniforms; void main( void )
#define HULL_QUAD_MAIN_SRT layout( vertices = 4 ) out; uniform UniformBuffer lUniforms; void main( void )
#define DOMAIN_TRI_MAIN_SRT layout( triangles, fractional_even_spacing ) in; uniform UniformBuffer lUniforms; void main( void )
#define DOMAIN_QUAD_MAIN_SRT layout( quads, fractional_even_spacing ) in; uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define VOID_MAIN_COLOUR FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH FRAGMENT_COLOUR_VEC4_DEFINE void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_GE_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_DEPTH_LE_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR_EARLYZ_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_UICOLOUR_SRT FRAGMENT_COLOUR_UVEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define VOID_MAIN_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define VOID_MAIN_DEPTH_SRT FRAGMENT_COLOUR_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR01_SRT FRAGMENT_COLOUR01_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#define FRAGMENT_MAIN_COLOUR01_DEPTH_SRT FRAGMENT_COLOUR01_VEC4_DEFINE uniform UniformBuffer lUniforms; void main( void )
#elif defined( D_PLATFORM_PC_COMPUTE )
#define COMPUTE_MAIN_SRT( X, Y, Z ) layout (local_size_x = X, local_size_y = Y, local_size_z = Z) in; void main( void )
#define FRAGMENT_MAIN_COLOUR_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR01_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#elif defined( D_PLATFORM_ORBIS_COMPUTE )
#define COMPUTE_MAIN_SRT( X, Y, Z ) [NUM_THREADS(X, Y, Z)] void main(uint3 groupID : S_GROUP_ID, uint3 groupThreadID : S_GROUP_THREAD_ID, uint3 dispatchThreadID : S_DISPATCH_THREAD_ID, UniformBuffer lUniforms : S_SRT_DATA)
#define FRAGMENT_MAIN_COLOUR_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR01_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT COMPUTE_MAIN_SRT( 8,8,1 )
#elif defined( D_PLATFORM_ORBIS )
#define VERTEX_MAIN void main( cInput In, out cOutput Out )
#define VERTEX_MAIN_SRT void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define HULL_TRI_MAIN_SRT [DOMAIN_PATCH_TYPE("tri")] \
[PARTITIONING_TYPE("integer")] \
[OUTPUT_TOPOLOGY_TYPE("triangle_cw")] \
[OUTPUT_CONTROL_POINTS(3)] \
[PATCH_CONSTANT_FUNC("ConstantsHS")] \
[MAX_TESS_FACTOR(16.0)] \
void main( \
InputPatch<cInput, 3> In, \
uint uCPID : S_OUTPUT_CONTROL_POINT_ID, \
UniformBuffer lUniforms : S_SRT_DATA, \
out cOutput Out )
#define HULL_QUAD_MAIN_SRT [DOMAIN_PATCH_TYPE("quad")] \
[PARTITIONING_TYPE("integer")] \
[OUTPUT_TOPOLOGY_TYPE("triangle_cw")] \
[OUTPUT_CONTROL_POINTS(4)] \
[PATCH_CONSTANT_FUNC("ConstantsHS")] \
[MAX_TESS_FACTOR(16.0)] \
void main( \
InputPatch<cInput, 4> In, \
uint uCPID : S_OUTPUT_CONTROL_POINT_ID, \
UniformBuffer lUniforms : S_SRT_DATA, \
out cOutput Out )
#define DOMAIN_TRI_MAIN_SRT [DOMAIN_PATCH_TYPE("tri")] \
void main( \
HSConstantOutputData patchIn, \
const OutputPatch<cInput, 3> In, \
out cOutput Out, \
UniformBuffer lUniforms : S_SRT_DATA, \
float3 domainCoordinates : S_DOMAIN_LOCATION )
#define DOMAIN_QUAD_MAIN_SRT [DOMAIN_PATCH_TYPE("quad")] \
void main( \
HSConstantOutputData patchIn, \
const OutputPatch<cInput, 4> In, \
out cOutput Out, \
UniformBuffer lUniforms : S_SRT_DATA, \
float2 domainCoordinates : S_DOMAIN_LOCATION )
#define GEOMETRY_MAIN_SRT( MAX_VERTS ) cOutput Out; [MAX_VERTEX_COUNT(MAX_VERTS)] void main( inout TriangleBuffer<cOutput> TriStream, Triangle cInput In[3], UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out )
#define VOID_MAIN_COLOUR struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; void main( cInput In, out cOutput Out )
#define FRAGMENT_MAIN_COLOUR_DEPTH struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out )
#define VOID_MAIN_SRT void main( cInput In, UniformBuffer lUniforms : S_SRT_DATA )
#if defined( D_TAA_RENDER_TARGETS )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#elif !defined( D_ATTRIBUTES )
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_DEPTH_GE_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_GE_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_DEPTH_LE_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; float mDepth : S_DEPTH_LE_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour : S_TARGET_OUTPUT; }; void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define VOID_MAIN_DEPTH_SRT struct cOutput { float mDepth : S_DEPTH_OUTPUT; }; [RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define VOID_MAIN_COLOUR_EARLYZ_SRT [FORCE_EARLY_DEPTH_STENCIL] void main( cInput In, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR01_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR01_DEPTH_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
float mDepth : S_DEPTH_OUTPUT; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#else
// #pragma PSSL_target_output_format(target 1 FMT_32_AR)
#define FRAGMENT_MAIN_COLOUR_DEPTH_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; \
float mDepth : S_DEPTH_OUTPUT; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; }; \
[RE_Z] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#define FRAGMENT_MAIN_COLOUR_EARLYZ_SRT struct cOutput { vec4 mColour0 : S_TARGET_OUTPUT0; \
vec4 mColour1 : S_TARGET_OUTPUT1; \
vec4 mColour2 : S_TARGET_OUTPUT2; \
vec4 mColour3 : S_TARGET_OUTPUT3; }; \
[FORCE_EARLY_DEPTH_STENCIL] void main( cInput In, out cOutput Out, UniformBuffer lUniforms : S_SRT_DATA )
#endif
#endif
// =================================================================================================
// Texture resolution
// =================================================================================================
#ifdef D_PLATFORM_ORBIS
uvec2 GetResolution( Texture2D lTexture )
{
uvec2 lResolution;
lTexture.GetDimensionsFast(lResolution.x, lResolution.y);
return lResolution;
}
uvec2 GetResolution( RW_Texture2D<float4> lTexture )
{
uvec2 lResolution;
lTexture.GetDimensionsFast(lResolution.x, lResolution.y);
return lResolution;
}
#else
uvec2 GetResolution( sampler2D lTexture )
{
return textureSize( lTexture, 0 );
}
#endif
// =================================================================================================
// Viewport
// =================================================================================================
#ifdef D_PLATFORM_PC
#define SCREENSPACE_AS_RENDERTARGET_UVS( A ) A.xy
#elif defined(D_PLATFORM_ORBIS)
#define SCREENSPACE_AS_RENDERTARGET_UVS( A ) ( float2( A.x, 1.0 - A.y ) )
#endif
#ifdef D_USING_LOGDEPTH
#define D_DEPTH_CLEARVALUE (1.0)
#else
#define D_DEPTH_CLEARVALUE (0.0)
#endif
// =================================================================================================
// Texture usage feedback
// =================================================================================================
#if defined( D_TEXTURE_FEEDBACK ) && defined( D_PLATFORM_PC )
layout(r32i) uniform iimage2D gTexFeedbackImg;
void WriteTexFeedback( in int liCounter, in float liMip )
{
if( liCounter != 0 )
{
#if defined( GL_ARB_shader_ballot ) && ( GL_ARB_shader_ballot == 1 )
if( readFirstInvocationARB( gl_SubGroupInvocationARB ) == gl_SubGroupInvocationARB )
#endif
{
int liIntMip = int(floor(liMip));
//imageStore( gTexFeedbackImg, ivec2( liCounter, liIntMip ), ivec4(1,0,0,0) );
imageAtomicAdd( gTexFeedbackImg, ivec2( liCounter, liIntMip ), int(1) );
}
}
}
vec4 Tex2dFeedback( in sampler2D lSamp, in int liCounter, in vec2 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex2dLodFeedback( in sampler2D lSamp, in int liCounter, in vec2 lCoords, in float liLod )
{
WriteTexFeedback( liCounter, liLod );
return textureLod( lSamp, lCoords, liLod );
}
vec4 Tex2dArrayFeedback( in sampler2DArray lSamp, in int liCounter, in vec3 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords.xy ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex3dFeedback( in sampler3D lSamp, in int liCounter, in vec3 lCoords )
{
float liLod = textureQueryLOD( lSamp, lCoords ).x;
WriteTexFeedback( liCounter, liLod );
return texture( lSamp, lCoords );
}
vec4 Tex3dLodFeedback( in sampler3D lSamp, in int liCounter, in vec3 lCoords, in float liLod )
{
WriteTexFeedback( liCounter, liLod );
return textureLod( lSamp, lCoords, liLod );
}
#endif
#endif
//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------
// Global Data
//-----------------------------------------------------------------------------
///
/// CalculateFadeValue
///
/// @brief Hash
///
/// @param vec2 lPositionVec2
/// @return float
///
//-----------------------------------------------------------------------------
vec3
DecodeNormalMap(
vec4 lNormalTexVec4 )
{
lNormalTexVec4 = ( lNormalTexVec4 * ( 2.0 * 255.0 / 256.0 ) ) - 1.0;
return ( vec3( lNormalTexVec4.r, lNormalTexVec4.g, sqrt( max( 1.0 - lNormalTexVec4.r*lNormalTexVec4.r - lNormalTexVec4.g*lNormalTexVec4.g, 0.0 ) ) ) );
}
//-----------------------------------------------------------------------------
///
/// ReadDualParaboloidMap
///
/// @brief ReadDualParaboloidMap
///
/// @param lBackMap
/// @param lFrontMap
/// @param in vec3 lReflectionVec3
/// @return vec3
///
//-----------------------------------------------------------------------------
vec3
ReadDualParaboloidMap(
SAMPLER2DARG( lBackMap ),
SAMPLER2DARG( lFrontMap ),
in vec3 lReflectionVec3,
in int liMipLevel )
{
vec2 lEnvCoordsVec2;
lEnvCoordsVec2.xy = lReflectionVec3.xy / ( 1.0 + abs(lReflectionVec3.z) );
lEnvCoordsVec2.x = 0.5 * lEnvCoordsVec2.x + 0.5; //bias and scale to correctly sample a d3d texture
lEnvCoordsVec2.y = -0.5 * lEnvCoordsVec2.y + 0.5;
#if defined( D_PLATFORM_ORBIS )
//lEnvCoordsVec2.y = 1.0 - lFrontCoordsVec2.y;
#endif
// Potentially use clever math, and write them both to one image, ala Cascading Shadow Map
float lInEq = ( -lReflectionVec3.z + 1.0 );
float isBack = ( lReflectionVec3.x > -lInEq && lReflectionVec3.x < lInEq) &&
( lReflectionVec3.y > -lInEq && lReflectionVec3.y < lInEq) ? 1.0 : 0.0;
vec3 lEnvironmentMapBackVec3 = texture2DLod( lBackMap, lEnvCoordsVec2, float( liMipLevel ) ).xyz; // sample the front paraboloid map
vec3 lEnvironmentMapFrontVec3 = texture2DLod( lFrontMap, lEnvCoordsVec2, float( liMipLevel ) ).xyz; // sample the back paraboloid map
return lEnvironmentMapBackVec3 * isBack + lEnvironmentMapFrontVec3 * (1.0 - isBack);
}
//-----------------------------------------------------------------------------
///
/// GetUpperValue
///
///
//-----------------------------------------------------------------------------
float
GetUpperValue(
float lValue )
{
int a = int( lValue * 255 );
return ( float(a >> 4) / 16.0 );
}
//-----------------------------------------------------------------------------
///
/// GetLowerValue
///
///
//-----------------------------------------------------------------------------
float
GetLowerValue(
float lValue )
{
int a = int( lValue * 255 );
float lReturn = float( a & 0xf ) / 16.0;
lReturn = clamp( lReturn - GetUpperValue( lValue ), 0.0, 1.0 );
return lReturn;
}
#endif
//-----------------------------------------------------------------------------
// Global Data
#if defined(D_PLATFORM_PC)
uniform vec4 gaAverageColoursVec4[ D_TERRAINCOLOURARRAY_SIZE ];
uniform vec4 gaTerrainColoursVec4[ D_TERRAINCOLOURARRAY_SIZE ];
#endif
//-----------------------------------------------------------------------------
// Functions
vec3
GetTriPlanarColour(
vec3 lNormalVec3,
vec3 lWorldPositionVec3,
vec2 lAnimationOffsetVec2,
float lfScale,
SAMPLER2DARG( lTexture ) )
{
#if defined( D_TERRAIN_X_FACING )
vec3 m = vec3( 1.0, 0.0, 0.0 );
#elif defined( D_TERRAIN_Y_FACING )
vec3 m = vec3( 0.0, 1.0, 0.0 );
#elif defined( D_TERRAIN_Z_FACING )
vec3 m = vec3( 0.0, 0.0, 1.0 );
#else
vec3 m = pow( abs( lNormalVec3 ), vec3( 32.0,32.0,32.0 ) );
#endif
vec2 lCoord1Vec2 = lWorldPositionVec3.yz * lfScale + lAnimationOffsetVec2;
vec2 lCoord2Vec2 = lWorldPositionVec3.zx * lfScale + lAnimationOffsetVec2;
vec2 lCoord3Vec2 = lWorldPositionVec3.xy * lfScale + lAnimationOffsetVec2;
vec3 lColour1Vec3 = texture2DLod( lTexture, lCoord1Vec2, 0.0 ).rgb;
vec3 lColour2Vec3 = texture2DLod( lTexture, lCoord2Vec2, 0.0 ).rgb;
vec3 lColour3Vec3 = texture2DLod( lTexture, lCoord3Vec2, 0.0 ).rgb;
return ( lColour1Vec3 * m.x + lColour2Vec3 * m.y + lColour3Vec3 * m.z ) / (m.x + m.y + m.z);
}
// mip-mapped variant of the above
vec3
GetTriPlanarColourMM(
vec3 lNormalVec3,
vec3 lWorldPositionVec3,
vec2 lAnimationOffsetVec2,
float lfScale,
SAMPLER2DARG( lTexture ) )
{
#if defined( D_TERRAIN_X_FACING )
vec3 m = vec3( 1.0, 0.0, 0.0 );
#elif defined( D_TERRAIN_Y_FACING )
vec3 m = vec3( 0.0, 1.0, 0.0 );
#elif defined( D_TERRAIN_Z_FACING )
vec3 m = vec3( 0.0, 0.0, 1.0 );
#else
vec3 m = pow( abs( lNormalVec3 ), vec3( 32.0,32.0,32.0 ) );
#endif
vec2 lCoord1Vec2 = lWorldPositionVec3.yz * lfScale + lAnimationOffsetVec2;
vec2 lCoord2Vec2 = lWorldPositionVec3.zx * lfScale + lAnimationOffsetVec2;
vec2 lCoord3Vec2 = lWorldPositionVec3.xy * lfScale + lAnimationOffsetVec2;
vec3 lColour1Vec3 = texture2DComputeGrad( lTexture, lCoord1Vec2 ).rgb;
vec3 lColour2Vec3 = texture2DComputeGrad( lTexture, lCoord2Vec2 ).rgb;
vec3 lColour3Vec3 = texture2DComputeGrad( lTexture, lCoord3Vec2 ).rgb;
return ( lColour1Vec3 * m.x + lColour2Vec3 * m.y + lColour3Vec3 * m.z ) / (m.x + m.y + m.z);
}
vec3
GetTriPlanarNormal(
vec3 lNormalVec3,
vec3 lWorldPositionVec3,
vec2 lAnimationOffsetVec2,
float lfScale,
SAMPLER2DARG( lTexture ) )
{
#if defined( D_TERRAIN_X_FACING )
vec3 m = vec3( 1.0, 0.0, 0.0 );
#elif defined( D_TERRAIN_Y_FACING )
vec3 m = vec3( 0.0, 1.0, 0.0 );
#elif defined( D_TERRAIN_Z_FACING )
vec3 m = vec3( 0.0, 0.0, 1.0 );
#else
vec3 m = pow( abs( lNormalVec3 ), vec3( 32.0,32.0,32.0 ) );
#endif
vec2 lCoord1Vec2 = vec2( lWorldPositionVec3.z, -lWorldPositionVec3.y ) * lfScale + lAnimationOffsetVec2;
vec2 lCoord2Vec2 = vec2( lWorldPositionVec3.z, lWorldPositionVec3.x ) * lfScale + lAnimationOffsetVec2;
vec2 lCoord3Vec2 = vec2( lWorldPositionVec3.x, -lWorldPositionVec3.y ) * lfScale + lAnimationOffsetVec2;
vec3 lNormal1Vec3 = DecodeNormalMap( texture2D( lTexture, lCoord1Vec2 ) );
vec3 lNormal2Vec3 = DecodeNormalMap( texture2D( lTexture, lCoord2Vec2 ) );
vec3 lNormal3Vec3 = DecodeNormalMap( texture2D( lTexture, lCoord3Vec2 ) );
lNormal1Vec3 = vec3( 0.0, lNormal1Vec3.x, lNormal1Vec3.y ); // YZ
lNormal2Vec3 = vec3( -lNormal2Vec3.x, 0.0, lNormal2Vec3.y ); // ZX
lNormal3Vec3 = vec3( lNormal3Vec3.y, lNormal3Vec3.x, 0.0 ); // XY
return (lNormal1Vec3 * m.x + lNormal2Vec3 * m.y + lNormal3Vec3 * m.z) / (m.x + m.y + m.z);
}
#ifdef D_TEXTURE_ARRAYS
//-----------------------------------------------------------------------------
///
/// GetTriPlanarNormal
///
/// @brief GetTriPlanarNormal
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
vec3
GetTriPlanarNormalArray(
in vec2 lCoordVec2,
SAMPLER2DARRAYARG( lNormalMap ),
SAMPLER2DARRAYARG( lSubstanceNormalMap ),
in int liIndex,
out float lfHeight,
out float lfSpecular )
{
vec4 lTexValueVec4;
if( liIndex < 16 )
{
lTexValueVec4 = texture2DArray( lNormalMap, vec3( lCoordVec2, float( liIndex ) ) );
}
else
{
lTexValueVec4 = texture2DArray( lSubstanceNormalMap, vec3( lCoordVec2, float( liIndex & 15 ) ) );
}
//vec3 lLocalNormalAVec3 = DecodeNormalMap( lTexValueVec4 );
vec3 lLocalNormalAVec3 = vec3( lTexValueVec4.a * 2.0 - 1.0, lTexValueVec4.g * 2.0 - 1.0, 0.0 );
lfHeight = lTexValueVec4.r;
lfSpecular = lTexValueVec4.b;
return lLocalNormalAVec3;
}
//-----------------------------------------------------------------------------
///
/// GetTriPlanarColour
///
/// @brief GetTriPlanarColour
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
vec3
GetTriPlanarColourArray(
in vec2 lCoordVec2,
SAMPLER2DARRAYARG( lDiffuseMap ),
SAMPLER2DARRAYARG( lSubstanceDiffuseMap ),
in int liIndex,
in vec3 lAverageHSVVec3,
in vec3 lRecolourVec3 )
{
vec3 lColourVec3;
if( liIndex < 16 )
{
lColourVec3 = texture2DArray( lDiffuseMap, vec3( lCoordVec2, float( liIndex ) ) ).rgb;
}
else
{
lColourVec3 = texture2DArray( lSubstanceDiffuseMap, vec3( lCoordVec2, float( liIndex & 15 ) ) ).rgb;
}
lColourVec3.r = fract( ( lColourVec3.r - lAverageHSVVec3.r ) + lRecolourVec3.r );
lColourVec3.g = saturate( min( lRecolourVec3.g, lColourVec3.g ) );
lColourVec3.b = saturate( ( lColourVec3.b - lAverageHSVVec3.b ) + lRecolourVec3.b );
lColourVec3 = saturate( HSVToRGB( lColourVec3 ) );
return lColourVec3;
}
//-----------------------------------------------------------------------------
///
/// GetBlendedNormal
///
/// @brief GetBlendedNormal
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
vec3
GetBlendedNormal(
in vec2 lTileCoordsVec2,
SAMPLER2DARRAYARG( lNormalMap ),
SAMPLER2DARRAYARG( lSubstanceNormalMap ),
in uvec4 lTile1Vec4,
in uvec4 lTile2Vec4,
in float lfTileType,
in float lfSlope,
in float lfPatch,
out float lfSpecular,
out float lfHeight1,
out float lfHeight2,
out float lfHeight3,
out float lfHeight4,
out float lfHeight5,
out float lfHeight6,
out float lfHeight7 )
{
#ifndef D_LOW_QUALITY
const float lfThreshold = 1.0 / 100.0;
const float lfOffset = 0.12;
const float lfDefaultHeight = 0.5;
vec3 lNormal5 = vec3( 0.0, 0.0, 0.0 );
vec3 lNormal6 = vec3( 0.0, 0.0, 0.0 );
float lfSpecular1 = 0.0;
float lfSpecular2 = 0.0;
float lfSpecular3 = 0.0;
float lfSpecular4 = 0.0;
float lfSpecular5 = 0.0;
float lfSpecular6 = 0.0;
lfHeight1 = 0.0;
lfHeight2 = 0.0;
lfHeight3 = 0.0;
lfHeight4 = 0.0;
lfHeight5 = 0.0;
lfHeight6 = 0.0;
lfHeight7 = 0.0;
float lfHeightE = lfDefaultHeight;
float lfHeightF = lfDefaultHeight;
if( lfPatch < 1.0 - lfThreshold )
{
float lfHeightC = lfDefaultHeight;
float lfHeightD = lfDefaultHeight;
vec3 lNormal1 = vec3(0.0, 0.0, 0.0);
vec3 lNormal2 = vec3(0.0, 0.0, 0.0);
vec3 lNormal3 = vec3(0.0, 0.0, 0.0);
vec3 lNormal4 = vec3(0.0, 0.0, 0.0);
if( lfSlope < 1.0 - lfThreshold )
{
float lfHeightA = lfDefaultHeight;
float lfHeightB = lfDefaultHeight;
if( lfTileType < 1.0 - lfThreshold )
{
lNormal1 = GetTriPlanarNormalArray( lTileCoordsVec2, SAMPLER2DARRAYPARAM( lNormalMap ), SAMPLER2DARRAYPARAM( lSubstanceNormalMap ), int( lTile1Vec4[ 0 ] ), lfHeightA, lfSpecular1 );
}
if( lfTileType > lfThreshold )
{
lNormal2 = GetTriPlanarNormalArray( lTileCoordsVec2,SAMPLER2DARRAYPARAM( lNormalMap ), SAMPLER2DARRAYPARAM( lSubstanceNormalMap ), int( lTile1Vec4[ 1 ] ), lfHeightB, lfSpecular2 );
}
// blend between height textures
lfHeight1 = mix( lfHeightA, 1.0 - lfHeightB, lfTileType );
// use height as a cutoff for smoothstep to get sharp transition between height maps
float lfHeight = smoothstep( lfHeight1 - lfOffset, lfHeight1 + lfOffset, lfTileType );
lfSpecular3 = mix( lfSpecular1, lfSpecular2, lfHeight );
lNormal3 = mix( lNormal1, lNormal2, lfHeight );
// blend between height maps again to get map which can be combined with other height maps
lfHeightC = mix( lfHeightA, lfHeightB, lfHeight );
}
if( lfSlope > lfThreshold )
{
float lfHeightA = lfDefaultHeight;
float lfHeightB = lfDefaultHeight;
if( lfTileType < 1.0 - lfThreshold )
{
lNormal1 = GetTriPlanarNormalArray( lTileCoordsVec2, SAMPLER2DARRAYPARAM( lNormalMap ), SAMPLER2DARRAYPARAM( lSubstanceNormalMap ), int( lTile1Vec4[ 2 ] ), lfHeightA, lfSpecular1 );
}
if( lfTileType > lfThreshold )
{
lNormal2 = GetTriPlanarNormalArray( lTileCoordsVec2, SAMPLER2DARRAYPARAM( lNormalMap ), SAMPLER2DARRAYPARAM( lSubstanceNormalMap ), int( lTile1Vec4[ 3 ] ), lfHeightB, lfSpecular2 );
}
lfHeight2 = mix( lfHeightA, 1.0 - lfHeightB, lfTileType );
float lfHeight = smoothstep( lfHeight2 - lfOffset, lfHeight2 + lfOffset, lfTileType );
lfSpecular4 = mix( lfSpecular1, lfSpecular2, lfHeight );
lNormal4 = mix( lNormal1, lNormal2, lfHeight );
lfHeightD = mix( lfHeightA, lfHeightB, lfHeight );
}
lfHeight5 = mix( lfHeightC, 1.0 - lfHeightD, lfSlope );
float lfHeight = smoothstep( lfHeight5 - lfOffset, lfHeight5 + lfOffset, lfSlope );
lfSpecular5 = mix( lfSpecular3, lfSpecular4, lfHeight );
lNormal5 = mix( lNormal3, lNormal4, lfHeight );
lfHeightE = mix( lfHeightC, lfHeightD, lfHeight );
}
if( lfPatch > lfThreshold )
{
vec3 lNormal1 = vec3(0.0, 0.0, 0.0);
vec3 lNormal2 = vec3(0.0, 0.0, 0.0);
vec3 lNormal3 = vec3(0.0, 0.0, 0.0);
vec3 lNormal4 = vec3(0.0, 0.0, 0.0);
float lfHeightC = lfDefaultHeight;
float lfHeightD = lfDefaultHeight;
if( lfSlope < 1.0 - lfThreshold )
{
float lfHeightA = lfDefaultHeight;
float lfHeightB = lfDefaultHeight;
if( lfTileType < 1.0 - lfThreshold )
{
lNormal1 = GetTriPlanarNormalArray( lTileCoordsVec2, SAMPLER2DARRAYPARAM( lNormalMap ), SAMPLER2DARRAYPARAM( lSubstanceNormalMap ), int( lTile2Vec4[ 0 ] ), lfHeightA, lfSpecular1 );
}
if( lfTileType > lfThreshold )
{
lNormal2 = GetTriPlanarNormalArray( lTileCoordsVec2, SAMPLER2DARRAYPARAM( lNormalMap ), SAMPLER2DARRAYPARAM( lSubstanceNormalMap ), int( lTile2Vec4[ 1 ] ), lfHeightB, lfSpecular2 );
}
lfHeight3 = mix( lfHeightA, 1.0 - lfHeightB, lfTileType );
float lfHeight = smoothstep( lfHeight3 - lfOffset, lfHeight3 + lfOffset, lfTileType );
lfSpecular3 = mix( lfSpecular1, lfSpecular2, lfHeight );
lNormal3 = mix( lNormal1, lNormal2, lfHeight );
lfHeightC = mix( lfHeightA, 1.0 - lfHeightB, lfHeight );
}
if( lfSlope > lfThreshold )
{
float lfHeightA = lfDefaultHeight;
float lfHeightB = lfDefaultHeight;
if( lfTileType < 1.0 - lfThreshold )
{
lNormal1 = GetTriPlanarNormalArray( lTileCoordsVec2, SAMPLER2DARRAYPARAM( lNormalMap ), SAMPLER2DARRAYPARAM( lSubstanceNormalMap ), int( lTile2Vec4[ 2 ] ), lfHeightA, lfSpecular1 );
}
if( lfTileType > lfThreshold )
{
lNormal2 = GetTriPlanarNormalArray( lTileCoordsVec2, SAMPLER2DARRAYPARAM( lNormalMap ), SAMPLER2DARRAYPARAM( lSubstanceNormalMap ), int( lTile2Vec4[ 3 ] ), lfHeightB, lfSpecular2 );
}
lfHeight4 = mix( lfHeightA, 1.0 - lfHeightB, lfTileType );
float lfHeight = smoothstep( lfHeight4 - lfOffset, lfHeight4 + lfOffset, lfTileType );
lfSpecular4 = mix( lfSpecular1, lfSpecular2, lfHeight );
lNormal4 = mix( lNormal1, lNormal2, lfHeight );
lfHeightD = mix( lfHeightA, lfHeightB, lfHeight );
}
lfHeight6 = mix( lfHeightC, 1.0 - lfHeightD, lfSlope );
float lfHeight = smoothstep( lfHeight6 - lfOffset, lfHeight6 + lfOffset, lfSlope );
lfSpecular6 = mix( lfSpecular3, lfSpecular4, lfHeight );
lNormal6 = mix( lNormal3, lNormal4, lfHeight );
lfHeightF = mix( lfHeightC, lfHeightD, lfHeight );
}
lfHeight7 = mix( lfHeightE, 1.0 - lfHeightF, lfPatch );
float lfHeight = smoothstep( lfHeight7 - lfOffset, lfHeight7 + lfOffset, lfPatch );
lfSpecular = mix( lfSpecular5, lfSpecular6, lfHeight );
return mix( lNormal5, lNormal6, lfHeight );
#else
vec3 lNormal = GetTriPlanarNormalArray(
lTileCoordsVec2,
SAMPLER2DARRAYPARAM( lNormalMap ),
SAMPLER2DARRAYPARAM( lSubstanceNormalMap ),
int( lTile1Vec4[ 0 ] ),
lfHeight1,
lfSpecular );
lfHeight2 = lfHeight1;
lfHeight3 = lfHeight1;
lfHeight4 = lfHeight1;
lfHeight5 = lfHeight1;
lfHeight6 = lfHeight1;
lfHeight7 = lfHeight1;
return lNormal;
#endif
}
vec3
GetBlendedColour(
in CustomPerMaterialUniforms lCustomUniforms,
in vec2 lTileCoordsVec2,
SAMPLER2DARRAYARG( lDiffuseMap ),
SAMPLER2DARRAYARG( lSubstanceDiffuseMap ),
in vec4 lTile1Vec4,
in vec4 lTile2Vec4,
in float lfHeight1,
in float lfHeight2,
in float lfHeight3,
in float lfHeight4,
in float lfHeight5,
in float lfHeight6,
in float lfHeight7,
out float lfMetallic )
{
lfMetallic = 0.0;
#ifndef D_LOW_QUALITY
const float lfThreshold = 1.0 / 100.0;
vec3 lColour5 = vec3( 0.0, 0.0, 0.0 );
vec3 lColour6 = vec3( 0.0, 0.0, 0.0 );
float lfMetallic5 = 0.0;
float lfMetallic6 = 0.0;
if( lfHeight7 < 1.0 - lfThreshold )
{
#ifdef D_PLATFORM_PC
if( lfHeight5 < 1.0 - lfThreshold )
#endif
{
if( ( 1.0 - lfHeight1 ) * ( 1.0 - lfHeight5 ) > lfThreshold )
{
int liIndex = int( floor( lTile1Vec4.x ) );
vec3 lOriginalColourVec3 = ARRAY_LOOKUP_FS( lCustomUniforms, gaAverageColoursVec4, liIndex ).rgb;
vec3 lRecolourVec3 = ARRAY_LOOKUP_FS( lCustomUniforms, gaTerrainColoursVec4, liIndex ).rgb;
lfMetallic5 += ( 1.0 - lfHeight1 ) * ( 1.0 - lfHeight5 ) * ( 1.0 - ARRAY_LOOKUP_FS( lCustomUniforms, gaTerrainColoursVec4, liIndex ).a );
lColour5 += ( 1.0 - lfHeight1 ) * ( 1.0 - lfHeight5 ) * GetTriPlanarColourArray( lTileCoordsVec2, SAMPLER2DARRAYPARAM( lDiffuseMap ), SAMPLER2DARRAYPARAM( lSubstanceDiffuseMap ), liIndex, lOriginalColourVec3, lRecolourVec3 ).xyz;
}
if( lfHeight1 * ( 1.0 - lfHeight5 ) > lfThreshold )
{
int liIndex = int( floor( lTile1Vec4.y ) );
vec3 lOriginalColourVec3 = ARRAY_LOOKUP_FS( lCustomUniforms, gaAverageColoursVec4, liIndex ).rgb;
vec3 lRecolourVec3 = ARRAY_LOOKUP_FS( lCustomUniforms, gaTerrainColoursVec4, liIndex ).rgb;
lfMetallic5 += lfHeight1 * ( 1.0 - lfHeight5 ) * ( 1.0 - ARRAY_LOOKUP_FS( lCustomUniforms, gaTerrainColoursVec4, liIndex ).a );
lColour5 += lfHeight1 * ( 1.0 - lfHeight5 ) * GetTriPlanarColourArray( lTileCoordsVec2, SAMPLER2DARRAYPARAM( lDiffuseMap ), SAMPLER2DARRAYPARAM( lSubstanceDiffuseMap ), liIndex, lOriginalColourVec3, lRecolourVec3 ).xyz;
}
}
#ifdef D_PLATFORM_PC
if( lfHeight5 > lfThreshold )
#endif
{
if( ( 1.0 - lfHeight2 ) * lfHeight5 > lfThreshold )
{
int liIndex = int( floor( lTile1Vec4.z ) );
vec3 lOriginalColourVec3 = ARRAY_LOOKUP_FS( lCustomUniforms, gaAverageColoursVec4, liIndex ).rgb;
vec3 lRecolourVec3 = ARRAY_LOOKUP_FS( lCustomUniforms, gaTerrainColoursVec4, liIndex ).rgb;
lfMetallic5 += ( 1.0 - lfHeight2 ) * lfHeight5 * ( 1.0 - ARRAY_LOOKUP_FS( lCustomUniforms, gaTerrainColoursVec4, liIndex ).a );
lColour5 += ( 1.0 - lfHeight2 ) * lfHeight5 * GetTriPlanarColourArray( lTileCoordsVec2, SAMPLER2DARRAYPARAM( lDiffuseMap ), SAMPLER2DARRAYPARAM( lSubstanceDiffuseMap ), liIndex, lOriginalColourVec3, lRecolourVec3 ).xyz;
}
if( lfHeight2 * lfHeight5 > lfThreshold )
{
int liIndex = int( floor( lTile1Vec4.w ) );
vec3 lOriginalColourVec3 = ARRAY_LOOKUP_FS( lCustomUniforms, gaAverageColoursVec4, liIndex ).rgb;
vec3 lRecolourVec3 = ARRAY_LOOKUP_FS( lCustomUniforms, gaTerrainColoursVec4, liIndex ).rgb;
lfMetallic5 += lfHeight2 * lfHeight5 * ( 1.0 - ARRAY_LOOKUP_FS( lCustomUniforms, gaTerrainColoursVec4, liIndex ).a );
lColour5 += lfHeight2 * lfHeight5 * GetTriPlanarColourArray( lTileCoordsVec2, SAMPLER2DARRAYPARAM( lDiffuseMap ), SAMPLER2DARRAYPARAM( lSubstanceDiffuseMap ), liIndex, lOriginalColourVec3, lRecolourVec3 ).xyz;
}
}
}
if( lfHeight7 > lfThreshold )
{
#ifdef D_PLATFORM_PC
if( lfHeight6 < 1.0 - lfThreshold )
#endif
{
if( ( 1.0 - lfHeight3 ) * ( 1.0 - lfHeight6 ) > lfThreshold )
{
int liIndex = int( floor( lTile2Vec4.x ) );
vec3 lOriginalColourVec3 = ARRAY_LOOKUP_FS( lCustomUniforms, gaAverageColoursVec4, liIndex ).rgb;
vec3 lRecolourVec3 = ARRAY_LOOKUP_FS( lCustomUniforms, gaTerrainColoursVec4, liIndex ).rgb;
lfMetallic6 += ( 1.0 - lfHeight3 ) * ( 1.0 - lfHeight6 ) * ( 1.0 - ARRAY_LOOKUP_FS( lCustomUniforms, gaTerrainColoursVec4, liIndex ).a );
lColour6 += ( 1.0 - lfHeight3 ) * ( 1.0 - lfHeight6 ) * GetTriPlanarColourArray( lTileCoordsVec2, SAMPLER2DARRAYPARAM( lDiffuseMap ), SAMPLER2DARRAYPARAM( lSubstanceDiffuseMap ), liIndex, lOriginalColourVec3, lRecolourVec3 ).xyz;
}
if( lfHeight3 * ( 1.0 - lfHeight6 ) > lfThreshold )
{
int liIndex = int( floor( lTile2Vec4.y ) );
vec3 lOriginalColourVec3 = ARRAY_LOOKUP_FS( lCustomUniforms, gaAverageColoursVec4, liIndex ).rgb;
vec3 lRecolourVec3 = ARRAY_LOOKUP_FS( lCustomUniforms, gaTerrainColoursVec4, liIndex ).rgb;
lfMetallic6 += lfHeight3 * ( 1.0 - lfHeight6 ) * ( 1.0 - ARRAY_LOOKUP_FS( lCustomUniforms, gaTerrainColoursVec4, liIndex ).a );
lColour6 += lfHeight3 * ( 1.0 - lfHeight6 ) * GetTriPlanarColourArray( lTileCoordsVec2, SAMPLER2DARRAYPARAM( lDiffuseMap ), SAMPLER2DARRAYPARAM( lSubstanceDiffuseMap ), liIndex, lOriginalColourVec3, lRecolourVec3 ).xyz;
}
}
#ifdef D_PLATFORM_PC
if( lfHeight6 > lfThreshold )
#endif
{
if( ( 1.0 - lfHeight4 ) * lfHeight6 > lfThreshold )
{
int liIndex = int( floor( lTile2Vec4.z ) );
vec3 lOriginalColourVec3 = ARRAY_LOOKUP_FS( lCustomUniforms, gaAverageColoursVec4, liIndex ).rgb;
vec3 lRecolourVec3 = ARRAY_LOOKUP_FS( lCustomUniforms, gaTerrainColoursVec4, liIndex ).rgb;
lfMetallic6 += ( 1.0 - lfHeight4 ) * lfHeight6 * ( 1.0 - ARRAY_LOOKUP_FS( lCustomUniforms, gaTerrainColoursVec4, liIndex ).a );
lColour6 += ( 1.0 - lfHeight4 ) * lfHeight6 * GetTriPlanarColourArray( lTileCoordsVec2, SAMPLER2DARRAYPARAM( lDiffuseMap ), SAMPLER2DARRAYPARAM( lSubstanceDiffuseMap ), liIndex, lOriginalColourVec3, lRecolourVec3 ).xyz;
}
#ifdef D_DEFER
if( lfHeight4 * lfHeight6 > lfThreshold )
{
int liIndex = int( floor( lTile2Vec4.w ) );
vec3 lOriginalColourVec3 = ARRAY_LOOKUP_FS( lCustomUniforms, gaAverageColoursVec4, liIndex ).rgb;
vec3 lRecolourVec3 = ARRAY_LOOKUP_FS( lCustomUniforms, gaTerrainColoursVec4, liIndex ).rgb;
lfMetallic6 += lfHeight4 * lfHeight6 * ( 1.0 - ARRAY_LOOKUP_FS( lCustomUniforms, gaTerrainColoursVec4, liIndex ).a );
lColour6 += lfHeight4 * lfHeight6 * GetTriPlanarColourArray( lTileCoordsVec2, SAMPLER2DARRAYPARAM( lDiffuseMap ), SAMPLER2DARRAYPARAM( lSubstanceDiffuseMap ), liIndex, lOriginalColourVec3, lRecolourVec3 ).xyz;
}
#endif
}
}
lfMetallic = mix( lfMetallic5, lfMetallic6, lfHeight7 );
return mix( lColour5, lColour6, lfHeight7 );
#else
int liIndex = int( floor( lTile1Vec4[ 0 ] ) );
vec3 lOriginalColourVec3 = ARRAY_LOOKUP_FS( lCustomUniforms, gaAverageColoursVec4, liIndex ).rgb;
vec3 lRecolourVec3 = ARRAY_LOOKUP_FS( lCustomUniforms, gaTerrainColoursVec4, liIndex ).rgb;
return GetTriPlanarColourArray(
lTileCoordsVec2,
SAMPLER2DARRAYPARAM( lDiffuseMap ),
SAMPLER2DARRAYPARAM( lSubstanceDiffuseMap ),
int( lTile1Vec4[ 0 ] ),
lOriginalColourVec3,
lRecolourVec3 );
#endif
}
vec3
GetTileColourAndNormal(
in CustomPerMaterialUniforms lCustomUniforms,
in vec3 lSmoothNormalVec3,
in vec3 lFacetNormalVec3,
in vec3 lCenterPositionVec3,
in vec3 lTilePositionVec3,
in uvec4 lTileTextureIndicesSmall1Vec4,
in uvec4 lTileTextureIndicesSmall2Vec4,
in uvec4 lTileTextureIndicesLarge1Vec4,
in uvec4 lTileTextureIndicesLarge2Vec4,
in float lfTileType,
in float lfSlope,
in float lfPatch,
out vec3 lOutWorldNormalVec3,
in float lfSmallScale,
in float lfLargeScale,
in float lfFade,
SAMPLER2DARRAYARG( lDiffuseMap ),
SAMPLER2DARRAYARG( lNormalMap ),
SAMPLER2DARRAYARG( lSubstanceDiffuseMap ),
SAMPLER2DARRAYARG( lSubstanceNormalMap ),
out float lfSpecular,
out float lfSubsurface,
out float lfMetallic,
out float lfGlow )
{
#if defined( D_TERRAIN_X_FACING )
vec3 lWeightsVec3 = vec3( 1.0, 0.0, 0.0 );
#elif defined( D_TERRAIN_Y_FACING )
vec3 lWeightsVec3 = vec3( 0.0, 1.0, 0.0 );
#elif defined( D_TERRAIN_Z_FACING )
vec3 lWeightsVec3 = vec3( 0.0, 0.0, 1.0 );
#else
vec3 lWeightsVec3 = pow( abs( lSmoothNormalVec3 ), vec3( 32.0,32.0,32.0 ) );
#endif
vec3 lTexCoordsVec3;
vec3 lSmallTexCoordsVec3;
vec3 lLargeTexCoordsVec3;
float lfWeightRecip = 1.0 / ( lWeightsVec3.x + lWeightsVec3.y + lWeightsVec3.z );
vec3 lNormalVec3;
#if 0
{
float lfDot = dot(normalize(lSmoothNormalVec3), normalize(lFacetNormalVec3));
lNormalVec3 = mix( lFacetNormalVec3, lSmoothNormalVec3, smoothstep(0.9, 0.95, lfDot ) );
}
#else
lNormalVec3 = lSmoothNormalVec3;
#endif
lfSubsurface = 0.0;
lfMetallic = 0.0;
lfGlow = 0.0;
// these two offsets tell us how much fractional part of the planet offset is left
// after the texture has wrapped around many many times. They have some error but
// it is the same error everywhere on a planet - so it should not have a visible effect.
vec3 lCenterPositionFlippedVec3 = lCenterPositionVec3;
lCenterPositionFlippedVec3.y = -lCenterPositionFlippedVec3.y; // this must match the y flip of the tex coords
vec3 lTextureOffsetSmall = fract( lCenterPositionFlippedVec3 * lfSmallScale );
vec3 lTextureOffsetLarge = fract( lCenterPositionFlippedVec3 * lfLargeScale );
lTexCoordsVec3 = lTilePositionVec3;
lTexCoordsVec3.y = -lTexCoordsVec3.y;
lSmallTexCoordsVec3 = ( lTexCoordsVec3 * lfSmallScale ) + lTextureOffsetSmall;
lLargeTexCoordsVec3 = ( lTexCoordsVec3 * lfLargeScale ) + lTextureOffsetLarge;
vec3 lWeightsVec3N = lWeightsVec3 * lfWeightRecip;
// Normals + (Spec and Height)
float lafHeights[7] = { 0., 0, 0, 0, 0, 0, 0 };
{
vec3 lSmallMappedNormalVec3 = vec3( 0.0, 0.0, 0.0 );
vec3 lLargeMappedNormalVec3 = vec3( 0.0, 0.0, 0.0 );
vec3 lSpecularLargeVec3 = vec3(0.0, 0.0, 0.0);
vec3 lSpecularSmallVec3 = vec3(0.0, 0.0, 0.0);
vec3 lHeightsLargeVec3[ 7 ] = { vec3( 0.5, 0.5, 0.5 ), vec3( 0.5, 0.5, 0.5 ), vec3( 0.5, 0.5, 0.5 ), vec3( 0.5, 0.5, 0.5 ), vec3( 0.5, 0.5, 0.5 ), vec3( 0.5, 0.5, 0.5 ), vec3( 0.5, 0.5, 0.5 ) };
vec3 lHeightsSmallVec3[ 7 ] = { vec3( 0.5, 0.5, 0.5 ), vec3( 0.5, 0.5, 0.5 ), vec3( 0.5, 0.5, 0.5 ), vec3( 0.5, 0.5, 0.5 ), vec3( 0.5, 0.5, 0.5 ), vec3( 0.5, 0.5, 0.5 ), vec3( 0.5, 0.5, 0.5 ) };
float lfFadeThreshold = 1.0 / 100.0;
if( lfFade > lfFadeThreshold )
{
if( lWeightsVec3N.x > 0.003 )
{
vec3 lNormalLargeVec3 = GetBlendedNormal( lLargeTexCoordsVec3.zy, SAMPLER2DARRAYPARAM( lNormalMap ), SAMPLER2DARRAYPARAM( lSubstanceNormalMap ), lTileTextureIndicesLarge1Vec4, lTileTextureIndicesLarge2Vec4, lfTileType, lfSlope, lfPatch, lSpecularLargeVec3.x,
lHeightsLargeVec3[ 0 ].x, lHeightsLargeVec3[ 1 ].x, lHeightsLargeVec3[ 2 ].x, lHeightsLargeVec3[ 3 ].x, lHeightsLargeVec3[ 4 ].x, lHeightsLargeVec3[ 5 ].x, lHeightsLargeVec3[ 6 ].x );
lLargeMappedNormalVec3 += lfFade * lWeightsVec3N.x * vec3( 0.0, lNormalLargeVec3.x, lNormalLargeVec3.y ); // YZ
}
if( lWeightsVec3N.y > 0.003 )
{
vec3 lNormalLargeVec3 = GetBlendedNormal( lLargeTexCoordsVec3.zx, SAMPLER2DARRAYPARAM( lNormalMap ), SAMPLER2DARRAYPARAM( lSubstanceNormalMap ), lTileTextureIndicesLarge1Vec4, lTileTextureIndicesLarge2Vec4, lfTileType, lfSlope, lfPatch, lSpecularLargeVec3.y,
lHeightsLargeVec3[ 0 ].y, lHeightsLargeVec3[ 1 ].y, lHeightsLargeVec3[ 2 ].y, lHeightsLargeVec3[ 3 ].y, lHeightsLargeVec3[ 4 ].y, lHeightsLargeVec3[ 5 ].y, lHeightsLargeVec3[ 6 ].y );
lLargeMappedNormalVec3 += lfFade * lWeightsVec3N.y * vec3( -lNormalLargeVec3.x, 0.0, lNormalLargeVec3.y ); // ZX
}
if( lWeightsVec3N.z > 0.003 )
{
vec3 lNormalLargeVec3 = GetBlendedNormal( lLargeTexCoordsVec3.xy, SAMPLER2DARRAYPARAM( lNormalMap ), SAMPLER2DARRAYPARAM( lSubstanceNormalMap ), lTileTextureIndicesLarge1Vec4, lTileTextureIndicesLarge2Vec4, lfTileType, lfSlope, lfPatch, lSpecularLargeVec3.z,
lHeightsLargeVec3[ 0 ].z, lHeightsLargeVec3[ 1 ].z, lHeightsLargeVec3[ 2 ].z, lHeightsLargeVec3[ 3 ].z, lHeightsLargeVec3[ 4 ].z, lHeightsLargeVec3[ 5 ].z, lHeightsLargeVec3[ 6 ].z );
lLargeMappedNormalVec3 += lfFade * lWeightsVec3N.z * vec3( lNormalLargeVec3.y, lNormalLargeVec3.x, 0.0 ); // XY
}
}
else
{
lfFade = 0.0;
}
if( lfFade < 1.0 - lfFadeThreshold )
{
if( lWeightsVec3N.x > 0.003 )
{
vec3 lNormalSmallVec3 = GetBlendedNormal( lSmallTexCoordsVec3.zy, SAMPLER2DARRAYPARAM( lNormalMap ), SAMPLER2DARRAYPARAM( lSubstanceNormalMap ), lTileTextureIndicesSmall1Vec4, lTileTextureIndicesSmall2Vec4, lfTileType, lfSlope, lfPatch, lSpecularSmallVec3.x,
lHeightsSmallVec3[ 0 ].x, lHeightsSmallVec3[ 1 ].x, lHeightsSmallVec3[ 2 ].x, lHeightsSmallVec3[ 3 ].x, lHeightsSmallVec3[ 4 ].x, lHeightsSmallVec3[ 5 ].x, lHeightsSmallVec3[ 6 ].x );
lSmallMappedNormalVec3 += (1.0 - lfFade ) * lWeightsVec3N.x * vec3( 0.0, lNormalSmallVec3.x, lNormalSmallVec3.y ); // YZ
}
if( lWeightsVec3N.y > 0.003 )
{
vec3 lNormalSmallVec3 = GetBlendedNormal( lSmallTexCoordsVec3.zx, SAMPLER2DARRAYPARAM( lNormalMap ), SAMPLER2DARRAYPARAM( lSubstanceNormalMap ), lTileTextureIndicesSmall1Vec4, lTileTextureIndicesSmall2Vec4, lfTileType, lfSlope, lfPatch, lSpecularSmallVec3.y,
lHeightsSmallVec3[ 0 ].y, lHeightsSmallVec3[ 1 ].y, lHeightsSmallVec3[ 2 ].y, lHeightsSmallVec3[ 3 ].y, lHeightsSmallVec3[ 4 ].y, lHeightsSmallVec3[ 5 ].y, lHeightsSmallVec3[ 6 ].y );
lSmallMappedNormalVec3 += (1.0 - lfFade ) * lWeightsVec3N.y * vec3( -lNormalSmallVec3.x, 0.0, lNormalSmallVec3.y ); // ZX
}
if( lWeightsVec3N.z > 0.003 )
{
vec3 lNormalSmallVec3 = GetBlendedNormal( lSmallTexCoordsVec3.xy, SAMPLER2DARRAYPARAM( lNormalMap ), SAMPLER2DARRAYPARAM( lSubstanceNormalMap ), lTileTextureIndicesSmall1Vec4, lTileTextureIndicesSmall2Vec4, lfTileType, lfSlope, lfPatch, lSpecularSmallVec3.z,
lHeightsSmallVec3[ 0 ].z, lHeightsSmallVec3[ 1 ].z, lHeightsSmallVec3[ 2 ].z, lHeightsSmallVec3[ 3 ].z, lHeightsSmallVec3[ 4 ].z, lHeightsSmallVec3[ 5 ].z, lHeightsSmallVec3[ 6 ].z );
lSmallMappedNormalVec3 += (1.0 - lfFade ) * lWeightsVec3N.z * vec3( lNormalSmallVec3.y, lNormalSmallVec3.x, 0.0 ); // XY
}
}
else
{
lfFade = 1.0;
}
{
for( int i = 0; i < 7; i++ )
{
float lfHeightLarge = dot( lHeightsLargeVec3[ i ], lWeightsVec3 ) * lfWeightRecip;
float lfHeightSmall = dot( lHeightsSmallVec3[ i ], lWeightsVec3 ) * lfWeightRecip;
lafHeights[ i ] = mix( lfHeightSmall, lfHeightLarge, lfFade );
}
lafHeights[ 0 ] = smoothstep( lafHeights[ 0 ] - 0.12, lafHeights[ 0 ] + 0.12, lfTileType );
lafHeights[ 1 ] = smoothstep( lafHeights[ 1 ] - 0.12, lafHeights[ 1 ] + 0.12, lfTileType );
lafHeights[ 2 ] = smoothstep( lafHeights[ 2 ] - 0.12, lafHeights[ 2 ] + 0.12, lfTileType );
lafHeights[ 3 ] = smoothstep( lafHeights[ 3 ] - 0.12, lafHeights[ 3 ] + 0.12, lfTileType );
lafHeights[ 4 ] = smoothstep( lafHeights[ 4 ] - 0.12, lafHeights[ 4 ] + 0.12, lfSlope );
lafHeights[ 5 ] = smoothstep( lafHeights[ 5 ] - 0.12, lafHeights[ 5 ] + 0.12, lfSlope );
lafHeights[ 6 ] = smoothstep( lafHeights[ 6 ] - 0.12, lafHeights[ 6 ] + 0.12, lfPatch );
float lfSpecularLarge = dot(lSpecularLargeVec3, lWeightsVec3) * lfWeightRecip;
float lfSpecularSmall = dot(lSpecularSmallVec3, lWeightsVec3) * lfWeightRecip;
lSmallMappedNormalVec3 = vec3( lSmallMappedNormalVec3.x + lLargeMappedNormalVec3.x, lSmallMappedNormalVec3.y * lLargeMappedNormalVec3.y, lSmallMappedNormalVec3.z + lLargeMappedNormalVec3.z );
lOutWorldNormalVec3 = normalize( lNormalVec3 + lSmallMappedNormalVec3 * 1.2 );
lfSpecular = mix( lfSpecularSmall, lfSpecularLarge, lfFade );
}
}
#ifdef D_PLATFORM_PC
vec3 lTileColourVec3 = vec3(0.0, 0.0, 0.0);
{
if (lWeightsVec3N.x * lfFade > 0.003)
{
lTileColourVec3 += lfFade * lWeightsVec3N.x * GetBlendedColour(lCustomUniforms, lLargeTexCoordsVec3.zy, SAMPLER2DARRAYPARAM(lDiffuseMap), SAMPLER2DARRAYPARAM(lSubstanceDiffuseMap), lTileTextureIndicesLarge1Vec4, lTileTextureIndicesLarge2Vec4,
lafHeights[0], lafHeights[1], lafHeights[2], lafHeights[3], lafHeights[4], lafHeights[5], lafHeights[6], lfMetallic).xyz;
}
if (lWeightsVec3N.y * lfFade > 0.003)
{
lTileColourVec3 += lfFade * lWeightsVec3N.y * GetBlendedColour(lCustomUniforms, lLargeTexCoordsVec3.zx, SAMPLER2DARRAYPARAM(lDiffuseMap), SAMPLER2DARRAYPARAM(lSubstanceDiffuseMap), lTileTextureIndicesLarge1Vec4, lTileTextureIndicesLarge2Vec4,
lafHeights[0], lafHeights[1], lafHeights[2], lafHeights[3], lafHeights[4], lafHeights[5], lafHeights[6], lfMetallic).xyz;
}
if (lWeightsVec3N.z * lfFade > 0.003)
{
lTileColourVec3 += lfFade * lWeightsVec3N.z * GetBlendedColour(lCustomUniforms, lLargeTexCoordsVec3.xy, SAMPLER2DARRAYPARAM(lDiffuseMap), SAMPLER2DARRAYPARAM(lSubstanceDiffuseMap), lTileTextureIndicesLarge1Vec4, lTileTextureIndicesLarge2Vec4,
lafHeights[0], lafHeights[1], lafHeights[2], lafHeights[3], lafHeights[4], lafHeights[5], lafHeights[6], lfMetallic).xyz;
}
if (lWeightsVec3N.x * (1.0 - lfFade) > 0.003)
{
lTileColourVec3 += (1.0 - lfFade) * lWeightsVec3N.x * GetBlendedColour(lCustomUniforms, lSmallTexCoordsVec3.zy, SAMPLER2DARRAYPARAM(lDiffuseMap), SAMPLER2DARRAYPARAM(lSubstanceDiffuseMap), lTileTextureIndicesSmall1Vec4, lTileTextureIndicesSmall2Vec4,
lafHeights[0], lafHeights[1], lafHeights[2], lafHeights[3], lafHeights[4], lafHeights[5], lafHeights[6], lfMetallic).xyz;
}
if (lWeightsVec3N.y * (1.0 - lfFade) > 0.003)
{
lTileColourVec3 += (1.0 - lfFade) * lWeightsVec3N.y * GetBlendedColour(lCustomUniforms, lSmallTexCoordsVec3.zx, SAMPLER2DARRAYPARAM(lDiffuseMap), SAMPLER2DARRAYPARAM(lSubstanceDiffuseMap), lTileTextureIndicesSmall1Vec4, lTileTextureIndicesSmall2Vec4,
lafHeights[0], lafHeights[1], lafHeights[2], lafHeights[3], lafHeights[4], lafHeights[5], lafHeights[6], lfMetallic).xyz;
}
if (lWeightsVec3N.z * (1.0 - lfFade) > 0.003)
{
lTileColourVec3 += (1.0 - lfFade) * lWeightsVec3N.z * GetBlendedColour(lCustomUniforms, lSmallTexCoordsVec3.xy, SAMPLER2DARRAYPARAM(lDiffuseMap), SAMPLER2DARRAYPARAM(lSubstanceDiffuseMap), lTileTextureIndicesSmall1Vec4, lTileTextureIndicesSmall2Vec4,
lafHeights[0], lafHeights[1], lafHeights[2], lafHeights[3], lafHeights[4], lafHeights[5], lafHeights[6], lfMetallic).xyz;
}
}
#else
vec3 lTileColourSmallVec3 = vec3( 0.0, 0.0, 0.0 );
vec3 lTileColourLargeVec3 = vec3( 0.0, 0.0, 0.0 );
{
if( lWeightsVec3N.x > 0.003 )
{
lTileColourLargeVec3 += lWeightsVec3N.x * GetBlendedColour( lCustomUniforms, lLargeTexCoordsVec3.zy, SAMPLER2DARRAYPARAM( lDiffuseMap ), SAMPLER2DARRAYPARAM( lSubstanceDiffuseMap ), lTileTextureIndicesLarge1Vec4, lTileTextureIndicesLarge2Vec4,
lafHeights[ 0 ], lafHeights[ 1 ], lafHeights[ 2 ], lafHeights[ 3 ], lafHeights[ 4 ], lafHeights[ 5 ], lafHeights[ 6 ], lfMetallic ).xyz;
lTileColourSmallVec3 += lWeightsVec3N.x * GetBlendedColour( lCustomUniforms, lSmallTexCoordsVec3.zy, SAMPLER2DARRAYPARAM( lDiffuseMap ), SAMPLER2DARRAYPARAM( lSubstanceDiffuseMap ), lTileTextureIndicesSmall1Vec4, lTileTextureIndicesSmall2Vec4,
lafHeights[ 0 ], lafHeights[ 1 ], lafHeights[ 2 ], lafHeights[ 3 ], lafHeights[ 4 ], lafHeights[ 5 ], lafHeights[ 6 ], lfMetallic ).xyz;
}
if( lWeightsVec3N.y > 0.003 )
{
lTileColourLargeVec3 += lWeightsVec3N.y * GetBlendedColour( lCustomUniforms, lLargeTexCoordsVec3.zx, SAMPLER2DARRAYPARAM( lDiffuseMap ), SAMPLER2DARRAYPARAM( lSubstanceDiffuseMap ), lTileTextureIndicesLarge1Vec4, lTileTextureIndicesLarge2Vec4,
lafHeights[ 0 ], lafHeights[ 1 ], lafHeights[ 2 ], lafHeights[ 3 ], lafHeights[ 4 ], lafHeights[ 5 ], lafHeights[ 6 ], lfMetallic ).xyz;
lTileColourSmallVec3 += lWeightsVec3N.y * GetBlendedColour( lCustomUniforms, lSmallTexCoordsVec3.zx, SAMPLER2DARRAYPARAM( lDiffuseMap ), SAMPLER2DARRAYPARAM( lSubstanceDiffuseMap ), lTileTextureIndicesSmall1Vec4, lTileTextureIndicesSmall2Vec4,
lafHeights[ 0 ], lafHeights[ 1 ], lafHeights[ 2 ], lafHeights[ 3 ], lafHeights[ 4 ], lafHeights[ 5 ], lafHeights[ 6 ], lfMetallic ).xyz;
}
if( lWeightsVec3N.z > 0.003 )
{
lTileColourLargeVec3 += lWeightsVec3N.z * GetBlendedColour( lCustomUniforms, lLargeTexCoordsVec3.xy, SAMPLER2DARRAYPARAM( lDiffuseMap ), SAMPLER2DARRAYPARAM( lSubstanceDiffuseMap ), lTileTextureIndicesLarge1Vec4, lTileTextureIndicesLarge2Vec4,
lafHeights[ 0 ], lafHeights[ 1 ], lafHeights[ 2 ], lafHeights[ 3 ], lafHeights[ 4 ], lafHeights[ 5 ], lafHeights[ 6 ], lfMetallic ).xyz;
lTileColourSmallVec3 += lWeightsVec3N.z * GetBlendedColour( lCustomUniforms, lSmallTexCoordsVec3.xy, SAMPLER2DARRAYPARAM( lDiffuseMap ), SAMPLER2DARRAYPARAM( lSubstanceDiffuseMap ), lTileTextureIndicesSmall1Vec4, lTileTextureIndicesSmall2Vec4,
lafHeights[ 0 ], lafHeights[ 1 ], lafHeights[ 2 ], lafHeights[ 3 ], lafHeights[ 4 ], lafHeights[ 5 ], lafHeights[ 6 ], lfMetallic ).xyz;
}
}
vec3 lTileColourVec3;
lTileColourVec3 = mix( lTileColourSmallVec3, lTileColourLargeVec3, lfFade );
#endif
lTileColourVec3 = GammaCorrectInput( lTileColourVec3 );
return lTileColourVec3;
}
#endif
#endif
//-----------------------------------------------------------------------------
// Global Data
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
///
/// Caustics
///
/// @brief Caustics
///
/// @param in vec3 lSkyColourVec3,
/// @param in vec3 lFragmentColourVec3
/// @param in vec4 lFogVec4,
/// @param in vec3 lCameraPositionVec3
/// @return vec3
///
//-----------------------------------------------------------------------------
vec3
Caustics(
in vec3 lFragmentColourVec3,
in vec3 lWorldPositionVec3,
in vec3 lLocalNormalVec3,
in vec3 lWorldUpVec3,
in float lfWaterHeight,
in float lfTime,
SAMPLER2DARG( lTexture ),
SAMPLER2DARG( lOffsetTexture ),
inout vec3 lSunColourVec3
)
{
float lfWaterDepth;
float lfCausticStrength;
vec3 lOutColVec3;
vec3 lWaterPositionVec3;
lWaterPositionVec3 = normalize( lWorldPositionVec3 ) * lfWaterHeight;
lfWaterDepth = ( lfWaterHeight - length( lWorldPositionVec3 ) );
//start with the current colour
lOutColVec3 = lFragmentColourVec3;
if( lfWaterDepth >= 0.0 )
{
vec2 lAnimationVec2 = vec2( lfTime * 0.005 * 3.0 + 7.0, -lfTime * 0.005 * 3.0 );
float lfOffset = GetTriPlanarColourMM( lLocalNormalVec3, lWorldPositionVec3, lAnimationVec2, 0.01, SAMPLER2DPARAM( lOffsetTexture ) ).g;
lAnimationVec2 = vec2( lfOffset, 1.0 - lfOffset ) * 0.06 + vec2( lfTime * 0.0025 * 3.0, lfTime * 0.0025 * 2.5 + 7.0 );
lfCausticStrength = GetTriPlanarColourMM( lLocalNormalVec3, lWaterPositionVec3, lAnimationVec2, 0.04, SAMPLER2DPARAM( lTexture ) ).g;
lAnimationVec2 = vec2( lfOffset, 1.0 - lfOffset ) * 0.05 + vec2( lfTime * 0.0025 * 2.0 + 5.0, -lfTime * 0.0025 * 2.5 );
lfCausticStrength += GetTriPlanarColourMM( lLocalNormalVec3, lWaterPositionVec3, lAnimationVec2, 0.03, SAMPLER2DPARAM( lTexture ) ).g;
lOutColVec3.xyz *= vec3( lfCausticStrength * 2.0 + 0.6 );
lSunColourVec3 *= vec3( lfCausticStrength * 2.0 + 0.6 );
}
return lOutColVec3;
}
#endif
////////////////////////////////////////////////////////////////////////////////
///
/// @file CommonPlanet.h
/// @author User
/// @date
///
/// @brief CommonPlanetShader
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Compilation defines
#ifndef D_COMMONPLANET_H
#define D_COMMONPLANET_H
//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------
// Global Data
STATIC_CONST vec3 kUp = vec3( 0.0, 1.0, 0.0 );
STATIC_CONST float kfPi = 3.14159;
STATIC_CONST float kfAccuracy = 0.001;
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
///
/// GetHeight
///
/// @brief GetHeight
///
/// @param in vec3 lWorldPosition
/// @return float
///
//-----------------------------------------------------------------------------
float
GetHeight(
in vec3 lWorldPosition,
in vec4 lPlanetPosition )
{
vec3 lOffset = lWorldPosition - lPlanetPosition.xyz;
return length(lOffset) - lPlanetPosition.w;
}
//-----------------------------------------------------------------------------
///
/// GetHeight
///
/// @brief GetHeight
///
/// @param in vec3 lWorldPosition
/// @return float
///
//-----------------------------------------------------------------------------
float
GetDistanceFromCenter(
in vec3 lWorldPosition,
in vec4 lPlanetPosition )
{
vec3 lOffset = lWorldPosition - lPlanetPosition.xyz;
return length(lOffset);
}
//-----------------------------------------------------------------------------
///
/// GetWorldUp
///
/// @brief GetWorldUp
///
/// @param in vec3 lWorldPosition
/// @return vec3
///
//-----------------------------------------------------------------------------
vec3
GetWorldUp(
in vec3 lWorldPosition,
in vec4 lPlanetPosition )
{
#ifdef D_ASTEROID
return kUp;
#else
return normalize(lWorldPosition / lPlanetPosition.w - lPlanetPosition.xyz / lPlanetPosition.w);
#endif
}
//-----------------------------------------------------------------------------
///
/// GetWorldUp
///
/// @brief GetWorldUp
///
/// @param in vec3 lWorldPosition
/// @param out float lfHeight
/// @return vec3
///
//-----------------------------------------------------------------------------
vec3
GetWorldUp(
in vec3 lWorldPosition,
in vec4 lPlanetPosition,
out float lfHeight )
{
vec3 lOffset;
// Get the offset from planet centre
lOffset = (lWorldPosition - lPlanetPosition.xyz);
// Get the length of the offset
lfHeight = length(lOffset);
// Normalise the offset to get the world up
lOffset /= lfHeight;
// Remove the planet radius to get the height
lfHeight -= lPlanetPosition.w;
return lOffset;
}
//-----------------------------------------------------------------------------
///
/// GetWorldUpTransform
///
/// @brief GetWorldUpTransform
///
/// @param in vec3 lViewPosition
/// @return mat3
///
//-----------------------------------------------------------------------------
mat3
GetRotation(
in vec3 lFromVec3,
in vec3 lToVec3 )
{
mat3 lMatrix;
vec3 lAxisVec3 = cross( lFromVec3, lToVec3 );
float lfDot = dot( lFromVec3, lToVec3 );
float lfAngle = length( lAxisVec3 );
if( lfAngle > kfAccuracy && lfDot < ( 1.0 - kfAccuracy ) && lfDot > -( 1.0 - kfAccuracy ) )
{
lfAngle = length( lAxisVec3 );
lAxisVec3 = normalize( lAxisVec3 );
}
else
{
return mat3( vec3( 1.0, 0.0, 0.0 ), vec3( 0.0, 1.0, 0.0 ), vec3( 0.0, 0.0, 1.0 ) );
}
lfAngle = clamp( lfAngle, -1.0, 1.0 );
lfAngle = asin( lfAngle );
if( lfDot < 0.0 )
{
lfAngle = kfPi - lfAngle;
}
float lfCos = cos( lfAngle );
float lfInv = 1.0 - lfCos;
float lfSin = sin( lfAngle );
MAT3_SET_COLUMN( lMatrix, 0, vec3( lfCos + lAxisVec3.x * lAxisVec3.x * lfInv, lAxisVec3.y * lAxisVec3.z * lfInv + lAxisVec3.z * lfSin, lAxisVec3.z * lAxisVec3.x * lfInv - lAxisVec3.y * lfSin ) );
MAT3_SET_COLUMN( lMatrix, 1, vec3( lAxisVec3.x * lAxisVec3.y * lfInv - lAxisVec3.z * lfSin, lfCos + lAxisVec3.y * lAxisVec3.y * lfInv, lAxisVec3.z * lAxisVec3.y * lfInv + lAxisVec3.x * lfSin ) );
MAT3_SET_COLUMN( lMatrix, 2, vec3( lAxisVec3.x * lAxisVec3.z * lfInv + lAxisVec3.y * lfSin, lAxisVec3.y * lAxisVec3.z * lfInv - lAxisVec3.x * lfSin, lfCos + lAxisVec3.z * lAxisVec3.z * lfInv ) );
return lMatrix;
}
//-----------------------------------------------------------------------------
///
/// GetWorldUpTransform
///
/// @brief GetWorldUpTransform
///
/// @param in vec3 lViewPosition
/// @return mat3
///
//-----------------------------------------------------------------------------
mat3
GetWorldUpTransform(
in vec3 lViewPosition,
in vec4 lPlanetPosition )
{
vec3 lUp = vec3( 0.0, 1.0, 0.0);
vec3 lWorldUp = GetWorldUp( lViewPosition, lPlanetPosition );
return GetRotation( lUp, lWorldUp );
}
//-----------------------------------------------------------------------------
///
/// GetWorldUpTransform
///
/// @brief GetWorldUpTransform
///
/// @param in vec3 lViewPosition
/// @return mat3
///
//-----------------------------------------------------------------------------
mat3
GetInverseWorldUpTransform(
in vec3 lViewPosition,
in vec4 lPlanetPosition )
{
vec3 lUp = vec3( 0.0, 1.0, 0.0 );
vec3 lWorldUp = GetWorldUp( lViewPosition, lPlanetPosition );
return GetRotation( lWorldUp, lUp );
}
#endif
////////////////////////////////////////////////////////////////////////////////
///
/// @file CommonDepth.h
/// @author User
/// @date
///
/// @brief CommonDepth
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Compilation defines
#ifndef D_COMMONNOISE_H
#define D_COMMONNOISE_H
#define D_USE_NOISETEXTURE
//-----------------------------------------------------------------------------
// Include files
////////////////////////////////////////////////////////////////////////////////
///
/// @file Common.h
/// @author User
/// @date
///
/// @brief Common
///
/// Copyright (c) 2008 Hello Games Ltd. All Rights Reserved.
///
////////////////////////////////////////////////////////////////////////////////
#ifndef D_COMMON_H
#define D_COMMON_H
#define D_TERRAINCOLOURARRAY_SIZE 23
STATIC_CONST vec3 kGammaOutVec3 = vec3( 1.0 / 2.2 );
STATIC_CONST vec3 kGammaInVec3 = vec3( 2.2 );
STATIC_CONST vec4 RGBToHSV_K = vec4( 0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0 );
STATIC_CONST vec4 HSVToRGB_K = vec4( 1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0 );
#ifdef D_PLATFORM_ORBIS
STATIC_CONST float3x3 BT709_TO_BT2020 = float3x3( //ref: ARIB STD-B62 and BT.2087
#else
STATIC_CONST mat3 BT709_TO_BT2020 = mat3( //ref: ARIB STD-B62 and BT.2087
#endif
0.6274, 0.3293, 0.0433,
0.0691, 0.9195, 0.0114,
0.0164, 0.0880, 0.8956
);
#ifdef D_PLATFORM_ORBIS
STATIC_CONST float3x3 BT2020_TO_BT709 = float3x3(
#else
STATIC_CONST mat3 BT2020_TO_BT709 = mat3(
#endif
1.6605, -0.5877, -0.0728,
-0.1246, 1.1330, -0.0084,
-0.0182, -0.1006, 1.1187
);
//-----------------------------------------------------------------------------
///
/// GammaCorrect
///
//-----------------------------------------------------------------------------
vec3
GammaCorrectInput(
in vec3 lColourVec3 )
{
vec3 lCorrectColourVec3;
lCorrectColourVec3 = lColourVec3 * ( lColourVec3 * ( lColourVec3 * vec3( 0.305306011 ) + vec3( 0.682171111 ) ) + vec3( 0.012522878 ) );
return lCorrectColourVec3;
}
//-----------------------------------------------------------------------------
///
/// GammaCorrect
///
//-----------------------------------------------------------------------------
vec3
GammaCorrectOutput(
in vec3 lColourVec3 )
{
vec3 lCorrectColourVec3;
lCorrectColourVec3 = pow( lColourVec3, kGammaOutVec3 );
return lCorrectColourVec3;
}
//-----------------------------------------------------------------------------
///
/// RGBToHSV
///
//-----------------------------------------------------------------------------
vec3
RGBToHSV(
vec3 lRGB )
{
//vec4 p = mix( vec4(lRGB.bg, RGBToHSV_K.wz), vec4(lRGB.gb, RGBToHSV_K.xy), step(lRGB.b, lRGB.g) );
//vec4 q = mix( vec4(p.xyw, lRGB.r), vec4(lRGB.r, p.yzx), step(p.x, lRGB.r) );
// This variant is faster, since it generates conditional moves
vec4 p = lRGB.g < lRGB.b ? vec4(lRGB.bg, RGBToHSV_K.wz) : vec4(lRGB.gb, RGBToHSV_K.xy);
vec4 q = lRGB.r < p.x ? vec4(p.xyw, lRGB.r) : vec4(lRGB.r, p.yzx);
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
//-----------------------------------------------------------------------------
///
/// HSVToRGB
///
/// @brief http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
///
//-----------------------------------------------------------------------------
vec3
HSVToRGB(
vec3 lHSV )
{
vec3 p = abs(fract(lHSV.xxx + HSVToRGB_K.xyz) * 6.0 - HSVToRGB_K.www);
return lHSV.z * mix(HSVToRGB_K.xxx, saturate(p - HSVToRGB_K.xxx), lHSV.y);
}
//-----------------------------------------------------------------------------
///
/// HDR ( Perceptual Quantizer(PQ), Rec. 2020 color space. ) helpers
///
//------------------------------------------------------------------------------
#ifdef D_PLATFORM_PC
float CndMask(bool cnd, float src0, float src1)
{
return cnd ? src0 : src1;
}
#endif
STATIC_CONST float kRefWhiteLevel = 100.0;
vec4 SRGB_OETF(vec4 L)
{
vec3 dark = L.xyz * 12.92;
vec3 light = 1.055 * pow(L.xyz, vec3(1.0 / 2.4)) - 0.055;
vec4 r;
r.x = CndMask(L.x <= 0.0031308, dark.x, light.x);
r.y = CndMask(L.y <= 0.0031308, dark.y, light.y);
r.z = CndMask(L.z <= 0.0031308, dark.z, light.z);
r.w = L.w;
return r;
}
vec4 SRGB_EOTF(vec4 E)
{
vec3 dark = E.xyz / 12.92;
vec3 light = pow((E.xyz + 0.055) / (1 + 0.055), vec3(2.4));
vec4 r;
r.x = CndMask(E.x <= 0.04045, dark.x, light.x);
r.y = CndMask(E.y <= 0.04045, dark.y, light.y);
r.z = CndMask(E.z <= 0.04045, dark.z, light.z);
r.w = E.w;
return r;
}
//apply gamma adjustment to (minL, maxL).
vec4 GammaAdjOOTF(vec4 L, float minLNits, float maxLNits, float gamma, bool inverse)
{
vec3 nits = L.xyz * kRefWhiteLevel;
vec4 i = vec4((nits - minLNits) / (maxLNits - minLNits), 1.0);
vec3 j;
if (inverse){
j = SRGB_EOTF(pow(i, vec4(1 / gamma))).xyz;
}
else{
j = pow(SRGB_OETF(i).xyz,vec3(gamma));
}
vec3 adj = (minLNits + (maxLNits - minLNits) * j) / kRefWhiteLevel;
vec4 ret;
ret.x = CndMask(nits.x >= minLNits && nits.x < maxLNits, adj.x, L.x);
ret.y = CndMask(nits.y >= minLNits && nits.y < maxLNits, adj.y, L.y);
ret.z = CndMask(nits.z >= minLNits && nits.z < maxLNits, adj.z, L.z);
ret.w = L.w;
return ret;
}
//input: normalized L in units of RefWhite (1.0=100nits), output: normalized E
vec4 PQ_OETF(vec4 L, uint gamma_adj, float gamma)
{
if (gamma_adj != 0)
L = GammaAdjOOTF(L, 0.0, 300.0, gamma, false);
const float c1 = 0.8359375;//3424.f/4096.f;
const float c2 = 18.8515625;//2413.f/4096.f*32.f;
const float c3 = 18.6875; //2392.f/4096.f*32.f;
const float m1 = 0.159301758125; //2610.f / 4096.f / 4;
const float m2 = 78.84375;// 2523.f / 4096.f * 128.f;
L = L * kRefWhiteLevel / 10000.0;
vec3 Lm1 = pow(L.xyz, vec3(m1));
vec3 X = (c1 + c2 * Lm1) / (1 + c3 * Lm1);
vec4 res = vec4(pow(X, vec3(m2)), L.w);
return res;
}
//input: normalized E (0.0, 1.0), output: normalized L in units of RefWhite
vec4 PQ_EOTF(vec4 E, uint gamma_adj, float gamma)
{
const float c1 = 0.8359375;//3424.f/4096.f;
const float c2 = 18.8515625;//2413.f/4096.f*32.f;
const float c3 = 18.6875; //2392.f/4096.f*32.f;
const float m1 = 0.159301758125; //2610.f / 4096.f / 4;
const float m2 = 78.84375;// 2523.f / 4096.f * 128.f;
vec3 M = c2 - c3 * pow(E.xyz, vec3(1 / m2));
vec3 N = max(pow(E.xyz, vec3(1 / m2)) - c1, 0);
vec3 L = pow(N / M, vec3(1 / m1)); //normalized nits (1.0 = 10000nits)
L = L * 10000.0 / kRefWhiteLevel; //convert to normalized L in units of RefWhite
return (gamma_adj !=0) ? GammaAdjOOTF(vec4(L, E.w), 0.0, 300.0, gamma, true) : vec4(L, E.w);
}
// PQ OETF fast approximation
// http://www.glowybits.com/blog/2017/01/04/ifl_iss_hdr_2/
vec3 PQ_OETF_Fast(vec3 x)
{
x = (x * (x * (x * (x * (x * 533095.76 + 47438306.2) + 29063622.1) + 575216.76) + 383.09104) + 0.000487781) /
(x * (x * (x * (x * 66391357.4 + 81884528.2) + 4182885.1) + 10668.404) + 1.0);
return x;
}
//-----------------------------------------------------------------------------
///
/// BrightnessVibranceContrast
///
//-----------------------------------------------------------------------------
vec3 BrightnessVibranceContrast(
vec3 lInputColour,
float lfBrightness,
float lfVibrance,
float lfContrast)
{
vec3 lBrtResult = lInputColour * lfBrightness;
// get lum
vec3 lLuma = vec3( dot(lBrtResult, vec3( 0.2125, 0.7154, 0.0721 )) );
// get saturation
float lfMaxCol = max( lBrtResult.r, max(lBrtResult.g, lBrtResult.b) );
float lfMinCol = min( lBrtResult.r, min(lBrtResult.g, lBrtResult.b) );
float lfCurSatV = lfMaxCol - lfMinCol;
// lerp by 1 + (1 - vibrance) - current saturation
float lfVibranceMix = (1.0 + (lfVibrance * (1.0 - (sign(lfVibrance) * lfCurSatV))));
vec3 lVibResult = mix( lLuma, lBrtResult, lfVibranceMix );
// lerp from mid gray for contrast
vec3 lContrastBase = vec3( 0.5, 0.5, 0.5 );
vec3 lConResult = mix( lContrastBase , lVibResult, lfContrast );
return lConResult;
}
//-----------------------------------------------------------------------------
///
/// Desaturate
///
//-----------------------------------------------------------------------------
vec3 Desaturate( vec3 color, float lfAmount )
{
vec3 gray = vec3( dot( vec3( 0.299, 0.587, 0.114 ), color) );
return mix( color, gray, lfAmount );
}
// improved rgb lerp by @stormoid
// https://www.shadertoy.com/view/lsdGzN
//---------------Improved RGB--------------
/*
The idea behind this function is to avoid the low saturation area in the
rgb color space. This is done by getting the direction to that diagonal
and displacing the interpolated color by it's inverse while scaling it
by saturation error and desired lightness.
I find it behaves very well under most circumstances, the only instance
where it doesn't behave ideally is when the hues are very close to 180
degrees apart, since the method I am using to find the displacement vector
does not compensate for non-curving motion. I tried a few things to
circumvent this problem but none were cheap and effective enough..
*/
//Changes the strength of the displacement
#define DSP_STR 1.5
//-----------------------------------------------------------------------------
float _getsat( vec3 lColour )
{
float mi = min(min(lColour.x, lColour.y), lColour.z);
float ma = max(max(lColour.x, lColour.y), lColour.z);
return (ma - mi) / (ma + 1e-7);
}
vec3 NmzRgbLerp( vec3 a, vec3 b, float x )
{
// interpolated base color (with singularity fix)
vec3 ic = mix( a, b, x ) + vec3( 1e-6, 0.0, 0.0 );
// saturation difference from ideal scenario
float sd = abs( _getsat( ic ) - mix( _getsat( a ), _getsat( b ), x ) );
// displacement direction
vec3 dir = normalize(
vec3( 2.0 * ic.x - ic.y - ic.z,
2.0 * ic.y - ic.x - ic.z,
2.0 * ic.z - ic.y - ic.x )
);
// simple Lighntess
float lgt = dot( vec3( 1.0 ), ic );
// extra scaling factor for the displacement
float ff = dot( dir, normalize( ic ) );
// displace the color
ic += DSP_STR * dir * sd * ff * lgt;
return clamp( ic, 0.0, 1.0 );
}
//-----------------------------------------------------------------------------
///
/// Inverse
///
//-----------------------------------------------------------------------------
mat4
Inverse(
const mat4 lInMat4 )
{
#ifdef D_PLATFORM_PC
return inverse( lInMat4 );
#else
float det = determinant( lInMat4 );
det = 1.0f / det;
mat4 M = lInMat4;
mat4 IM;
IM[0][0] = det * ( M[1][2]*M[2][3]*M[3][1] - M[1][3]*M[2][2]*M[3][1] + M[1][3]*M[2][1]*M[3][2] - M[1][1]*M[2][3]*M[3][2] - M[1][2]*M[2][1]*M[3][3] + M[1][1]*M[2][2]*M[3][3] );
IM[0][1] = det * ( M[0][3]*M[2][2]*M[3][1] - M[0][2]*M[2][3]*M[3][1] - M[0][3]*M[2][1]*M[3][2] + M[0][1]*M[2][3]*M[3][2] + M[0][2]*M[2][1]*M[3][3] - M[0][1]*M[2][2]*M[3][3] );
IM[0][2] = det * ( M[0][2]*M[1][3]*M[3][1] - M[0][3]*M[1][2]*M[3][1] + M[0][3]*M[1][1]*M[3][2] - M[0][1]*M[1][3]*M[3][2] - M[0][2]*M[1][1]*M[3][3] + M[0][1]*M[1][2]*M[3][3] );
IM[0][3] = det * ( M[0][3]*M[1][2]*M[2][1] - M[0][2]*M[1][3]*M[2][1] - M[0][3]*M[1][1]*M[2][2] + M[0][1]*M[1][3]*M[2][2] + M[0][2]*M[1][1]*M[2][3] - M[0][1]*M[1][2]*M[2][3] );
IM[1][0] = det * ( M[1][3]*M[2][2]*M[3][0] - M[1][2]*M[2][3]*M[3][0] - M[1][3]*M[2][0]*M[3][2] + M[1][0]*M[2][3]*M[3][2] + M[1][2]*M[2][0]*M[3][3] - M[1][0]*M[2][2]*M[3][3] );
IM[1][1] = det * ( M[0][2]*M[2][3]*M[3][0] - M[0][3]*M[2][2]*M[3][0] + M[0][3]*M[2][0]*M[3][2] - M[0][0]*M[2][3]*M[3][2] - M[0][2]*M[2][0]*M[3][3] + M[0][0]*M[2][2]*M[3][3] );
IM[1][2] = det * ( M[0][3]*M[1][2]*M[3][0] - M[0][2]*M[1][3]*M[3][0] - M[0][3]*M[1][0]*M[3][2] + M[0][0]*M[1][3]*M[3][2] + M[0][2]*M[1][0]*M[3][3] - M[0][0]*M[1][2]*M[3][3] );
IM[1][3] = det * ( M[0][2]*M[1][3]*M[2][0] - M[0][3]*M[1][2]*M[2][0] + M[0][3]*M[1][0]*M[2][2] - M[0][0]*M[1][3]*M[2][2] - M[0][2]*M[1][0]*M[2][3] + M[0][0]*M[1][2]*M[2][3] );
IM[2][0] = det * ( M[1][1]*M[2][3]*M[3][0] - M[1][3]*M[2][1]*M[3][0] + M[1][3]*M[2][0]*M[3][1] - M[1][0]*M[2][3]*M[3][1] - M[1][1]*M[2][0]*M[3][3] + M[1][0]*M[2][1]*M[3][3] );
IM[2][1] = det * ( M[0][3]*M[2][1]*M[3][0] - M[0][1]*M[2][3]*M[3][0] - M[0][3]*M[2][0]*M[3][1] + M[0][0]*M[2][3]*M[3][1] + M[0][1]*M[2][0]*M[3][3] - M[0][0]*M[2][1]*M[3][3] );
IM[2][2] = det * ( M[0][1]*M[1][3]*M[3][0] - M[0][3]*M[1][1]*M[3][0] + M[0][3]*M[1][0]*M[3][1] - M[0][0]*M[1][3]*M[3][1] - M[0][1]*M[1][0]*M[3][3] + M[0][0]*M[1][1]*M[3][3] );
IM[2][3] = det * ( M[0][3]*M[1][1]*M[2][0] - M[0][1]*M[1][3]*M[2][0] - M[0][3]*M[1][0]*M[2][1] + M[0][0]*M[1][3]*M[2][1] + M[0][1]*M[1][0]*M[2][3] - M[0][0]*M[1][1]*M[2][3] );
IM[3][0] = det * ( M[1][2]*M[2][1]*M[3][0] - M[1][1]*M[2][2]*M[3][0] - M[1][2]*M[2][0]*M[3][1] + M[1][0]*M[2][2]*M[3][1] + M[1][1]*M[2][0]*M[3][2] - M[1][0]*M[2][1]*M[3][2] );
IM[3][1] = det * ( M[0][1]*M[2][2]*M[3][0] - M[0][2]*M[2][1]*M[3][0] + M[0][2]*M[2][0]*M[3][1] - M[0][0]*M[2][2]*M[3][1] - M[0][1]*M[2][0]*M[3][2] + M[0][0]*M[2][1]*M[3][2] );
IM[3][2] = det * ( M[0][2]*M[1][1]*M[3][0] - M[0][1]*M[1][2]*M[3][0] - M[0][2]*M[1][0]*M[3][1] + M[0][0]*M[1][2]*M[3][1] + M[0][1]*M[1][0]*M[3][2] - M[0][0]*M[1][1]*M[3][2] );
IM[3][3] = det * ( M[0][1]*M[1][2]*M[2][0] - M[0][2]*M[1][1]*M[2][0] + M[0][2]*M[1][0]*M[2][1] - M[0][0]*M[1][2]*M[2][1] - M[0][1]*M[1][0]*M[2][2] + M[0][0]*M[1][1]*M[2][2] );
return IM;
#endif
}
float
lengthSquared( vec3 lInVec3 )
{
return dot( lInVec3, lInVec3 );
}
#endif
#ifndef D_NOISE3D
#define D_NOISE3D
STATIC_CONST vec2 lCVec4 = vec2( 1.0/6.0, 1.0/3.0 );
STATIC_CONST vec4 lDVec4 = vec4( 0.0, 0.5, 1.0, 2.0 );
vec3 mod289(vec3 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}
vec4 mod289(vec4 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}
vec4 permute(vec4 x) {
return mod289(((x*34.0)+1.0)*x);
}
vec4 taylorInvSqrt(vec4 r)
{
return 1.79284291400159 - 0.85373472095314 * r;
}
float snoise(vec3 v)
{
// First corner
vec3 i = floor(v + dot(v, lCVec4.yyy) );
vec3 x0 = v - i + dot(i, lCVec4.xxx) ;
// Other corners
vec3 g = step(x0.yzx, x0.xyz);
vec3 l = 1.0 - g;
vec3 i1 = min( g.xyz, l.zxy );
vec3 i2 = max( g.xyz, l.zxy );
// x0 = x0 - 0.0 + 0.0 * C.xxx;
// x1 = x0 - i1 + 1.0 * C.xxx;
// x2 = x0 - i2 + 2.0 * C.xxx;
// x3 = x0 - 1.0 + 3.0 * C.xxx;
vec3 x1 = x0 - i1 + lCVec4.xxx;
vec3 x2 = x0 - i2 + lCVec4.yyy; // 2.0*C.x = 1/3 = C.y
vec3 x3 = x0 - lDVec4.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
// Permutations
i = mod289(i);
vec4 p = permute( permute( permute(
i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
+ i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
+ i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
// Gradients: 7x7 points over a square, mapped onto an octahedron.
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
float n_ = 0.142857142857; // 1.0/7.0
vec3 ns = n_ * lDVec4.wyz - lDVec4.xzx;
vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)
vec4 x_ = floor(j * ns.z);
vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)
vec4 x = x_ *ns.x + ns.yyyy;
vec4 y = y_ *ns.x + ns.yyyy;
vec4 h = 1.0 - abs(x) - abs(y);
vec4 b0 = vec4( x.xy, y.xy );
vec4 b1 = vec4( x.zw, y.zw );
//vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
vec4 s0 = floor(b0)*2.0 + 1.0;
vec4 s1 = floor(b1)*2.0 + 1.0;
vec4 sh = -step(h, vec4(0.0));
vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
vec3 p0 = vec3(a0.xy,h.x);
vec3 p1 = vec3(a0.zw,h.y);
vec3 p2 = vec3(a1.xy,h.z);
vec3 p3 = vec3(a1.zw,h.w);
//Normalise gradients
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;
// Mix final noise value
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
m = m * m;
return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
dot(p2,x2), dot(p3,x3) ) );
}
#endif
//-----------------------------------------------------------------------------
// Global Data
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
// Global Data
STATIC_CONST mat3 kNoiseMat3 = mat3( 0.00, 0.80, 0.60,
-0.80, 0.36, -0.48,
-0.60, -0.48, 0.64 );
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
///
/// Hash
///
/// @brief Hash
///
/// @param float lfNumber
/// @return Hash
///
//-----------------------------------------------------------------------------
float
Hash(
float lfNumber )
{
return fract( sin( lfNumber ) * 43758.5453 );
}
//-----------------------------------------------------------------------------
///
/// Noise
///
/// @brief Noise
///
/// @param vec3 lfIndex
/// @return
///
//-----------------------------------------------------------------------------
#if defined ( D_USE_NOISETEXTURE )
//const mat3 m = mat3( 0.00, 0.80, 0.60, -0.80, 0.36, -0.48, -0.60, -0.48, 0.64 );
float Noise3D(
in vec3 lPositionVec3,
SAMPLER2DARG( lNoiseMap ) )
{
vec3 p = floor(lPositionVec3);
vec3 f = fract(lPositionVec3);
f = f*f*(3.0-2.0*f);
vec2 uv = (p.xy+vec2(37.0,17.0)*p.z) + f.xy;
vec2 rg = texture2DLod( lNoiseMap, (uv+ 0.5)/256.0, 0.0 ).yx;
#ifdef D_NORMALISED_NOISE
return mix( rg.x, rg.y, f.z );
#else
return -1.0+2.0*mix( rg.x, rg.y, f.z );
#endif
}
float Noise3DFast(
in vec3 lPositionVec3,
SAMPLER2DARG(lNoiseMap))
{
vec3 p = floor(lPositionVec3);
vec3 f = fract(lPositionVec3);
vec2 uv = (p.xy + vec2(37.0, 17.0) * p.z) + f.xy;
vec2 rg = texture2DLod(lNoiseMap, (uv + 0.5) / 256.0, 0.0).yx;
return mix(rg.x, rg.y, f.z);
}
#else
float
Noise3D(
in vec3 lPositionVec3,
SAMPLER2DARG( lNoiseMap ) )
{
vec3 lFloorVec3 = floor( lPositionVec3 );
vec3 lFractVec3 = fract( lPositionVec3 );
lFractVec3 = lFractVec3 * lFractVec3 * ( 3.0 - 2.0 * lFractVec3 );
float lfIndex = lFloorVec3.x + lFloorVec3.y * 57.0 + 113.0 * lFloorVec3.z;
float res = mix( mix( mix( Hash( lfIndex + 0.0 ), Hash( lfIndex + 1.0 ), lFractVec3.x ),
mix( Hash( lfIndex + 57.0 ), Hash( lfIndex + 58.0 ), lFractVec3.x ), lFractVec3.y ),
mix( mix( Hash( lfIndex + 113.0 ), Hash( lfIndex + 114.0 ), lFractVec3.x ),
mix( Hash( lfIndex + 170.0 ), Hash( lfIndex + 171.0 ), lFractVec3.x ), lFractVec3.y ), lFractVec3.z );
return res;
}
float
Noise3DFast(
in vec3 lPositionVec3,
SAMPLER2DARG( lNoiseMap ) )
{
return Noise3D( lPositionVec3, lNoiseMap );
}
#endif
//-----------------------------------------------------------------------------
///
/// FractBrownianMotion
///
/// @brief FractBrownianMotion
///
/// @param vec3 lfIndex
/// @return
///
//-----------------------------------------------------------------------------
float
FractBrownianMotion4(
vec3 lPositionVec3,
SAMPLER2DARG( lNoiseMap ) )
{
vec3 lPosCopy = lPositionVec3; // copy because for some reason PSSL compiler balks if you operate on this directly then pass it on.
float lfSum;
lfSum = 0.5000 * Noise3D( lPosCopy, SAMPLER2DPARAM( lNoiseMap ) );
lPosCopy = MUL( kNoiseMat3, ( lPosCopy * 2.02 ) );
lfSum += 0.2500 * Noise3D( lPosCopy, SAMPLER2DPARAM( lNoiseMap ) );
lPosCopy = MUL( kNoiseMat3, ( lPosCopy * 2.03 ) );
lfSum += 0.1250 * Noise3D( lPosCopy, SAMPLER2DPARAM( lNoiseMap ) );
lPosCopy = MUL( kNoiseMat3, ( lPosCopy * 2.01 ) );
lfSum += 0.0625 * Noise3D( lPosCopy, SAMPLER2DPARAM( lNoiseMap ) );
return lfSum / 0.9375;
}
// Faster variant (also normalized 0.0.1.0)
float
FractBrownianMotion4Fast(
vec3 lPositionVec3,
SAMPLER2DARG(lNoiseMap))
{
vec3 lPosCopy = lPositionVec3; // copy because for some reason PSSL compiler balks if you operate on this directly then pass it on.
float lfSum;
lfSum = 0.5000 * Noise3DFast(lPosCopy, SAMPLER2DPARAM(lNoiseMap));
lPosCopy = MUL(kNoiseMat3, (lPosCopy * 2.02));
lfSum += 0.2500 * Noise3DFast(lPosCopy, SAMPLER2DPARAM(lNoiseMap));
lPosCopy = MUL(kNoiseMat3, (lPosCopy * 2.03));
lfSum += 0.1250 * Noise3DFast(lPosCopy, SAMPLER2DPARAM(lNoiseMap));
lPosCopy = MUL(kNoiseMat3, (lPosCopy * 2.01));
lfSum += 0.0625 * Noise3DFast(lPosCopy, SAMPLER2DPARAM(lNoiseMap));
return lfSum / 0.9375;
}
//-----------------------------------------------------------------------------
///
/// FractBrownianMotion6
///
/// @brief FractBrownianMotion6
///
/// @param vec3 lPositionVec3
/// @param SAMPLER2DARG
/// @param lNoiseMap
/// @return float
///
//-----------------------------------------------------------------------------
float
FractBrownianMotion6(
vec3 lPositionVec3,
SAMPLER2DARG( lNoiseMap ) )
{
vec3 lPosCopy = lPositionVec3;
float lfSum = 0.0;
lfSum += 0.500000*( 0.5+0.5*Noise3D( lPosCopy, SAMPLER2DPARAM( lNoiseMap ) ) );
lPosCopy = MUL( kNoiseMat3, ( lPosCopy * 2.02 ) );
lfSum += 0.250000*( 0.5+0.5*Noise3D( lPosCopy, SAMPLER2DPARAM( lNoiseMap ) ) );
lPosCopy = MUL( kNoiseMat3, ( lPosCopy * 2.03 ) );
lfSum += 0.125000*( 0.5+0.5*Noise3D( lPosCopy, SAMPLER2DPARAM( lNoiseMap ) ) );
lPosCopy = MUL( kNoiseMat3, ( lPosCopy * 2.01 ) );
lfSum += 0.062500*( 0.5+0.5*Noise3D( lPosCopy, SAMPLER2DPARAM( lNoiseMap ) ) );
lPosCopy = MUL( kNoiseMat3, ( lPosCopy * 2.04 ) );
lfSum += 0.031250*( 0.5+0.5*Noise3D( lPosCopy, SAMPLER2DPARAM( lNoiseMap ) ) );
lPosCopy = MUL( kNoiseMat3, ( lPosCopy * 2.01 ) );
lfSum += 0.015625*( 0.5+0.5*Noise3D( lPosCopy, SAMPLER2DPARAM( lNoiseMap ) ) );
return lfSum/0.96875;
}
//-----------------------------------------------------------------------------
///
/// DistortedNoise
///
/// @brief DistortedNoise
///
/// @param vec3 lPositionVec3
/// @param float lfScale1
/// @param float lfScale2
/// @param SAMPLER2DARG
/// @param lNoiseMap
/// @return float
///
//-----------------------------------------------------------------------------
float
DistortedNoise(
vec3 lPositionVec3,
float lfScale1,
float lfScale2,
SAMPLER2DARG( lNoiseMap ) )
{
float lfNoise1 = FractBrownianMotion4Fast( lPositionVec3 * lfScale1, SAMPLER2DPARAM( lNoiseMap ) );
float lfNoise2 = FractBrownianMotion4Fast( lPositionVec3 * lfScale1 + vec3( 1000.0 ), SAMPLER2DPARAM( lNoiseMap ) );
vec3 lInputVec3 = vec3( lfNoise1, lfNoise2, 1.0 );
float lfReturn = FractBrownianMotion6( lPositionVec3 * lfScale1 + lInputVec3 * lfScale2, SAMPLER2DPARAM( lNoiseMap ) );
return lfReturn * 0.5 + 0.5;
}
#endif
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
// the original scan shader is here, it's useful reference!
/*
vec3 lWorldUp = GetWorldUp( IN(mWorldPositionVec4).xyz, lUniforms.mpCommonPerMaterial.gPlanetPositionVec4 );
vec3 lViewToPos = IN(mWorldPositionVec4).xyz - lUniforms.mpCommonPerMaterial.gViewPositionVec3;
float lfViewToPosHeight = dot( lWorldUp, lViewToPos );
vec3 lViewToPosFlat = lViewToPos - lWorldUp*lfViewToPosHeight;
float lfDistance = length(lViewToPosFlat) * lUniforms.mpCustomPerMesh.gScanParams2Vec4.r;
lfDistance += lfViewToPosHeight * lUniforms.mpCustomPerMesh.gScanParamsVec4.b;
float lfLine = sin( lfDistance * 10.0 - lUniforms.mpCustomPerMesh.gScanParamsVec4.g * 30.0 ) * smoothstep( 0.6, 1.0, cos( lfDistance * lUniforms.mpCustomPerMesh.gScanParamsVec4.a - lUniforms.mpCustomPerMesh.gScanParamsVec4.g * 5.0 ) );
vec3 lLineColour = vec3( smoothstep( 0.75, 0.95, lfLine ), smoothstep( 0.9, 0.95, lfLine ), smoothstep( 0.95, 0.97, lfLine ) );
lLineColour *= 1.0 - clamp( lfDistance / 100.0, 0.0, 1.0 );
lLineColour *= lUniforms.mpCustomPerMesh.gScanParams2Vec4.g * lUniforms.mpCustomPerMesh.gScanParams2Vec4.a;
#ifndef _F45_SCANABLE
lLineColour *= lUniforms.mpCustomPerMesh.gScanParams2Vec4.b;
#endif
lFragmentColourVec4.xyz += lLineColour;
*/
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Old scan shader
/*vec3
ScanPulseEffectOverlay(
vec3 lInputColour,
vec3 lWorldPosition,
vec4 lScanConfigPos,
vec4 lScanConfigA,
vec4 lScanConfigB )
{
if ( lScanConfigA.x <= 0.0 )
return lInputColour;
vec3 lWorldToScanPt = lWorldPosition - lScanConfigPos.xyz;
float lfDistToScanPt = length(lWorldToScanPt);
// adjust distance so that values inside the pulse radius fall 0..1
float lfCurrent01 = lfDistToScanPt * lScanConfigPos.w;
float lfTarget = lScanConfigA.y;
float lfScanTime = lScanConfigA.z;
float lfClipOutEdge = saturate( 2.0 - lfCurrent01 );
lfClipOutEdge = smoothstep( 0.9, 1.0, lfClipOutEdge );
float lfAbsTargetToCurrent = abs(lfTarget - lfCurrent01) * lScanConfigB.x;
float lfCurrentToTarget = (lfCurrent01 - lfTarget) * lScanConfigB.y;
float lfLargeWaveMask = 1.0 - lfAbsTargetToCurrent;
lfLargeWaveMask -= lfCurrentToTarget * 0.8;
// lfLargeWaveMask = clamp(lfLargeWaveMask, 0.0, 1.0);
float lfBaseWaveMask = 1.0 - (lfAbsTargetToCurrent * 2.0);
float lfEdge = clamp(lfBaseWaveMask, 0.0, 1.0);
lfBaseWaveMask -= lfCurrentToTarget * 2.0;
lfBaseWaveMask = clamp(lfBaseWaveMask, 0.0, 1.0);
lfBaseWaveMask = smoothstep(0.0, 1.1, lfBaseWaveMask * lfBaseWaveMask);
float lfWaveMult = lScanConfigB.z * lfBaseWaveMask;
float waveScaleRoot = lScanConfigB.w;
float waveScale1 = waveScaleRoot;
float waveScale2 = waveScaleRoot * 0.44;
float waveScale3 = waveScaleRoot * 0.11;
float waveShift1 = lfScanTime * -0.8;
//float waveShift2 = lfScanTime * 1.6;
float wave1 = lfBaseWaveMask + cos( (lfCurrent01 * waveScale1 + waveShift1) ) * lfWaveMult;
float wave2 = lfBaseWaveMask + sin( (lfCurrent01 * waveScale2 + waveShift1) ) * lfWaveMult;
float wave3 = lfBaseWaveMask + cos( (lfCurrent01 * waveScale3) + (lfLargeWaveMask * lfLargeWaveMask * waveScale3) ) * 1.25;
float waveC = mix( wave1, wave2, wave3 * wave3 );
waveC += smoothstep(0.88, 0.98, lfEdge * lfEdge) * 5.0;
waveC = max(waveC, 0.0);
waveC *= lfClipOutEdge;
vec3 lScanFX = vec3(waveC, waveC * 0.72, waveC * 0.15);
return lInputColour + ( lScanFX * lScanConfigA.x );
}*/
//-----------------------------------------------------------------------------
vec3
ScanPulseEffectOverlay(
float lfTime,
vec2 lScreenSpaceUV,
vec3 lInputColour,
vec3 lWorldPosition,
vec4 lScanConfigPos,
vec4 lColour1AndBlend,
vec4 lColour2AndTime,
inout vec3 lSunColourVec3 )
{
// MIXING COLOURS
if (lColour1AndBlend.w <= 0.0)
return lInputColour;
// Make the scan effect slower at the beginning
lColour2AndTime.w = pow(lColour2AndTime.w, 3.0);
vec3 lWorldToScanPt = lWorldPosition - lScanConfigPos.xyz;
float lfDistToScanPt = length(lWorldToScanPt);
// adjust distance so that values inside the pulse radius fall 0..1
float lfDistanceScale = 2.0 / lfDistToScanPt;
float lfRadius = 1.0 / lScanConfigPos.w;
float lfCurrent01 = lfDistToScanPt * lScanConfigPos.w * lfRadius * lfDistanceScale;
float lfTarget = lColour2AndTime.w * lfRadius * lfDistanceScale;
float lfAbsTargetToCurrent = abs(lfTarget - lfCurrent01) * 3.0;
float lfCurrentToTarget = (lfCurrent01 - lfTarget) * 2.9;
float lfBaseWaveMask = 1.0 - (lfAbsTargetToCurrent * 2.0);
float lfEdge = clamp(lfBaseWaveMask, -0.0, 1.0);
lfBaseWaveMask -= lfCurrentToTarget * 2.0;
lfBaseWaveMask = clamp(lfBaseWaveMask, 0.0, 1.0);
lfBaseWaveMask = smoothstep(0.0, 1.1, pow(lfBaseWaveMask, 8.0));
float lfFineEdgeMask = smoothstep(0.88, 0.98, lfEdge * lfEdge) * 5.0;
vec3 scanCol = lColour1AndBlend.xyz;
vec3 scanCol2 = lColour2AndTime.xyz;
vec3 origColour = lInputColour;
vec3 origSun = lSunColourVec3;
// Wave
vec3 waveCol = mix(scanCol2, scanCol, lfAbsTargetToCurrent);
lInputColour = mix(lInputColour, waveCol, lfBaseWaveMask);
lSunColourVec3 = mix(lSunColourVec3, vec3(0.0), lfBaseWaveMask);
// Detail scan lines
float scanDetailLines = clamp(
sin((lScreenSpaceUV.y) * 1500.0 + lfTime* 5.0) * 0.8,
0.0, 1.0);
lInputColour = mix(lInputColour, scanCol, scanDetailLines * lfBaseWaveMask);
lSunColourVec3 = mix(lSunColourVec3, vec3(0.0), scanDetailLines * lfBaseWaveMask);
// Edge line
vec3 lEdgeColour = mix(vec3(1.0), vec3(1.0, 0.0, 0.0), smoothstep(0.25, 1.0, 0.9));
//lInputColour = mix(lInputColour, vec3(1.0), lfFineEdgeMask);
lInputColour += vec3(1.0) * lfFineEdgeMask;
float lfScanLuminance = (lInputColour.x * 0.3) + (lInputColour.y * 0.59) + (lInputColour.z * 0.11);
float alpha = 0.9;
origColour = mix(origColour,
origColour * 0.0,
(1.0 - lfScanLuminance) * scanDetailLines * lfBaseWaveMask * lColour1AndBlend.w);
lInputColour = mix(origColour, lInputColour, alpha*lColour1AndBlend.w);
lSunColourVec3 = mix(origSun, lSunColourVec3, alpha*lColour1AndBlend.w);
return lInputColour;
}
//-----------------------------------------------------------------------------
vec3
ApplyMaterialFX(
vec3 lInputColour,
vec3 lWorldPosition,
vec4 lMaterialFXConfig )
{
return mix(lInputColour.xyz, lMaterialFXConfig.xyz, lMaterialFXConfig.w * 0.8);
}
//-----------------------------------------------------------------------------
vec4
MiningHotspot(
vec4 lInputColourVec4,
vec4 lWorldPositionVec4,
vec4 lMiningPosVec4 )
{
const float kfSpotRadius = 4.0f;
const vec3 kfSpotColour = vec3( 1.0, 0.0, 0.0 );
vec4 lOutputColourVec4 = lInputColourVec4;
float lfHeat = clamp( length( lWorldPositionVec4.xyz - lMiningPosVec4.xyz ) / kfSpotRadius, 0.0, 1.0 );
lfHeat = (1.0 - lfHeat)*(1.0 - lfHeat) * lMiningPosVec4.w;
lOutputColourVec4.xyz = mix( lOutputColourVec4.xyz, kfSpotColour, lfHeat );
return lOutputColourVec4;
}
vec3
GetWaterScattering(
in PerFrameUniforms lPerFrameUniforms,
in CommonPerMeshUniforms lMeshUniforms,
in CustomPerMaterialUniforms lCustomUniforms,
in vec3 lColourVec3,
in vec3 lPositionVec3,
inout vec3 lSunColourVec3
)
{
vec3 lFragmentColourVec3 = lColourVec3;
//// Water Fog
float lfHeightFade = length( lPerFrameUniforms.gViewPositionVec3 - lMeshUniforms.gPlanetPositionVec4.xyz ) - lMeshUniforms.gPlanetPositionVec4.w;
lfHeightFade = 1.0 - clamp( ( lfHeightFade - 700.0 ) / 200.0, 0.0, 1.0 );
float lfLowHeightFade = length( lPerFrameUniforms.gViewPositionVec3 - lMeshUniforms.gPlanetPositionVec4.xyz ) - lMeshUniforms.gPlanetPositionVec4.w;
lfLowHeightFade = 1.0 - clamp( ( lfLowHeightFade - 250.0 ) / 200.0, 0.0, 1.0 );
vec3 lPlanetPosition = lMeshUniforms.gPlanetPositionVec4.xyz;
float lfRadius = lMeshUniforms.gPlanetPositionVec4.w;
vec3 lWaterColourNearVec3 = /*GammaCorrectInput*/( lCustomUniforms.gWaterColourNearVec4.rgb );
vec3 lWaterColourFarVec3 = /*GammaCorrectInput*/( lCustomUniforms.gWaterColourFarVec4.rgb );
vec3 lLightColourVec3 = /*GammaCorrectInput*/( lMeshUniforms.gLightColourVec4.rgb );
float lfWaterHeight = lCustomUniforms.gWaterFogVec4.r;
float lfWaterStrength = lCustomUniforms.gWaterFogVec4.g;
float lfWaterColourStrength = lCustomUniforms.gWaterFogVec4.b;
float lfWaterMultiplyStrength = lCustomUniforms.gWaterFogVec4.a;
float lfWaterMultiplyMax = lCustomUniforms.gWaterColourNearVec4.a;
vec3 lNearPosition = lPerFrameUniforms.gViewPositionVec3 - lPlanetPosition;
vec3 lFarPosition = lPositionVec3 - lPlanetPosition;
if( length( lNearPosition ) <= lfRadius + lfWaterHeight || length( lFarPosition ) <= lfRadius + lfWaterHeight )
{
float lfDarken = clamp( dot( -lPerFrameUniforms.gLightDirectionVec4.xyz, normalize( lFarPosition ) ), 0.0, 1.0 );
float lfFogDistance = length( lFarPosition - lNearPosition );
float lfFogValue = lfFogDistance * lfWaterStrength;
lfFogValue = 1.0 / exp( lfFogValue * lfFogValue );
lfFogValue = 1.0 - clamp( lfFogValue, 0.0, 1.0 );
float lfWaterFade = lfFogDistance * lfWaterColourStrength;
lfWaterFade = 1.0 / exp( lfWaterFade * lfWaterFade );
lfWaterFade = 1.0 - clamp( lfWaterFade, 0.0, 1.0 );
float lfMultiplyFade = lfFogDistance * lfWaterMultiplyStrength;
lfMultiplyFade = 1.0 / exp( lfMultiplyFade * lfMultiplyFade );
lfMultiplyFade = 1.0 - clamp( lfMultiplyFade, 1.0 - lfWaterMultiplyMax, 1.0 );
vec3 lWaterColour = mix( lWaterColourNearVec3, lWaterColourFarVec3, clamp( lfWaterFade, 0.0, 1.0 ) ) * lLightColourVec3 * lfDarken;
lFragmentColourVec3 = mix( lColourVec3, lColourVec3 * lWaterColourNearVec3, lfLowHeightFade * lfMultiplyFade );
lFragmentColourVec3 = mix( lFragmentColourVec3, lWaterColour, clamp( lfHeightFade * lfFogValue, 0.0, 1.0 ) );
#ifdef D_SPLIT_SHADOW
lSunColourVec3 = mix( lSunColourVec3, lSunColourVec3 * lWaterColourNearVec3, lfLowHeightFade * lfMultiplyFade );
lSunColourVec3 = mix( lSunColourVec3, vec3(0.0), clamp( lfHeightFade * lfFogValue, 0.0, 1.0 ) );
#endif
}
return lFragmentColourVec3;
}
vec3
Scanline(
vec2 uv,
float angle,
vec3 color,
float size,
float strength,
float decay )
{
//uv[1] -= 0.5 + 0.5 * cos(mod(angle, 3.14*2.0) / 2.0);
uv[1] -= 0.5 + 0.5 * cos(mod(angle, 3.14*2.0) / 2.0);
uv[1] *= 1000.0 * size;
float col = 1.0 / uv[1];
float damp = clamp(pow(abs(uv[0]), decay) + pow(abs(1.0 - uv[0]), decay), 0.0, 1.0);
col -= damp * 0.2;
col = clamp(col, 0.0, strength);
return color * col;
}
vec3 ScanlineWorldPos(
vec2 uv,
float angle,
float size,
vec3 color,
float strength,
float decay)
{
float PI = 3.1416;
//uv.y += sin(uv.x * 4.0 + sin(uv.x*30.63)) * 0.1;
float val = sin(uv.y*size + angle);
float val2 = sin(uv.y*size*2.0 + angle * 2.0 + PI);
//val2 = pow(val2, -1.0);
val2 = 1.0 / val2;
val2 = clamp(val2, 0.0, 1.0);
float damp = clamp(pow(abs(val), decay), 0.0, 1.0);
val *= val2 * damp;
val = clamp(val, 0.0, 1.0);
return val * color * strength;
}
vec4 ScanEffect(
float lfTime,
vec2 lScreenSpaceUV,
vec4 lInputColour,
vec4 lScanColour,
vec4 lScanEffectConfig,
vec3 lViewPositionVec3,
vec3 lWorldPositionVec3,
vec3 lNormalVec3,
vec4 lPlanetPositionVec4,
inout vec3 lSunColourVec3
)
{
if (lScanColour.w <= 0.0)
return lInputColour;
float lScanBaseLevel = lScanEffectConfig.x;
float lScanLinesSeparation = abs( lScanEffectConfig.y );
float lFresnelIntensity = abs( lScanEffectConfig.z );
int lConfigInt = int(lScanEffectConfig.w);
// Decode scanner config
float lWavesOffset = float(lConfigInt & 0x000F) / 15.0;
float lTransparent = float(lConfigInt & 0x0020) / (1 << 5);
float lWavesActive = float(lConfigInt & 0x0040) / (1 << 6);
float lFixedUpAxis = float(lConfigInt & 0x0080) / (1 << 7);
float lGlowIntensity = float(lConfigInt & 0xFF00) / (255 << 8);
// Variables
float lfScanSpeed = 2.0;
float lfScanAnim = sin(lfTime * lfScanSpeed) * 0.5 + 1.0;
float lfFlickering = 0.4 * step(0.9, sin(lfTime + 9.0 * cos(lfTime*3.0))) *
(sin(lfTime)* sin(lfTime * 20.0) +
(0.5 + 0.1 * sin(lfTime * 2000.) * cos(lfTime)));
// Planet height
float lfHeight = GetHeight(lWorldPositionVec3, lPlanetPositionVec4) * (1.0 - lFixedUpAxis) + lWorldPositionVec3.y * lFixedUpAxis;
// Colours
vec3 lScanColorVec3 = lScanColour.rgb;// vec3(0.0, 0.8, 1.0);
vec3 lScanColorSecondaryVec3 = vec3(0.8, 0.8, 1.0);
vec3 lScanColorFresnelVec3 = vec3(1.0);
// Fresnel
float lfFresnel = clamp(dot(normalize(lViewPositionVec3 - lWorldPositionVec3), lNormalVec3), 0.0, 1.0);
lfFresnel = 1.0 - lfFresnel;
float lfFresnel2 = pow(lfFresnel, 3.0 * 0.15); // Pulse
lfFresnel = pow(lfFresnel, lfScanAnim * lFresnelIntensity); // Pulse
//vec3 lColVec3 = lInputColour.rgb * scanBlue * 0.5;
vec3 lColVec3 = lScanColorVec3 * lScanBaseLevel;
// Fresnel outline
vec3 lScanColVec3 = mix(lScanColorFresnelVec3, lScanColorVec3, smoothstep(0.25, 1.0, 1.0 - (lfFresnel)));
lColVec3 = mix(lColVec3, lScanColVec3, max(lfFresnel - lfFlickering*0.6, 0.0));
// Detail scan lines
lScreenSpaceUV.y *= lScanLinesSeparation;
float lfScanDetailLinesVal = (lScreenSpaceUV.y + sin(lScreenSpaceUV.x*500.0)*0.007*lfFlickering);
float scanDetailLines = clamp(sin((lfScanDetailLinesVal + lfFlickering) * 1500.0 + lfTime * 5.0) * 0.5, 0.0, 1.0);
lColVec3 = mix(lColVec3, lScanColVec3, scanDetailLines*lfFresnel2);
// Scanline waves (screen space)
//lColVec3 += Scanline(lScreenSpaceUV, lfTime*lfScanSpeed + 1.3, lScanColVec3, 0.05, 0.5, 3.0);
//lColVec3 += Scanline(lScreenSpaceUV, lfTime*lfScanSpeed + 1.3, scanBlue2, 0.5, 0.6, 10.0);
lfFlickering = clamp(sin(lfTime * 1.0 + sin(lfTime*3.63)) * 0.5 + 0.5, 0.3, 1.0);
float lfDisplacement = sin(lfTime * 3.0 + sin(lfTime*3.63)) * 0.5 + 0.5;
vec2 lPositionVec2 = vec2(0.0, lfHeight + lfDisplacement);
// Scanline waves (world pos)
lColVec3 += ScanlineWorldPos(lPositionVec2, lfTime * lfScanSpeed * 1.0 + lWavesOffset, 0.2, lScanColVec3, 0.8, 1.0) * lfFlickering * lWavesActive;
lColVec3 += ScanlineWorldPos(lPositionVec2, lfTime * lfScanSpeed * 1.0 + lWavesOffset, 0.2, lScanColorSecondaryVec3, 0.8, 50.0) * lfFlickering * lWavesActive;
// "Noisy" scanlines
lfFlickering = clamp(lfDisplacement, 0.0, 1.0);
lfDisplacement = sin(lfTime * 2.0 + sin(lfTime*3.63)) * 0.5 + 0.5;
lPositionVec2.y = lfHeight + lfDisplacement * 3.0;
lColVec3 += ScanlineWorldPos(lPositionVec2, lfTime * lfScanSpeed * 4.0 + lWavesOffset, 0.6, lScanColVec3, 0.1, 2.0) * lfFlickering * lWavesActive;
lColVec3 += ScanlineWorldPos(lPositionVec2, lfTime * lfScanSpeed * 4.0 + lWavesOffset, 0.6, lScanColorSecondaryVec3, 0.1, 20.0) * lfFlickering * lWavesActive;
float lfAlpha = max(max(max(lColVec3.x, lColVec3.y), lColVec3.z), 0.4);
float flickering = 0.95 + 0.05 * sin(110.0*lfTime);
lColVec3 *= flickering;
lColVec3 += lfFresnel * lGlowIntensity * 7.0;
lInputColour.rgb = mix(lInputColour.rgb, saturate( lColVec3 ), saturate( lScanColour.a * lfAlpha ) * 0.9 );
if( lTransparent > 0 )
{
lInputColour.a = saturate( lScanColour.a * lfAlpha );
}
if( lScanEffectConfig.z < 0.0 )
{
lInputColour.a = saturate( lScanColour.a * lfAlpha );
float lfFresnel3 = 1.0 - clamp( dot( normalize( lViewPositionVec3 - lWorldPositionVec3 ), lNormalVec3 ), 0.0, 1.0 );
if( lScanEffectConfig.y < 0.0 )
{
lfFresnel3 = smoothstep( 0.05 + lfFlickering*0.3, 0.7, lfFresnel3 );
}
lInputColour.a = min( lInputColour.a, lfFresnel3 );
}
#ifdef D_SPLIT_SHADOW
lSunColourVec3 = mix(lInputColour.rgb, vec3(0.0), saturate( lScanColour.a * lfAlpha ) * 0.9 );
#endif
return lInputColour;
}
//-----------------------------------------------------------------------------
///
/// PostProcess
///
/// @brief PostProcess
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
vec4
PostProcessPreLighting(
in PerFrameUniforms lPerFrameUniforms,
in CommonPerMeshUniforms lMeshUniforms,
in CustomPerMaterialUniforms lCustomUniforms,
in vec4 lColourVec4,
in vec3 lPositionVec3,
inout vec3 lNormalVec3,
inout float lfRoughness,
in int liMaterialID,
in vec4 lScreenSpacePositionVec4 )
{
vec4 lFragmentColourVec4 = lColourVec4;
if( ( liMaterialID & D_DETAILOVERLAY ) != 0 )
{
vec3 lUpDirection = normalize( lPositionVec3 );
float lfTile = max( dot( lUpDirection, lNormalVec3 ), 0.0 );
lfTile = asin( lfTile ) / ( 3.1415 * 0.5 );
lfTile = lfTile * lfTile;
vec3 lRelativePositionVec3 = ( lPositionVec3 - lMeshUniforms.gPlanetPositionVec4.xyz );
vec3 lOverlayVec3;
vec3 lOverlayNormalVec3;
float lfDistance = length( lPositionVec3 - lPerFrameUniforms.gViewPositionVec3 );
float lfFade0 = saturate( ( lfDistance - 40.0f ) / 50.0f );
float lfFade1 = saturate( ( lfDistance - 150.0f ) / 100.0f );
vec3 lMultiplyVec3 = vec3( 1.0 );
if( ( liMaterialID & D_CLAMPAMBIENT ) == 0 )
{
if( lCustomUniforms.gHueOverlayParamsVec4.z > 0.0 )
{
lOverlayVec3 = GetTriPlanarColourMM( lNormalVec3, lRelativePositionVec3, vec2( 100.0, 0.0 ), lCustomUniforms.gHueOverlayParamsVec4.y, SAMPLER2DPARAM( lCustomUniforms.gHSVOverlay ) ).rgb;
lOverlayNormalVec3 = GetTriPlanarNormal( lNormalVec3, lRelativePositionVec3, vec2( 100.0, 0.0 ), lCustomUniforms.gHueOverlayParamsVec4.y, SAMPLER2DPARAM( lCustomUniforms.gHSVNormalOverlay ) ).rgb;
lOverlayVec3 = lOverlayVec3 * lCustomUniforms.gHueOverlayParamsVec4.z + ( 1.0 - lCustomUniforms.gHueOverlayParamsVec4.z );
lOverlayVec3 = ( lOverlayVec3 + lCustomUniforms.gHueOverlayParamsVec4.x );
lMultiplyVec3 *= lOverlayVec3;
}
}
if( lCustomUniforms.gValueOverlayParamsVec4.z > 0.0 )
{
lOverlayVec3 = GetTriPlanarColourMM( lNormalVec3, lRelativePositionVec3, vec2( 100.0, 0.0 ), lCustomUniforms.gValueOverlayParamsVec4.y, SAMPLER2DPARAM( lCustomUniforms.gHSVOverlay ) ).rgb;
lOverlayNormalVec3 += GetTriPlanarNormal( lNormalVec3, lRelativePositionVec3, vec2( 100.0, 0.0 ), lCustomUniforms.gValueOverlayParamsVec4.y, SAMPLER2DPARAM( lCustomUniforms.gHSVNormalOverlay ) ).rgb;
lOverlayVec3 = lOverlayVec3 * lCustomUniforms.gValueOverlayParamsVec4.z + ( 1.0 - lCustomUniforms.gValueOverlayParamsVec4.z );
lOverlayVec3 = ( lOverlayVec3 + lCustomUniforms.gValueOverlayParamsVec4.x );
lMultiplyVec3 *= lOverlayVec3;
}
if( lCustomUniforms.gSaturationOverlayParamsVec4.z > 0.0 )
{
lOverlayVec3 = GetTriPlanarColourMM( lNormalVec3, lRelativePositionVec3, vec2( 100.0, 0.0 ), lCustomUniforms.gSaturationOverlayParamsVec4.y, SAMPLER2DPARAM( lCustomUniforms.gHSVOverlay ) ).rgb;
lOverlayNormalVec3 += GetTriPlanarNormal( lNormalVec3, lRelativePositionVec3, vec2( 100.0, 0.0 ), lCustomUniforms.gSaturationOverlayParamsVec4.y, SAMPLER2DPARAM( lCustomUniforms.gHSVNormalOverlay ) ).rgb;
lOverlayVec3 = lOverlayVec3 * lCustomUniforms.gSaturationOverlayParamsVec4.z + ( 1.0 - lCustomUniforms.gSaturationOverlayParamsVec4.z );
lOverlayVec3 = ( lOverlayVec3 + lCustomUniforms.gSaturationOverlayParamsVec4.x );
lMultiplyVec3 *= lOverlayVec3;
}
lFragmentColourVec4.rgb *= lMultiplyVec3;
}
return lFragmentColourVec4;
}
//-----------------------------------------------------------------------------
///
/// PostProcess
///
/// @brief WriteOutput
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
vec4
PostProcess(
in PerFrameUniforms lPerFrameUniforms,
in CommonPerMeshUniforms lMeshUniforms,
in CustomPerMaterialUniforms lCustomUniforms,
in vec4 lColourVec4,
in vec3 lPositionVec3,
in vec3 lNormalVec3,
in int liMaterialID,
in vec4 lScreenSpacePositionVec4,
inout vec3 lSunColourVec3
)
{
vec4 lFragmentColourVec4;
//-----------------------------------------------------------------------------
///
/// Fog
///
//-----------------------------------------------------------------------------
//// Caustics
lFragmentColourVec4 = lColourVec4;
if( lCustomUniforms.gWaterFogVec4.r > 0.0 )
{
float lfWaterFade = length(lPerFrameUniforms.gViewPositionVec3 - lMeshUniforms.gPlanetPositionVec4.xyz) - lMeshUniforms.gPlanetPositionVec4.w;
lfWaterFade = clamp((lfWaterFade - 700.0) / 200.0, 0.0, 1.0);
float lfDistanceFade = length(lPerFrameUniforms.gViewPositionVec3 - lPositionVec3);
lfDistanceFade = clamp((lfDistanceFade - 200.0) / 100.0, 0.0, 1.0);
vec3 lSunCausticsVec3 = lSunColourVec3;
vec3 lCausticsVec3 = Caustics(
lColourVec4.rgb,
lPositionVec3 - lMeshUniforms.gPlanetPositionVec4.xyz,
lNormalVec3,
normalize( lPerFrameUniforms.gViewPositionVec3 - lMeshUniforms.gPlanetPositionVec4.xyz ),
lCustomUniforms.gWaterFogVec4.r + lMeshUniforms.gPlanetPositionVec4.w,
lPerFrameUniforms.gfTime.x,
SAMPLER2DPARAM( lCustomUniforms.gCausticMap ),
SAMPLER2DPARAM( lCustomUniforms.gCausticOffsetMap ),
lSunColourVec3 );
lFragmentColourVec4.rgb = mix( lCausticsVec3, lFragmentColourVec4.rgb, max( lfWaterFade, lfDistanceFade ) );
lSunColourVec3 = mix( lSunCausticsVec3, lSunColourVec3, max( lfWaterFade, lfDistanceFade ) );
//-----------------------------------------------------------------------------
///
/// Water
///
//-----------------------------------------------------------------------------
if( ( liMaterialID & D_NOWATER ) == 0 )
{
lFragmentColourVec4.rgb = GetWaterScattering(
lPerFrameUniforms,
lMeshUniforms,
lCustomUniforms,
lFragmentColourVec4.rgb,
lPositionVec3,
lSunColourVec3
);
}
}
//-----------------------------------------------------------------------------
///
/// Scan / Mtl FX
///
//-----------------------------------------------------------------------------
// pulse-from-point global scan overlay effect
vec2 lScreenSpaceUV = ((lScreenSpacePositionVec4.xy / lScreenSpacePositionVec4.w) * 0.5) + vec2(0.5);
lFragmentColourVec4.rgb = ScanPulseEffectOverlay(
lPerFrameUniforms.gfTime.x,
lScreenSpaceUV,
lFragmentColourVec4.rgb,
lPositionVec3,
lMeshUniforms.gScanParamsPosVec4,
lMeshUniforms.gScanParamsCfg1Vec4,
lMeshUniforms.gScanParamsCfg2Vec4,
lSunColourVec3 );
// Second scan wave
/*lFragmentColourVec4.rgb = ScanPulseEffectOverlay(
lPerFrameUniforms.gfTime.x,
lScreenSpaceUV,
lFragmentColourVec4.rgb,
lPositionVec3,
lMeshUniforms.gScanParamsPosVec4 * vec4(1.0, 1.0, 1.0, 2.0),
lMeshUniforms.gScanParamsCfg1Vec4,
lMeshUniforms.gScanParamsCfg2Vec4 + vec4(0.0, 0.0, 0.0, -0.3));*/
#if !defined( D_TERRAIN )
{
// FX applied via material-cloning per node; eg. scan analysis
lFragmentColourVec4 = ScanEffect(
lPerFrameUniforms.gfTime.x,
lScreenSpaceUV,
lFragmentColourVec4,
lCustomUniforms.gMaterialSFXColVec4,
lCustomUniforms.gMaterialSFXVec4,
lPerFrameUniforms.gViewPositionVec3,
lPositionVec3,
lNormalVec3,
lMeshUniforms.gPlanetPositionVec4,
lSunColourVec3
);
}
#endif
return lFragmentColourVec4;
}
#endif
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
///
/// WriteOutput
///
/// @brief WriteOutput
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
void
WriteOutput(
out vec4 lOutColours0Vec4,
out vec4 lOutColours1Vec4,
out vec4 lOutColours2Vec4,
out vec4 lOutColours3Vec4,
out vec4 lOutColours4Vec4,
in PerFrameUniforms lPerFrameUniforms,
in CommonPerMeshUniforms lMeshUniforms,
in CustomPerMaterialUniforms lCustomUniforms,
in vec4 lColourVec4,
in vec3 lPositionVec3,
in vec3 lNormalVec3,
in int liMaterialID,
in float lfMetallic,
in float lfRoughness,
in float lfSubsurface,
in float lfGlow,
in vec4 lScreenSpacePositionVec4,
in vec4 lPrevScreenPositionVec4,
#ifndef _F07_
in mat3 lUpMatrix,
#endif
in float lfPixelDepth,
in bool lbFrontFacing)
{
vec4 lFragmentColourVec4;
vec3 lSunColourVec3 = vec3(0.0);
lFragmentColourVec4 = lColourVec4;
//-----------------------------------------------------------------------------
///
/// Lighting
///
//-----------------------------------------------------------------------------
#ifndef _F07_
{
vec3 lLightDirectionVec3 = -lPerFrameUniforms.gLightDirectionVec4.xyz;
lFragmentColourVec4.rgb = ComputeLightColour(
lCustomUniforms,
lPerFrameUniforms,
lMeshUniforms,
lLightDirectionVec3,
lMeshUniforms.gLightColourVec4.xyz * lMeshUniforms.gLightColourVec4.w,
lPositionVec3,
lScreenSpacePositionVec4.xy / lScreenSpacePositionVec4.w,
lNormalVec3,
lColourVec4.rgb,
lUpMatrix,
liMaterialID,
lfMetallic,
lfRoughness,
lfSubsurface,
0.5,
1.0,
lSunColourVec3 );
}
#endif
#ifdef _F34_
{
lFragmentColourVec4.rgb = mix( lFragmentColourVec4.rgb, lColourVec4.rgb, lfGlow );
#ifdef _F35_
{
lFragmentColourVec4.a = lfGlow;
}
#endif
}
#endif
#if !defined( _F50_ ) && !defined( D_NO_POSTPROCESS )
{
lFragmentColourVec4 = PostProcess(
lPerFrameUniforms,
lMeshUniforms,
lCustomUniforms,
lFragmentColourVec4,
lPositionVec3,
lNormalVec3,
liMaterialID,
lScreenSpacePositionVec4,
lSunColourVec3);
}
#endif
//-----------------------------------------------------------------------------
///
/// Output
///
//-----------------------------------------------------------------------------
lOutColours0Vec4 = lFragmentColourVec4;
}
#endif
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
///
/// Fragment Main
///
/// @brief Fragment Main
///
/// @param void
/// @return Nothing.
///
//-----------------------------------------------------------------------------
#if (defined( _F47_ ) && defined( D_USING_LOGDEPTH )) || defined( D_DEPTH_CLEAR )
FRAGMENT_MAIN_COLOUR_DEPTH_SRT
#else
FRAGMENT_MAIN_COLOUR_SRT
#endif
{
#ifdef D_DEPTH_CLEAR
FRAGMENT_COLOUR = vec4( 0.0, 0.0, 0.0, 0.0 );
FRAGMENT_DEPTH = D_DEPTH_CLEARVALUE;
return;
#endif
vec4 lFragmentColourVec4;
vec3 lNormalVec3 = vec3(0.0,1.0,0.0);
#ifdef D_TEXCOORDS
//{
vec4 lTexCoordsVec4;
lTexCoordsVec4 = IN( mTexCoordsVec4 );
// WARNING THIS IS TEMPORARY AND ALSO SHIT
#ifdef D_PLATFORM_PC
lTexCoordsVec4.y = 1.0 - lTexCoordsVec4.y;
#endif
//}
#endif
//-----------------------------------------------------------------------------
/// Diffuse
//-----------------------------------------------------------------------------
vec4 lDiffuseColourVec4;
#ifdef _F01_
{
{
vec2 lFracTexCoordsVec2;
lFracTexCoordsVec2.x = fract(lTexCoordsVec4.x);
lFracTexCoordsVec2.y = fract(lTexCoordsVec4.y);
// --- float lfColourSeperateAmount = lUniforms.mpCustomPerMaterial.gUIDeformVec4.z; // [peter] was never used
float lfOverallMagnitude = 1.0;
float lfFlickerAmount = 0.5;
vec2 lDeformedCoordsVec2 = lFracTexCoordsVec2;
lDeformedCoordsVec2.x +=
((lfFlickerAmount * 0.1) + 2.0 * (max( sin( lUniforms.mpPerFrame.gfTime + sin( lUniforms.mpPerFrame.gfTime * 31.0 ) ), 0.98) - 0.98)) *
0.05 *
sin( 113.0 * lUniforms.mpPerFrame.gfTime * sin( lDeformedCoordsVec2.y * 137.0 ) ) *
lfOverallMagnitude;
//lfColourSeperateAmount = lfColourSeperateAmount*(max( sin( gCommon.gfTime + sin( gCommon.gfTime * 13.0 ) ), 0.0));
// --- lfColourSeperateAmount = 4.0/lUniforms.mpCustomPerMaterial.gUIDeformVec4.z; // [peter] was never used
// Colour separation
//lEffectsColourVec3.r = texture2D(gDiffuseMap,vec2( lDeformedCoordsVec2.x+lfColourSeperateAmount, lDeformedCoordsVec2.y)).x;
//lEffectsColourVec3.g = texture2D(gDiffuseMap,vec2( lDeformedCoordsVec2.x, lDeformedCoordsVec2.y)).y;
//lEffectsColourVec3.b = texture2D(gDiffuseMap,vec2( lDeformedCoordsVec2.x-lfColourSeperateAmount, lDeformedCoordsVec2.y)).z;
//lFragmentColourVec3 = clamp(lFragmentColourVec3*0.5+0.5*lFragmentColourVec3*lFragmentColourVec3*1.2,0.0,1.0);
/*lEffectsColourVec3 *= 2.5;
lEffectsColourVec3.x = pow( lEffectsColourVec3.x, 3.0 );
lEffectsColourVec3.y = pow( lEffectsColourVec3.y, 3.0 );
lEffectsColourVec3.z = pow( lEffectsColourVec3.z, 3.0 );*/
float lfPulseIntensity = 0.9 + 0.3 * sin(13.0*lUniforms.mpPerFrame.gfTime)*sin(5.0*lUniforms.mpPerFrame.gfTime)*sin(23.0*lUniforms.mpPerFrame.gfTime);
// Glitch
float lfGlitch = sin(18.245*lUniforms.mpPerFrame.gfTime)*cos(11.323*lUniforms.mpPerFrame.gfTime)*sin(4.313*lUniforms.mpPerFrame.gfTime);
lfGlitch *= max(0.0, sin(10.0*lUniforms.mpPerFrame.gfTime));
lfGlitch *= lfGlitch;
lTexCoordsVec4.x += sin(lTexCoordsVec4.y*19.1)*lfGlitch*.01;
lTexCoordsVec4.x += sin(lTexCoordsVec4.y*459.1)*lfGlitch*lfGlitch*.02;
lDiffuseColourVec4 = texture2D(lUniforms.mpCustomPerMaterial.gDiffuseMap, lTexCoordsVec4.xy);
vec3 lEffectsColourVec3 = lDiffuseColourVec4.xyz;
// Gamma corection
lEffectsColourVec3 = GammaCorrectInput(lEffectsColourVec3);
// Vignette
float lfVignette = lTexCoordsVec4.x*lTexCoordsVec4.y*(1.0-lTexCoordsVec4.x)*(1.0-lTexCoordsVec4.y) * 10.0;
lfVignette = clamp( lfVignette, 0.0, 1.0 );
lEffectsColourVec3 = mix( vec3(0.0), lEffectsColourVec3, lfVignette );
lEffectsColourVec3 *= 1.0 + 0.04 * sin(5.0 * lUniforms.mpPerFrame.gfTime - lDeformedCoordsVec2.y*150.0) * (1.0 - lTexCoordsVec4.y) * (1.0 - lTexCoordsVec4.y); // Scan lines
lEffectsColourVec3 *= lfPulseIntensity; // Pulse
lEffectsColourVec3 *= (12.0 + mod(lDeformedCoordsVec2.y * 30.0 + lUniforms.mpPerFrame.gfTime, 2.0)) / 13.0;
//lEffectsColourVec3.b *= 1.0 + (1.0 - lDeformedCoordsVec2.y) * 2.0;
lDiffuseColourVec4.xyz = lEffectsColourVec3;
}
}
#else
{
lDiffuseColourVec4 = IN( mMaterialVec4 );
}
#endif
#ifdef _F21_
{
lDiffuseColourVec4 *= IN( mColourVec4 );
}
#endif
lFragmentColourVec4 = lDiffuseColourVec4;
lFragmentColourVec4.a = 1.0;
//-----------------------------------------------------------------------------
///
/// Transparency
///
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
///
/// Output
///
//-----------------------------------------------------------------------------
int liMaterialID = 0;
#ifdef _F10_
liMaterialID |= D_NORECEIVESHADOW;
#endif
#ifdef _F50_
liMaterialID |= D_DISABLE_POSTPROCESS;
#endif
#ifdef _F07_
liMaterialID |= D_UNLIT;
#endif
#if defined( _F57_ )
liMaterialID |= D_DETAILOVERLAY;
#endif
liMaterialID |= D_CLAMP_AA;
vec4 lOutColours0Vec4;
vec4 lOutColours1Vec4;
vec4 lOutColours2Vec4;
vec4 lOutColours3Vec4;
vec4 lOutColours4Vec4;
WriteOutput(
lOutColours0Vec4,
lOutColours1Vec4,
lOutColours2Vec4,
lOutColours3Vec4,
lOutColours4Vec4,
DEREF_PTR( lUniforms.mpPerFrame ),
DEREF_PTR( lUniforms.mpCommonPerMesh ),
DEREF_PTR( lUniforms.mpCustomPerMaterial ),
lFragmentColourVec4,
IN( mWorldPositionVec3_mfSpare ).xyz,
lNormalVec3,
liMaterialID,
0.0,
1.0,
0.0,
0.0,
#ifdef D_USE_SCREEN_POSITION
IN( mScreenSpacePositionVec4 ).xyzw,
#else
vec4( 0.0 ),
#endif
#ifdef D_OUTPUT_MOTION_VECTORS
IN( mPrevScreenPosition ).xyzw,
#else
vec4( 0.0 ),
#endif
#if !defined( D_DEFER ) && !defined( _F07_ )
GetInverseWorldUpTransform(lUniforms.mpPerFrame.gViewPositionVec3, lUniforms.mpCommonPerMesh.gLightOriginVec4),
#endif
0.0,
false
);
#if !defined( D_ATTRIBUTES )
FRAGMENT_COLOUR = lOutColours0Vec4;
#else
FRAGMENT_COLOUR0 = lOutColours0Vec4;
FRAGMENT_COLOUR1 = lOutColours1Vec4;
FRAGMENT_COLOUR2 = lOutColours2Vec4;
FRAGMENT_COLOUR3 = lOutColours3Vec4;
#endif
#if defined( _F47_ ) && defined( D_USING_LOGDEPTH )
{
// For large polys we need to write z per pixel instead of letting it interpolate as it becomes slightly inaccurate and we get depth artifacts. (logZ is used in a calculation in the pixel shader).
FRAGMENT_DEPTH = LinearToLogDepth_Pixel( IN( mfLogZ ), lUniforms.mpPerFrame.gClipPlanesVec4 );
}
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment