diff --git a/crt/metacrt.slangp b/crt/metacrt.slangp index d19d6531..b7a209ba 100644 --- a/crt/metacrt.slangp +++ b/crt/metacrt.slangp @@ -1,13 +1,25 @@ -shaders = 2 +shaders = 4 shader0 = shaders/metacrt/bufC.slang scale_type0 = viewport filter_linear0 = true +float_framebuffer0 = true -shader1 = ../anti-aliasing/shaders/fxaa.slang +shader1 = shaders/metacrt/bufD.slang +scale_type1 = viewport +filter_linear1 = true +float_framebuffer1 = true + +shader2 = shaders/metacrt/Image.slang +scale_type2 = viewport +filter_linear2 = true +float_framebuffer2 = true + +shader3 = ../anti-aliasing/shaders/fxaa.slang +filter_linear3 = true textures = "cubeMap;table" cubeMap = shaders/metacrt/basilica.png cubeMap_wrap_mode = repeat table = shaders/metacrt/woodgrain.png -table_wrap_mode = repeat \ No newline at end of file +table_wrap_mode = repeat diff --git a/crt/shaders/metacrt/Image.slang b/crt/shaders/metacrt/Image.slang deleted file mode 100644 index 9a10c20d..00000000 --- a/crt/shaders/metacrt/Image.slang +++ /dev/null @@ -1,367 +0,0 @@ -#version 450 - -// Meta CRT - @P_Malin -// https://www.shadertoy.com/view/4dlyWX# -// In which I add and remove aliasing - -layout(push_constant) uniform Push -{ - vec4 SourceSize; - vec4 OriginalSize; - vec4 OutputSize; - uint FrameCount; -} params; - -layout(std140, set = 0, binding = 0) uniform UBO -{ - mat4 MVP; -} global; - -#pragma stage vertex -layout(location = 0) in vec4 Position; -layout(location = 1) in vec2 TexCoord; -layout(location = 0) out vec2 vTexCoord; - -void main() -{ - gl_Position = global.MVP * Position; - vTexCoord = TexCoord; -} - -#pragma stage fragment -layout(location = 0) in vec2 vTexCoord; -layout(location = 0) out vec4 FragColor; -layout(set = 0, binding = 2) uniform sampler2D Source; - -#define iGlobalTime float(params.FrameCount) -#define iResolution params.SourceSize -#define iChannel0 Source - -// Postprocessing Pass -// Motion blur, Depth of Field, Vignetting & Tonemap - - -#define ENABLE_DOF -#define ENABLE_MOTION_BLUR - -/////////////////////////// -// Hash Functions -/////////////////////////// - -// From: Hash without Sine by Dave Hoskins -// https://www.shadertoy.com/view/4djSRW - -// *** Use this for integer stepped ranges, ie Value-Noise/Perlin noise functions. -//#define HASHSCALE1 .1031 -//#define HASHSCALE3 vec3(.1031, .1030, .0973) -//#define HASHSCALE4 vec4(1031, .1030, .0973, .1099) - -// For smaller input rangers like audio tick or 0-1 UVs use these... -#define HASHSCALE1 443.8975 -#define HASHSCALE3 vec3(443.897, 441.423, 437.195) -#define HASHSCALE4 vec3(443.897, 441.423, 437.195, 444.129) - - -//---------------------------------------------------------------------------------------- -// 2 out, 1 in... -vec2 hash21(float p) -{ - vec3 p3 = fract(vec3(p) * HASHSCALE3); - p3 += dot(p3, p3.yzx + 19.19); - return fract((p3.xx+p3.yz)*p3.zy); - -} - -/// 2 out, 3 in... -vec2 hash23(vec3 p3) -{ - p3 = fract(p3 * HASHSCALE3); - p3 += dot(p3, p3.yzx+19.19); - return fract((p3.xx+p3.yz)*p3.zy); -} - -// 1 out, 3 in... -float hash13(vec3 p3) -{ - p3 = fract(p3 * HASHSCALE1); - p3 += dot(p3, p3.yzx + 19.19); - return fract((p3.x + p3.y) * p3.z); -} - - -/////////////////////////// -// Data Storage -/////////////////////////// - -vec4 LoadVec4( sampler2D tex, in ivec2 vAddr ) -{ - return texelFetch( tex, vAddr, 0 ); -} - -vec3 LoadVec3( sampler2D tex, in ivec2 vAddr ) -{ - return LoadVec4( tex, vAddr ).xyz; -} - -bool AtAddress( ivec2 p, ivec2 c ) { return all( equal( p, c ) ); } - -void StoreVec4( in ivec2 vAddr, in vec4 vValue, inout vec4 fragColor, in ivec2 fragCoord ) -{ - fragColor = AtAddress( fragCoord, vAddr ) ? vValue : fragColor; -} - -void StoreVec3( in ivec2 vAddr, in vec3 vValue, inout vec4 fragColor, in ivec2 fragCoord ) -{ - StoreVec4( vAddr, vec4( vValue, 0.0 ), fragColor, fragCoord); -} - -/////////////////////////// -// Camera -/////////////////////////// - -struct CameraState -{ - vec3 vPos; - vec3 vTarget; - float fFov; - vec2 vJitter; - float fPlaneInFocus; -}; - -void Cam_LoadState( out CameraState cam, sampler2D tex, ivec2 addr ) -{ - vec4 vPos = LoadVec4( tex, addr + ivec2(0,0) ); - cam.vPos = vPos.xyz; - vec4 targetFov = LoadVec4( tex, addr + ivec2(1,0) ); - cam.vTarget = targetFov.xyz; - cam.fFov = targetFov.w; - vec4 jitterDof = LoadVec4( tex, addr + ivec2(2,0) ); - cam.vJitter = jitterDof.xy; - cam.fPlaneInFocus = jitterDof.z; -} - -void Cam_StoreState( ivec2 addr, const in CameraState cam, inout vec4 fragColor, in ivec2 fragCoord ) -{ - StoreVec4( addr + ivec2(0,0), vec4( cam.vPos, 0 ), fragColor, fragCoord ); - StoreVec4( addr + ivec2(1,0), vec4( cam.vTarget, cam.fFov ), fragColor, fragCoord ); - StoreVec4( addr + ivec2(2,0), vec4( cam.vJitter, cam.fPlaneInFocus, 0 ), fragColor, fragCoord ); -} - -mat3 Cam_GetWorldToCameraRotMatrix( const CameraState cameraState ) -{ - vec3 vForward = normalize( cameraState.vTarget - cameraState.vPos ); - vec3 vRight = normalize( cross(vec3(0, 1, 0), vForward) ); - vec3 vUp = normalize( cross(vForward, vRight) ); - - return mat3( vRight, vUp, vForward ); -} - -vec2 Cam_GetViewCoordFromUV( const in vec2 vUV ) -{ - vec2 vWindow = vUV * 2.0 - 1.0; - vWindow.x *= iResolution.x / iResolution.y; - - return vWindow; -} - -void Cam_GetCameraRay( const vec2 vUV, const CameraState cam, out vec3 vRayOrigin, out vec3 vRayDir ) -{ - vec2 vView = Cam_GetViewCoordFromUV( vUV ); - vRayOrigin = cam.vPos; - float fPerspDist = 1.0 / tan( radians( cam.fFov ) ); - vRayDir = normalize( Cam_GetWorldToCameraRotMatrix( cam ) * vec3( vView, fPerspDist ) ); -} - -vec2 Cam_GetUVFromWindowCoord( const in vec2 vWindow ) -{ - vec2 vScaledWindow = vWindow; - vScaledWindow.x *= iResolution.y / iResolution.x; - - return (vScaledWindow * 0.5 + 0.5); -} - -vec2 Cam_WorldToWindowCoord(const in vec3 vWorldPos, const in CameraState cameraState ) -{ - vec3 vOffset = vWorldPos - cameraState.vPos; - vec3 vCameraLocal; - - vCameraLocal = vOffset * Cam_GetWorldToCameraRotMatrix( cameraState ); - - vec2 vWindowPos = vCameraLocal.xy / (vCameraLocal.z * tan( radians( cameraState.fFov ) )); - - return vWindowPos; -} - -float EncodeDepthAndObject( float depth, int objectId ) -{ - //depth = max( 0.0, depth ); - //objectId = max( 0, objectId + 1 ); - //return exp2(-depth) + float(objectId); - return depth; -} - -float DecodeDepthAndObjectId( float value, out int objectId ) -{ - objectId = 0; - return max(0.0, value); - //objectId = int( floor( value ) ) - 1; - //return abs( -log2(fract(value)) ); -} - -/////////////////////////////// - -vec3 Tonemap( vec3 x ) -{ - float a = 0.010; - float b = 0.132; - float c = 0.010; - float d = 0.163; - float e = 0.101; - - return ( x * ( a * x + b ) ) / ( x * ( c * x + d ) + e ); -} - - -float GetVignetting( const in vec2 vUV, float fScale, float fPower, float fStrength ) -{ - vec2 vOffset = (vUV - 0.5) * sqrt(2.0) * fScale; - - float fDist = max( 0.0, 1.0 - length( vOffset ) ); - - float fShade = 1.0 - pow( fDist, fPower ); - - fShade = 1.0 - fShade * fStrength; - - return fShade; -} - - - - -float GetCoC( float fDistance, float fPlaneInFocus ) -{ -#ifdef ENABLE_DOF - // http://http.developer.nvidia.com/GPUGems/gpugems_ch23.html - - float fAperture = min(1.0, fPlaneInFocus * fPlaneInFocus * 0.5); - float fFocalLength = 0.03; - - return abs(fAperture * (fFocalLength * (fDistance - fPlaneInFocus)) / - (fDistance * (fPlaneInFocus - fFocalLength))); -#else - return 0.0f; -#endif -} - -// Depth of field pass - -#define BLUR_TAPS 64 -float fGolden = 3.141592 * (3.0 - sqrt(5.0)); - -#define MOD2 vec2(4.438975,3.972973) - -float Hash( float p ) -{ - // https://www.shadertoy.com/view/4djSRW - Dave Hoskins - vec2 p2 = fract(vec2(p) * MOD2); - p2 += dot(p2.yx, p2.xy+19.19); - return fract(p2.x * p2.y); -} - - -void main() -{ - vec2 fragCoord = vTexCoord.xy * params.OutputSize.xy; - CameraState camCurr; - Cam_LoadState( camCurr, iChannel0, ivec2(0) ); - - CameraState camPrev; - Cam_LoadState( camPrev, iChannel0, ivec2(3,0) ); - - vec2 vUV = fragCoord.xy / iResolution.xy; - //vUV -= camCurr.vJitter / iResolution.xy; // TAA has removed jitter - - vec4 vSample = texelFetch( iChannel0, ivec2(fragCoord.xy), 0 ).rgba; - - int iObjectId; - float fDepth = DecodeDepthAndObjectId( vSample.w, iObjectId ); - - vec3 vRayOrigin, vRayDir; - - Cam_GetCameraRay( vUV, camCurr, vRayOrigin, vRayDir ); - vec3 vWorldPos = vRayOrigin + vRayDir * fDepth; - - vec2 vPrevUV = Cam_GetUVFromWindowCoord( Cam_WorldToWindowCoord(vWorldPos, camPrev) );// - camPrev.vJitter / iResolution.xy; - - vec3 vResult = vec3(0.0); - - float fTot = 0.0; - - float fPlaneInFocus = camCurr.fPlaneInFocus; - - float fCoC = GetCoC( fDepth, camCurr.fPlaneInFocus ); - - float r = 1.0; - vec2 vangle = vec2(0.0,fCoC); // Start angle - - float fWeight = max( 0.001, fCoC ); - vResult.rgb = vSample.rgb * fWeight; - fTot += fWeight; - -#if defined(ENABLE_DOF) || defined(ENABLE_MOTION_BLUR) - float fMotionBlurTaps = float(BLUR_TAPS); - - float fShutterAngle = 0.5; - - float f = 0.0; - float fIndex = 0.0; - for(int i=1; i 0.0 ) - { - float fCurrCoC = GetCoC( fTapDepth, fPlaneInFocus ); - - float fCurrWeight = max( 0.001, fCurrCoC ); - - vResult += vTapSample.rgb * fCurrWeight; - fTot += fCurrWeight; - } - f += 1.0; - fIndex += 1.0; - } -#endif - vResult /= fTot; - - FragColor = vec4(vResult, 1.0); - - float fShade = GetVignetting( vUV, 0.7, 2.0, 1.0 ); - - FragColor.rgb *= fShade; - - FragColor.rgb = Tonemap( FragColor.rgb ) * 2.0; - FragColor.a = 1.0; -} \ No newline at end of file diff --git a/crt/shaders/metacrt/bufC.slang b/crt/shaders/metacrt/bufC.slang deleted file mode 100644 index 591c4eb9..00000000 --- a/crt/shaders/metacrt/bufC.slang +++ /dev/null @@ -1,1182 +0,0 @@ -#version 450 - -// Meta CRT - @P_Malin -// https://www.shadertoy.com/view/4dlyWX# -// In which I add and remove aliasing - -#define iChannel0 Source -#define iChannel1 cubeMap -#define iChannel2 table -#define iResolution params.SourceSize -#define vFragCoord (vTexCoord.xy * params.OutputSize.xy) -#define iGlobalTime float(params.FrameCount) - -layout(push_constant) uniform Push -{ - vec4 SourceSize; - vec4 OriginalSize; - vec4 OutputSize; - uint FrameCount; - float cam_index; - float showSphere; - float snow; - float Fov; - float PosX; - float PosY; - float PosZ; - float TargetX; - float TargetY; -// float TargetZ; -} params; - -//#pragma parameter cam_index "Cam Pos Index" 0.0 0.0 9.0 1.0 -#pragma parameter showSphere "Sphere Toggle" 0.0 0.0 1.0 1.0 -#pragma parameter snow "Static Toggle" 0.0 0.0 1.0 1.0 -#pragma parameter Fov "Field of View" -9.0 -20.0 20.0 0.1 -#pragma parameter PosX "Tilt Pos X" -0.30 -10.0 10.0 0.12 -#pragma parameter PosY "Tilt Pos Y" 0.25 -10.0 10.0 0.12 -#pragma parameter PosZ "Cam Zoom" -3.25 -10.0 10.0 0.12 -#pragma parameter TargetX "Cam X Pos" -0.25 -10.0 10.0 0.05 -#pragma parameter TargetY "Cam Y Pos Y" 0.25 -10.0 10.0 0.05 -//#pragma parameter TargetZ "Cam Target Z" 0.0 -10.0 10.0 0.05 - -layout(std140, set = 0, binding = 0) uniform UBO -{ - mat4 MVP; -} global; - -#pragma stage vertex -layout(location = 0) in vec4 Position; -layout(location = 1) in vec2 TexCoord; -layout(location = 0) out vec2 vTexCoord; - -void main() -{ - gl_Position = global.MVP * Position; - vTexCoord = TexCoord; -} - -#pragma stage fragment -layout(location = 0) in vec2 vTexCoord; -layout(location = 0) out vec4 FragColor; -layout(set = 0, binding = 2) uniform sampler2D Source; -layout(set = 0, binding = 3) uniform sampler2D cubeMap; -layout(set = 0, binding = 4) uniform sampler2D table; - -// Scene Rendering - -#define ENABLE_TAA_JITTER - -#define kMaxTraceDist 1000.0 -#define kFarDist 1100.0 - -#define MAT_FG_BEGIN 10 - -#define PI 3.141592654 - -/////////////////////////// -// Hash Functions -/////////////////////////// - -// From: Hash without Sine by Dave Hoskins -// https://www.shadertoy.com/view/4djSRW - -// *** Use this for integer stepped ranges, ie Value-Noise/Perlin noise functions. -//#define HASHSCALE1 .1031 -//#define HASHSCALE3 vec3(.1031, .1030, .0973) -//#define HASHSCALE4 vec4(1031, .1030, .0973, .1099) - -// For smaller input rangers like audio tick or 0-1 UVs use these... -#define HASHSCALE1 443.8975 -#define HASHSCALE3 vec3(443.897, 441.423, 437.195) -#define HASHSCALE4 vec3(443.897, 441.423, 437.195, 444.129) - - -//---------------------------------------------------------------------------------------- -// 1 out, 1 in... -float hash11(float p) -{ - vec3 p3 = fract(vec3(p) * HASHSCALE1); - p3 += dot(p3, p3.yzx + 19.19); - return fract((p3.x + p3.y) * p3.z); -} - -// 2 out, 1 in... -vec2 hash21(float p) -{ - vec3 p3 = fract(vec3(p) * HASHSCALE3); - p3 += dot(p3, p3.yzx + 19.19); - return fract((p3.xx+p3.yz)*p3.zy); - -} - -/// 2 out, 3 in... -vec2 hash23(vec3 p3) -{ - p3 = fract(p3 * HASHSCALE3); - p3 += dot(p3, p3.yzx+19.19); - return fract((p3.xx+p3.yz)*p3.zy); -} - -// 1 out, 3 in... -float hash13(vec3 p3) -{ - p3 = fract(p3 * HASHSCALE1); - p3 += dot(p3, p3.yzx + 19.19); - return fract((p3.x + p3.y) * p3.z); -} - - -/////////////////////////// -// Data Storage -/////////////////////////// - -vec4 LoadVec4( sampler2D tex, in ivec2 vAddr ) -{ - return texelFetch( tex, vAddr, 0 ); -} - - -vec3 LoadVec3( sampler2D tex, in ivec2 vAddr ) -{ - return LoadVec4( tex, vAddr ).xyz; -} - -bool AtAddress( ivec2 p, ivec2 c ) { return all( equal( p, c ) ); } - -void StoreVec4( in ivec2 vAddr, in vec4 vValue, inout vec4 fragColor, in ivec2 fragCoord ) -{ - fragColor = AtAddress( fragCoord, vAddr ) ? vValue : fragColor; -} - -void StoreVec3( in ivec2 vAddr, in vec3 vValue, inout vec4 fragColor, in ivec2 fragCoord ) -{ - StoreVec4( vAddr, vec4( vValue, 0.0 ), fragColor, fragCoord); -} - -/////////////////////////// -// Camera -/////////////////////////// - -struct CameraState -{ - vec3 vPos; - vec3 vTarget; - float fFov; - vec2 vJitter; - float fPlaneInFocus; -}; - -void Cam_LoadState( out CameraState cam, sampler2D tex, ivec2 addr ) -{ - vec4 vPos = LoadVec4( tex, addr + ivec2(0,0) ); - cam.vPos = vPos.xyz; - vec4 targetFov = LoadVec4( tex, addr + ivec2(1,0) ); - cam.vTarget = targetFov.xyz; - cam.fFov = targetFov.w; - vec4 jitterDof = LoadVec4( tex, addr + ivec2(2,0) ); - cam.vJitter = jitterDof.xy; - cam.fPlaneInFocus = jitterDof.z; -} - -void Cam_StoreState( ivec2 addr, const in CameraState cam, inout vec4 fragColor, in ivec2 fragCoord ) -{ - StoreVec4( addr + ivec2(0,0), vec4( cam.vPos, 0 ), fragColor, fragCoord ); - StoreVec4( addr + ivec2(1,0), vec4( cam.vTarget, cam.fFov ), fragColor, fragCoord ); - StoreVec4( addr + ivec2(2,0), vec4( cam.vJitter, cam.fPlaneInFocus, 0 ), fragColor, fragCoord ); -} - -mat3 Cam_GetWorldToCameraRotMatrix( const CameraState cameraState ) -{ - vec3 vForward = normalize( cameraState.vTarget - cameraState.vPos ); - vec3 vRight = normalize( cross(vec3(0, 1, 0), vForward) ); - vec3 vUp = normalize( cross(vForward, vRight) ); - - return mat3( vRight, vUp, vForward ); -} - -vec2 Cam_GetViewCoordFromUV( const in vec2 vUV ) -{ - vec2 vWindow = vUV * 2.0 - 1.0; - vWindow.x *= iResolution.x / iResolution.y; - - return vWindow; -} - -void Cam_GetCameraRay( const vec2 vUV, const CameraState cam, out vec3 vRayOrigin, out vec3 vRayDir ) -{ - vec2 vView = Cam_GetViewCoordFromUV( vUV ); - vRayOrigin = cam.vPos; - float fPerspDist = 1.0 / tan( radians( cam.fFov ) ); - vRayDir = normalize( Cam_GetWorldToCameraRotMatrix( cam ) * vec3( vView, fPerspDist ) ); -} - -vec2 Cam_GetUVFromWindowCoord( const in vec2 vWindow ) -{ - vec2 vScaledWindow = vWindow; - vScaledWindow.x *= iResolution.y / iResolution.x; - - return (vScaledWindow * 0.5 + 0.5); -} - -vec2 Cam_WorldToWindowCoord(const in vec3 vWorldPos, const in CameraState cameraState ) -{ - vec3 vOffset = vWorldPos - cameraState.vPos; - vec3 vCameraLocal; - - vCameraLocal = vOffset * Cam_GetWorldToCameraRotMatrix( cameraState ); - - vec2 vWindowPos = vCameraLocal.xy / (vCameraLocal.z * tan( radians( cameraState.fFov ) )); - - return vWindowPos; -} - -float EncodeDepthAndObject( float depth, int objectId ) -{ - //depth = max( 0.0, depth ); - //objectId = max( 0, objectId + 1 ); - //return exp2(-depth) + float(objectId); - return depth; -} - -float DecodeDepthAndObjectId( float value, out int objectId ) -{ - objectId = 0; - return max(0.0, value); - //objectId = int( floor( value ) ) - 1; - //return abs( -log2(fract(value)) ); -} - -/////////////////////////////// - -/////////////////////////// -// Scene -/////////////////////////// - -struct SceneResult -{ - float fDist; - int iObjectId; - vec3 vUVW; -}; - -void Scene_Union( inout SceneResult a, in SceneResult b ) -{ - if ( b.fDist < a.fDist ) - { - a = b; - } -} - - -void Scene_Subtract( inout SceneResult a, in SceneResult b ) -{ - if ( a.fDist < -b.fDist ) - { - a.fDist = -b.fDist; - a.iObjectId = b.iObjectId; - a.vUVW = b.vUVW; - } -} - -SceneResult Scene_GetDistance( vec3 vPos ); - -vec3 Scene_GetNormal(const in vec3 vPos) -{ - const float fDelta = 0.0001; - vec2 e = vec2( -1, 1 ); - - vec3 vNormal = - Scene_GetDistance( e.yxx * fDelta + vPos ).fDist * e.yxx + - Scene_GetDistance( e.xxy * fDelta + vPos ).fDist * e.xxy + - Scene_GetDistance( e.xyx * fDelta + vPos ).fDist * e.xyx + - Scene_GetDistance( e.yyy * fDelta + vPos ).fDist * e.yyy; - - return normalize( vNormal ); -} - -SceneResult Scene_Trace( const in vec3 vRayOrigin, const in vec3 vRayDir, float minDist, float maxDist ) -{ - SceneResult result; - result.fDist = 0.0; - result.vUVW = vec3(0.0); - result.iObjectId = -1; - - float t = minDist; - const int kRaymarchMaxIter = 128; - for(int i=0; i maxDist ) - { - result.iObjectId = -1; - t = maxDist; - break; - } - - if ( result.fDist > 1.0 ) - { - result.iObjectId = -1; - } - - t += result.fDist; - } - - result.fDist = t; - - - return result; -} - -float Scene_TraceShadow( const in vec3 vRayOrigin, const in vec3 vRayDir, const in float fMinDist, const in float fLightDist ) -{ - //return 1.0; - //return ( Scene_Trace( vRayOrigin, vRayDir, 0.1, fLightDist ).fDist < fLightDist ? 0.0 : 1.0; - - float res = 1.0; - float t = fMinDist; - for( int i=0; i<16; i++ ) - { - float h = Scene_GetDistance( vRayOrigin + vRayDir * t ).fDist; - res = min( res, 8.0*h/t ); - t += clamp( h, 0.02, 0.10 ); - if( h<0.0001 || t>fLightDist ) break; - } - return clamp( res, 0.0, 1.0 ); -} - -float Scene_GetAmbientOcclusion( const in vec3 vPos, const in vec3 vDir ) -{ - float fOcclusion = 0.0; - float fScale = 1.0; - for( int i=0; i<5; i++ ) - { - float fOffsetDist = 0.001 + 0.1*float(i)/4.0; - vec3 vAOPos = vDir * fOffsetDist + vPos; - float fDist = Scene_GetDistance( vAOPos ).fDist; - fOcclusion += (fOffsetDist - fDist) * fScale; - fScale *= 0.4; - } - - return clamp( 1.0 - 30.0*fOcclusion, 0.0, 1.0 ); -} - -/////////////////////////// -// Lighting -/////////////////////////// - -struct SurfaceInfo -{ - vec3 vPos; - vec3 vNormal; - vec3 vBumpNormal; - vec3 vAlbedo; - vec3 vR0; - float fSmoothness; - vec3 vEmissive; -}; - -SurfaceInfo Scene_GetSurfaceInfo( const in vec3 vRayOrigin, const in vec3 vRayDir, SceneResult traceResult ); - -struct SurfaceLighting -{ - vec3 vDiffuse; - vec3 vSpecular; -}; - -SurfaceLighting Scene_GetSurfaceLighting( const in vec3 vRayDir, in SurfaceInfo surfaceInfo ); - -float Light_GIV( float dotNV, float k) -{ - return 1.0 / ((dotNV + 0.0001) * (1.0 - k)+k); -} - -void Light_Add(inout SurfaceLighting lighting, SurfaceInfo surface, const in vec3 vViewDir, const in vec3 vLightDir, const in vec3 vLightColour) -{ - float fNDotL = clamp(dot(vLightDir, surface.vBumpNormal), 0.0, 1.0); - - lighting.vDiffuse += vLightColour * fNDotL; - - vec3 vH = normalize( -vViewDir + vLightDir ); - float fNdotV = clamp(dot(-vViewDir, surface.vBumpNormal), 0.0, 1.0); - float fNdotH = clamp(dot(surface.vBumpNormal, vH), 0.0, 1.0); - - float alpha = 1.0 - surface.fSmoothness; - // D - - float alphaSqr = alpha * alpha; - float denom = fNdotH * fNdotH * (alphaSqr - 1.0) + 1.0; - float d = alphaSqr / (PI * denom * denom); - - float k = alpha / 2.0; - float vis = Light_GIV(fNDotL, k) * Light_GIV(fNdotV, k); - - float fSpecularIntensity = d * vis * fNDotL; - lighting.vSpecular += vLightColour * fSpecularIntensity; -} - -void Light_AddPoint(inout SurfaceLighting lighting, SurfaceInfo surface, const in vec3 vViewDir, const in vec3 vLightPos, const in vec3 vLightColour) -{ - vec3 vPos = surface.vPos; - vec3 vToLight = vLightPos - vPos; - - vec3 vLightDir = normalize(vToLight); - float fDistance2 = dot(vToLight, vToLight); - float fAttenuation = 10.0 / (fDistance2);//100.0 / (fDistance2); - - float fShadowFactor = Scene_TraceShadow( surface.vPos, vLightDir, 0.1, length(vToLight) ); - - Light_Add( lighting, surface, vViewDir, vLightDir, vLightColour * fShadowFactor * fAttenuation); -} - -void Light_AddDirectional(inout SurfaceLighting lighting, SurfaceInfo surface, const in vec3 vViewDir, const in vec3 vLightDir, const in vec3 vLightColour) -{ - float fAttenuation = 1.0; - float fShadowFactor = Scene_TraceShadow( surface.vPos, vLightDir, 0.1, 10.0 ); - - Light_Add( lighting, surface, vViewDir, vLightDir, vLightColour * fShadowFactor * fAttenuation); -} - -vec3 Light_GetFresnel( vec3 vView, vec3 vNormal, vec3 vR0, float fGloss ) -{ - float NdotV = max( 0.0, dot( vView, vNormal ) ); - -// return vR0 + (vec3(1.0) - vR0) * pow( 1.0 - NdotV, 5.0 ) * pow( fGloss, 20.0 ); - return vR0 + (vec3(0.5) - vR0) * pow( 1.0 - NdotV, 1.5 ) * pow( fGloss, 20.0 ); -} - -void Env_AddPointLightFlare(inout vec3 vEmissiveGlow, const in vec3 vRayOrigin, const in vec3 vRayDir, const in float fIntersectDistance, const in vec3 vLightPos, const in vec3 vLightColour) -{ - vec3 vToLight = vLightPos - vRayOrigin; - float fPointDot = dot(vToLight, vRayDir); - fPointDot = clamp(fPointDot, 0.0, fIntersectDistance); - - vec3 vClosestPoint = vRayOrigin + vRayDir * fPointDot; - float fDist = length(vClosestPoint - vLightPos); - vEmissiveGlow += sqrt(vLightColour * 0.05 / (fDist * fDist)); -} - -void Env_AddDirectionalLightFlareToFog(inout vec3 vFogColour, const in vec3 vRayDir, const in vec3 vLightDir, const in vec3 vLightColour) -{ - float fDirDot = clamp(dot(vLightDir, vRayDir) * 0.5 + 0.5, 0.0, 1.0); - float kSpreadPower = 2.0; - vFogColour += vLightColour * pow(fDirDot, kSpreadPower) * 0.25; -} - - -/////////////////////////// -// Rendering -/////////////////////////// - -vec4 Env_GetSkyColor( const vec3 vViewPos, const vec3 vViewDir ); -vec3 Env_ApplyAtmosphere( const in vec3 vColor, const in vec3 vRayOrigin, const in vec3 vRayDir, const in float fDist ); -vec3 FX_Apply( in vec3 vColor, const in vec3 vRayOrigin, const in vec3 vRayDir, const in float fDist); - -vec4 Scene_GetColorAndDepth( vec3 vRayOrigin, vec3 vRayDir ) -{ - vec3 vResultColor = vec3(0.0); - - SceneResult firstTraceResult; - - float fStartDist = 0.0f; - float fMaxDist = 10.0f; - - vec3 vRemaining = vec3(0.5);//vec3(1.0); - - for( int iPassIndex=0; iPassIndex < 1; iPassIndex++ ) - { - SceneResult traceResult = Scene_Trace( vRayOrigin, vRayDir, fStartDist, fMaxDist ); - - if ( iPassIndex == 0 ) - { - firstTraceResult = traceResult; - } - - vec3 vColor = vec3(0); - vec3 vReflectAmount = vec3(0); - - if( traceResult.iObjectId < 0 ) - { - vColor = Env_GetSkyColor( vRayOrigin, vRayDir ).rgb; - } - else - { - - SurfaceInfo surfaceInfo = Scene_GetSurfaceInfo( vRayOrigin, vRayDir, traceResult ); - SurfaceLighting surfaceLighting = Scene_GetSurfaceLighting( vRayDir, surfaceInfo ); - - // calculate reflectance (Fresnel) - vReflectAmount = Light_GetFresnel( -vRayDir, surfaceInfo.vBumpNormal, surfaceInfo.vR0, surfaceInfo.fSmoothness ); - - vColor = (surfaceInfo.vAlbedo * surfaceLighting.vDiffuse + surfaceInfo.vEmissive) * (vec3(1.0) - vReflectAmount); - - vec3 vReflectRayOrigin = surfaceInfo.vPos; - vec3 vReflectRayDir = normalize( reflect( vRayDir, surfaceInfo.vBumpNormal ) ); - fStartDist = 0.001 / max(0.0000001,abs(dot( vReflectRayDir, surfaceInfo.vNormal ))); - - vColor += surfaceLighting.vSpecular * vReflectAmount; - - vColor = Env_ApplyAtmosphere( vColor, vRayOrigin, vRayDir, traceResult.fDist ); - vColor = FX_Apply( vColor, vRayOrigin, vRayDir, traceResult.fDist ); - - vRayOrigin = vReflectRayOrigin; - vRayDir = vReflectRayDir; - } - - vResultColor += vColor * vRemaining; - vRemaining *= vReflectAmount; - } - - return vec4( vResultColor, EncodeDepthAndObject( firstTraceResult.fDist, firstTraceResult.iObjectId ) ); -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////// - -///////////////////////// -// Scene Description -///////////////////////// - -// Materials - -#define MAT_SKY -1 -#define MAT_DEFAULT 0 -#define MAT_SCREEN 1 -#define MAT_TV_CASING 2 -#define MAT_TV_TRIM 3 -#define MAT_CHROME 4 - - -vec3 PulseIntegral( vec3 x, float s1, float s2 ) -{ - // Integral of function where result is 1.0 between s1 and s2 and 0 otherwise - - // V1 - //if ( x > s2 ) return s2 - s1; - //else if ( x > s1 ) return x - s1; - //return 0.0f; - - // V2 - //return clamp( (x - s1), 0.0f, s2 - s1); - //return t; - - return clamp( (x - s1), vec3(0.0f), vec3(s2 - s1)); -} - -float PulseIntegral( float x, float s1, float s2 ) -{ - // Integral of function where result is 1.0 between s1 and s2 and 0 otherwise - - // V1 - //if ( x > s2 ) return s2 - s1; - //else if ( x > s1 ) return x - s1; - //return 0.0f; - - // V2 - //return clamp( (x - s1), 0.0f, s2 - s1); - //return t; - - return clamp( (x - s1), (0.0f), (s2 - s1)); -} - -vec3 Bayer( vec2 vUV, vec2 vBlur ) -{ - vec3 x = vec3(vUV.x); - vec3 y = vec3(vUV.y); - - x += vec3(0.66, 0.33, 0.0); - y += 0.5 * step( fract( x * 0.5 ), vec3(0.5) ); - - //x -= 0.5f; - //y -= 0.5f; - - x = fract( x ); - y = fract( y ); - - // cell centered at 0.5 - - vec2 vSize = vec2(0.16f, 0.75f); - - vec2 vMin = 0.5 - vSize * 0.5; - vec2 vMax = 0.5 + vSize * 0.5; - - vec3 vResult= vec3(0.0); - - vec3 vResultX = (PulseIntegral( x + vBlur.x, vMin.x, vMax.x) - PulseIntegral( x - vBlur.x, vMin.x, vMax.x)) / min( vBlur.x, 1.0); - vec3 vResultY = (PulseIntegral(y + vBlur.y, vMin.y, vMax.y) - PulseIntegral(y - vBlur.y, vMin.y, vMax.y)) / min( vBlur.y, 1.0); - - vResult = min(vResultX,vResultY) * 5.0; - - //vResult = vec3(1.0); - - return vResult; -} - -vec3 GetPixelMatrix( vec2 vUV ) -{ -#if 1 - vec2 dx = dFdx( vUV ); - vec2 dy = dFdy( vUV ); - float dU = length( vec2( dx.x, dy.x ) ); - float dV = length( vec2( dx.y, dy.y ) ); - if (dU <= 0.0 || dV <= 0.0 ) return vec3(1.0); - return Bayer( vUV, vec2(dU, dV) * 1.0); -#else - return vec3(1.0); -#endif -} - -float Scanline( float y, float fBlur ) -{ - float fResult = sin( y * 10.0 ) * 0.45 + 0.55; - return mix( fResult, 1.0f, min( 1.0, fBlur ) ); -} - - -float GetScanline( vec2 vUV ) -{ -#if 1 - vUV.y *= 0.25; - vec2 dx = dFdx( vUV ); - vec2 dy = dFdy( vUV ); - float dV = length( vec2( dx.y, dy.y ) ); - if (dV <= 0.0 ) return 1.0; - return Scanline( vUV.y, dV * 1.3 ); -#else - return 1.0; -#endif -} - - -vec2 kScreenRsolution = vec2(480.0f, 576.0f); - -struct Interference -{ - float noise; - float scanLineRandom; -}; - -float InterferenceHash(float p) -{ - float hashScale = 0.1031; - - vec3 p3 = fract(vec3(p, p, p) * hashScale); - p3 += dot(p3, p3.yzx + 19.19); - return fract((p3.x + p3.y) * p3.z); -} - - -float InterferenceSmoothNoise1D( float x ) -{ - float f0 = floor(x); - float fr = fract(x); - - float h0 = InterferenceHash( f0 ); - float h1 = InterferenceHash( f0 + 1.0 ); - - return h1 * fr + h0 * (1.0 - fr); -} - - -float InterferenceNoise( vec2 uv ) -{ - float displayVerticalLines = 483.0; - float scanLine = floor(uv.y * displayVerticalLines); - float scanPos = scanLine + uv.x; - float timeSeed = fract( iGlobalTime * 123.78 ); - - return InterferenceSmoothNoise1D( scanPos * 234.5 + timeSeed * 12345.6 ); -} - -Interference GetInterference( vec2 vUV ) -{ - Interference interference; - - interference.noise = InterferenceNoise( vUV ); - interference.scanLineRandom = InterferenceHash(vUV.y * 100.0 + fract(iGlobalTime * 1234.0) * 12345.0); - - return interference; -} - -vec3 SampleScreen( vec3 vUVW ) -{ - vec3 vAmbientEmissive = vec3(0.1); - vec3 vBlackEmissive = vec3(0.02); - float fBrightness = 1.75; - vec2 vResolution = vec2(480.0f, 576.0f); - vec2 vPixelCoord = vUVW.xy * vResolution; - - vec3 vPixelMatrix = GetPixelMatrix( vPixelCoord ); - float fScanline = GetScanline( vPixelCoord ); - - vec2 vTextureUV = vUVW.xy; - //vec2 vTextureUV = vPixelCoord; -// vTextureUV = floor(vTextureUV * vResolution * 2.0) / (vResolution * 2.0f); - - Interference interference = GetInterference( vTextureUV ); - - float noiseIntensity = 0.1; - - //vTextureUV.x += (interference.scanLineRandom * 2.0f - 1.0f) * 0.025f * noiseIntensity; - - - vec3 vPixelEmissive = textureLod( Source, vTextureUV.xy * vec2(1.0, -1.0) + vec2(0.0, 1.), 0.0 ).rgb; - - if (params.snow > 0.5) vPixelEmissive = clamp( vPixelEmissive + (interference.noise - 0.5) * 2.0 * noiseIntensity, 0.0, 1.0 ); - - vec3 vResult = (vPixelEmissive * vPixelEmissive * fBrightness + vBlackEmissive) * vPixelMatrix * fScanline + vAmbientEmissive; - - // TODO: feather edge? - if( any( greaterThanEqual( vUVW.xy, vec2(1.0) ) ) || any ( lessThan( vUVW.xy, vec2(0.0) ) ) || ( vUVW.z > 0.0 ) ) - { - return vec3(0.0); - } - - return vResult; - -} - -SurfaceInfo Scene_GetSurfaceInfo( const in vec3 vRayOrigin, const in vec3 vRayDir, SceneResult traceResult ) -{ - SurfaceInfo surfaceInfo; - - surfaceInfo.vPos = vRayOrigin + vRayDir * (traceResult.fDist); - - surfaceInfo.vNormal = Scene_GetNormal( surfaceInfo.vPos ); - surfaceInfo.vBumpNormal = surfaceInfo.vNormal; - surfaceInfo.vAlbedo = textureLod( cubeMap, traceResult.vUVW.xz * -1.0, 0.0 ).rgb; - surfaceInfo.vR0 = vec3( 0.02 ); - surfaceInfo.fSmoothness = 1.0; - surfaceInfo.vEmissive = vec3( 0.0 ); - //return surfaceInfo; - - if ( traceResult.iObjectId == MAT_DEFAULT ) - { - surfaceInfo.vR0 = vec3( 0.02 ); - surfaceInfo.vAlbedo = textureLod( iChannel2, traceResult.vUVW.xz * 2.0, 0.0 ).rgb; - surfaceInfo.vAlbedo = surfaceInfo.vAlbedo * surfaceInfo.vAlbedo; - - surfaceInfo.fSmoothness = clamp( 1.0 - surfaceInfo.vAlbedo.r * surfaceInfo.vAlbedo.r * 2.0, 0.0, 1.0); - - } - - if ( traceResult.iObjectId == MAT_SCREEN ) - { - surfaceInfo.vAlbedo = vec3(0.02); - surfaceInfo.vEmissive = SampleScreen( traceResult.vUVW ); - } - - if ( traceResult.iObjectId == MAT_TV_CASING ) - { - surfaceInfo.vAlbedo = vec3(0.5, 0.4, 0.3); - surfaceInfo.fSmoothness = 0.4; - } - - if ( traceResult.iObjectId == MAT_TV_TRIM ) - { - surfaceInfo.vAlbedo = vec3(0.03, 0.03, 0.05); - surfaceInfo.fSmoothness = 0.5; - } - - if ( traceResult.iObjectId == MAT_CHROME ) - { - surfaceInfo.vAlbedo = vec3(0.01, 0.01, 0.01); - surfaceInfo.fSmoothness = 0.9; - surfaceInfo.vR0 = vec3( 0.8 ); - } - - return surfaceInfo; -} - -// Scene Description - -float SmoothMin( float a, float b, float k ) -{ - //return min(a,b); - - - //float k = 0.06; - float h = clamp( 0.5 + 0.5*(b-a)/k, 0.0, 1.0 ); - return mix( b, a, h ) - k*h*(1.0-h); -} - -float UdRoundBox( vec3 p, vec3 b, float r ) -{ - //vec3 vToFace = abs(p) - b; - //vec3 vConstrained = max( vToFace, 0.0 ); - //return length( vConstrained ) - r; - return length(max(abs(p)-b,0.0))-r; -} - -SceneResult Scene_GetCRT( vec3 vScreenDomain, vec2 vScreenWH, float fScreenCurveRadius, float fBevel, float fDepth ) -{ - SceneResult resultScreen; -#if 1 - vec3 vScreenClosest; - vScreenClosest.xy = max(abs(vScreenDomain.xy)-vScreenWH,0.0); - vec2 vCurveScreenDomain = vScreenDomain.xy; - vCurveScreenDomain = clamp( vCurveScreenDomain, -vScreenWH, vScreenWH ); - float fCurveScreenProjection2 = fScreenCurveRadius * fScreenCurveRadius - vCurveScreenDomain.x * vCurveScreenDomain.x - vCurveScreenDomain.y * vCurveScreenDomain.y; - float fCurveScreenProjection = sqrt( fCurveScreenProjection2 ) - fScreenCurveRadius; - vScreenClosest.z = vScreenDomain.z - clamp( vScreenDomain.z, -fCurveScreenProjection, fDepth ); - resultScreen.vUVW.z = vScreenDomain.z + fCurveScreenProjection; - resultScreen.fDist = (length( vScreenClosest ) - fBevel) * 0.95; - //resultScreen.fDist = (length( vScreenDomain - vec3(0,0,fScreenCurveRadius)) - fScreenCurveRadius - fBevel); -#endif - -#if 0 - vec3 vScreenClosest; - vScreenClosest.xyz = max(abs(vScreenDomain.xyz)-vec3(vScreenWH, fDepth),0.0); - float fRoundDist = length( vScreenClosest.xyz ) - fBevel; - float fSphereDist = length( vScreenDomain - vec3(0,0,fScreenCurveRadius) ) - (fScreenCurveRadius + fBevel); - resultScreen.fDist = max(fRoundDist, fSphereDist); -#endif - - resultScreen.vUVW.xy = (vScreenDomain.xy / vScreenWH) * 0.5 + 0.5f; - resultScreen.iObjectId = MAT_SCREEN; - return resultScreen; -} - -SceneResult Scene_GetComputer( vec3 vPos ) -{ - SceneResult resultComputer; - resultComputer.vUVW = vPos.xzy; - - float fXSectionStart = -0.2; - float fXSectionLength = 0.15; - float fXSectionT = clamp( (vPos.z - fXSectionStart) / fXSectionLength, 0.0, 1.0); - float fXSectionR1 = 0.03; - float fXSectionR2 = 0.05; - float fXSectionR = mix( fXSectionR1, fXSectionR2, fXSectionT ); - float fXSectionZ = fXSectionStart + fXSectionT * fXSectionLength; - - vec2 vXSectionCentre = vec2(fXSectionR, fXSectionZ ); - vec2 vToPos = vPos.yz - vXSectionCentre; - float l = length( vToPos ); - if ( l > fXSectionR ) l = fXSectionR; - vec2 vXSectionClosest = vXSectionCentre + normalize(vToPos) * l; - //float fXSectionDist = length( vXSectionClosest ) - fXSectionR; - - float x = max( abs( vPos.x ) - 0.2f, 0.0 ); - - resultComputer.fDist = length( vec3(x, vXSectionClosest - vPos.yz) )-0.01; - //resultComputer.fDist = x; - - resultComputer.iObjectId = MAT_TV_CASING; -/* - vec3 vKeyPos = vPos.xyz - vec3(0,0.125,0); - vKeyPos.y -= vKeyPos.z * (fXSectionR2 - fXSectionR1) * 2.0 / fXSectionLength; - float fDomainRepeatScale = 0.02; - if ( fract(vKeyPos.z * 0.5 / fDomainRepeatScale + 0.25) > 0.5) vKeyPos.x += fDomainRepeatScale * 0.5; - vec2 vKeyIndex = round(vKeyPos.xz / fDomainRepeatScale); - vKeyIndex.x = clamp( vKeyIndex.x, -8.0, 8.0 ); - vKeyIndex.y = clamp( vKeyIndex.y, -10.0, -5.0 ); - //vKeyPos.xz = (fract( vKeyPos.xz / fDomainRepeatScale ) - 0.5) * fDomainRepeatScale; - vKeyPos.xz = (vKeyPos.xz - (vKeyIndex) * fDomainRepeatScale); - vKeyPos.xz /= 0.7 + vKeyPos.y; - SceneResult resultKey; - resultKey.vUVW = vPos.xzy; - resultKey.fDist = UdRoundBox( vKeyPos, vec3(0.01), 0.001 ); - resultKey.iObjectId = MAT_TV_TRIM; - Scene_Union( resultComputer, resultKey ); -*/ - return resultComputer; -} - -SceneResult Scene_GetDistance( vec3 vPos ) -{ - SceneResult result; - - //result.fDist = vPos.y; - float fBenchBevel = 0.01; - result.fDist = UdRoundBox( vPos - vec3(0,-0.02-fBenchBevel,0.0), vec3(2.0, 0.02, 1.0), fBenchBevel ); - result.vUVW = vPos; - result.iObjectId = MAT_DEFAULT; - - vec3 vSetPos = vec3(0.0, 0.0, 0.0); - vec3 vScreenPos = vSetPos + vec3(0.0, 0.25, 0.00); - - //vPos.x = fract( vPos.x - 0.5) - 0.5; - - vec2 vScreenWH = vec2(4.0, 3.0) / 25.0; - - SceneResult resultSet; - resultSet.vUVW = vPos.xzy; - resultSet.fDist = UdRoundBox( vPos - vScreenPos - vec3(0.0,-0.01,0.2), vec3(.21, 0.175, 0.18), 0.01 ); - resultSet.iObjectId = MAT_TV_CASING; - Scene_Union( result, resultSet ); - - SceneResult resultSetRecess; - resultSetRecess.vUVW = vPos.xzy; - resultSetRecess.fDist = UdRoundBox( vPos - vScreenPos - vec3(0.0,-0.0, -0.05), vec3(vScreenWH + 0.01, 0.05) + 0.005, 0.015 ); - resultSetRecess.iObjectId = MAT_TV_TRIM; - Scene_Subtract( result, resultSetRecess ); - - SceneResult resultSetBase; - resultSetBase.vUVW = vPos.xzy; - float fBaseBevel = 0.03; - resultSetBase.fDist = UdRoundBox( vPos - vSetPos - vec3(0.0,0.04,0.22), vec3(0.2, 0.04, 0.17) - fBaseBevel, fBaseBevel ); - resultSetBase.iObjectId = MAT_TV_CASING; - Scene_Union( result, resultSetBase ); - - SceneResult resultScreen = Scene_GetCRT( vPos - vScreenPos, vScreenWH, 0.75f, 0.02f, 0.1f ); - Scene_Union( result, resultScreen ); - - //SceneResult resultComputer = Scene_GetComputer( vPos - vec3(0.0, 0.0, -0.1) ); - //Scene_Union( result, resultComputer ); -if (params.showSphere > 0.5){ - SceneResult resultSphere; - resultSet.vUVW = vPos.xzy; - resultSet.fDist = length(vPos - vec3(0.25,0.075,-0.1)) - 0.075; - resultSet.iObjectId = MAT_CHROME; - Scene_Union( result, resultSet ); -} - return result; -} - - - -// Scene Lighting - -vec3 g_vSunDir = normalize(vec3(0.3, 0.4, -0.5)); -vec3 g_vSunColor = vec3(1, 0.95, 0.8) * 3.0; -vec3 g_vAmbientColor = vec3(0.8, 0.8, 0.8) * 1.0; - -SurfaceLighting Scene_GetSurfaceLighting( const in vec3 vViewDir, in SurfaceInfo surfaceInfo ) -{ - SurfaceLighting surfaceLighting; - - surfaceLighting.vDiffuse = vec3(0.0); - surfaceLighting.vSpecular = vec3(0.0); - - Light_AddDirectional( surfaceLighting, surfaceInfo, vViewDir, g_vSunDir, g_vSunColor ); - - Light_AddPoint( surfaceLighting, surfaceInfo, vViewDir, vec3(1.4, 2.0, 0.8), vec3(1,1,1) * 0.2 ); - - float fAO = Scene_GetAmbientOcclusion( surfaceInfo.vPos, surfaceInfo.vNormal ); - // AO - surfaceLighting.vDiffuse += fAO * (surfaceInfo.vBumpNormal.y * 0.5 + 0.5) * g_vAmbientColor; - - return surfaceLighting; -} - -// Environment - -vec4 Env_GetSkyColor( const vec3 vViewPos, const vec3 vViewDir ) -{ - vec4 vResult = vec4( 0.0, 0.0, 0.0, kFarDist ); - -#if 1 - vec3 vEnvMap = textureLod( iChannel1, vViewDir.zy, 0.0 ).rgb; - vEnvMap = vEnvMap * vEnvMap; - float kEnvmapExposure = 0.999; - vResult.rgb = -log2(1.0 - vEnvMap * kEnvmapExposure); - -#endif - - // Sun - //float NdotV = dot( g_vSunDir, vViewDir ); - //vResult.rgb += smoothstep( cos(radians(.7)), cos(radians(.5)), NdotV ) * g_vSunColor * 5000.0; - - return vResult; -} - -float Env_GetFogFactor(const in vec3 vRayOrigin, const in vec3 vRayDir, const in float fDist ) -{ - float kFogDensity = 0.00001; - return exp(fDist * -kFogDensity); -} - -vec3 Env_GetFogColor(const in vec3 vDir) -{ - return vec3(0.2, 0.5, 0.6) * 2.0; -} - -vec3 Env_ApplyAtmosphere( const in vec3 vColor, const in vec3 vRayOrigin, const in vec3 vRayDir, const in float fDist ) -{ - //return vColor; - vec3 vResult = vColor; - - - float fFogFactor = Env_GetFogFactor( vRayOrigin, vRayDir, fDist ); - vec3 vFogColor = Env_GetFogColor( vRayDir ); - //Env_AddDirectionalLightFlareToFog( vFogColor, vRayDir, g_vSunDir, g_vSunColor * 3.0); - vResult = mix( vFogColor, vResult, fFogFactor ); - - return vResult; -} - - -vec3 FX_Apply( in vec3 vColor, const in vec3 vRayOrigin, const in vec3 vRayDir, const in float fDist) -{ - return vColor; -} - - -vec4 MainCommon( vec3 vRayOrigin, vec3 vRayDir ) -{ - vec4 vColorLinAndDepth = Scene_GetColorAndDepth( vRayOrigin, vRayDir ); - vColorLinAndDepth.rgb = max( vColorLinAndDepth.rgb, vec3(0.0) ); - - vec4 vFragColor = vColorLinAndDepth; - - float fExposure = 2.0f; - - vFragColor.rgb *= fExposure; - - vFragColor.a = vColorLinAndDepth.w; - - return vFragColor; -} - -CameraState GetCameraPosition( int index ) -{ - CameraState cam; - -// int index = int(params.cam_index); - - vec3 vFocus = vec3(0,0.25,-0.012); - - if ( index > 9 ) - { - index = int(hash11(float(index) / 10.234) * 100.0); - index = index % 10; - } - - index=0; - - if ( index == 0 ) - { - cam.vPos = vec3(-0.1,0.2,-0.08); - cam.vTarget = vec3(0,0.25,0.1); - cam.fFov = 10.0; - } - if ( index == 1 ) - { - cam.vPos = vec3(0.01,0.334,-0.03); - cam.vTarget = vec3(0,0.3,0.1); - cam.fFov = 10.0; - } - if ( index == 2 ) - { - cam.vPos = vec3(-0.8,0.3,-1.0); - cam.vTarget = vec3(0.4,0.18,0.5); - cam.fFov = 10.0; - } - if ( index == 3 ) - { - cam.vPos = vec3(-0.8,1.0,-1.5); - cam.vTarget = vec3(0.2,0.0,0.5); - cam.fFov = 10.0; - } - if ( index == 4 ) - { - cam.vPos = vec3(-0.8,0.3,-1.0); - cam.vTarget = vec3(0.4,0.18,0.5); - cam.fFov = 20.0; - } - if ( index == 5 ) - { - cam.vPos = vec3(-0.244,0.334,-0.0928); - cam.vTarget = vec3(0,0.25,0.1); - cam.fFov = 20.0; - } - if ( index == 6 ) - { - cam.vPos = vec3(0.0,0.1,-0.5); - cam.vTarget = vec3(0.2,0.075,-0.1); - vFocus = cam.vTarget; - cam.fFov = 15.0; - } - if ( index == 7 ) - { - cam.vPos = vec3(-0.01,0.01,-0.25); - cam.vTarget = vec3(0.01,0.27,0.1); - vFocus = cam.vTarget; - cam.fFov = 23.0; - } - if ( index == 8 ) - { - cam.vPos = vec3(-0.23,0.3,-0.05); - cam.vTarget = vec3(0.1,0.2,0.1); - cam.fFov = 15.0; - } - if ( index == 9 ) - { - cam.vPos = vec3(0.4,0.2,-0.2); - cam.vTarget = vec3(-0.1,0.25,0.1); - cam.fFov = 12.0; - } - - cam.vPos += vec3(params.PosX, params.PosY, params.PosZ); - cam.vTarget += vec3(params.TargetX, params.TargetY, 0.0); - cam.fFov += params.Fov; - - cam.fPlaneInFocus = length( vFocus - cam.vPos); - cam.vJitter = vec2(0.0); - - return cam; -} - -void main() -{ - vec2 vUV = vec2(1.0, -1.0) * vFragCoord.xy / iResolution.xy; - - CameraState cam; - - { - CameraState camA; - CameraState camB; - - float fSeqTime = iGlobalTime; - float fSequenceSegLength = 5.0; - float fSeqIndex = floor(fSeqTime / fSequenceSegLength); - float fSeqPos = fract(fSeqTime / fSequenceSegLength); - int iIndex = int(fSeqIndex); - int iIndexNext = int(fSeqIndex) + 1; - camA = GetCameraPosition(iIndex); - camB = GetCameraPosition(iIndexNext); - - float t = smoothstep(0.3, 1.0, fSeqPos); - cam.vPos = mix(camA.vPos, camB.vPos, t ); - cam.vTarget = mix(camA.vTarget, camB.vTarget, t ); - cam.fFov = mix(camA.fFov, camB.fFov, t ); - cam.fPlaneInFocus = mix(camA.fPlaneInFocus, camB.fPlaneInFocus, t ); - } -/* - if ( iMouse.z > 0.0 ) - { - float fDist = 0.01 + 3.0 * (iMouse.y / iResolution.y); - - float fAngle = (iMouse.x / iResolution.x) * radians(360.0); - //float fElevation = (iMouse.y / iResolution.y) * radians(90.0); - float fElevation = 0.15f * radians(90.0); - - cam.vPos = vec3(sin(fAngle) * fDist * cos(fElevation),sin(fElevation) * fDist,cos(fAngle) * fDist * cos(fElevation)); - cam.vTarget = vec3(0,0.25,0.1); - cam.vPos +=cam.vTarget; - cam.fFov = 20.0 / (1.0 + fDist * 0.5); - vec3 vFocus = vec3(0,0.25,-0.012); - cam.fPlaneInFocus = length( vFocus - cam.vPos ); - } -*/ -#ifdef ENABLE_TAA_JITTER - cam.vJitter = hash21( fract( iGlobalTime ) ) - 0.5f; -#endif - - - vec3 vRayOrigin, vRayDir; - vec2 vJitterUV = vUV + cam.vJitter / iResolution.xy; - Cam_GetCameraRay( vJitterUV, cam, vRayOrigin, vRayDir ); - - float fHitDist = 0.0f; - FragColor = MainCommon( vRayOrigin, vRayDir ); - - - Cam_StoreState( ivec2(0), cam, FragColor, ivec2(vFragCoord.xy) ); -} \ No newline at end of file diff --git a/crt/shaders/metacrt/bufD.slang b/crt/shaders/metacrt/bufD.slang deleted file mode 100644 index ae4864f0..00000000 --- a/crt/shaders/metacrt/bufD.slang +++ /dev/null @@ -1,307 +0,0 @@ -#version 450 - -// Meta CRT - @P_Malin -// https://www.shadertoy.com/view/4dlyWX# -// In which I add and remove aliasing - -layout(push_constant) uniform Push -{ - vec4 SourceSize; - vec4 OriginalSize; - vec4 OutputSize; - uint FrameCount; -} params; - -layout(std140, set = 0, binding = 0) uniform UBO -{ - mat4 MVP; -} global; - -#pragma stage vertex -layout(location = 0) in vec4 Position; -layout(location = 1) in vec2 TexCoord; -layout(location = 0) out vec2 vTexCoord; - -void main() -{ - gl_Position = global.MVP * Position; - vTexCoord = TexCoord; -} - -#pragma stage fragment -layout(location = 0) in vec2 vTexCoord; -layout(location = 0) out vec4 FragColor; -layout(set = 0, binding = 2) uniform sampler2D Source; -layout(set = 0, binding = 3) uniform sampler2D Original; - -#define iResolution params.SourceSize -#define iChannel0 Source -#define iChannel1 Source -#define vFragCoord vec2(vTexCoord.xy * params.OutputSize.xy) -#define iGlobalTime float(params.FrameCount) - -// Temporal Anti-aliasing Pass - -#define ENABLE_TAA - -/////////////////////////// -// Hash Functions -/////////////////////////// - -// From: Hash without Sine by Dave Hoskins -// https://www.shadertoy.com/view/4djSRW - -// *** Use this for integer stepped ranges, ie Value-Noise/Perlin noise functions. -//#define HASHSCALE1 .1031 -//#define HASHSCALE3 vec3(.1031, .1030, .0973) -//#define HASHSCALE4 vec4(1031, .1030, .0973, .1099) - -// For smaller input rangers like audio tick or 0-1 UVs use these... -#define HASHSCALE1 443.8975 -#define HASHSCALE3 vec3(443.897, 441.423, 437.195) -#define HASHSCALE4 vec3(443.897, 441.423, 437.195, 444.129) - - -//---------------------------------------------------------------------------------------- -// 2 out, 1 in... -vec2 hash21(float p) -{ - vec3 p3 = fract(vec3(p) * HASHSCALE3); - p3 += dot(p3, p3.yzx + 19.19); - return fract((p3.xx+p3.yz)*p3.zy); - -} - -/// 2 out, 3 in... -vec2 hash23(vec3 p3) -{ - p3 = fract(p3 * HASHSCALE3); - p3 += dot(p3, p3.yzx+19.19); - return fract((p3.xx+p3.yz)*p3.zy); -} - -// 1 out, 3 in... -float hash13(vec3 p3) -{ - p3 = fract(p3 * HASHSCALE1); - p3 += dot(p3, p3.yzx + 19.19); - return fract((p3.x + p3.y) * p3.z); -} - - -/////////////////////////// -// Data Storage -/////////////////////////// - -vec4 LoadVec4( sampler2D tex, in ivec2 vAddr ) -{ - return texelFetch( tex, vAddr, 0 ); -} - -vec3 LoadVec3( sampler2D tex, in ivec2 vAddr ) -{ - return LoadVec4( tex, vAddr ).xyz; -} - -bool AtAddress( ivec2 p, ivec2 c ) { return all( equal( p, c ) ); } - -void StoreVec4( in ivec2 vAddr, in vec4 vValue, inout vec4 fragColor, in ivec2 fragCoord ) -{ - fragColor = AtAddress( fragCoord, vAddr ) ? vValue : fragColor; -} - -void StoreVec3( in ivec2 vAddr, in vec3 vValue, inout vec4 fragColor, in ivec2 fragCoord ) -{ - StoreVec4( vAddr, vec4( vValue, 0.0 ), fragColor, fragCoord); -} - -/////////////////////////// -// Camera -/////////////////////////// - -struct CameraState -{ - vec3 vPos; - vec3 vTarget; - float fFov; - vec2 vJitter; - float fPlaneInFocus; -}; - -void Cam_LoadState( out CameraState cam, sampler2D tex, ivec2 addr ) -{ - vec4 vPos = LoadVec4( tex, addr + ivec2(0,0) ); - cam.vPos = vPos.xyz; - vec4 targetFov = LoadVec4( tex, addr + ivec2(1,0) ); - cam.vTarget = targetFov.xyz; - cam.fFov = targetFov.w; - vec4 jitterDof = LoadVec4( tex, addr + ivec2(2,0) ); - cam.vJitter = jitterDof.xy; - cam.fPlaneInFocus = jitterDof.z; -} - -void Cam_StoreState( ivec2 addr, const in CameraState cam, inout vec4 fragColor, in ivec2 fragCoord ) -{ - StoreVec4( addr + ivec2(0,0), vec4( cam.vPos, 0 ), fragColor, fragCoord ); - StoreVec4( addr + ivec2(1,0), vec4( cam.vTarget, cam.fFov ), fragColor, fragCoord ); - StoreVec4( addr + ivec2(2,0), vec4( cam.vJitter, cam.fPlaneInFocus, 0 ), fragColor, fragCoord ); -} - -mat3 Cam_GetWorldToCameraRotMatrix( const CameraState cameraState ) -{ - vec3 vForward = normalize( cameraState.vTarget - cameraState.vPos ); - vec3 vRight = normalize( cross(vec3(0, 1, 0), vForward) ); - vec3 vUp = normalize( cross(vForward, vRight) ); - - return mat3( vRight, vUp, vForward ); -} - -vec2 Cam_GetViewCoordFromUV( const in vec2 vUV ) -{ - vec2 vWindow = vUV * 2.0 - 1.0; - vWindow.x *= iResolution.x / iResolution.y; - - return vWindow; -} - -void Cam_GetCameraRay( const vec2 vUV, const CameraState cam, out vec3 vRayOrigin, out vec3 vRayDir ) -{ - vec2 vView = Cam_GetViewCoordFromUV( vUV ); - vRayOrigin = cam.vPos; - float fPerspDist = 1.0 / tan( radians( cam.fFov ) ); - vRayDir = normalize( Cam_GetWorldToCameraRotMatrix( cam ) * vec3( vView, fPerspDist ) ); -} - -vec2 Cam_GetUVFromWindowCoord( const in vec2 vWindow ) -{ - vec2 vScaledWindow = vWindow; - vScaledWindow.x *= iResolution.y / iResolution.x; - - return (vScaledWindow * 0.5 + 0.5); -} - -vec2 Cam_WorldToWindowCoord(const in vec3 vWorldPos, const in CameraState cameraState ) -{ - vec3 vOffset = vWorldPos - cameraState.vPos; - vec3 vCameraLocal; - - vCameraLocal = vOffset * Cam_GetWorldToCameraRotMatrix( cameraState ); - - vec2 vWindowPos = vCameraLocal.xy / (vCameraLocal.z * tan( radians( cameraState.fFov ) )); - - return vWindowPos; -} - -float EncodeDepthAndObject( float depth, int objectId ) -{ - //depth = max( 0.0, depth ); - //objectId = max( 0, objectId + 1 ); - //return exp2(-depth) + float(objectId); - return depth; -} - -float DecodeDepthAndObjectId( float value, out int objectId ) -{ - objectId = 0; - return max(0.0, value); - //objectId = int( floor( value ) ) - 1; - //return abs( -log2(fract(value)) ); -} - -/////////////////////////////// - - -#define iChannelCurr iChannel0 -#define iChannelHistory iChannel1 - -vec3 Tonemap( vec3 x ) -{ - float a = 0.010; - float b = 0.132; - float c = 0.010; - float d = 0.163; - float e = 0.101; - - return ( x * ( a * x + b ) ) / ( x * ( c * x + d ) + e ); -} - -vec3 TAA_ColorSpace( vec3 color ) -{ - return Tonemap(color); -} - -void main() -{ - CameraState camCurr; - Cam_LoadState( camCurr, iChannelCurr, ivec2(0) ); - - CameraState camPrev; - Cam_LoadState( camPrev, iChannelHistory, ivec2(0) ); - - vec2 vUV = vFragCoord.xy / iResolution.xy; - vec2 vUnJitterUV = vUV - camCurr.vJitter / iResolution.xy; - - FragColor = textureLod(iChannelCurr, vUnJitterUV, 0.0); - - -#ifdef ENABLE_TAA - vec3 vRayOrigin, vRayDir; - Cam_GetCameraRay( vUV, camCurr, vRayOrigin, vRayDir ); - float fDepth; - int iObjectId; - vec4 vCurrTexel = texelFetch( iChannelCurr, ivec2(vFragCoord.xy), 0); - fDepth = DecodeDepthAndObjectId( vCurrTexel.w, iObjectId ); - vec3 vWorldPos = vRayOrigin + vRayDir * fDepth; - - vec2 vPrevUV = Cam_GetUVFromWindowCoord( Cam_WorldToWindowCoord(vWorldPos, camPrev) );// + camPrev.vJitter / iResolution.xy; - - if ( all( greaterThanEqual( vPrevUV, vec2(0) )) && all( lessThan( vPrevUV, vec2(1) )) ) - { - vec3 vMin = vec3( 10000); - vec3 vMax = vec3(-10000); - - ivec2 vCurrXY = ivec2(floor(vFragCoord.xy)); - - int iNeighborhoodSize = 1; - for ( int iy=-iNeighborhoodSize; iy<=iNeighborhoodSize; iy++) - { - for ( int ix=-iNeighborhoodSize; ix<=iNeighborhoodSize; ix++) - { - ivec2 iOffset = ivec2(ix, iy); - vec3 vTest = TAA_ColorSpace( texelFetch( iChannelCurr, vCurrXY + iOffset, 0 ).rgb ); - - vMin = min( vMin, vTest ); - vMax = max( vMax, vTest ); - } - } - - float epsilon = 0.001; - vMin -= epsilon; - vMax += epsilon; - - float fBlend = 0.0f; - - //ivec2 vPrevXY = ivec2(floor(vPrevUV.xy * iResolution.xy)); - vec4 vHistory = textureLod( iChannelHistory, vPrevUV, 0.0 ); - - vec3 vPrevTest = TAA_ColorSpace( vHistory.rgb ); - if( all( greaterThanEqual(vPrevTest, vMin ) ) && all( lessThanEqual( vPrevTest, vMax ) ) ) - { - fBlend = 0.9; - //FragColor.r *= 0.0; - } - - FragColor.rgb = mix( FragColor.rgb, vHistory.rgb, fBlend); - } - else - { - //FragColor.gb *= 0.0; - } - -#endif - - FragColor.rgb += (hash13( vec3( vFragCoord, iGlobalTime ) ) * 2.0 - 1.0) * 0.03; - - Cam_StoreState( ivec2(0), camCurr, FragColor, ivec2(vFragCoord.xy) ); - Cam_StoreState( ivec2(3,0), camPrev, FragColor, ivec2(vFragCoord.xy) ); -} \ No newline at end of file