Created
June 29, 2020 06:18
-
-
Save strzlee/35003b6143328db672f6d6ca72564222 to your computer and use it in GitHub Desktop.
nms shader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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