chg: replicate previous project tree layout
fix: fixed issue when mounting empty zipfiles (likely to happen in computers with many cpu cores) (thanks @zpl-zak!) new: forked milestone in https://github.com/r-lyeh/FWK.2022 chg: update teal + gamecontrollerdb add: added tools/plugins/ stub folder brk: renamed `WITH_` > `ENABLE_` directives chg: updated docsmain
|
@ -0,0 +1,683 @@
|
||||||
|
#!/bin/bash 2>nul || goto :windows
|
||||||
|
|
||||||
|
# linux + osx -----------------------------------------------------------------
|
||||||
|
cd `dirname $0`
|
||||||
|
|
||||||
|
# copy demos to root folder. local changes are preserved
|
||||||
|
# cp -n demos/*.c .
|
||||||
|
|
||||||
|
# rem tests
|
||||||
|
# clang editor.c -I. -lm -lX11 -g -fsanitize=address,undefined && ./a.out
|
||||||
|
# cl editor.c -I. -fsanitize=address /DEBUG /Zi && editor
|
||||||
|
|
||||||
|
# tidy environment
|
||||||
|
if [ "$1" = "tidy" ]; then
|
||||||
|
rm 0?-* 2> /dev/null
|
||||||
|
rm fwk.o 2> /dev/null
|
||||||
|
rm .art*.zip 2> /dev/null
|
||||||
|
rm demos/lua/.art*.zip 2> /dev/null
|
||||||
|
rm demos/html5/.art*.zip 2> /dev/null
|
||||||
|
rm demos/lua/libfwk* 2> /dev/null
|
||||||
|
rm fwk_*.* 2> /dev/null
|
||||||
|
rm 3rd_*.* 2> /dev/null
|
||||||
|
rm libfwk* 2> /dev/null
|
||||||
|
rm -rf *.dSYM 2> /dev/null
|
||||||
|
rm *.png 2> /dev/null
|
||||||
|
rm *.mp4 2> /dev/null
|
||||||
|
rm editor.linux 2> /dev/null
|
||||||
|
rm editor.osx 2> /dev/null
|
||||||
|
rm temp_* 2> /dev/null
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
# shortcuts for split & join amalgamation scripts
|
||||||
|
if [ "$1" = "split" ]; then
|
||||||
|
sh tools/split.bat
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
if [ "$1" = "join" ]; then
|
||||||
|
sh tools/join.bat
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
# cook
|
||||||
|
if [ "$1" = "cook" ]; then
|
||||||
|
cc -o cook tools/cook.c -I.
|
||||||
|
./cook
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
# sync
|
||||||
|
if [ "$1" = "sync" ]; then
|
||||||
|
git reset --hard HEAD^^1 && git pull
|
||||||
|
sh MAKE.bat tidy
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
export dll=dll
|
||||||
|
export build=dev
|
||||||
|
export args=
|
||||||
|
export cc=cc
|
||||||
|
|
||||||
|
while [ $# -ge 1 ]; do
|
||||||
|
if [ "$1" = "help" ]; then
|
||||||
|
echo sh MAKE.bat
|
||||||
|
echo sh MAKE.bat [gcc,clang,tcc] [dbg,dev,rel] [dll,static]
|
||||||
|
echo sh MAKE.bat [tidy]
|
||||||
|
echo sh MAKE.bat [split,join]
|
||||||
|
echo sh MAKE.bat [cook]
|
||||||
|
echo sh MAKE.bat [sln]
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
if [ "$1" = "dll" ]; then
|
||||||
|
export dll=dll
|
||||||
|
fi
|
||||||
|
if [ "$1" = "static" ]; then
|
||||||
|
export dll=static
|
||||||
|
fi
|
||||||
|
if [ "$1" = "dbg" ]; then
|
||||||
|
export build=dbg
|
||||||
|
export flags="-O0 -g"
|
||||||
|
fi
|
||||||
|
if [ "$1" = "dev" ]; then
|
||||||
|
export build=dev
|
||||||
|
export flags="-O1 -g"
|
||||||
|
fi
|
||||||
|
if [ "$1" = "rel" ]; then
|
||||||
|
export build=rel
|
||||||
|
export flags="-O3 -DNDEBUG"
|
||||||
|
fi
|
||||||
|
if [ "$1" = "gcc" ]; then
|
||||||
|
export cc=gcc
|
||||||
|
fi
|
||||||
|
if [ "$1" = "clang" ]; then
|
||||||
|
export cc=clang
|
||||||
|
fi
|
||||||
|
if [ "$1" = "tcc" ]; then
|
||||||
|
export cc="tcc -D__STDC_NO_VLA__"
|
||||||
|
fi
|
||||||
|
if [ "$1" = "sln" ]; then
|
||||||
|
if [ "$(uname)" != "Darwin" ]; then
|
||||||
|
chmod +x tools/premake5.linux
|
||||||
|
tools/premake5.linux gmake
|
||||||
|
tools/premake5.linux ninja
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
if [ "$(uname)" = "Darwin" ]; then
|
||||||
|
chmod +x tools/premake5.osx
|
||||||
|
tools/premake5.osx xcode4
|
||||||
|
tools/premake5.osx ninja
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ "$1" = "--" ]; then
|
||||||
|
shift
|
||||||
|
export args=$*
|
||||||
|
shift $#
|
||||||
|
fi
|
||||||
|
if [ $# -ge 1 ]; then
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$(uname)" != "Darwin" ]; then
|
||||||
|
|
||||||
|
# setup (ArchLinux)
|
||||||
|
[ ! -f ".setup" ] && sudo pacman -S --noconfirm tcc && echo>.setup
|
||||||
|
# setup (Debian, Ubuntu, etc)
|
||||||
|
[ ! -f ".setup" ] && sudo apt-get -y update
|
||||||
|
[ ! -f ".setup" ] && sudo apt-get -y install tcc libx11-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev && echo>.setup # absolute minimum
|
||||||
|
# sudo apt-get -y install clang xorg-dev # memorable, around 100 mib
|
||||||
|
# sudo apt-get -y install clang xorg-dev libglfw3-dev libassimp-dev gcc # initial revision
|
||||||
|
# sudo apt-get -y install ffmpeg || (sudo apt-get install snapd && sudo snap install ffmpeg) # variant
|
||||||
|
|
||||||
|
# pipeline
|
||||||
|
#cc tools/ass2iqe.c -o tools/ass2iqe.linux -lm -ldl -lpthread -w -g -lassimp
|
||||||
|
#cc tools/iqe2iqm.cpp -o tools/iqe2iqm.linux -lm -ldl -lpthread -w -g -lstdc++
|
||||||
|
#cc tools/mid2wav.c -o tools/mid2wav.linux -lm -ldl -lpthread -w -g
|
||||||
|
|
||||||
|
# change permissions of precompiled tools binaries because of 'Permission denied' runtime error (@procedural)
|
||||||
|
chmod +x tools/ass2iqe.linux
|
||||||
|
chmod +x tools/cook.linux
|
||||||
|
chmod +x tools/cuttlefish.linux
|
||||||
|
chmod +x tools/ffmpeg.linux
|
||||||
|
chmod +x tools/furnace.linux
|
||||||
|
chmod +x tools/iqe2iqm.linux
|
||||||
|
chmod +x tools/mid2wav.linux
|
||||||
|
chmod +x tools/mod2wav.linux
|
||||||
|
chmod +x tools/PVRTexToolCLI.linux
|
||||||
|
chmod +x tools/sfxr2wav.linux
|
||||||
|
chmod +x tools/xlsx2ini.linux
|
||||||
|
chmod +x tools/premake5.linux
|
||||||
|
chmod +x tools/ninja.linux
|
||||||
|
chmod +x demos/lua/luajit.linux
|
||||||
|
|
||||||
|
echo build=$build, type=$dll, cc=$cc, args=$args
|
||||||
|
|
||||||
|
# framework (as dynamic library)
|
||||||
|
if [ "$dll" = "dll" ]; then
|
||||||
|
echo libfwk.so && $cc -o libfwk.so engine/fwk.c -shared -fPIC -w -lX11 -lm -ldl -lpthread $flags $args
|
||||||
|
cp libfwk.so demos/lua/
|
||||||
|
export import="libfwk.so -Wl,-rpath,./"
|
||||||
|
else
|
||||||
|
# framework (static)
|
||||||
|
echo fwk && $cc -c engine/fwk.c -w $flags $args
|
||||||
|
export import=fwk.o
|
||||||
|
fi
|
||||||
|
|
||||||
|
# editor
|
||||||
|
# echo editor && $cc -o editor.linux tools/editor/editor.c -lm -ldl -lpthread -lX11 -w -Iengine/ $flags $import $args &
|
||||||
|
|
||||||
|
# demos
|
||||||
|
echo hello && $cc -o hello hello.c -lm -ldl -lpthread -lX11 -w -Iengine/ $flags $args &
|
||||||
|
# echo 00-ui && $cc -o 00-ui demos/00-ui.c -lm -ldl -lpthread -lX11 -w -Iengine/ $flags $import $args &
|
||||||
|
# echo 01-sprite && $cc -o 01-sprite demos/01-sprite.c -lm -ldl -lpthread -lX11 -w -Iengine/ $flags $import $args &
|
||||||
|
# echo 02-ddraw && $cc -o 02-ddraw demos/02-ddraw.c -lm -ldl -lpthread -lX11 -w -Iengine/ $flags $import $args &
|
||||||
|
# echo 03-anims && $cc -o 03-anims demos/03-anims.c -lm -ldl -lpthread -lX11 -w -Iengine/ $flags $import $args &
|
||||||
|
# echo 04-actor && $cc -o 04-actor demos/04-actor.c -lm -ldl -lpthread -lX11 -w -Iengine/ $flags $import $args &
|
||||||
|
# echo 04-controller && $cc -o 04-controller demos/04-controller.c -lm -ldl -lpthread -lX11 -w -Iengine/ $flags $import $args &
|
||||||
|
# echo 05-scene && $cc -o 05-scene demos/05-scene.c -lm -ldl -lpthread -lX11 -w -Iengine/ $flags $import $args &
|
||||||
|
# echo 06-pbr && $cc -o 06-pbr demos/06-pbr.c -lm -ldl -lpthread -lX11 -w -Iengine/ $flags $import $args &
|
||||||
|
# echo 07-network && $cc -o 07-network demos/07-network.c -lm -ldl -lpthread -lX11 -w -Iengine/ $flags $import $args
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$(uname)" = "Darwin" ]; then
|
||||||
|
# setup (osx)
|
||||||
|
export SDKROOT=$(xcrun --show-sdk-path)
|
||||||
|
# brew install glfw
|
||||||
|
|
||||||
|
# pipeline
|
||||||
|
#cc tools/ass2iqe.c -o tools/ass2iqe.osx -w -g -lassimp
|
||||||
|
#cc tools/iqe2iqm.cpp -o tools/iqe2iqm.osx -w -g -lstdc++
|
||||||
|
#cc tools/mid2wav.c -o tools/mid2wav.osx -w -g
|
||||||
|
|
||||||
|
# change permissions of precompiled tools binaries because of 'Permission denied' runtime error (@procedural)
|
||||||
|
chmod +x tools/ass2iqe.osx
|
||||||
|
chmod +x tools/cook.osx
|
||||||
|
chmod +x tools/cuttlefish.osx
|
||||||
|
chmod +x tools/ffmpeg.osx
|
||||||
|
chmod +x tools/furnace.osx
|
||||||
|
chmod +x tools/iqe2iqm.osx
|
||||||
|
chmod +x tools/mid2wav.osx
|
||||||
|
chmod +x tools/mod2wav.osx
|
||||||
|
chmod +x tools/PVRTexToolCLI.osx
|
||||||
|
chmod +x tools/sfxr2wav.osx
|
||||||
|
chmod +x tools/xlsx2ini.osx
|
||||||
|
chmod +x tools/premake5.osx
|
||||||
|
chmod +x tools/ninja.osx
|
||||||
|
chmod +x demos/lua/luajit.osx
|
||||||
|
|
||||||
|
echo build=$build, type=$dll, cc=$cc, args=$args
|
||||||
|
|
||||||
|
# framework (as dynamic library)
|
||||||
|
if [ "$dll" = "dll" ]; then
|
||||||
|
echo libfwk && cc -ObjC -dynamiclib -o libfwk.dylib engine/fwk.c -framework cocoa -framework iokit -framework audiotoolbox -w $flags $args
|
||||||
|
cp libfwk.dylib demos/lua
|
||||||
|
export import=libfwk.dylib
|
||||||
|
else
|
||||||
|
# framework
|
||||||
|
echo fwk && cc -c -ObjC engine/fwk.c -w $flags $args
|
||||||
|
export import=fwk.o
|
||||||
|
fi
|
||||||
|
|
||||||
|
# editor
|
||||||
|
# echo editor && cc -o editor.osx -ObjC tools/editor/editor.c -w -Iengine/ $import $flags $args -framework cocoa -framework iokit -framework audiotoolbox &
|
||||||
|
|
||||||
|
# demos
|
||||||
|
echo hello && cc -o hello -ObjC hello.c -w -Iengine/ $flags $args -framework cocoa -framework iokit -framework audiotoolbox &
|
||||||
|
# echo 00-ui && cc -o 00-ui demos/00-ui.c -w -Iengine/ $import $flags $args -framework cocoa -framework iokit -framework audiotoolbox &
|
||||||
|
# echo 01-sprite && cc -o 01-sprite demos/01-sprite.c -w -Iengine/ $import $flags $args -framework cocoa -framework iokit -framework audiotoolbox &
|
||||||
|
# echo 02-ddraw && cc -o 02-ddraw demos/02-ddraw.c -w -Iengine/ $import $flags $args -framework cocoa -framework iokit -framework audiotoolbox &
|
||||||
|
# echo 03-anims && cc -o 03-anims demos/03-anims.c -w -Iengine/ $import $flags $args -framework cocoa -framework iokit -framework audiotoolbox &
|
||||||
|
# echo 04-actor && cc -o 04-actor demos/04-actor.c -w -Iengine/ $import $flags $args -framework cocoa -framework iokit -framework audiotoolbox &
|
||||||
|
# echo 04-controller && cc -o 04-controller demos/04-controller.c -w -Iengine/ $import $flags $args -framework cocoa -framework iokit -framework audiotoolbox &
|
||||||
|
# echo 05-scene && cc -o 05-scene demos/05-scene.c -w -Iengine/ $import $flags $args -framework cocoa -framework iokit -framework audiotoolbox &
|
||||||
|
# echo 06-pbr && cc -o 06-pbr demos/06-pbr.c -w -Iengine/ $import $flags $args -framework cocoa -framework iokit -framework audiotoolbox &
|
||||||
|
# echo 07-network && cc -o 07-network demos/07-network.c -w -Iengine/ $import $flags $args -framework cocoa -framework iokit -framework audiotoolbox
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit
|
||||||
|
|
||||||
|
|
||||||
|
:: -----------------------------------------------------------------------------
|
||||||
|
:windows
|
||||||
|
|
||||||
|
@echo off
|
||||||
|
setlocal enableDelayedExpansion
|
||||||
|
cd /d "%~dp0"
|
||||||
|
|
||||||
|
rem show help
|
||||||
|
if "%1"=="-?" goto showhelp
|
||||||
|
if "%1"=="-h" goto showhelp
|
||||||
|
if "%1"=="help" (
|
||||||
|
:showhelp
|
||||||
|
echo %0 ; compile everything: `make dll dev` alias
|
||||||
|
echo %0 [help] ; show this screen
|
||||||
|
echo %0 [docs] ; generate tools/docs/docs.html file
|
||||||
|
echo %0 [cook] ; cook .zipfiles with tools/cook.ini cookbook
|
||||||
|
echo %0 [sync] ; sync repo to latest
|
||||||
|
echo %0 [tidy] ; clean up temp files
|
||||||
|
echo %0 [bindings] ; generate demos/lua bindings
|
||||||
|
echo %0 [checkmem] ; check untracked allocators in FWK
|
||||||
|
echo %0 [split^|join] ; engine/fwk* ^>split^> engine/split/* or engine/split/* ^>join^> engine/fwk*
|
||||||
|
echo %0 [amalgamation] ; combine engine/fwk* into a single-header file
|
||||||
|
echo %0 [sln] ; generate a xcode/gmake/ninja/visual studio solution
|
||||||
|
echo %0 [cl^|tcc^|cc^|gcc^|clang^|clang-cl] [dbg^|dev^|rel] [static^|dll] [nofwk^|nodemos^|noeditor] [vis] [-- args]
|
||||||
|
echo cl \
|
||||||
|
echo tcc ^|
|
||||||
|
echo cc ^| select compiler. must be accessible in PATH
|
||||||
|
echo gcc ^| (will be autodetected when no option is provided^)
|
||||||
|
echo clang ^|
|
||||||
|
echo clang-cl /
|
||||||
|
echo dbg \ debug build: [x] ASAN [x] poison [x] asserts [x] profiler [x] symbols [ ] zero optimizations
|
||||||
|
echo dev ^| develop build: [ ] ASAN [x] poison [x] asserts [x] profiler [x] symbols [*] some optimizations (default^)
|
||||||
|
echo rel / release build: [ ] ASAN [ ] poison [ ] asserts [ ] profiler [x] symbols (cl,clang-cl only^) [x] many optimizations
|
||||||
|
echo static \ link fwk as static library
|
||||||
|
echo dll / link fwk as dynamic library (dll^) (default^)
|
||||||
|
echo nofwk \ do not compile framework
|
||||||
|
echo nodemos ^| do not compile demos
|
||||||
|
echo noeditor / do not compile editor
|
||||||
|
echo vis ^> visualize invokation cmdline.
|
||||||
|
echo args ^> after `--` separator is found, pass all remaining arguments to compiler as-is
|
||||||
|
echo.
|
||||||
|
exit /b
|
||||||
|
)
|
||||||
|
|
||||||
|
rem sync repo to latest
|
||||||
|
if "%1"=="sync" (
|
||||||
|
call MAKE.bat tidy
|
||||||
|
git reset --hard HEAD~1 && git pull
|
||||||
|
exit /b
|
||||||
|
)
|
||||||
|
|
||||||
|
rem cook asset files
|
||||||
|
if "%1"=="cook" (
|
||||||
|
rem generate cooker twice: use multi-threaded version if available (cl). then cook.
|
||||||
|
rem call tools\tcc tools\cook.c -Iengine engine\fwk.c
|
||||||
|
rem cl tools\cook.c -Iengine engine\fwk.c
|
||||||
|
rem cook
|
||||||
|
tools\cook
|
||||||
|
|
||||||
|
exit /b
|
||||||
|
)
|
||||||
|
rem generate bindings
|
||||||
|
if "%1"=="bindings" (
|
||||||
|
rem luajit
|
||||||
|
tools\luajit tools\luajit_make_bindings.lua > fwk.lua
|
||||||
|
move /y fwk.lua demos\lua
|
||||||
|
|
||||||
|
exit /b
|
||||||
|
)
|
||||||
|
rem generate documentation
|
||||||
|
if "%1"=="docs" (
|
||||||
|
rem set symbols...
|
||||||
|
git describe --tags --abbrev=0 > info.obj
|
||||||
|
set /p VERSION=<info.obj
|
||||||
|
git rev-list --count --first-parent HEAD > info.obj
|
||||||
|
set /p GIT_REVISION=<info.obj
|
||||||
|
git rev-parse --abbrev-ref HEAD > info.obj
|
||||||
|
set /p GIT_BRANCH=<info.obj
|
||||||
|
date /t > info.obj
|
||||||
|
set /p LAST_MODIFIED=<info.obj
|
||||||
|
|
||||||
|
rem ...and generate docs
|
||||||
|
cl tools\docs\docs.c engine\fwk.c -Iengine %2
|
||||||
|
docs engine\fwk.h --excluded=3rd_glad.h,fwk.h,fwk_compat.h, > fwk.html
|
||||||
|
move /y fwk.html engine\
|
||||||
|
|
||||||
|
exit /b
|
||||||
|
)
|
||||||
|
rem generate single-header distribution
|
||||||
|
if "%1"=="amalgamation" (
|
||||||
|
echo // This file is intended to be consumed by a compiler. Do not read. > fwk.h
|
||||||
|
echo // **Browse to any of the sources in engine/split/ folder instead** >> fwk.h
|
||||||
|
echo // ---------------------------------------------------------------- >> fwk.h
|
||||||
|
echo // #define FWK_IMPLEMENTATION early in **one** C file to unroll the >> fwk.h
|
||||||
|
echo // implementation. The symbol must be defined in a C (not C++^) file>> fwk.h
|
||||||
|
echo // ---------------------------------------------------------------- >> fwk.h
|
||||||
|
echo #pragma once >> fwk.h
|
||||||
|
type engine\split\3rd_font_md.h >> fwk.h
|
||||||
|
type engine\split\3rd_glad.h >> fwk.h
|
||||||
|
type engine\fwk.h >> fwk.h
|
||||||
|
echo #ifdef FWK_IMPLEMENTATION >> fwk.h
|
||||||
|
echo #define FWK_3RD >> fwk.h
|
||||||
|
type engine\fwk >> fwk.h
|
||||||
|
type engine\fwk.c >> fwk.h
|
||||||
|
echo #endif // FWK_IMPLEMENTATION >> fwk.h
|
||||||
|
move /y fwk.h engine\joint
|
||||||
|
exit /b
|
||||||
|
)
|
||||||
|
|
||||||
|
rem generate prior files to a github release
|
||||||
|
if "%1"=="github" (
|
||||||
|
rem call make.bat dll
|
||||||
|
call make.bat docs
|
||||||
|
call make.bat bindings
|
||||||
|
|
||||||
|
call make.bat amalgamation
|
||||||
|
call make.bat split
|
||||||
|
|
||||||
|
rem rd /q /s engine\split
|
||||||
|
rem md engine\split
|
||||||
|
rem move /y fwk_*.? engine\split\
|
||||||
|
rem move /y 3rd_*.? engine\split\
|
||||||
|
|
||||||
|
call make.bat tidy
|
||||||
|
|
||||||
|
exit /b
|
||||||
|
)
|
||||||
|
|
||||||
|
rem shortcuts for split & join amalgamation scripts
|
||||||
|
if "%1"=="split" (
|
||||||
|
call tools\split
|
||||||
|
exit /b
|
||||||
|
)
|
||||||
|
if "%1"=="join" (
|
||||||
|
call tools\join
|
||||||
|
exit /b
|
||||||
|
)
|
||||||
|
|
||||||
|
rem check memory api calls
|
||||||
|
if "%1"=="checkmem" (
|
||||||
|
findstr /RNC:"[^_xv]realloc[(]" engine\fwk.c engine\split\fwk*
|
||||||
|
findstr /RNC:"[^_xv]malloc[(]" engine\fwk.c engine\split\fwk*
|
||||||
|
findstr /RNC:"[^_xv]free[(]" engine\fwk.c engine\split\fwk*
|
||||||
|
findstr /RNC:"[^_xv]calloc[(]" engine\fwk.c engine\split\fwk*
|
||||||
|
findstr /RNC:"[^_xv]strdup[(]" engine\fwk.c engine\split\fwk*
|
||||||
|
exit /b
|
||||||
|
)
|
||||||
|
|
||||||
|
rem copy demos to root folder. local changes are preserved
|
||||||
|
rem echo n | copy /-y demos\*.c 1> nul 2> nul
|
||||||
|
|
||||||
|
rem tidy environment
|
||||||
|
if "%1"=="tidy" (
|
||||||
|
move /y ??-*.png demos > nul 2> nul
|
||||||
|
move /y ??-*.c demos > nul 2> nul
|
||||||
|
del demos\lua\fwk.dll > nul 2> nul
|
||||||
|
del .temp*.* > nul 2> nul
|
||||||
|
del *.zip > nul 2> nul
|
||||||
|
del *.mem > nul 2> nul
|
||||||
|
del *.exp > nul 2> nul
|
||||||
|
del *.lib > nul 2> nul
|
||||||
|
del *.exe > nul 2> nul
|
||||||
|
del *.obj > nul 2> nul
|
||||||
|
del *.o > nul 2> nul
|
||||||
|
del *.a > nul 2> nul
|
||||||
|
del *.pdb > nul 2> nul
|
||||||
|
del *.ilk > nul 2> nul
|
||||||
|
del *.png > nul 2> nul
|
||||||
|
del *.mp4 > nul 2> nul
|
||||||
|
del *.def > nul 2> nul
|
||||||
|
del *.dll > nul 2> nul
|
||||||
|
del 3rd_*.* > nul 2> nul
|
||||||
|
del fwk_*.* > nul 2> nul
|
||||||
|
rem del ??-*.* > nul 2> nul
|
||||||
|
del temp_*.* > nul 2> nul
|
||||||
|
rd /q /s .vs > nul 2> nul
|
||||||
|
rd /q /s _debug > nul 2> nul
|
||||||
|
rd /q /s _devel > nul 2> nul
|
||||||
|
rd /q /s _release > nul 2> nul
|
||||||
|
rem rd /q /s _project > nul 2> nul
|
||||||
|
del tcc.bat > nul 2> nul
|
||||||
|
del sh.bat > nul 2> nul
|
||||||
|
exit /b
|
||||||
|
)
|
||||||
|
|
||||||
|
set cc=%cc%
|
||||||
|
set dll=dll
|
||||||
|
set build=dev
|
||||||
|
set args=-Iengine
|
||||||
|
set other=
|
||||||
|
set fwk=yes
|
||||||
|
set demos=yes
|
||||||
|
set editor=yes
|
||||||
|
set vis=no
|
||||||
|
set sln=no
|
||||||
|
set rc=0
|
||||||
|
|
||||||
|
:parse_args
|
||||||
|
if "%1"=="--" shift && goto parse_compiler_args
|
||||||
|
|
||||||
|
if "%1"=="dll" set "dll=%1" && goto loop
|
||||||
|
if "%1"=="static" set "dll=%1" && goto loop
|
||||||
|
|
||||||
|
if "%1"=="dbg" set "build=%1" && goto loop
|
||||||
|
if "%1"=="dev" set "build=%1" && goto loop
|
||||||
|
if "%1"=="rel" set "build=%1" && goto loop
|
||||||
|
|
||||||
|
if "%1"=="debug" set "build=dbg" && goto loop
|
||||||
|
if "%1"=="devel" set "build=dev" && goto loop
|
||||||
|
if "%1"=="develop" set "build=dev" && goto loop
|
||||||
|
if "%1"=="developer" set "build=dev" && goto loop
|
||||||
|
if "%1"=="development" set "build=dev" && goto loop
|
||||||
|
if "%1"=="release" set "build=rel" && goto loop
|
||||||
|
|
||||||
|
if "%1"=="vis" set "vis=yes" && goto loop
|
||||||
|
|
||||||
|
if "%1"=="nofwk" set "fwk=no" && goto loop
|
||||||
|
if "%1"=="nodemos" set "demos=no" && goto loop
|
||||||
|
if "%1"=="noeditor" set "editor=no" && goto loop
|
||||||
|
|
||||||
|
if "%1"=="tcc" set "cc=%1" && goto loop
|
||||||
|
if "%1"=="cl" set "cc=%1" && goto loop
|
||||||
|
if "%1"=="vc" set "cc=cl" && goto loop
|
||||||
|
if "%1"=="cc" set "cc=%1" && goto loop
|
||||||
|
if "%1"=="gcc" set "cc=%1" && goto loop
|
||||||
|
if "%1"=="clang" set "cc=%1" && goto loop
|
||||||
|
if "%1"=="clang-cl" set "cc=%1" && goto loop
|
||||||
|
|
||||||
|
if "%1"=="sln" set "sln=yes" && goto loop
|
||||||
|
|
||||||
|
if not "%1"=="" set "other=!other! %1" && set "editor=no" && set "demos=no"
|
||||||
|
|
||||||
|
:loop
|
||||||
|
if not "%1"=="" shift && goto parse_args
|
||||||
|
|
||||||
|
:parse_compiler_args
|
||||||
|
if not "%1"=="" set "args=!args! %1" && shift && goto parse_compiler_args
|
||||||
|
|
||||||
|
set vs=00
|
||||||
|
rem detect setup
|
||||||
|
if "!cc!"=="" (
|
||||||
|
echo Detecting VS 2022/2019/2017/2015/2013 x64 ...
|
||||||
|
set cc=cl
|
||||||
|
if exist "%VS170COMNTOOLS%/../../VC/Auxiliary/Build/vcvarsx86_amd64.bat" (
|
||||||
|
@call "%VS170COMNTOOLS%/../../VC/Auxiliary/Build/vcvarsx86_amd64.bat" > nul && set "vs=22"
|
||||||
|
) else if exist "%VS160COMNTOOLS%/../../VC/Auxiliary/Build/vcvarsx86_amd64.bat" (
|
||||||
|
@call "%VS160COMNTOOLS%/../../VC/Auxiliary/Build/vcvarsx86_amd64.bat" > nul && set "vs=19"
|
||||||
|
) else if exist "%VS150COMNTOOLS%/../../VC/Auxiliary/Build/vcvarsx86_amd64.bat" (
|
||||||
|
@call "%VS150COMNTOOLS%/../../VC/Auxiliary/Build/vcvarsx86_amd64.bat" > nul && set "vs=17"
|
||||||
|
) else if exist "%VS140COMNTOOLS%/../../VC/bin/x86_amd64/vcvarsx86_amd64.bat" (
|
||||||
|
@call "%VS140COMNTOOLS%/../../VC/bin/x86_amd64/vcvarsx86_amd64.bat" > nul && set "vs=15"
|
||||||
|
) else if exist "%VS120COMNTOOLS%/../../VC/bin/x86_amd64/vcvarsx86_amd64.bat" (
|
||||||
|
@call "%VS120COMNTOOLS%/../../VC/bin/x86_amd64/vcvarsx86_amd64.bat" > nul && set "vs=13"
|
||||||
|
) else if exist "%ProgramFiles%/microsoft visual studio/2022/community/VC/Auxiliary/Build/vcvarsx86_amd64.bat" (
|
||||||
|
@call "%ProgramFiles%/microsoft visual studio/2022/community/VC/Auxiliary/Build/vcvarsx86_amd64.bat" > nul && set "vs=22"
|
||||||
|
) else if exist "%ProgramFiles(x86)%/microsoft visual studio/2019/community/VC/Auxiliary/Build/vcvarsx86_amd64.bat" (
|
||||||
|
@call "%ProgramFiles(x86)%/microsoft visual studio/2019/community/VC/Auxiliary/Build/vcvarsx86_amd64.bat" > nul && set "vs=19"
|
||||||
|
) else if exist "%ProgramFiles(x86)%/microsoft visual studio/2017/community/VC/Auxiliary/Build/vcvarsx86_amd64.bat" (
|
||||||
|
@call "%ProgramFiles(x86)%/microsoft visual studio/2017/community/VC/Auxiliary/Build/vcvarsx86_amd64.bat" > nul && set "vs=17"
|
||||||
|
) else (
|
||||||
|
echo Detecting Mingw64 ...
|
||||||
|
set cc=gcc
|
||||||
|
where /q gcc.exe || ( echo Detecting TCC ... && set "cc=tcc" )
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
rem solution. @todo: lin/osx
|
||||||
|
if "!sln!"=="yes" if not "%vs%"=="" pushd tools && premake5 vs20%vs% & popd
|
||||||
|
if "!sln!"=="yes" pushd tools && premake5 ninja & popd
|
||||||
|
if "!sln!"=="yes" pushd tools && premake5 gmake & popd & exit /b
|
||||||
|
|
||||||
|
rem --- pipeline
|
||||||
|
rem cl tools/ass2iqe.c /Fetools/ass2iqe.exe /nologo /openmp /O2 /Oy /MT /DNDEBUG assimp.lib
|
||||||
|
rem cl tools/iqe2iqm.cpp /Fetools/iqe2iqm.exe /nologo /openmp /O2 /Oy /MT /DNDEBUG
|
||||||
|
rem cl tools/mid2wav.c /Fetools/mid2wav.exe /nologo /openmp /O2 /Oy /MT /DNDEBUG
|
||||||
|
rem cl tools/xml2json.c /Fetools/xml2json.exe /nologo /openmp /O2 /Oy /MT /DNDEBUG
|
||||||
|
rem --- pipeline
|
||||||
|
rem gcc tools/ass2iqe.c -o tools/ass2iqe.exe -w -lassimp
|
||||||
|
rem gcc tools/iqe2iqm.cpp -o tools/iqe2iqm.exe -w -lstdc++
|
||||||
|
rem gcc tools/mid2wav.c -o tools/mid2wav.exe -w
|
||||||
|
rem gcc tools/xml2json.c -o tools/xml2json.exe -w
|
||||||
|
rem --- different strategies for release builds
|
||||||
|
rem 4.6s 6.9MiB (default)
|
||||||
|
rem 33.7s 6.6MiB /Ox /Oy /MT /DNDEBUG
|
||||||
|
rem 35.8s 5.3MiB /O2 /Oy /MT /DNDEBUG
|
||||||
|
rem 17.9s 4.6MiB /O1 /MT /DNDEBUG /GL /GF /arch:AVX2
|
||||||
|
rem 17.8s 4.6MiB /Os /Ox /O2 /Oy /MT /DNDEBUG /GL /GF /arch:AVX2
|
||||||
|
rem 18.8s 4.6MiB /Os /Ox /O2 /Oy /MT /DNDEBUG /GL /GF /Gw /link /OPT:ICF /LTCG
|
||||||
|
rem 18.0s 4.6MiB /openmp /Os /Ox /O2 /Oy /MT /DNDEBUG /GL /GF /Gw /arch:AVX2 /link /OPT:ICF /LTCG
|
||||||
|
|
||||||
|
if "!cc!"=="cl" (
|
||||||
|
|
||||||
|
if "!dll!"=="static" (
|
||||||
|
set export=/c
|
||||||
|
set import=fwk.obj
|
||||||
|
) else (
|
||||||
|
set export=/DAPI=EXPORT /LD
|
||||||
|
set import=/DAPI=IMPORT fwk.lib
|
||||||
|
)
|
||||||
|
|
||||||
|
if "!build!"=="rel" (
|
||||||
|
set args=/nologo /Zi /MT /openmp /DNDEBUG !args! /Os /Ox /O2 /Oy /GL /GF /Gw /arch:AVX2 /link /OPT:ICF /LTCG
|
||||||
|
)
|
||||||
|
if "!build!"=="dev" (
|
||||||
|
set args=/nologo /Zi /MT /openmp /DEBUG !args! && REM /Os /Ox /O2 /Oy /GL /GF /Gw /arch:AVX2
|
||||||
|
)
|
||||||
|
if "!build!"=="dbg" (
|
||||||
|
set args=/nologo /Zi /MT /DEBUG !args! /Od /fsanitize=address
|
||||||
|
rem make -- /RTC1, or make -- /Zi /fsanitize=address /DEBUG
|
||||||
|
)
|
||||||
|
|
||||||
|
set o=/Fe:
|
||||||
|
set echo=REM
|
||||||
|
|
||||||
|
) else if "!cc!"=="clang-cl" (
|
||||||
|
|
||||||
|
if "!dll!"=="static" (
|
||||||
|
set export=/c
|
||||||
|
set import=fwk.obj
|
||||||
|
) else (
|
||||||
|
set export=/DAPI=EXPORT /LD
|
||||||
|
set import=/DAPI=IMPORT fwk.lib
|
||||||
|
)
|
||||||
|
|
||||||
|
set warnings_fwkc=-Wno-deprecated-declarations -Wno-tautological-constant-out-of-range-compare
|
||||||
|
set warnings_demos=-Wno-empty-body -Wno-format-security -Wno-pointer-sign
|
||||||
|
set warnings=!warnings_fwkc! !warnings_demos!
|
||||||
|
|
||||||
|
if "!build!"=="rel" (
|
||||||
|
set args=!warnings! /nologo /Zi /MT /openmp /DNDEBUG !args! /Os /Ox /O2 /Oy /GF /Gw /arch:AVX2
|
||||||
|
)
|
||||||
|
if "!build!"=="dev" (
|
||||||
|
set args=!warnings! /nologo /Zi /MT /openmp /DEBUG !args! && REM /Os /Ox /O2 /Oy /GF /Gw /arch:AVX2
|
||||||
|
)
|
||||||
|
if "!build!"=="dbg" (
|
||||||
|
set args=!warnings! /nologo /Zi /MT /DEBUG !args! /Od /fsanitize=address
|
||||||
|
)
|
||||||
|
|
||||||
|
set o=-o
|
||||||
|
set echo=echo
|
||||||
|
|
||||||
|
) else if "!cc!"=="tcc" (
|
||||||
|
|
||||||
|
if "!dll!"=="static" (
|
||||||
|
set export=-c
|
||||||
|
set import=fwk.o
|
||||||
|
) else (
|
||||||
|
set export=-DAPI=EXPORT -shared
|
||||||
|
set import=-DAPI=IMPORT fwk.def
|
||||||
|
)
|
||||||
|
|
||||||
|
if "!build!"=="rel" (
|
||||||
|
set args=-O3 -DNDEBUG !args!
|
||||||
|
)
|
||||||
|
if "!build!"=="dev" (
|
||||||
|
set args=-O2 -g !args!
|
||||||
|
)
|
||||||
|
if "!build!"=="dbg" (
|
||||||
|
set args=-O0 -g !args!
|
||||||
|
)
|
||||||
|
|
||||||
|
set o=-o
|
||||||
|
set echo=echo
|
||||||
|
|
||||||
|
) else ( rem if "!cc!"=="gcc" or "clang"
|
||||||
|
|
||||||
|
set libs=-lws2_32 -lgdi32 -lwinmm -ldbghelp -lole32 -lshell32 -lcomdlg32
|
||||||
|
|
||||||
|
if "!dll!"=="static" (
|
||||||
|
set export=-c
|
||||||
|
set import=fwk.o !libs! -Wl,--allow-multiple-definition
|
||||||
|
) else (
|
||||||
|
set export=-DAPI=EXPORT -shared -o fwk.dll !libs! -Wl,--out-implib,fwk.a
|
||||||
|
set import=-DAPI=IMPORT fwk.a
|
||||||
|
)
|
||||||
|
|
||||||
|
set args=-Wno-implicit-function-declaration !args!
|
||||||
|
|
||||||
|
if "!build!"=="rel" (
|
||||||
|
rem @todo see: https://stackoverflow.com/questions/866721/how-to-generate-gcc-debug-symbol-outside-the-build-target
|
||||||
|
set args=-O3 -DNDEBUG !args!
|
||||||
|
)
|
||||||
|
if "!build!"=="dev" (
|
||||||
|
set args=-g -O1 !args!
|
||||||
|
)
|
||||||
|
if "!build!"=="dbg" (
|
||||||
|
set args=-g -O0 !args!
|
||||||
|
)
|
||||||
|
|
||||||
|
set o=-o
|
||||||
|
set echo=echo
|
||||||
|
)
|
||||||
|
|
||||||
|
echo build=!build!, type=!dll!, cc=!cc!, other=!other!, args=!args!
|
||||||
|
echo import=!import!, export=!export!
|
||||||
|
|
||||||
|
if "!cc!"=="tcc" set "cc=call tools\tcc"
|
||||||
|
|
||||||
|
rem detect wether user-defined sources use single-header distro
|
||||||
|
rem if so, remove API=IMPORT flags and also do not produce fwk.dll by default
|
||||||
|
if not "!other!"=="" (
|
||||||
|
>nul find "FWK_IMPLEMENTATION" !other! && (
|
||||||
|
set import=
|
||||||
|
set fwk=no
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
rem framework
|
||||||
|
if "!fwk!"=="yes" (
|
||||||
|
if "!vis!"=="yes" echo !cc! engine\fwk.c !export! !args! ^&^& if "!dll!"=="dll" copy /y fwk.dll demos\lua ^> nul
|
||||||
|
!echo! fwk && !cc! engine\fwk.c !export! !args! && if "!dll!"=="dll" copy /y fwk.dll demos\lua > nul || set rc=1
|
||||||
|
)
|
||||||
|
|
||||||
|
rem editor
|
||||||
|
if "!editor!"=="yes" (
|
||||||
|
set edit=-DCOOK_ON_DEMAND -DUI_LESSER_SPACING -DUI_ICONS_SMALL
|
||||||
|
if "!vis!"=="yes" echo !cc! !o! editor.exe tools\editor\editor.c !edit! !import! !args!
|
||||||
|
rem !echo! editor && !cc! !o! editor.exe tools\editor\editor.c !edit! !import! !args! || set rc=1
|
||||||
|
rem !echo! editor2 && !cc! !o! editor2.exe tools\editor\editor2.c !edit! !args! || set rc=1
|
||||||
|
)
|
||||||
|
|
||||||
|
rem demos
|
||||||
|
if "!demos!"=="yes" (
|
||||||
|
!echo! hello && !cc! !o! hello.exe hello.c !args! || set rc=1
|
||||||
|
rem !echo! 00-ui && !cc! !o! 00-ui.exe demos\00-ui.c !import! !args! || set rc=1
|
||||||
|
rem !echo! 01-sprite && !cc! !o! 01-sprite.exe demos\01-sprite.c !import! !args! || set rc=1
|
||||||
|
rem !echo! 02-ddraw && !cc! !o! 02-ddraw.exe demos\02-ddraw.c !import! !args! || set rc=1
|
||||||
|
rem !echo! 03-anims && !cc! !o! 03-anims.exe demos\03-anims.c !import! !args! || set rc=1
|
||||||
|
rem !echo! 04-actor && !cc! !o! 04-actor.exe demos\04-actor.c !import! !args! || set rc=1
|
||||||
|
rem !echo! 04-controller && !cc! !o! 04-controller.exe demos\04-controller.c !import! !args! || set rc=1
|
||||||
|
rem !echo! 05-scene && !cc! !o! 05-scene.exe demos\05-scene.c !import! !args! || set rc=1
|
||||||
|
rem !echo! 06-pbr && !cc! !o! 06-pbr.exe demos\06-pbr.c !import! !args! || set rc=1
|
||||||
|
rem !echo! 07-network && !cc! !o! 07-network.exe demos\07-network.c !import! !args! || set rc=1
|
||||||
|
)
|
||||||
|
|
||||||
|
rem user-defined apps
|
||||||
|
if not "!other!"=="" (
|
||||||
|
if "!vis!"=="yes" echo !cc! !other! !import! !args!
|
||||||
|
!echo! !other! && !cc! !other! !import! !args! || set rc=1
|
||||||
|
)
|
||||||
|
|
||||||
|
rem PAUSE only if double-clicked from Windows explorer
|
||||||
|
(((echo.%cmdcmdline%)|%WINDIR%\system32\find.exe /I "%~0")>nul)&&pause
|
||||||
|
|
||||||
|
cmd /c exit !rc!
|
|
@ -0,0 +1,308 @@
|
||||||
|
<h1 align="center"><a href="https://bit.ly/-f-w-k-">F·W·K</a></h1>
|
||||||
|
<p align="center">
|
||||||
|
3D game framework in C.<br/>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img src="https://i.imgur.com/sInbRoA.gif"/><br/>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## Goals
|
||||||
|
- [x] ~~C++~~. C.
|
||||||
|
- [x] ~~Fast~~. Naive.
|
||||||
|
- [x] ~~Modern~~. Simple.
|
||||||
|
- [x] ~~Full featured~~. Small.
|
||||||
|
- [x] ~~Rich build system~~. Single file.
|
||||||
|
- [x] ~~Royaltie fee~~. Free and unlicensed.
|
||||||
|
|
||||||
|
## Features ᕦ(ᐛ)ᕤ
|
||||||
|
- [x] Pipeline: configurable and integrated [asset pipeline](tools/cook.ini).
|
||||||
|
- [x] Embedded: single-file header, all dependencies included.
|
||||||
|
- [x] Compiler: MSVC, MINGW64, TCC, GCC, clang, clang-cl and emscripten.
|
||||||
|
- [x] Linkage: Both static linkage and dynamic .dll/.so/.dylib support.
|
||||||
|
- [x] Platform: Windows, Linux and OSX. Partial HTML5/Web support.
|
||||||
|
- [x] DS: hash, sort, array/vector, map, set.
|
||||||
|
- [x] Math: rand, noise, ease, vec2/3/4, mat33/34/44, quat.
|
||||||
|
- [x] Geometry: ray, line, plane, aabb, sphere, capsule, triangle, poly and frustum.
|
||||||
|
- [x] Window: windowed, soft/hard fullscreen, msaa, icon, cursor handling.
|
||||||
|
- [x] Input: keyboard, mouse and gamepads.
|
||||||
|
- [x] Script: Lua scripting, Luajit bindings.
|
||||||
|
- [x] Network: downloads (HTTPS) and sockets (TCP/UDP). <!-- [*] Object, GameObject, W/ECS -->
|
||||||
|
- [x] AI: Swarm/Boids.
|
||||||
|
- [x] UI: button, list, slider, toggle, checkbox, editbox, dialog, color, image, menu, window, notify...
|
||||||
|
- [x] Font: TTF, OTF and TTC. Basic syntax highlighter. Glyph ranges. Atlasing.
|
||||||
|
- [x] Localization/I18N: XLSX and INI. Unicode.
|
||||||
|
- [x] Image: JPG, PNG, BMP, PSD, PIC, PNM, ICO.
|
||||||
|
- [x] Texture: KTX/2, PVR, DDS, ASTC, BASIS, HDR, TGA.
|
||||||
|
- [x] Texel: Depth, R, RG, RGB, RGBA, BC1/2/3/4/5/6/7, PVRI/II, ETC1/2, ASTC.
|
||||||
|
- [x] Audio: WAV/FLAC, OGG/MP1/MP3, FUR, MOD/XM/S3M/IT, SFXR and MID+SF2/SF3.
|
||||||
|
- [x] Video: MP4, MPG, OGV, MKV, WMV and AVI. Also, MP4 recording with MPEG-1 fallback.
|
||||||
|
- [x] Model: IQM/E, GLTF/2, GLB, FBX, OBJ, DAE, BLEND, MD3/5, MS3D, SMD, X, 3DS, BVH, DXF, LWO.
|
||||||
|
- [x] Render: PBR (metallic-roughness) workflow. <!-- @todo: merge demo_pbr.c rendering code into fwk_render.c -->
|
||||||
|
- [x] Render: Cubemaps, panoramas and spherical harmonics. Rayleigh/Mie scattering.
|
||||||
|
- [x] Render: Post-effects (SSAO,FXAA1/3,CRT,Contrast,Grain,Outline,Vignette...).
|
||||||
|
- [x] Render: 3D Anims, skeletal anims, hardware skinning and instanced rendering.
|
||||||
|
- [x] Render: 3D Debugdraw, batching and vectorial font.
|
||||||
|
- [x] Render: 2D Sprites, spritesheets, AA zooming and batching.
|
||||||
|
- [x] Render: 2D Tilemaps and tilesets: TMX, TSX.
|
||||||
|
- [x] Compression: DEFLATE, LZMA, LZ4, ULZ, BALZ, BCM, CRUSH, LZW3, LZSS and PPP.
|
||||||
|
- [x] Virtual filesystem: ZIP, PAK, TAR and DIR.
|
||||||
|
- [x] Level data: JSON, JSON5, SJSON, XML, INI.
|
||||||
|
- [x] Disk cache.
|
||||||
|
- [x] Scene handling.
|
||||||
|
- [x] Profiler, stats and leaks finder.
|
||||||
|
- [x] [Editor (wip)](https://user-images.githubusercontent.com/35402248/174457347-f787a6a2-aac8-404c-a5da-f44310c3d432.mp4).
|
||||||
|
- [x] [Documentation (wip)](https://bit.ly/-f-w-k-).
|
||||||
|
|
||||||
|
## Roadmap ᕕ(ᐛ)ᕗ (in order of arrival; ✱: partial support)
|
||||||
|
- [ ] AI pass: actors, waypoints, pathfinding, behavior trees (h/fsm,goap), and navmesh generation.
|
||||||
|
- [ ] Render pass: reverse-Z, automatic LODs, impostors, decals.
|
||||||
|
- [ ] Materials: (colors✱, textures✱, matcaps✱, videos✱, shadertoys✱). Shadertoys as post-fx✱. <!--materials as postfx, as they have an update() method -->
|
||||||
|
- [ ] Lighting: Hard/soft shadow mapping (VSM,CCSM). Baked lightmaps. Refl probes. Integrated PBR.
|
||||||
|
- [ ] Network/VM pass: Entity/component/systems and worlds. <!-- W/ECS, gameobj, serialization:load/save/merge, diff/patch ;; dead reckoning, interpolation, extrapolation, bandwidth budgets -->
|
||||||
|
- [ ] Message pipeline and replication. <!-- manual/replication channels, node sharding/clustering. -->
|
||||||
|
- [ ] Digital signals, message buffering and event polling.
|
||||||
|
- [ ] World streaming and level loading.
|
||||||
|
- [ ] Scenegraphs and spatial partioning. BVH, PVS, occluders, frustum culling.
|
||||||
|
- [ ] Server/client architecture. Hybrid P2P.
|
||||||
|
- [ ] NAT traversal. Socketless API, message API and pub/sub wrappers (enet/websocket).
|
||||||
|
- [ ] Tools pass
|
||||||
|
- [ ] Extend shaders + bindings. Per-platform✱, per-type✱, per-asset options. GIF, PKM.
|
||||||
|
- [ ] Extend atlas (sprite/lightmaps). Fit packing (sprites).
|
||||||
|
- [ ] Extend bindings and messaging: parse C headers during cooking stage. <!-- msgs,docs,refl,meta,lua -- (*.c, *.h) as .proto/.pbc maybe, free reflection+automatic bindings -->
|
||||||
|
- [ ] API pass
|
||||||
|
- [ ] Discuss API and freeze it.
|
||||||
|
- [ ] Document everything.
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Nice to have/extend (engine dependant):
|
||||||
|
- Animation pass: playlists, additive, blend/shapes, ik/bones, animgraph/controllers.
|
||||||
|
// 6) anims, I (playlist: ~~forward/backwards/loop/rewind)~~, II (~~blend~~/shapes), III (ik/bone), IV (graph/controller)
|
||||||
|
// ~~blend anims~~, animtracks+animevents, additive anims,
|
||||||
|
// fwk_data: quantization: ~~half, quant, microfloat~~.
|
||||||
|
// anim; ~~keyframes[] { frame+delay,frame+delay,... }, anim duration, anim flip,~~
|
||||||
|
// anim tracks / anim events
|
||||||
|
- Audio pass: 3D audio, HRTF, FFT, filtering and sound occlusion.
|
||||||
|
- Design pass: Dialogue, quests and inventory.
|
||||||
|
- Design pass: Input gestures and combos.
|
||||||
|
- Design pass: Integrated cinematics QTE.
|
||||||
|
- Design pass: Scripting, bindings and game modules.
|
||||||
|
- Design pass: Scripting: DLL (module->plugin/sys), Lua, Luajit, Teal and TypeScript.
|
||||||
|
- FX pass: Particles, billboards, emitters, trails and paths.
|
||||||
|
- Tools pass: Asset journaling.
|
||||||
|
// expose uniforms as ui options, also model_uniform();
|
||||||
|
// Pipeline: Extend asset pipeline (shaders, bindings, xml). Asset options.
|
||||||
|
// cook: slang: hlsl2glsl (XShaderCompiler), hlsl2spirv (dxc), spirv2many (spirv-cross), glsl2many (sokol-shdc)
|
||||||
|
// cook: tlfx22json
|
||||||
|
- Render pass: Frustum culling.
|
||||||
|
- Render pass: FX: particles and emitters (TLFX2), kawaii physics, clothes, breakables.
|
||||||
|
- Render pass: Lighting: hard/soft shadow mapping, spotlights (VSM), omnilights (VSMCube), CSM and baked lightmaps.
|
||||||
|
// lightmaps: https://blackpawn.com/texts/lightmaps/default.html
|
||||||
|
// https://github.com/jpcy/xatlas
|
||||||
|
- Render pass: Material: colors, textures, matcaps, videos, shadertoys. Shadertoys as post-fx.
|
||||||
|
- Render pass: Render: LODs, object instancing, billboards, impostors, decals, reflection probes.
|
||||||
|
// lod: https://github.com/songrun/SeamAwareDecimater
|
||||||
|
- Render pass: Skydomes.
|
||||||
|
- Render pass: Voxels
|
||||||
|
- Render pass: VR.
|
||||||
|
- Script pass: Refl/Meta binding tool (during cook stage).
|
||||||
|
- System pass: Buffer encryption.
|
||||||
|
- System pass: Mobile iOS/Android, HTML5✱, Web/WASM, RaspberryPi.
|
||||||
|
- Social pass: Achievements, Scores, Rankings, Friends, Invites, Steam/Itchio 1st-party store integrations, etc.
|
||||||
|
- UI pass: HUD, UI Widgets, touch input, touch gestures.
|
||||||
|
- UI pass: Font text layout and shaping, underlining, soft/hard shadows, outlines.
|
||||||
|
// font: M/SDF https://github.com/WilliamBundy/wiggle https://github.com/Chlumsky/msdf-atlas-gen
|
||||||
|
- UI pass: Game flow and game UI.
|
||||||
|
- UI pass: Localization, subtitles and unicode.
|
||||||
|
|
||||||
|
Engine types:
|
||||||
|
- 2DY Pong (70)
|
||||||
|
- 2DXY Platformer (80) (dizzy, rick dangerous) screens
|
||||||
|
- 2DXY+ Platformer (80) (megaman) scroll
|
||||||
|
- 2DXY Arcade (80) (snowbros, bomberman) screens
|
||||||
|
- 2DXZ Racing (outrun)
|
||||||
|
- 2DXYZ Isometric adventure (knight lore, diablo)
|
||||||
|
- AGI (maniac)
|
||||||
|
- First person shooter (80-90) (wolf3d > doom > hl1)
|
||||||
|
- First person adventure (bloodwych)
|
||||||
|
- Text adventure (z)
|
||||||
|
|
||||||
|
Nice to have:
|
||||||
|
- [ ] fix leaks and todos
|
||||||
|
- [ ] fwk_app: cpu usage, orientation
|
||||||
|
- [ ] fwk_input: mouse clip, mouse wrap,
|
||||||
|
- [ ] zip0 seek-vfs optimization. zip_append_file is suboptimal, and requires tons of contiguous memory for giant files.
|
||||||
|
|
||||||
|
Almost done:
|
||||||
|
- [x] shadertoy textures
|
||||||
|
- [*] billboards (follow sprite API? state instead? ie, billboard(true); before rendering?)
|
||||||
|
|
||||||
|
- Docs pass: API, functions, samples, examples, pipeline.
|
||||||
|
|
||||||
|
// plan:
|
||||||
|
//[ ] cam: friction, projections (dimetric, isometric, ...)
|
||||||
|
//[ ] Render: Materials (textures, matcaps, videos, shadertoys).
|
||||||
|
// material: fixed color, texture or script that returns color
|
||||||
|
// animated textures (shadertoys, videos)
|
||||||
|
// 8) vm/ecs core + engines: custom frontends & backends
|
||||||
|
// vm: ram, workqueues, threading, priorities, load/save
|
||||||
|
// service protocols: websocket bqqbarbhg/bq_websocket, https, handshake
|
||||||
|
// databases, services, quotas, black/whitelists, etc
|
||||||
|
// 7) network replication & messaging
|
||||||
|
// network: replication, dead reckoning, interpolation, extrapolation, bandwidth
|
||||||
|
// network: messaging: un/reliable, fragmentation, priority, etc
|
||||||
|
// network: topologies: bus, star, p2p, pubsub, etc
|
||||||
|
// network: filesystem
|
||||||
|
// int send_game_state(void *ptr, int len, int flags); PROTOCOL_V1|QUANTIZE|COMPRESS|RLE
|
||||||
|
// int recv_game_state(); compensate, extrapolate, intrapolate(); lerp();
|
||||||
|
// 9) render+
|
||||||
|
// 2d: billboards
|
||||||
|
// IBL/materials (from Foxotron+sgorsten) + shading models
|
||||||
|
// lightmapping/xatlas (demos), reflection probes
|
||||||
|
// renderbuckets
|
||||||
|
// tessellation
|
||||||
|
// 2d: particles (tlfx2)
|
||||||
|
// reverse-z {
|
||||||
|
// fbo attach format D16_UNORM -> D32_SFLOAT
|
||||||
|
// pipeline depth compare LEQUAL -> GEQUAL
|
||||||
|
// pipeline depth clear 1.0 -> 0.0
|
||||||
|
// proj matrix: float a = zfar / (zfar - znear); -> float a = -znear / (zfar - znear);
|
||||||
|
// proj matrix: float b = (-znear * zfar) / (zfar - znear); -> float b = (znear * zfar) / (zfar - znear);
|
||||||
|
// }
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Hello FWK
|
||||||
|
```C
|
||||||
|
#include "fwk.h" // Minimal C sample
|
||||||
|
int main() {
|
||||||
|
window_create(75.0, 0); // 75% size, no extra flags
|
||||||
|
while( window_swap() && !input(KEY_ESC) ) { // game loop
|
||||||
|
puts("hello FWK from C!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```C
|
||||||
|
#include "fwk.h" // Minimal HTML5 sample
|
||||||
|
void render(void *arg) {
|
||||||
|
if( !input(KEY_ESC) ) puts("hello FWK from HTML5!");
|
||||||
|
}
|
||||||
|
int main() {
|
||||||
|
window_create(75.0, 0); // 75% size, no extra flags
|
||||||
|
window_loop(render, NULL); // game loop
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local fwk = require("fwk") -- Minimal Lua sample
|
||||||
|
fwk.window_create(75.0,0) -- 75% size, no extra flags
|
||||||
|
while fwk.window_swap() and fwk.input(fwk.KEY_ESC) == 0 do -- game loop
|
||||||
|
print("hello FWK from Lua!")
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quickstart
|
||||||
|
```bat
|
||||||
|
echo win/vc && cl hello.c
|
||||||
|
echo win/clang-cl && clang-cl hello.c
|
||||||
|
echo win/tcc && tools\tcc hello.c -m64
|
||||||
|
echo win/mingw && gcc hello.c -lws2_32 -lwinmm -ldbghelp -lole32 -luser32 -lgdi32 -lcomdlg32
|
||||||
|
echo win/clang && clang hello.c -lws2_32 -lwinmm -ldbghelp -lole32 -luser32 -lgdi32 -lcomdlg32
|
||||||
|
echo linux && cc hello.c -lm -ldl -lpthread -lX11
|
||||||
|
echo linux/tcc && tcc hello.c -lm -ldl -lpthread -lX11 -D__STDC_NO_VLA__
|
||||||
|
echo osx && cc -ObjC hello.c -framework cocoa -framework iokit -framework audiotoolbox
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cook
|
||||||
|
- Most asset types need to be cooked before being used in your application. Some other assets like `.png` do not.
|
||||||
|
- Cooked assets will be written into .zipfiles close to your executable, and mounted before entering game loop.
|
||||||
|
- Cooked .zipfiles and your executable are the only required assets when releasing your game.
|
||||||
|
- Cook manually your assets by invoking supplied [`tools/cook` standalone binary](tools/).
|
||||||
|
- Cook automatically your assets by just playing your game: a runtime cook is already embedded into your binary.
|
||||||
|
- In order to achieve this, ensure the [`tools/` folder](tools/) is close to your executable.
|
||||||
|
- This folder contains all the related binaries to perform any asset conversion plus the [cookbook](tools/cook.ini) to do so.
|
||||||
|
|
||||||
|
## Extra tips
|
||||||
|
- Any ico/png file named after the executable name will be automatically used as app icon.
|
||||||
|
- Similar to the ico/png case above, the cooked .zipfiles can be named after the main executable as well.
|
||||||
|
- Dropped files into game window will be imported & saved into [`import/`](art/engine/import) folder.
|
||||||
|
- Update the gamepad controller database by upgrading the [`gamecontrollerdb.txt`](art/engine/input) file.
|
||||||
|
- Depending on your IDE, you might need to browse to [`split/`](split/) sources when debugging FWK.
|
||||||
|
- Cook assets on demand, as opposed to cook all existing assets on depot, by using `--cook-on-demand` flag.
|
||||||
|
- Linux/OSX users can optionally install wine and use the Windows tools instead (by using `--cook-wine` flag).
|
||||||
|
- Disable automatic cooking by using `--cook-jobs=0` flag (not recommended).
|
||||||
|
- Generate a project solution by dropping `split/fwk.h, fwk.c and fwk` files into it.
|
||||||
|
<!-- - Note: Windows: Assimp.dll may need [this package installed](https://www.microsoft.com/en-us/download/confirmation.aspx?id=30679).-->
|
||||||
|
|
||||||
|
## Credits (Artwork + demos)
|
||||||
|
- [Nanofactory](https://sketchfab.com/3d-models/kgirls01-d2f946f58a8040ae993cda70c97b302c), for kgirls01 3D model (CC BY-NC-ND 4.0).
|
||||||
|
- [RottingPixels](https://opengameart.org/content/2d-castle-platformer-tileset-16x16), for castle-tileset (CC0).
|
||||||
|
- [wwwtyro](https://github.com/wwwtyro/glsl-atmosphere), for nicest rayleigh/mie scattering shader around (CC0).
|
||||||
|
|
||||||
|
## Credits (Tools)
|
||||||
|
- [Aaron Barany](https://github.com/akb825/Cuttlefish), for cuttlefish (APACHE2).
|
||||||
|
- [Arseny Kapoulkine](https://github.com/zeux/pugixml/), for pugixml (MIT).
|
||||||
|
- [Assimp authors](https://github.com/assimp/assimp), for assimp (BSD3).
|
||||||
|
- [Bernhard Schelling](https://github.com/schellingb/TinySoundFont), for tml.h (Zlib) and tsf.h (MIT).
|
||||||
|
- [ffmpeg authors](https://www.ffmpeg.org/), for ffmpeg (LGPL21).
|
||||||
|
- [Imagination](https://developer.imaginationtech.com/pvrtextool/), for pvrtextoolcli (ITL).
|
||||||
|
- [Krzysztof Gabis](https://github.com/kgabis/ape), for split.py/join.py (MIT).
|
||||||
|
- [Lee Salzman](https://github.com/lsalzman/iqm/tree/5882b8c32fa622eba3861a621bb715d693573420/demo), for iqm.cpp (PD).
|
||||||
|
- [Mattias Gustavsson](https://github.com/mattiasgustavsson/libs), for mid.h (PD).
|
||||||
|
- [Michael Schmoock](http://github.com/willsteel/lcpp), for lcpp (MIT).
|
||||||
|
- [Olivier Lapicque, Konstanty Bialkowski](https://github.com/Konstanty/libmodplug), for libmodplug (PD).
|
||||||
|
- [Polyglot Team](https://docs.google.com/spreadsheets/d/17f0dQawb-s_Fd7DHgmVvJoEGDMH_yoSd8EYigrb0zmM/edit), for polyglot gamedev (CC0).
|
||||||
|
- [Tildearrow](https://github.com/tildearrow/furnace/), for Furnace (GPL2).
|
||||||
|
- [Tomas Pettersson](http://www.drpetter.se/), for sfxr (PD).
|
||||||
|
- [Tor Andersson](https://github.com/ccxvii/asstools), for assiqe.c (BSD).
|
||||||
|
|
||||||
|
## Credits (Runtime)
|
||||||
|
- [Barerose](https://github.com/barerose), for swrap (CC0).
|
||||||
|
- [Camilla Löwy](https://github.com/elmindreda), for glfw3 (Zlib).
|
||||||
|
- [Dave Rand](https://tools.ietf.org/html/rfc1978) for ppp (PD).
|
||||||
|
- [David Herberth](https://github.com/dav1dde/), for glad generated code (PD).
|
||||||
|
- [David Reid](https://github.com/mackron), for miniaudio (PD).
|
||||||
|
- [Dominic Szablewski](https://github.com/phoboslab/pl_mpeg), for pl_mpeg (MIT).
|
||||||
|
- [Dominik Madarász](https://github.com/zaklaus), for json5 parser (PD).
|
||||||
|
- [Eduard Suica](https://github.com/eduardsui/tlse), for tlse (PD).
|
||||||
|
- [Gargaj+cce/Peisik](https://github.com/gargaj/foxotron), for Foxotron/PBR shaders (UNLICENSE).
|
||||||
|
- [Guillaume Vareille](http://tinyfiledialogs.sourceforge.net), for tinyfiledialogs (ZLIB).
|
||||||
|
- [Haruhiko Okumura](https://oku.edu.mie-u.ac.jp/~okumura/compression/) for lzss (PD).
|
||||||
|
- [Igor Pavlov](https://www.7-zip.org/) for LZMA (PD).
|
||||||
|
- [Ilya Muravyov](https://github.com/encode84) for bcm, balz, crush, ulz, lz4x (PD).
|
||||||
|
- [Jon Olick](https://www.jonolick.com/), for jo_mp1 and jo_mpeg (PD).
|
||||||
|
- [Joonas Pihlajamaa](https://github.com/jokkebk/JUnzip), for JUnzip library (PD).
|
||||||
|
- [Juliette Focault](https://github.com/juliettef/IconFontCppHeaders/blob/main/IconsMaterialDesign.h), for the generated MD header (ZLIB).
|
||||||
|
- [Lee Salzman](https://github.com/lsalzman/iqm/tree/5882b8c32fa622eba3861a621bb715d693573420/demo), for IQM spec & player (PD).
|
||||||
|
- [Lee Salzman, V.Hrytsenko, D.Madarász](https://github.com/zpl-c/enet/), for enet (MIT).
|
||||||
|
- [Libtomcrypt](https://github.com/libtom/libtomcrypt), for libtomcrypt (Unlicense).
|
||||||
|
- [Lua authors](https://www.lua.org/), for Lua language (MIT).
|
||||||
|
- [Mārtiņš Možeiko](https://gist.github.com/mmozeiko/68f0a8459ef2f98bcd879158011cc275), for A* pathfinding (PD).
|
||||||
|
- [Mattias Gustavsson](https://github.com/mattiasgustavsson/libs), for thread.h and https.h (PD).
|
||||||
|
- [Micha Mettke, Chris Willcocks, Dmitry Hrabrov](https://github.com/vurtun/nuklear), for nuklear (PD).
|
||||||
|
- [Michael Galetzka](https://github.com/Cultrarius/Swarmz), for swarmz (UNLICENSE).
|
||||||
|
- [Omar Cornut, vaiorabbit](https://github.com/ocornut/imgui/pull/3627), for tables of unicode ranges (MIT-0).
|
||||||
|
- [Rabia Alhaffar](https://github.com/Rabios/ice_libs), for ice_batt.h (PD).
|
||||||
|
- [Rich Geldreich](https://github.com/richgel999/miniz), for miniz (PD).
|
||||||
|
- [Ross Williams](http://ross.net/compression/lzrw3a.html) for lzrw3a (PD).
|
||||||
|
- [Samuli Raivio](https://github.com/bqqbarbhg/bq_websocket), for bq_websocket (PD).
|
||||||
|
- [Sean Barrett](https://github.com/nothings), for stb_image, stb_image_write, stb_sprintf, stb_truetype and stb_vorbis (PD).
|
||||||
|
- [Sebastian Steinhauer](https://github.com/kieselsteini), for sts_mixer (PD).
|
||||||
|
- [Stan Melax, Cloud Wu](https://web.archive.org/web/20031204035320/http://www.melax.com/polychop/gdmag.pdf), for polychop C algorithm (PD).
|
||||||
|
- [Stefan Gustavson](https://github.com/stegu/perlin-noise), for simplex noise (PD).
|
||||||
|
- [Tor Andersson](https://github.com/ccxvii/minilibs), for xml.c (PD).
|
||||||
|
- [Vassvik](https://github.com/vassvik/mv_easy_font), for mv_easy_font (Unlicense).
|
||||||
|
- Special thanks to [@ands](https://github.com/ands), [@barerose](https://github.com/barerose), [@datenwolf](https://github.com/datenwolf), [@evanw](https://github.com/evanw), [@glampert](https://github.com/glampert), [@krig](https://github.com/krig), [@sgorsten](https://github.com/sgorsten) and [@vurtun](https://github.com/vurtun) for their math libraries (PD,CC0,WTFPL2,CC0,PD,CC0,Unlicense,PD).
|
||||||
|
|
||||||
|
## Unlicense
|
||||||
|
This software is released into the [public domain](https://unlicense.org/). Also dual-licensed as [0-BSD](https://opensource.org/licenses/0BSD) or [MIT (No Attribution)](https://github.com/aws/mit-0) for those countries where public domain is a concern (sigh). Any contribution to this repository is implicitly subjected to the same release conditions aforementioned.
|
||||||
|
|
||||||
|
## Links
|
||||||
|
<p>
|
||||||
|
<a href="https://github.com/r-lyeh/FWK/issues"><img alt="Issues" src="https://img.shields.io/github/issues-raw/r-lyeh/FWK.svg"/></a>
|
||||||
|
<a href="https://discord.gg/vu6Vt9d"><img alt="Discord" src="https://img.shields.io/discord/270565488365535232?color=5865F2&label=chat&logo=discord&logoColor=white"/></a><br/>
|
||||||
|
|
||||||
|
Still looking for alternatives?
|
||||||
|
[amulet](https://github.com/ianmaclarty/amulet), [aroma](https://github.com/leafo/aroma/), [astera](https://github.com/tek256/astera), [blendelf](https://github.com/jesterKing/BlendELF), [bullordengine](https://github.com/MarilynDafa/Bulllord-Engine), [candle](https://github.com/EvilPudding/candle), [cave](https://github.com/kieselsteini/cave), [chickpea](https://github.com/ivansafrin/chickpea), [corange](https://github.com/orangeduck/Corange), [cute](https://github.com/RandyGaul/cute_framework), [dos-like](https://github.com/mattiasgustavsson/dos-like), [ejoy2d](https://github.com/ejoy/ejoy2d), [exengine](https://github.com/exezin/exengine), [gunslinger](https://github.com/MrFrenik/gunslinger), [hate](https://github.com/excessive/hate), [island](https://github.com/island-org/island), [juno](https://github.com/rxi/juno), [l](https://github.com/Lyatus/L), [lgf](https://github.com/Planimeter/lgf), [limbus](https://github.com/redien/limbus), [love](https://github.com/love2d/love/), [lovr](https://github.com/bjornbytes/lovr), [mini3d](https://github.com/mini3d/mini3d), [mintaro](https://github.com/mackron/mintaro), [mio](https://github.com/ccxvii/mio), [olive.c](https://github.com/tsoding/olive.c), [opensource](https://github.com/w23/OpenSource), [ouzel](https://github.com/elnormous/ouzel/), [pez](https://github.com/prideout/pez), [pixie](https://github.com/mattiasgustavsson/pixie), [punity](https://github.com/martincohen/Punity), [r96](https://github.com/badlogic/r96), [ricotech](https://github.com/dbechrd/RicoTech), [rizz](https://github.com/septag/rizz), [tigr](https://github.com/erkkah/tigr), [yourgamelib](https://github.com/duddel/yourgamelib)
|
||||||
|
</p>
|
|
@ -0,0 +1,184 @@
|
||||||
|
Assets from https://github.com/GameTechDev/stardust_vulkan/. Project license below:
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction, and
|
||||||
|
distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by the copyright
|
||||||
|
owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all other entities
|
||||||
|
that control, are controlled by, or are under common control with that entity.
|
||||||
|
For the purposes of this definition, "control" means (i) the power, direct or
|
||||||
|
indirect, to cause the direction or management of such entity, whether by
|
||||||
|
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity exercising
|
||||||
|
permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications, including
|
||||||
|
but not limited to software source code, documentation source, and configuration
|
||||||
|
files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical transformation or
|
||||||
|
translation of a Source form, including but not limited to compiled object code,
|
||||||
|
generated documentation, and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or Object form, made
|
||||||
|
available under the License, as indicated by a copyright notice that is included
|
||||||
|
in or attached to the work (an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object form, that
|
||||||
|
is based on (or derived from) the Work and for which the editorial revisions,
|
||||||
|
annotations, elaborations, or other modifications represent, as a whole, an
|
||||||
|
original work of authorship. For the purposes of this License, Derivative Works
|
||||||
|
shall not include works that remain separable from, or merely link (or bind by
|
||||||
|
name) to the interfaces of, the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including the original version
|
||||||
|
of the Work and any modifications or additions to that Work or Derivative Works
|
||||||
|
thereof, that is intentionally submitted to Licensor for inclusion in the Work
|
||||||
|
by the copyright owner or by an individual or Legal Entity authorized to submit
|
||||||
|
on behalf of the copyright owner. For the purposes of this definition,
|
||||||
|
"submitted" means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems, and
|
||||||
|
issue tracking systems that are managed by, or on behalf of, the Licensor for
|
||||||
|
the purpose of discussing and improving the Work, but excluding communication
|
||||||
|
that is conspicuously marked or otherwise designated in writing by the copyright
|
||||||
|
owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
|
||||||
|
of whom a Contribution has been received by Licensor and subsequently
|
||||||
|
incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of this
|
||||||
|
License, each Contributor hereby grants to You a perpetual, worldwide,
|
||||||
|
non-exclusive, no-charge, royalty-free, irrevocable copyright license to
|
||||||
|
reproduce, prepare Derivative Works of, publicly display, publicly perform,
|
||||||
|
sublicense, and distribute the Work and such Derivative Works in Source or
|
||||||
|
Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of this License,
|
||||||
|
each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||||
|
no-charge, royalty-free, irrevocable (except as stated in this section) patent
|
||||||
|
license to make, have made, use, offer to sell, sell, import, and otherwise
|
||||||
|
transfer the Work, where such license applies only to those patent claims
|
||||||
|
licensable by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s) with the Work
|
||||||
|
to which such Contribution(s) was submitted. If You institute patent litigation
|
||||||
|
against any entity (including a cross-claim or counterclaim in a lawsuit)
|
||||||
|
alleging that the Work or a Contribution incorporated within the Work
|
||||||
|
constitutes direct or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate as of the date
|
||||||
|
such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the Work or
|
||||||
|
Derivative Works thereof in any medium, with or without modifications, and in
|
||||||
|
Source or Object form, provided that You meet the following conditions:
|
||||||
|
You must give any other recipients of the Work or Derivative Works a copy of
|
||||||
|
this License; and
|
||||||
|
|
||||||
|
|
||||||
|
You must cause any modified files to carry prominent notices stating that You
|
||||||
|
changed the files; and
|
||||||
|
|
||||||
|
|
||||||
|
You must retain, in the Source form of any Derivative Works that You
|
||||||
|
distribute, all copyright, patent, trademark, and attribution notices from the
|
||||||
|
Source form of the Work, excluding those notices that do not pertain to any
|
||||||
|
part of the Derivative Works; and
|
||||||
|
|
||||||
|
|
||||||
|
If the Work includes a "NOTICE" text file as part of its distribution, then
|
||||||
|
any Derivative Works that You distribute must include a readable copy of the
|
||||||
|
attribution notices contained within such NOTICE file, excluding those notices
|
||||||
|
that do not pertain to any part of the Derivative Works, in at least one of
|
||||||
|
the following places: within a NOTICE text file distributed as part of the
|
||||||
|
Derivative Works; within the Source form or documentation, if provided along
|
||||||
|
with the Derivative Works; or, within a display generated by the Derivative
|
||||||
|
Works, if and wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and do not modify the
|
||||||
|
License. You may add Your own attribution notices within Derivative Works that
|
||||||
|
You distribute, alongside or as an addendum to the NOTICE text from the Work,
|
||||||
|
provided that such additional attribution notices cannot be construed as
|
||||||
|
modifying the License.
|
||||||
|
You may add Your own copyright statement to Your modifications and may provide
|
||||||
|
additional or different license terms and conditions for use, reproduction, or
|
||||||
|
distribution of Your modifications, or for any such Derivative Works as a whole,
|
||||||
|
provided Your use, reproduction, and distribution of the Work otherwise complies
|
||||||
|
with the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise, any
|
||||||
|
Contribution intentionally submitted for inclusion in the Work by You to the
|
||||||
|
Licensor shall be under the terms and conditions of this License, without any
|
||||||
|
additional terms or conditions. Notwithstanding the above, nothing herein shall
|
||||||
|
supersede or modify the terms of any separate license agreement you may have
|
||||||
|
executed with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade names,
|
||||||
|
trademarks, service marks, or product names of the Licensor, except as required
|
||||||
|
for reasonable and customary use in describing the origin of the Work and
|
||||||
|
reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in
|
||||||
|
writing, Licensor provides the Work (and each Contributor provides its
|
||||||
|
Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied, including, without limitation, any warranties
|
||||||
|
or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any risks
|
||||||
|
associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory, whether in
|
||||||
|
tort (including negligence), contract, or otherwise, unless required by
|
||||||
|
applicable law (such as deliberate and grossly negligent acts) or agreed to in
|
||||||
|
writing, shall any Contributor be liable to You for damages, including any
|
||||||
|
direct, indirect, special, incidental, or consequential damages of any character
|
||||||
|
arising as a result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill, work stoppage,
|
||||||
|
computer failure or malfunction, or any and all other commercial damages or
|
||||||
|
losses), even if such Contributor has been advised of the possibility of such
|
||||||
|
damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing the Work or
|
||||||
|
Derivative Works thereof, You may choose to offer, and charge a fee for,
|
||||||
|
acceptance of support, warranty, indemnity, or other liability obligations
|
||||||
|
and/or rights consistent with this License. However, in accepting such
|
||||||
|
obligations, You may act only on Your own behalf and on Your sole
|
||||||
|
responsibility, not on behalf of any other Contributor, and only if You agree to
|
||||||
|
indemnify, defend, and hold each Contributor harmless for any liability incurred
|
||||||
|
by, or claims asserted against, such Contributor by reason of your accepting any
|
||||||
|
such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following boilerplate
|
||||||
|
notice, with the fields enclosed by brackets "[]" replaced with your own
|
||||||
|
identifying information. (Don't include the brackets!) The text should be
|
||||||
|
enclosed in the appropriate comment syntax for the file format. We also
|
||||||
|
recommend that a file or class name and description of purpose be included on
|
||||||
|
the same "printed page" as the copyright notice for easier identification within
|
||||||
|
third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner] Licensed under the Apache License,
|
||||||
|
Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or
|
||||||
|
agreed to in writing, software distributed under the License is distributed on
|
||||||
|
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||||
|
or implied. See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
After Width: | Height: | Size: 396 KiB |
After Width: | Height: | Size: 665 KiB |
After Width: | Height: | Size: 414 KiB |
After Width: | Height: | Size: 397 KiB |
After Width: | Height: | Size: 523 KiB |
After Width: | Height: | Size: 557 KiB |
|
@ -0,0 +1,12 @@
|
||||||
|
uniform float intensity = 0.003f;
|
||||||
|
uniform float angle = 0.0f;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 uv = TEXCOORD.st;
|
||||||
|
vec2 offset = intensity * vec2( cos(angle), sin(angle) );
|
||||||
|
vec4 color = texture( iChannel0, uv);
|
||||||
|
color.r = texture( iChannel0, uv + offset ).x;
|
||||||
|
color.b = texture( iChannel0, uv - offset ).z;
|
||||||
|
|
||||||
|
FRAGCOLOR = color;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
uniform float intensity = 2.0;
|
||||||
|
|
||||||
|
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
|
||||||
|
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||||
|
vec4 src = texture(iChannel0, uv);
|
||||||
|
fragColor = vec4( clamp(src * intensity, 0.0, 1.0).rgb, src.a );
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
// [ref] https://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/
|
||||||
|
|
||||||
|
uniform float intensity = 4;
|
||||||
|
uniform vec2 direction = vec2(1.0, 0.0);
|
||||||
|
|
||||||
|
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
|
||||||
|
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||||
|
|
||||||
|
vec4 base = texture(iChannel0, uv), color = vec4(0.0);
|
||||||
|
vec2 offset = (direction * vec2(intensity)) / iResolution;
|
||||||
|
color += base * 0.30;
|
||||||
|
color += texture(iChannel0, uv + offset) * 0.35;
|
||||||
|
color += texture(iChannel0, uv - offset) * 0.35;
|
||||||
|
|
||||||
|
fragColor = vec4( color.rgb, base.a );
|
||||||
|
}
|
|
@ -0,0 +1,169 @@
|
||||||
|
//
|
||||||
|
// PUBLIC DOMAIN CRT STYLED SCAN-LINE SHADER
|
||||||
|
//
|
||||||
|
// by Timothy Lottes
|
||||||
|
//
|
||||||
|
// This is more along the style of a really good CGA arcade monitor.
|
||||||
|
// With RGB inputs instead of NTSC.
|
||||||
|
// The shadow mask example has the mask rotated 90 degrees for less chromatic aberration.
|
||||||
|
//
|
||||||
|
// Left it unoptimized to show the theory behind the algorithm.
|
||||||
|
//
|
||||||
|
// It is an example what I personally would want as a display option for pixel art games.
|
||||||
|
// Please take and use, change, or whatever.
|
||||||
|
//
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
// Emulated input resolution.
|
||||||
|
#if 0
|
||||||
|
// Fix resolution to set amount.
|
||||||
|
vec2 res=vec2(320.0/1.0,160.0/1.0);
|
||||||
|
#else
|
||||||
|
// Optimize for resize.
|
||||||
|
vec2 res=iResolution.xy/6.0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Hardness of scanline.
|
||||||
|
// -8.0 = soft
|
||||||
|
// -16.0 = medium
|
||||||
|
uniform float hardScan=-8.0;
|
||||||
|
|
||||||
|
// Hardness of pixels in scanline.
|
||||||
|
// -2.0 = soft
|
||||||
|
// -4.0 = hard
|
||||||
|
uniform float hardPix=-3.0;
|
||||||
|
|
||||||
|
// Display warp.
|
||||||
|
// 0.0 = none
|
||||||
|
// 1.0/8.0 = extreme
|
||||||
|
vec2 warp=vec2(1.0/32.0,1.0/24.0);
|
||||||
|
|
||||||
|
// Amount of shadow mask.
|
||||||
|
float maskDark=0.5;
|
||||||
|
float maskLight=1.5;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// sRGB to Linear.
|
||||||
|
// Assuing using sRGB typed textures this should not be needed.
|
||||||
|
float ToLinear1(float c){return(c<=0.04045)?c/12.92:pow((c+0.055)/1.055,2.4);}
|
||||||
|
vec3 ToLinear(vec3 c){return vec3(ToLinear1(c.r),ToLinear1(c.g),ToLinear1(c.b));}
|
||||||
|
|
||||||
|
// Linear to sRGB.
|
||||||
|
// Assuing using sRGB typed textures this should not be needed.
|
||||||
|
float ToSrgb1(float c){return(c<0.0031308?c*12.92:1.055*pow(c,0.41666)-0.055);}
|
||||||
|
vec3 ToSrgb(vec3 c){return vec3(ToSrgb1(c.r),ToSrgb1(c.g),ToSrgb1(c.b));}
|
||||||
|
|
||||||
|
// Nearest emulated sample given floating point position and texel offset.
|
||||||
|
// Also zero's off screen.
|
||||||
|
vec3 Fetch(vec2 pos,vec2 off){
|
||||||
|
pos=floor(pos*res+off)/res;
|
||||||
|
if(max(abs(pos.x-0.5),abs(pos.y-0.5))>0.5)return vec3(0.0,0.0,0.0);
|
||||||
|
return ToLinear(texture2D(iChannel0,pos.xy,-16.0).rgb);}
|
||||||
|
|
||||||
|
// Distance in emulated pixels to nearest texel.
|
||||||
|
vec2 Dist(vec2 pos){pos=pos*res;return -((pos-floor(pos))-vec2(0.5));}
|
||||||
|
|
||||||
|
// 1D Gaussian.
|
||||||
|
float Gaus(float pos,float scale){return exp2(scale*pos*pos);}
|
||||||
|
|
||||||
|
// 3-tap Gaussian filter along horz line.
|
||||||
|
vec3 Horz3(vec2 pos,float off){
|
||||||
|
vec3 b=Fetch(pos,vec2(-1.0,off));
|
||||||
|
vec3 c=Fetch(pos,vec2( 0.0,off));
|
||||||
|
vec3 d=Fetch(pos,vec2( 1.0,off));
|
||||||
|
float dst=Dist(pos).x;
|
||||||
|
// Convert distance to weight.
|
||||||
|
float scale=hardPix;
|
||||||
|
float wb=Gaus(dst-1.0,scale);
|
||||||
|
float wc=Gaus(dst+0.0,scale);
|
||||||
|
float wd=Gaus(dst+1.0,scale);
|
||||||
|
// Return filtered sample.
|
||||||
|
return (b*wb+c*wc+d*wd)/(wb+wc+wd);}
|
||||||
|
|
||||||
|
// 5-tap Gaussian filter along horz line.
|
||||||
|
vec3 Horz5(vec2 pos,float off){
|
||||||
|
vec3 a=Fetch(pos,vec2(-2.0,off));
|
||||||
|
vec3 b=Fetch(pos,vec2(-1.0,off));
|
||||||
|
vec3 c=Fetch(pos,vec2( 0.0,off));
|
||||||
|
vec3 d=Fetch(pos,vec2( 1.0,off));
|
||||||
|
vec3 e=Fetch(pos,vec2( 2.0,off));
|
||||||
|
float dst=Dist(pos).x;
|
||||||
|
// Convert distance to weight.
|
||||||
|
float scale=hardPix;
|
||||||
|
float wa=Gaus(dst-2.0,scale);
|
||||||
|
float wb=Gaus(dst-1.0,scale);
|
||||||
|
float wc=Gaus(dst+0.0,scale);
|
||||||
|
float wd=Gaus(dst+1.0,scale);
|
||||||
|
float we=Gaus(dst+2.0,scale);
|
||||||
|
// Return filtered sample.
|
||||||
|
return (a*wa+b*wb+c*wc+d*wd+e*we)/(wa+wb+wc+wd+we);}
|
||||||
|
|
||||||
|
// Return scanline weight.
|
||||||
|
float Scan(vec2 pos,float off){
|
||||||
|
float dst=Dist(pos).y;
|
||||||
|
return Gaus(dst+off,hardScan);}
|
||||||
|
|
||||||
|
// Allow nearest three lines to effect pixel.
|
||||||
|
vec3 Tri(vec2 pos){
|
||||||
|
vec3 a=Horz3(pos,-1.0);
|
||||||
|
vec3 b=Horz5(pos, 0.0);
|
||||||
|
vec3 c=Horz3(pos, 1.0);
|
||||||
|
float wa=Scan(pos,-1.0);
|
||||||
|
float wb=Scan(pos, 0.0);
|
||||||
|
float wc=Scan(pos, 1.0);
|
||||||
|
return a*wa+b*wb+c*wc;}
|
||||||
|
|
||||||
|
// Distortion of scanlines, and end of screen alpha.
|
||||||
|
vec2 Warp(vec2 pos){
|
||||||
|
pos=pos*2.0-1.0;
|
||||||
|
pos*=vec2(1.0+(pos.y*pos.y)*warp.x,1.0+(pos.x*pos.x)*warp.y);
|
||||||
|
return pos*0.5+0.5;}
|
||||||
|
|
||||||
|
// Shadow mask.
|
||||||
|
vec3 Mask(vec2 pos){
|
||||||
|
pos.x+=pos.y*3.0;
|
||||||
|
vec3 mask=vec3(maskDark,maskDark,maskDark);
|
||||||
|
pos.x=fract(pos.x/6.0);
|
||||||
|
if(pos.x<0.333)mask.r=maskLight;
|
||||||
|
else if(pos.x<0.666)mask.g=maskLight;
|
||||||
|
else mask.b=maskLight;
|
||||||
|
return mask;}
|
||||||
|
|
||||||
|
// Draw dividing bars.
|
||||||
|
float Bar(float pos,float bar){pos-=bar;return pos*pos<4.0?0.0:1.0;}
|
||||||
|
|
||||||
|
// Entry.
|
||||||
|
void main() {
|
||||||
|
#if 0
|
||||||
|
// Unmodified.
|
||||||
|
if(gl_FragCoord.x<iResolution.x*0.333){
|
||||||
|
color.rgb=Fetch(gl_FragCoord.xy/iResolution.xy+vec2(0.333,0.0),vec2(0.0,0.0));}
|
||||||
|
else{
|
||||||
|
vec2 pos=Warp(gl_FragCoord.xy/iResolution.xy+vec2(-0.333,0.0));
|
||||||
|
if(gl_FragCoord.x<iResolution.x*0.666){
|
||||||
|
hardScan=-12.0;
|
||||||
|
maskDark=maskLight=1.0;
|
||||||
|
pos=Warp(gl_FragCoord.xy/iResolution.xy);}
|
||||||
|
color.rgb=Tri(pos)*Mask(gl_FragCoord.xy);}
|
||||||
|
color.a=1.0;
|
||||||
|
color.rgb*=
|
||||||
|
Bar(gl_FragCoord.x,iResolution.x*0.333)*
|
||||||
|
Bar(gl_FragCoord.x,iResolution.x*0.666);
|
||||||
|
color.rgb=ToSrgb(color.rgb);
|
||||||
|
#else
|
||||||
|
// full
|
||||||
|
vec2 pos=Warp(gl_FragCoord.xy/iResolution.xy);
|
||||||
|
|
||||||
|
// classic
|
||||||
|
// hardScan=-12.0;
|
||||||
|
// maskDark=maskLight=1.0;
|
||||||
|
// vec2 pos=Warp(gl_FragCoord.xy/iResolution.xy);
|
||||||
|
|
||||||
|
color.rgb=Tri(pos)*Mask(gl_FragCoord.xy);
|
||||||
|
color.a=texture2D(iChannel0,gl_FragCoord.xy/iResolution.xy).a;
|
||||||
|
color.rgb=ToSrgb(color.rgb);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
// [src] https://github.com/Hammster/windows-terminal-shaders (CC0)
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
#define GRAIN_INTENSITY 0.02
|
||||||
|
#define TINT_COLOR vec4(1, 0.7f, 0, 0)
|
||||||
|
#define ENABLE_SCANLINES 1
|
||||||
|
#define ENABLE_REFRESHLINE 1
|
||||||
|
#define ENABLE_NOISE 1
|
||||||
|
#define ENABLE_CURVE 1
|
||||||
|
#define ENABLE_TINT 0
|
||||||
|
#define ENABLE_GRAIN 0
|
||||||
|
#define DEBUG 0
|
||||||
|
|
||||||
|
// Grain Lookup Table
|
||||||
|
#define a0 0.151015505647689
|
||||||
|
#define a1 -0.5303572634357367
|
||||||
|
#define a2 1.365020122861334
|
||||||
|
#define b0 0.132089632343748
|
||||||
|
#define b1 -0.7607324991323768
|
||||||
|
|
||||||
|
const vec4 tint = TINT_COLOR;
|
||||||
|
const vec4 scanlineTint = vec4(0.6f, 0.6f, 0.6f, 0.0f);
|
||||||
|
|
||||||
|
float permute(float x) {
|
||||||
|
x *= (34 * x + 1);
|
||||||
|
return 289 * fract(x * 1 / 289.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
float rand(float state) {
|
||||||
|
return fract(permute(state) / 41.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
float fmod(float x, float y) {
|
||||||
|
return x - y * trunc(x/y);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 CRT( vec2 uv ) {
|
||||||
|
vec2 xy = uv;
|
||||||
|
|
||||||
|
#if ENABLE_CURVE
|
||||||
|
// TODO: add control variable for transform intensity
|
||||||
|
xy -= 0.5f; // offcenter screen
|
||||||
|
float r = xy.x * xy.x + xy.y * xy.y; // get ratio
|
||||||
|
xy *= 4.2f + r; // apply ratio
|
||||||
|
xy *= 0.25f; // zoom
|
||||||
|
xy += 0.5f; // move back to center
|
||||||
|
|
||||||
|
// TODO: add monitor visuals and make colors static consts
|
||||||
|
// Outter Box
|
||||||
|
if(xy.x < -0.025f || xy.y < -0.025f) return vec4(0, 0, 0, 0);
|
||||||
|
if(xy.x > 1.025f || xy.y > 1.025f) return vec4(0, 0, 0, 0);
|
||||||
|
// Bazel
|
||||||
|
if(xy.x < -0.015f || xy.y < -0.015f) return vec4(0.03f, 0.03f, 0.03f, 0.0f);
|
||||||
|
if(xy.x > 1.015f || xy.y > 1.015f) return vec4(0.03f, 0.03f, 0.03f, 0.0f);
|
||||||
|
// Screen Border
|
||||||
|
if(xy.x < 0.001f || xy.y < 0.001f) return vec4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
if(xy.x > 0.999f || xy.y > 0.999f) return vec4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec4 color = texture(iChannel0, xy);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
if(xy.x < 0.5f) return color;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ENABLE_REFRESHLINE
|
||||||
|
float timeOver = fmod(iTime / 5, 1);
|
||||||
|
float refreshLineColorTint = timeOver - xy.y;
|
||||||
|
if(xy.y > timeOver && xy.y - 0.03f < timeOver ) color.rgb += (refreshLineColorTint * 2.0f);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ENABLE_SCANLINES
|
||||||
|
// scanlines are always every 1px
|
||||||
|
if(fmod(floor(uv.y * iResolution.y), 2) != 0) color *= scanlineTint;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ENABLE_TINT
|
||||||
|
float grayscale = (color.r + color.g + color.b) / 3.f;
|
||||||
|
color = vec4(grayscale, grayscale, grayscale, 0);
|
||||||
|
color *= tint;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ENABLE_GRAIN
|
||||||
|
vec3 m = vec3(tex, fmod(iTime, 5) / 5) + 1.;
|
||||||
|
float state = permute(permute(m.x) + m.y) + m.z;
|
||||||
|
|
||||||
|
float p = 0.95 * rand(state) + 0.025;
|
||||||
|
float q = p - 0.5;
|
||||||
|
float r2 = q * q;
|
||||||
|
|
||||||
|
float grain = q * (a2 + (a1 * r2 + a0) / (r2 * r2 + b1 * r2 + b0));
|
||||||
|
color.rgb += GRAIN_INTENSITY * grain;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
|
||||||
|
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||||
|
vec4 src = texture(iChannel0, uv);
|
||||||
|
|
||||||
|
fragColor = vec4(CRT(uv).rgb, src.a);
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
// [ref] https://www.inf.ufrgs.br/~oliveira/pubs_files/CVD_Simulation/CVD_Simulation.html
|
||||||
|
|
||||||
|
uniform int colorblind_mode = 2; // [0..4]
|
||||||
|
uniform mat3 colorblind_matrices[5] = mat3[5](
|
||||||
|
mat3(1.000,0.000,0.000, 0.000,1.000,0.000, 0.000,0.000,1.000), // 0 no colorblind
|
||||||
|
mat3(0.299,0.587,0.114, 0.299,0.587,0.114, 0.299,0.587,0.114), // 1 achromatopsia (luma)
|
||||||
|
mat3( // protanomaly (no red cone)
|
||||||
|
0.152286, 1.052583,-0.204868,
|
||||||
|
0.114503, 0.786281, 0.099216,
|
||||||
|
-0.003882,-0.048116, 1.051998
|
||||||
|
),
|
||||||
|
mat3( // deuteranomaly (no green cone)
|
||||||
|
0.367322, 0.860646, -0.227968,
|
||||||
|
0.280085, 0.672501, 0.047413,
|
||||||
|
-0.011820, 0.042940, 0.968881
|
||||||
|
),
|
||||||
|
mat3( // tritanomaly (no blue cone)
|
||||||
|
1.255528,-0.076749,-0.178779,
|
||||||
|
-0.078411, 0.930809, 0.147602,
|
||||||
|
0.004733, 0.691367, 0.303900
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
|
||||||
|
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||||
|
|
||||||
|
vec4 src = texture(iChannel0, uv);
|
||||||
|
fragColor = vec4( src.rgb * colorblind_matrices[colorblind_mode], src.a );
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
uniform float contrast = 1.5; // > 1 to saturate, < 1 to bleach-to-gray
|
||||||
|
uniform float brightness = 0;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 pixelColor = texture(iChannel0, TEXCOORD.st);
|
||||||
|
pixelColor.rgb /= pixelColor.a;
|
||||||
|
|
||||||
|
pixelColor.rgb = ((pixelColor.rgb - 0.5f) * max(contrast, 0)) + 0.5f;
|
||||||
|
|
||||||
|
pixelColor.rgb += brightness;
|
||||||
|
|
||||||
|
pixelColor.rgb *= pixelColor.a;
|
||||||
|
|
||||||
|
FRAGCOLOR = pixelColor;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
uniform float intensity = 0.004;
|
||||||
|
|
||||||
|
highp float rand(vec2 co) {
|
||||||
|
highp float a = 12.9898;
|
||||||
|
highp float b = 78.233;
|
||||||
|
highp float c = 43758.5453;
|
||||||
|
highp float dt= dot(co.xy ,vec2(a,b));
|
||||||
|
highp float sn= mod(dt,3.14);
|
||||||
|
return fract(sin(sn) * c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
|
||||||
|
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||||
|
vec4 fetch = texture(iChannel0, uv + intensity * rand(uv));
|
||||||
|
fragColor = fetch;
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
// https://en.wikipedia.org/wiki/Ordered_dithering
|
||||||
|
|
||||||
|
#define BAYER 4
|
||||||
|
|
||||||
|
#if BAYER == 2
|
||||||
|
|
||||||
|
const float threshold[4] = float[4](
|
||||||
|
1/4.,2/4.,
|
||||||
|
3/4.,1/4.
|
||||||
|
);
|
||||||
|
|
||||||
|
#elif BAYER == 4
|
||||||
|
|
||||||
|
const float threshold[16] = float[16](
|
||||||
|
1/16., 9/16., 3/16., 11/16.,
|
||||||
|
13/16., 5/16., 15/16., 7/16.,
|
||||||
|
4/16., 12/16., 2/16., 10/16.,
|
||||||
|
16/16., 8/16., 14/16., 6/16.
|
||||||
|
);
|
||||||
|
|
||||||
|
#else // 8
|
||||||
|
|
||||||
|
const float threshold[64] = float[64](
|
||||||
|
1/64.,33/64., 9/64.,41/64., 3/64.,35/64.,11/64.,43/64.,
|
||||||
|
49/64.,17/64.,57/64.,25/64.,51/64.,19/64.,59/64.,27/64.,
|
||||||
|
13/64.,45/64., 5/64.,37/64.,15/64.,47/64., 7/64.,39/64.,
|
||||||
|
61/64.,29/64.,53/64.,21/64.,63/64.,31/64.,55/64.,23/64.,
|
||||||
|
4/64.,36/64.,12/64.,42/64., 2/64.,34/64.,10/64.,42/64.,
|
||||||
|
52/64.,20/64.,60/64.,28/64.,50/64.,18/64.,58/64.,26/64.,
|
||||||
|
16/64.,48/64., 8/64.,40/64.,14/64.,46/64., 6/64.,38/64.,
|
||||||
|
64/64.,32/64.,56/64.,24/64.,62/64.,30/64.,54/64.,22/64.
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
|
||||||
|
vec2 uv = fragCoord/iResolution.xy;
|
||||||
|
vec4 src = texture(iChannel0, uv);
|
||||||
|
|
||||||
|
int x = int(fragCoord.x) % BAYER;
|
||||||
|
int y = int(fragCoord.y) % BAYER;
|
||||||
|
|
||||||
|
float luma = dot(vec3(0.2126, 0.7152, 0.0722), src.rgb);
|
||||||
|
luma = step(threshold[BAYER*x+y], luma); // find closest
|
||||||
|
|
||||||
|
fragColor = vec4(vec3(luma), src.a);
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
// FXAA fragment shader by Timothy Lottes (public domain)
|
||||||
|
// http://timothylottes.blogspot.com/
|
||||||
|
|
||||||
|
uniform sampler2D tex;
|
||||||
|
|
||||||
|
float FXAA_SUBPIX_SHIFT = 1.0/4.0;
|
||||||
|
|
||||||
|
// posPos: Output of FxaaVertexShader interpolated across screen.
|
||||||
|
// tex: Input texture.
|
||||||
|
// rcpFrame: const vec2(1.0/frameWidth, 1.0/frameHeight).
|
||||||
|
vec3 FxaaPixelShader(vec4 posPos, sampler2D tex, vec2 rcpFrame) {
|
||||||
|
#define FXAA_REDUCE_MIN (1.0/128.0)
|
||||||
|
#define FXAA_REDUCE_MUL (1.0/8.0)
|
||||||
|
#define FXAA_SPAN_MAX 8.0
|
||||||
|
|
||||||
|
vec3 rgbNW = texture2DLod(tex, posPos.zw, 0.0).xyz;
|
||||||
|
vec3 rgbNE = texture2DLod(tex, posPos.zw + vec2(1.0,0.0)*rcpFrame.xy, 0.0).xyz;
|
||||||
|
vec3 rgbSW = texture2DLod(tex, posPos.zw + vec2(0.0,1.0)*rcpFrame.xy, 0.0).xyz;
|
||||||
|
vec3 rgbSE = texture2DLod(tex, posPos.zw + vec2(1.0,1.0)*rcpFrame.xy, 0.0).xyz;
|
||||||
|
vec3 rgbM = texture2DLod(tex, posPos.xy,0.0).xyz;
|
||||||
|
|
||||||
|
vec3 luma = vec3(0.299, 0.587, 0.114);
|
||||||
|
float lumaNW = dot(rgbNW, luma);
|
||||||
|
float lumaNE = dot(rgbNE, luma);
|
||||||
|
float lumaSW = dot(rgbSW, luma);
|
||||||
|
float lumaSE = dot(rgbSE, luma);
|
||||||
|
float lumaM = dot(rgbM, luma);
|
||||||
|
|
||||||
|
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
|
||||||
|
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
|
||||||
|
|
||||||
|
vec2 dir;
|
||||||
|
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
|
||||||
|
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
|
||||||
|
|
||||||
|
float dirReduce = max(
|
||||||
|
(lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL),
|
||||||
|
FXAA_REDUCE_MIN);
|
||||||
|
float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);
|
||||||
|
dir = min(vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),
|
||||||
|
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
|
||||||
|
dir * rcpDirMin)) * rcpFrame.xy;
|
||||||
|
|
||||||
|
vec3 rgbA = (1.0/2.0) * (
|
||||||
|
texture2DLod(tex, posPos.xy + dir * (1.0/3.0 - 0.5),0.0).xyz +
|
||||||
|
texture2DLod(tex, posPos.xy + dir * (2.0/3.0 - 0.5),0.0).xyz);
|
||||||
|
vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (
|
||||||
|
texture2DLod(tex, posPos.xy + dir * (0.0/3.0 - 0.5),0.0).xyz +
|
||||||
|
texture2DLod(tex, posPos.xy + dir * (3.0/3.0 - 0.5),0.0).xyz);
|
||||||
|
float lumaB = dot(rgbB, luma);
|
||||||
|
if((lumaB < lumaMin) || (lumaB > lumaMax)) return rgbA;
|
||||||
|
return rgbB;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 FXAA(sampler2D tex, vec2 uv) {
|
||||||
|
vec2 rcpFrame = vec2(1.0/iWidth, 1.0/iHeight);
|
||||||
|
vec4 posPos = vec4(texcoord.st,texcoord.st -(rcpFrame * (0.5 + FXAA_SUBPIX_SHIFT)));
|
||||||
|
vec4 c = vec4(0.0);
|
||||||
|
c.rgb = FxaaPixelShader(posPos, tex, rcpFrame);
|
||||||
|
// c.rgb = texture2D(tex, posPos.xy).rgb - c.rgb; // debug
|
||||||
|
c.a = texture2D(tex, posPos.xy).a;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
FRAGCOLOR = FXAA(iChannel0, texcoord.st);
|
||||||
|
}
|
|
@ -0,0 +1,610 @@
|
||||||
|
/*****************************************
|
||||||
|
* FXAA 3.11 Implementation - effendiian
|
||||||
|
* -------------------------------------
|
||||||
|
* FXAA implementation based off of the
|
||||||
|
* work by Timothy Lottes in the Nvidia white paper:
|
||||||
|
* https://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf
|
||||||
|
*
|
||||||
|
* Also used these resources:
|
||||||
|
* - https://catlikecoding.com/unity/tutorials/advanced-rendering/fxaa/
|
||||||
|
* - https://blog.codinghorror.com/fast-approximate-anti-aliasing-fxaa/
|
||||||
|
*****************************************/
|
||||||
|
|
||||||
|
// Turn off FXAA.
|
||||||
|
// #define FXAA 0
|
||||||
|
|
||||||
|
// Turn on FXAA.
|
||||||
|
#define FXAA 1
|
||||||
|
|
||||||
|
// Turn on split screen between no-FXAA and FXAA.
|
||||||
|
// #define FXAA 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
/ FXAA setting, defined via preprocessor variables
|
||||||
|
*/
|
||||||
|
#ifndef FXAA_PRESET
|
||||||
|
#define FXAA_PRESET 5
|
||||||
|
#define FXAA_DEBUG_SKIPPED 0
|
||||||
|
#define FXAA_DEBUG_PASSTHROUGH 0
|
||||||
|
#define FXAA_DEBUG_HORZVERT 0
|
||||||
|
#define FXAA_DEBUG_PAIR 0
|
||||||
|
#define FXAA_DEBUG_NEGPOS 0
|
||||||
|
#define FXAA_DEBUG_OFFSET 0
|
||||||
|
#define FXAA_DEBUG_HIGHLIGHT 0
|
||||||
|
#define FXAA_LUMINANCE 1
|
||||||
|
#endif
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
#if (FXAA_PRESET == 0)
|
||||||
|
#define FXAA_EDGE_THRESHOLD (1.0/4.0)
|
||||||
|
#define FXAA_EDGE_THRESHOLD_MIN (1.0/12.0)
|
||||||
|
#define FXAA_SEARCH_STEPS 2
|
||||||
|
#define FXAA_SEARCH_ACCELERATION 4
|
||||||
|
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
|
||||||
|
#define FXAA_SUBPIX 1
|
||||||
|
#define FXAA_SUBPIX_FASTER 1
|
||||||
|
#define FXAA_SUBPIX_CAP (2.0/3.0)
|
||||||
|
#define FXAA_SUBPIX_TRIM (1.0/4.0)
|
||||||
|
#endif
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
#if (FXAA_PRESET == 1)
|
||||||
|
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
|
||||||
|
#define FXAA_EDGE_THRESHOLD_MIN (1.0/16.0)
|
||||||
|
#define FXAA_SEARCH_STEPS 4
|
||||||
|
#define FXAA_SEARCH_ACCELERATION 3
|
||||||
|
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
|
||||||
|
#define FXAA_SUBPIX 1
|
||||||
|
#define FXAA_SUBPIX_FASTER 0
|
||||||
|
#define FXAA_SUBPIX_CAP (3.0/4.0)
|
||||||
|
#define FXAA_SUBPIX_TRIM (1.0/4.0)
|
||||||
|
#endif
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
#if (FXAA_PRESET == 2)
|
||||||
|
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
|
||||||
|
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
|
||||||
|
#define FXAA_SEARCH_STEPS 8
|
||||||
|
#define FXAA_SEARCH_ACCELERATION 2
|
||||||
|
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
|
||||||
|
#define FXAA_SUBPIX 1
|
||||||
|
#define FXAA_SUBPIX_FASTER 0
|
||||||
|
#define FXAA_SUBPIX_CAP (3.0/4.0)
|
||||||
|
#define FXAA_SUBPIX_TRIM (1.0/4.0)
|
||||||
|
#endif
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
#if (FXAA_PRESET == 3)
|
||||||
|
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
|
||||||
|
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
|
||||||
|
#define FXAA_SEARCH_STEPS 16
|
||||||
|
#define FXAA_SEARCH_ACCELERATION 1
|
||||||
|
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
|
||||||
|
#define FXAA_SUBPIX 1
|
||||||
|
#define FXAA_SUBPIX_FASTER 0
|
||||||
|
#define FXAA_SUBPIX_CAP (3.0/4.0)
|
||||||
|
#define FXAA_SUBPIX_TRIM (1.0/4.0)
|
||||||
|
#endif
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
#if (FXAA_PRESET == 4)
|
||||||
|
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
|
||||||
|
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
|
||||||
|
#define FXAA_SEARCH_STEPS 24
|
||||||
|
#define FXAA_SEARCH_ACCELERATION 1
|
||||||
|
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
|
||||||
|
#define FXAA_SUBPIX 1
|
||||||
|
#define FXAA_SUBPIX_FASTER 0
|
||||||
|
#define FXAA_SUBPIX_CAP (3.0/4.0)
|
||||||
|
#define FXAA_SUBPIX_TRIM (1.0/4.0)
|
||||||
|
#endif
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
#if (FXAA_PRESET == 5)
|
||||||
|
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
|
||||||
|
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
|
||||||
|
#define FXAA_SEARCH_STEPS 32
|
||||||
|
#define FXAA_SEARCH_ACCELERATION 1
|
||||||
|
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
|
||||||
|
#define FXAA_SUBPIX 1
|
||||||
|
#define FXAA_SUBPIX_FASTER 0
|
||||||
|
#define FXAA_SUBPIX_CAP (3.0/4.0)
|
||||||
|
#define FXAA_SUBPIX_TRIM (1.0/4.0)
|
||||||
|
#endif
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
#define FXAA_SUBPIX_TRIM_SCALE (1.0/(1.0 - FXAA_SUBPIX_TRIM))
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Helper functions.
|
||||||
|
// --------------------------------------
|
||||||
|
|
||||||
|
// ---------------------
|
||||||
|
// Conversion functions.
|
||||||
|
|
||||||
|
// ToVec2
|
||||||
|
vec2 ToVec2( float value ) { return vec2(value, value); }
|
||||||
|
|
||||||
|
// ToVec3
|
||||||
|
vec3 ToVec3( float value ) { return vec3(value, value, value); }
|
||||||
|
vec3 ToVec3( vec2 vector, float z ) { return vec3(vector.x, vector.y, z); }
|
||||||
|
vec3 ToVec3( vec2 vector ) { return ToVec3(vector, 0.0); }
|
||||||
|
|
||||||
|
// ToVec4
|
||||||
|
vec4 ToVec4( vec2 vector, float z, float w ) { return vec4(vector.x, vector.y, z, w); }
|
||||||
|
vec4 ToVec4( vec2 vector, float z ) { return ToVec4(vector, z, 0.0); }
|
||||||
|
vec4 ToVec4( vec2 vector ) { return ToVec4(vector, 0.0); }
|
||||||
|
vec4 ToVec4( vec3 vector, float w ) { return vec4(vector.x, vector.y, vector.z, w); }
|
||||||
|
vec4 ToVec4( vec3 vector ) { return ToVec4(vector, 0.0); }
|
||||||
|
vec4 ToVec4( float value, float w ) { return vec4(value, value, value, w); }
|
||||||
|
vec4 ToVec4( float value ) { return ToVec4(value, 0.0); }
|
||||||
|
|
||||||
|
// ---------------------
|
||||||
|
// Texture sampler functions.
|
||||||
|
|
||||||
|
// Return sampled image from a point + offset texel space.
|
||||||
|
vec4 TextureOffset( sampler2D tex,
|
||||||
|
vec2 uv,
|
||||||
|
vec2 offset ) {
|
||||||
|
|
||||||
|
// Return color from the specified location.
|
||||||
|
return texture(tex, uv + offset);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------
|
||||||
|
// Grayscale functions.
|
||||||
|
|
||||||
|
// Return grayscaled image based off of the selected color channel.
|
||||||
|
vec3 Grayscale( vec3 color, int index ) {
|
||||||
|
int selectedChannel = clamp(index, 0, 2); // [0]r, [1]g, [2]b.
|
||||||
|
return ToVec3(color[selectedChannel]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return grayscaled image based off of the selected color channel.
|
||||||
|
vec4 Grayscale( vec4 color, int index ) {
|
||||||
|
int selectedChannel = clamp(index, 0, 3); // [0]r, [1]g, [2]b, [3]a.
|
||||||
|
return ToVec4(color[selectedChannel]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default to green color channel when no index is supplied.
|
||||||
|
vec3 Grayscale( vec3 color ) { return Grayscale(color, 1); }
|
||||||
|
vec4 Grayscale( vec4 color ) { return Grayscale(color, 1); }
|
||||||
|
|
||||||
|
// ---------------------
|
||||||
|
// Luminance functions.
|
||||||
|
|
||||||
|
// Map RGB to Luminance linearly.
|
||||||
|
float LinearRGBLuminance( vec3 color ) {
|
||||||
|
|
||||||
|
// Weights for relative luma from here: https://en.wikipedia.org/wiki/Luma_(video)
|
||||||
|
vec3 weight = vec3(0.2126729, 0.7151522, 0.0721750);
|
||||||
|
|
||||||
|
// Get the dot product:
|
||||||
|
// - color.r * weight.r + color.g * weight.g + color.b * weight*b.
|
||||||
|
return dot(color, weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Luminance based off of the original specification.
|
||||||
|
float FXAALuminance( vec3 color ) {
|
||||||
|
|
||||||
|
#if FXAA_LUMINANCE == 0
|
||||||
|
|
||||||
|
return LinearRGBLuminance( color );
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
return color.g * (0.587/0.299) + color.r;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------
|
||||||
|
// Vertical/Horizontal Edge Test functions.
|
||||||
|
|
||||||
|
float FXAAVerticalEdge( float lumaO,
|
||||||
|
float lumaN,
|
||||||
|
float lumaE,
|
||||||
|
float lumaS,
|
||||||
|
float lumaW,
|
||||||
|
float lumaNW,
|
||||||
|
float lumaNE,
|
||||||
|
float lumaSW,
|
||||||
|
float lumaSE ) {
|
||||||
|
|
||||||
|
// Slices to calculate.
|
||||||
|
float top = (0.25 * lumaNW) + (-0.5 * lumaN) + (0.25 * lumaNE);
|
||||||
|
float middle = (0.50 * lumaW ) + (-1.0 * lumaO) + (0.50 * lumaE );
|
||||||
|
float bottom = (0.25 * lumaSW) + (-0.5 * lumaS) + (0.25 * lumaSE);
|
||||||
|
|
||||||
|
// Return value.
|
||||||
|
return abs(top) + abs(middle) + abs(bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
float FXAAHorizontalEdge( float lumaO,
|
||||||
|
float lumaN,
|
||||||
|
float lumaE,
|
||||||
|
float lumaS,
|
||||||
|
float lumaW,
|
||||||
|
float lumaNW,
|
||||||
|
float lumaNE,
|
||||||
|
float lumaSW,
|
||||||
|
float lumaSE ) {
|
||||||
|
|
||||||
|
// Slices to calculate.
|
||||||
|
float top = (0.25 * lumaNW) + (-0.5 * lumaW) + (0.25 * lumaSW);
|
||||||
|
float middle = (0.50 * lumaN ) + (-1.0 * lumaO) + (0.50 * lumaS );
|
||||||
|
float bottom = (0.25 * lumaNE) + (-0.5 * lumaE) + (0.25 * lumaSE);
|
||||||
|
|
||||||
|
// Return value.
|
||||||
|
return abs(top) + abs(middle) + abs(bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------
|
||||||
|
// FXAA specific functions.
|
||||||
|
// ------------------------
|
||||||
|
|
||||||
|
// Entry point for the FXAA process.
|
||||||
|
vec3 applyFXAA(sampler2D textureSource,
|
||||||
|
vec2 textureDimensions,
|
||||||
|
vec2 pixelPosition,
|
||||||
|
vec2 screenResolution) {
|
||||||
|
|
||||||
|
// Normalized pixel coordinates (from 0 to 1).
|
||||||
|
vec2 uv = pixelPosition / screenResolution;
|
||||||
|
|
||||||
|
// Calculate distance between pixels in texture space.
|
||||||
|
vec2 texel = vec2(1.0, 1.0) / textureDimensions;
|
||||||
|
|
||||||
|
// Caculate the luminance.
|
||||||
|
// float luma = FXAALuminance(rgbO.xyz);
|
||||||
|
// float luma = LinearRGBLuminance(clamp(rgbO.xyz, 0.0, 1.0));
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
// 1. LOCAL CONTRAST CHECK
|
||||||
|
|
||||||
|
// Sample textures from cardinal directions.
|
||||||
|
vec3 rgbN = TextureOffset(textureSource, uv, vec2(0, -texel.y)).rgb; // NORTH
|
||||||
|
vec3 rgbW = TextureOffset(textureSource, uv, vec2(-texel.x, 0)).rgb; // WEST
|
||||||
|
vec3 rgbO = TextureOffset(textureSource, uv, vec2(0, 0)).rgb; // ORIGIN
|
||||||
|
vec3 rgbE = TextureOffset(textureSource, uv, vec2(texel.x, 0)).rgb; // EAST
|
||||||
|
vec3 rgbS = TextureOffset(textureSource, uv, vec2(0, texel.y)).rgb; // SOUTH
|
||||||
|
|
||||||
|
#if FXAA == 0
|
||||||
|
return rgbO; // Skip FXAA if it is off.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Calculate the luminance for each sampled value.
|
||||||
|
float lumaN = FXAALuminance(rgbN);
|
||||||
|
float lumaW = FXAALuminance(rgbW);
|
||||||
|
float lumaO = FXAALuminance(rgbO);
|
||||||
|
float lumaE = FXAALuminance(rgbE);
|
||||||
|
float lumaS = FXAALuminance(rgbS);
|
||||||
|
|
||||||
|
// Calculate the minimum luma range.
|
||||||
|
float minLuma = min( lumaO, min( min( lumaN, lumaW ), min( lumaS, lumaE ) ) );
|
||||||
|
float maxLuma = max( lumaO, max( max( lumaN, lumaW ), max( lumaS, lumaE ) ) );
|
||||||
|
float localContrast = maxLuma - minLuma;
|
||||||
|
|
||||||
|
// Check for early exit.
|
||||||
|
if(localContrast < max( FXAA_EDGE_THRESHOLD_MIN, maxLuma * FXAA_EDGE_THRESHOLD )) {
|
||||||
|
|
||||||
|
#if FXAA_DEBUG_SKIPPED
|
||||||
|
|
||||||
|
return vec3(0);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
return rgbO;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
// 2. SUB-PIXEL ALIASING TEST
|
||||||
|
|
||||||
|
// Calculate the pixel contrast ratio.
|
||||||
|
// - Sub-pixel aliasing is detected by taking the ratio of the
|
||||||
|
// pixel contrast over the local contrast. This ratio nears 1.0
|
||||||
|
// in the presence of single pixel dots and otherwise falls off
|
||||||
|
// towards 0.0 as more pixels contribute to an edge. This ratio
|
||||||
|
// is transformed into the amount of lowpass filter to blend in
|
||||||
|
// at the end of the algorithm.
|
||||||
|
|
||||||
|
#if FXAA_SUBPIX > 0
|
||||||
|
|
||||||
|
// Calculate sum of local samples for the lowpass.
|
||||||
|
vec3 rgbL = (rgbN + rgbW + rgbO + rgbE + rgbS);
|
||||||
|
|
||||||
|
#if FXAA_SUBPIX_FASTER
|
||||||
|
|
||||||
|
// Average the lowpass now since this skips the addition of the diagonal neighbors (NW, NE, SW, SE).
|
||||||
|
rgbL *= (1.0/5.0);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Calculate the lowpass luma.
|
||||||
|
// - Lowpass luma is calculated as the average between the luma of neigboring pixels.
|
||||||
|
float lumaL = (lumaN + lumaW + lumaS + lumaE) * 0.25;
|
||||||
|
|
||||||
|
// Calculate the pixel contrast.
|
||||||
|
// - Pixel contrast is the abs() difference between origin pixel luma and lowpass luma of neighbors.
|
||||||
|
float pixelContrast = abs(lumaL - lumaO);
|
||||||
|
|
||||||
|
// Remember:
|
||||||
|
// - pixel contrast is the origin - lowpass(neighbors).
|
||||||
|
// - local contrast is the min(origin + neighbors) - max(origin + neighbors) < threshold.
|
||||||
|
|
||||||
|
// Calculate the ratio between the pixelContrast and localContrast.
|
||||||
|
float contrastRatio = pixelContrast / localContrast;
|
||||||
|
float lowpassBlend = 0.0; // Default is zero. Will be changed depending on subpixel level.
|
||||||
|
|
||||||
|
#if FXAA_SUBPIX == 1
|
||||||
|
|
||||||
|
// Normal subpixel aliasing. Set based on FXAA algorithm for subpixel aliasing.
|
||||||
|
lowpassBlend = max( 0.0, contrastRatio - FXAA_SUBPIX_TRIM ) * FXAA_SUBPIX_TRIM_SCALE;
|
||||||
|
lowpassBlend = min( FXAA_SUBPIX_CAP, lowpassBlend );
|
||||||
|
|
||||||
|
#elif FXAA_SUBPIX == 2
|
||||||
|
|
||||||
|
// Full force subpixel aliasing. Set blend to ratio.
|
||||||
|
lowpassBlend = contrastRatio;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Show selected pixels if debug mode is active.
|
||||||
|
#if FXAA_DEBUG_PASSTHROUGH
|
||||||
|
|
||||||
|
#if FXAA_SUBPIX > 0
|
||||||
|
|
||||||
|
return vec3(localContrast, lowpassBlend, 0.0);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
return vec3(localContrast, 0.0, 0.0);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
// 3. VERTICAL & HORIZONTAL EDGE TEST
|
||||||
|
|
||||||
|
// Sample the additional diagonal neighbors.
|
||||||
|
vec3 rgbNW = TextureOffset(textureSource, uv, vec2(-texel.x, -texel.y)).rgb; // NORTH-WEST
|
||||||
|
vec3 rgbNE = TextureOffset(textureSource, uv, vec2(texel.x, -texel.y)).rgb; // NORTH-EAST
|
||||||
|
vec3 rgbSW = TextureOffset(textureSource, uv, vec2(-texel.x, texel.y)).rgb; // SOUTH-WEST
|
||||||
|
vec3 rgbSE = TextureOffset(textureSource, uv, vec2(texel.x, texel.y)).rgb; // SOUTH-EAST
|
||||||
|
|
||||||
|
// Average additional neighbors when sub-pix aliasing is on and it isn't in 'fast' mode.
|
||||||
|
#if FXAA_SUBPIX > 0
|
||||||
|
#if FXAA_SUBPIX_FASTER == 0
|
||||||
|
// Add missing neighbors and average them.
|
||||||
|
rgbL += (rgbNW + rgbNE + rgbSW + rgbSE);
|
||||||
|
rgbL *= (1.0/9.0);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Calculate luma for additional neighbors.
|
||||||
|
float lumaNW = FXAALuminance(rgbNW);
|
||||||
|
float lumaNE = FXAALuminance(rgbNE);
|
||||||
|
float lumaSW = FXAALuminance(rgbSW);
|
||||||
|
float lumaSE = FXAALuminance(rgbSE);
|
||||||
|
|
||||||
|
// Calculate the vertical and horizontal edges. (Uses algorithm from FXAA white paper).
|
||||||
|
float edgeVert = FXAAVerticalEdge(lumaO, lumaN, lumaE, lumaS, lumaW, lumaNW, lumaNE, lumaSW, lumaSE);
|
||||||
|
float edgeHori = FXAAHorizontalEdge(lumaO, lumaN, lumaE, lumaS, lumaW, lumaNW, lumaNE, lumaSW, lumaSE);
|
||||||
|
|
||||||
|
// Check if edge is horizontal.
|
||||||
|
bool isHorizontal = edgeHori >= edgeVert;
|
||||||
|
|
||||||
|
#if FXAA_DEBUG_HORZVERT
|
||||||
|
if(isHorizontal)
|
||||||
|
{
|
||||||
|
return vec3(1.0, 0.75, 0.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return vec3(0.10, 0.10, 1.0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
// 4. FIND HIGHEST CONTRAST PAIR 90deg TO EDGE
|
||||||
|
|
||||||
|
// Contain the appropriate sign for the top left.
|
||||||
|
float edgeSign = isHorizontal ? -texel.y : -texel.x; // Note, if isHorizontal == true, -texel.y is applied (not -texel.x).
|
||||||
|
|
||||||
|
// Calculate the gradients. The luma used changes based on the horizontal edge status.
|
||||||
|
float gradientNeg = isHorizontal ? abs(lumaN - lumaO) : abs(lumaW - lumaO);
|
||||||
|
float gradientPos = isHorizontal ? abs(lumaS - lumaO) : abs(lumaE - lumaO);
|
||||||
|
|
||||||
|
// Calculate the luma based on its direction.
|
||||||
|
// It is an average of the origin and the luma in the respective direction.
|
||||||
|
float lumaNeg = isHorizontal ? ((lumaN + lumaO) * 0.5) : ((lumaW + lumaO) * 0.5);
|
||||||
|
float lumaPos = isHorizontal ? ((lumaS + lumaO) * 0.5) : ((lumaE + lumaO) * 0.5);
|
||||||
|
|
||||||
|
// Select the highest gradient pair.
|
||||||
|
bool isNegative = (gradientNeg >= gradientPos);
|
||||||
|
float gradientHighest = isNegative ? gradientNeg : gradientPos; // Assign higher pair.
|
||||||
|
float lumaHighest = isNegative ? lumaNeg : lumaPos;
|
||||||
|
|
||||||
|
// If gradient pair in the negative direction is higher, flip the edge sign.
|
||||||
|
if(isNegative) { edgeSign *= -1.0; }
|
||||||
|
|
||||||
|
#if FXAA_DEBUG_PAIR
|
||||||
|
return isHorizontal ? vec3(0.0, gradientHighest, lumaHighest) : vec3(0.0, lumaHighest, gradientHighest);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
// 5. END-OF-EDGE SEARCH
|
||||||
|
|
||||||
|
// Select starting point.
|
||||||
|
vec2 pointN = vec2(0.0, 0.0);
|
||||||
|
pointN.x = uv.x + (isHorizontal ? 0.0 : edgeSign * 0.5);
|
||||||
|
pointN.y = uv.y + (isHorizontal ? edgeSign * 0.5 : 0.0);
|
||||||
|
|
||||||
|
// Assign search limiting values.
|
||||||
|
gradientHighest *= FXAA_SEARCH_THRESHOLD;
|
||||||
|
|
||||||
|
// Prepare variables for search.
|
||||||
|
vec2 pointP = pointN; // Start at the same point.
|
||||||
|
vec2 pointOffset = isHorizontal ? vec2(texel.x, 0.0) : vec2(0.0, texel.y);
|
||||||
|
float lumaNegEnd = lumaNeg;
|
||||||
|
float lumaPosEnd = lumaPos;
|
||||||
|
bool searchNeg = false;
|
||||||
|
bool searchPos = false;
|
||||||
|
|
||||||
|
// Apply values based on FXAA flags.
|
||||||
|
if(FXAA_SEARCH_ACCELERATION == 1) {
|
||||||
|
|
||||||
|
pointN += pointOffset * vec2(-1.0);
|
||||||
|
pointP += pointOffset * vec2(1.0);
|
||||||
|
// pointOffset *= vec2(1.0);
|
||||||
|
|
||||||
|
} else if(FXAA_SEARCH_ACCELERATION == 2) {
|
||||||
|
|
||||||
|
pointN += pointOffset * vec2(-1.5);
|
||||||
|
pointP += pointOffset * vec2(1.5);
|
||||||
|
pointOffset *= vec2(2.0);
|
||||||
|
|
||||||
|
} else if(FXAA_SEARCH_ACCELERATION == 3) {
|
||||||
|
|
||||||
|
pointN += pointOffset * vec2(-2.0);
|
||||||
|
pointP += pointOffset * vec2(2.0);
|
||||||
|
pointOffset *= vec2(3.0);
|
||||||
|
|
||||||
|
} else if(FXAA_SEARCH_ACCELERATION == 4) {
|
||||||
|
|
||||||
|
pointN += pointOffset * vec2(-2.5);
|
||||||
|
pointP += pointOffset * vec2(2.5);
|
||||||
|
pointOffset *= vec2(4.0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform the end-of-edge search.
|
||||||
|
for(int i = 0; i < FXAA_SEARCH_STEPS; i++)
|
||||||
|
{
|
||||||
|
if(FXAA_SEARCH_ACCELERATION == 1) {
|
||||||
|
if(!searchNeg) { lumaNegEnd = FXAALuminance(texture(textureSource, pointN).rgb); }
|
||||||
|
if(!searchPos) { lumaPosEnd = FXAALuminance(texture(textureSource, pointP).rgb); }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!searchNeg) { lumaNegEnd = FXAALuminance(textureGrad(textureSource, pointN, pointOffset, pointOffset).rgb); }
|
||||||
|
if(!searchPos) { lumaPosEnd = FXAALuminance(textureGrad(textureSource, pointP, pointOffset, pointOffset).rgb); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for significant change in luma compared to current highest pair.
|
||||||
|
#if 0 // original
|
||||||
|
searchNeg = searchNeg || (abs(lumaNegEnd - lumaNeg) >= gradientNeg);
|
||||||
|
searchPos = searchPos || (abs(lumaPosEnd - lumaPos) >= gradientPos);
|
||||||
|
#else // iradicator's fix
|
||||||
|
searchNeg = searchNeg || (abs(lumaNegEnd - lumaHighest) >= gradientHighest);
|
||||||
|
searchPos = searchPos || (abs(lumaPosEnd - lumaHighest) >= gradientHighest);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Display debug information regarding edges.
|
||||||
|
#if FXAA_DEBUG_NEGPOS
|
||||||
|
|
||||||
|
if(searchNeg) {
|
||||||
|
return vec3(abs(lumaNegEnd - gradientNeg), 0.0, 0.0);
|
||||||
|
} else if(searchPos) {
|
||||||
|
return vec3(0.0, 0.0, abs(lumaPosEnd - gradientPos));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Determine if search is over early.
|
||||||
|
if(searchNeg && searchPos) { break; }
|
||||||
|
|
||||||
|
// If still searching, increment offset.
|
||||||
|
if(!searchNeg) { pointN -= pointOffset; }
|
||||||
|
if(!searchPos) { pointP += pointOffset; }
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
// 6. SUB-PIXEL SHIFT
|
||||||
|
|
||||||
|
// Determine if sub-pixel center falls on positive or negative side.
|
||||||
|
float distanceNeg = isHorizontal ? uv.x - pointN.x : uv.y - pointN.y;
|
||||||
|
float distancePos = isHorizontal ? pointP.x - uv.x : pointP.y - uv.y;
|
||||||
|
bool isCloserToNegative = distanceNeg < distancePos;
|
||||||
|
|
||||||
|
// Assign respective luma.
|
||||||
|
float lumaEnd = isCloserToNegative ? lumaNegEnd : lumaPosEnd;
|
||||||
|
|
||||||
|
// Check if pixel is in area that receives no filtering.
|
||||||
|
if( ((lumaO - lumaNeg) < 0.0) == ((lumaEnd - lumaNeg) < 0.0) ) {
|
||||||
|
edgeSign = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute sub-pixel offset and filter span.
|
||||||
|
float filterSpanLength = (distancePos + distanceNeg);
|
||||||
|
float filterDistance = isCloserToNegative ? distanceNeg : distancePos;
|
||||||
|
float subpixelOffset = ( 0.5 + ( filterDistance * (-1.0 / filterSpanLength) ) ) * edgeSign;
|
||||||
|
|
||||||
|
#if FXAA_DEBUG_OFFSET
|
||||||
|
|
||||||
|
if(subpixelOffset < 0.0) {
|
||||||
|
return isHorizontal ? vec3(1.0, 0.0, 0.0) : vec3(1.0, 0.7, 0.1); // neg-horizontal (red) : neg-vertical (gold)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(subpixelOffset > 0.0) {
|
||||||
|
return isHorizontal ? vec3(0.0, 0.0, 1.0) : vec3(0.1, 0.3, 1.0); // pos-horizontal (blue) : pos-vertical (skyblue)
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Resample using the subpixel offset.
|
||||||
|
vec3 rgbOffset = textureLod(textureSource, vec2( uv.x + (isHorizontal ? 0.0 : subpixelOffset), uv.y + (isHorizontal ? subpixelOffset : 0.0)), 0.0).rgb;
|
||||||
|
|
||||||
|
// return vec3((lumaN + lumaS + lumaE + lumaW + lumaNW + lumaNE + lumaSW + lumaSE) * (1.0/9.0));
|
||||||
|
|
||||||
|
#if FXAA_DEBUG_HIGHLIGHT
|
||||||
|
|
||||||
|
return isHorizontal ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Return the FXAA effect.
|
||||||
|
#if FXAA_SUBPIX == 0
|
||||||
|
|
||||||
|
return vec3(rgbOffset);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
return mix(rgbOffset, rgbL, lowpassBlend);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------
|
||||||
|
// Main function.
|
||||||
|
// ------------------------
|
||||||
|
|
||||||
|
void mainImage( out vec4 fragColor, in vec2 fragCoord )
|
||||||
|
{
|
||||||
|
|
||||||
|
#if (FXAA == 2)
|
||||||
|
|
||||||
|
vec2 uv = fragCoord/iResolution.xy; // Normalized pixel coordinates (from 0 to 1)
|
||||||
|
vec3 resultFXAA = vec3(1.0);
|
||||||
|
|
||||||
|
float speed = 0.45;
|
||||||
|
vec2 extents = vec2(0.1, 0.8);
|
||||||
|
float divisor = ( ((sin(iTime * speed) * 0.5) + 0.5) * extents.y ) + extents.x;
|
||||||
|
float increment = 0.005;
|
||||||
|
|
||||||
|
float divNeg = divisor - increment;
|
||||||
|
float divPos = divisor + increment;
|
||||||
|
|
||||||
|
if(uv.x >= divNeg && uv.x <= divPos) { resultFXAA = vec3(0.1); }
|
||||||
|
if(uv.x < divNeg) { resultFXAA = mix(texture(iChannel0, vec2(uv.x, uv.y)).xyz, vec3(0.9, 0.9, 0.9), 0.1); }
|
||||||
|
if(uv.x > divPos) { resultFXAA = applyFXAA(iChannel0, iChannelResolution[0].xy, fragCoord, iResolution.xy); }
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Calculuate the FXAA value for the whole screen.
|
||||||
|
vec3 resultFXAA = applyFXAA(iChannel0, iChannelResolution[0].xy, fragCoord, iResolution.xy);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Return the sampled pixel.
|
||||||
|
fragColor = ToVec4(resultFXAA, 1.0);
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
uniform float intensity = 16.0;
|
||||||
|
|
||||||
|
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
|
||||||
|
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||||
|
vec4 color = texture(iChannel0, uv), outcolor;
|
||||||
|
|
||||||
|
float x = (uv.x + 4.0 ) * (uv.y + 4.0 ) * (iTime * 10.0);
|
||||||
|
vec4 grain = vec4(mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01)-0.005) * intensity;
|
||||||
|
|
||||||
|
outcolor = color + grain; // method 1
|
||||||
|
// outcolor = color * (1.0 - grain); // method 2
|
||||||
|
|
||||||
|
FRAGCOLOR = vec4(outcolor.rgb, color.a);
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
uniform float h = 1.0; // tint shift
|
||||||
|
uniform float s = 0.5; // saturate: >1, decolorize: <1
|
||||||
|
uniform float v = 1.0; // white: >1, gray: <1
|
||||||
|
|
||||||
|
vec3 hsv2rgb(vec3 c) {
|
||||||
|
return mix(vec3(1.),clamp((abs(fract(c.r+vec3(3.,2.,1.)/3.)*6.-3.)-1.),0.,1.),c.g)*c.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 rgb2hsv(vec3 c) {
|
||||||
|
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||||
|
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||||
|
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 uv = TEXCOORD.st;
|
||||||
|
vec4 src = texture2D( iChannel0, uv );
|
||||||
|
|
||||||
|
vec3 c = rgb2hsv(src.rgb);
|
||||||
|
|
||||||
|
FRAGCOLOR = vec4( hsv2rgb(c * vec3(h,s,v)), src.a );
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
void mainImage( out vec4 fragColor, in vec2 fragCoord )
|
||||||
|
{
|
||||||
|
// letterbox
|
||||||
|
if( abs(2.*fragCoord.y-iResolution.y) > iResolution.x * 0.42 ) {
|
||||||
|
fragColor = vec4( 0., 0., 0., 1. );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||||
|
fragColor = texture(iChannel0, uv);
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
uniform int thickness = 2;
|
||||||
|
uniform vec4 border_color = vec4(1,1,0,1);
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texel = texture(iChannel0, uv);
|
||||||
|
float outline = 0.0;
|
||||||
|
if( texel.a == 0.0 ) {
|
||||||
|
for( int x = -thickness; x <= thickness; x++ ) {
|
||||||
|
for( int y = -thickness;y <= thickness; y++ ) {
|
||||||
|
float sample = texture(iChannel0, uv+vec2(float(x)/iWidth, float(y)/iHeight)).a;
|
||||||
|
if( sample > 0.0 ) {
|
||||||
|
outline = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FRAGCOLOR = mix(texel, border_color, outline * border_color.a);
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
uniform float xCellSize = 2.5;
|
||||||
|
uniform float yCellSize = 2.5;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
float xPixels = iWidth/xCellSize, yPixels = iHeight/yCellSize;
|
||||||
|
vec2 uv = vec2(floor(texcoord.s * xPixels) / xPixels, floor(texcoord.t * yPixels) / yPixels);
|
||||||
|
FRAGCOLOR = texture(iChannel0, uv);
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
uniform float factor = 3.0; // [1(max)..255(min)]
|
||||||
|
|
||||||
|
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
|
||||||
|
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||||
|
vec4 src = texture(iChannel0, uv);
|
||||||
|
fragColor = vec4(floor(src.rgb * factor + 0.5) / factor, src.a);
|
||||||
|
}
|
|
@ -0,0 +1,132 @@
|
||||||
|
// based on code by arkano22. See: http://www.gamedev.net/forums/topic/550699-ssao-no-halo-artifacts/
|
||||||
|
// - rlyeh, public domain
|
||||||
|
|
||||||
|
uniform vec2 camerarange = vec2(1.0, 1024.0);
|
||||||
|
|
||||||
|
// uniform sampler2D som; // Depth texture (iChannel1)
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
uniform sampler2D rand; // Random texture (iChannel2)
|
||||||
|
|
||||||
|
vec2 getRandom(vec2 uv) {
|
||||||
|
vec3 random = texture2D(rand, uv.st);
|
||||||
|
return random*2.0-vec3(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define MOD3 vec3(.1031,.11369,.13787)
|
||||||
|
|
||||||
|
float hash12(vec2 p) {
|
||||||
|
vec3 p3 = fract(vec3(p.xyx) * MOD3);
|
||||||
|
p3 += dot(p3, p3.yzx + 19.19);
|
||||||
|
return fract((p3.x + p3.y) * p3.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 hash22(vec2 p) {
|
||||||
|
vec3 p3 = fract(vec3(p.xyx) * MOD3);
|
||||||
|
p3 += dot(p3, p3.yzx+19.19);
|
||||||
|
return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 getPosition(vec2 uv) {
|
||||||
|
float fl = textureLod(iChannel0, vec2(0.), 0.).x;
|
||||||
|
float d = textureLod(iChannel0, uv, 0.).w;
|
||||||
|
|
||||||
|
vec2 p = uv*2.-1.;
|
||||||
|
mat3 ca = mat3(1.,0.,0.,0.,1.,0.,0.,0.,-1./1.5);
|
||||||
|
vec3 rd = normalize( ca * vec3(p,fl) );
|
||||||
|
|
||||||
|
vec3 pos = rd * d;
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 getRandom(vec2 uv) {
|
||||||
|
return normalize(hash22(uv*126.1231) * 2. - 1.);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
float pw = 1.0/iResolution.x*0.5;
|
||||||
|
float ph = 1.0/iResolution.y*0.5;
|
||||||
|
|
||||||
|
float readDepth(in vec2 coord) {
|
||||||
|
if (coord.x<0||coord.y<0) return 1.0;
|
||||||
|
float nearZ = camerarange.x;
|
||||||
|
float farZ =camerarange.y;
|
||||||
|
float posZ = texture(iChannel1, coord).x;
|
||||||
|
return (2.0 * nearZ) / (nearZ + farZ - posZ * (farZ - nearZ));
|
||||||
|
}
|
||||||
|
|
||||||
|
float compareDepths(in float depth1, in float depth2,inout int far) {
|
||||||
|
float diff = (depth1 - depth2)*100; //depth difference (0-100)
|
||||||
|
float gdisplace = 0.2; //gauss bell center
|
||||||
|
float garea = 2.0; //gauss bell width 2
|
||||||
|
//reduce left bell width to avoid self-shadowing
|
||||||
|
if (diff<gdisplace){
|
||||||
|
garea = 0.1;
|
||||||
|
}else{
|
||||||
|
far = 1;
|
||||||
|
}
|
||||||
|
float gauss = pow(2.7182,-2*(diff-gdisplace)*(diff-gdisplace)/(garea*garea));
|
||||||
|
return gauss;
|
||||||
|
}
|
||||||
|
|
||||||
|
float calcAO(float depth, vec2 uv, float dw, float dh) {
|
||||||
|
float temp = 0;
|
||||||
|
float temp2 = 0;
|
||||||
|
float coordw = uv.x + dw/depth;
|
||||||
|
float coordh = uv.y + dh/depth;
|
||||||
|
float coordw2 = uv.x - dw/depth;
|
||||||
|
float coordh2 = uv.y - dh/depth;
|
||||||
|
if (coordw < 1.0 && coordw > 0.0 && coordh < 1.0 && coordh > 0.0){
|
||||||
|
vec2 coord = vec2(coordw , coordh);
|
||||||
|
vec2 coord2 = vec2(coordw2, coordh2);
|
||||||
|
int far = 0;
|
||||||
|
temp = compareDepths(depth, readDepth(coord),far);
|
||||||
|
//DEPTH EXTRAPOLATION:
|
||||||
|
if (far > 0){
|
||||||
|
temp2 = compareDepths(readDepth(coord2),depth,far);
|
||||||
|
temp += (1.0-temp)*temp2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mainImage( out vec4 fragColor, in vec2 fragCoord )
|
||||||
|
{
|
||||||
|
//randomization texture:
|
||||||
|
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||||
|
vec2 random = getRandom( uv + vec2(iTime) );
|
||||||
|
|
||||||
|
//initialize stuff:
|
||||||
|
float depth = readDepth(uv);
|
||||||
|
float ao = 0.0;
|
||||||
|
for(int i=0; i<4;++i) {
|
||||||
|
//calculate color bleeding and ao:
|
||||||
|
ao+=calcAO(depth, uv, pw, ph);
|
||||||
|
ao+=calcAO(depth, uv, pw, -ph);
|
||||||
|
ao+=calcAO(depth, uv, -pw, ph);
|
||||||
|
ao+=calcAO(depth, uv, -pw, -ph);
|
||||||
|
ao+=calcAO(depth, uv, pw*1.2, 0);
|
||||||
|
ao+=calcAO(depth, uv, -pw*1.2, 0);
|
||||||
|
ao+=calcAO(depth, uv, 0, ph*1.2);
|
||||||
|
ao+=calcAO(depth, uv, 0, -ph*1.2);
|
||||||
|
|
||||||
|
//sample jittering:
|
||||||
|
pw += random.x*0.0007;
|
||||||
|
ph += random.y*0.0007;
|
||||||
|
|
||||||
|
//increase sampling area:
|
||||||
|
pw *= 1.7;
|
||||||
|
ph *= 1.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
//final values, some adjusting:
|
||||||
|
vec4 texel = texture(iChannel0, uv);
|
||||||
|
float finalAO = 1.0-(ao/32.0); finalAO = 0.5+finalAO*0.5;
|
||||||
|
fragColor = vec4(texel.rgb * vec3(finalAO), texel.a);
|
||||||
|
//fragColor = vec4(vec3(finalAO), texel.a); // << debug
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
uniform float hardness = 0.1;
|
||||||
|
uniform float flickering = 0.01;
|
||||||
|
|
||||||
|
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
|
||||||
|
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||||
|
|
||||||
|
vec4 src = texture( iChannel0, vec2(uv.x,uv.y) );
|
||||||
|
vec3 color = src.rgb;
|
||||||
|
|
||||||
|
color *= (1.0 - hardness)+hardness*sin(10.0*iTime+uv.y*1000.0);
|
||||||
|
color *= (1.0 - flickering)+flickering*sin(100.0*iTime);
|
||||||
|
|
||||||
|
fragColor = vec4(color, src.a);
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
// https://www.shadertoy.com/view/4dcSRX
|
||||||
|
// https://www.shadertoy.com/view/MslGR8
|
||||||
|
// https://www.shadertoy.com/view/Md3XRf *
|
||||||
|
|
||||||
|
// note: valve edition from http://alex.vlachos.com/graphics/Alex_Vlachos_Advanced_VR_Rendering_GDC2015.pdf
|
||||||
|
// note: input in pixels (ie not normalized uv)
|
||||||
|
|
||||||
|
uniform float intensity = 250.0; // [2..255]
|
||||||
|
|
||||||
|
vec3 ScreenSpaceDither2(vec2 vScreenPos, float colorDepth) {
|
||||||
|
// lestyn's RGB dither (7 asm instructions) from Portal 2 X360, slightly modified for VR
|
||||||
|
vec3 vDither = vec3(dot(vec2(131.0, 312.0), vScreenPos.xy + iTime));
|
||||||
|
vDither.rgb = fract(vDither.rgb / vec3(103.0, 71.0, 97.0)) - vec3(0.5, 0.5, 0.5);
|
||||||
|
return (vDither.rgb / colorDepth) * 0.375;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
|
||||||
|
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||||
|
|
||||||
|
vec4 color = texture(iChannel0, uv);
|
||||||
|
fragColor = color + vec4(ScreenSpaceDither2(gl_FragCoord.xy,255.0 - intensity), 0);
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
uniform float intensity = 1.0;
|
||||||
|
|
||||||
|
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
|
||||||
|
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||||
|
vec4 src = texture(iChannel0, uv);
|
||||||
|
|
||||||
|
vec3 color = vec3(
|
||||||
|
dot(src.rgb, vec3(0.393 * intensity, 0.769 * intensity, 0.189 * intensity)),
|
||||||
|
dot(src.rgb, vec3(0.349 * intensity, 0.686 * intensity, 0.168 * intensity)),
|
||||||
|
dot(src.rgb, vec3(0.272 * intensity, 0.534 * intensity, 0.131 * intensity))
|
||||||
|
);
|
||||||
|
|
||||||
|
fragColor = vec4(color, src.a);
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
uniform float intensity = 1.0;
|
||||||
|
|
||||||
|
void mainImage( out vec4 fragColor, in vec2 fragCoord ){
|
||||||
|
vec2 uv = fragCoord / iResolution.xy;
|
||||||
|
vec4 src = texture(iChannel0, uv);
|
||||||
|
vec3 kernel = src.rgb * 9. +
|
||||||
|
-1. * texture(iChannel0, uv + vec2(-1,-1) / iResolution.xy).rgb
|
||||||
|
-1. * texture(iChannel0, uv + vec2( 0,-1) / iResolution.xy).rgb
|
||||||
|
-1. * texture(iChannel0, uv + vec2( 1,-1) / iResolution.xy).rgb
|
||||||
|
-1. * texture(iChannel0, uv + vec2(-1, 0) / iResolution.xy).rgb
|
||||||
|
-1. * texture(iChannel0, uv + vec2( 1, 0) / iResolution.xy).rgb
|
||||||
|
-1. * texture(iChannel0, uv + vec2(-1, 1) / iResolution.xy).rgb
|
||||||
|
-1. * texture(iChannel0, uv + vec2( 0, 1) / iResolution.xy).rgb
|
||||||
|
-1. * texture(iChannel0, uv + vec2( 1, 1) / iResolution.xy).rgb;
|
||||||
|
vec3 outcolor = mix(src.rgb, kernel, intensity);
|
||||||
|
fragColor = vec4(outcolor, src.a);
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
// https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
|
||||||
|
vec3 acesFilm(const vec3 x) {
|
||||||
|
const float a = 2.51;
|
||||||
|
const float b = 0.03;
|
||||||
|
const float c = 2.43;
|
||||||
|
const float d = 0.59;
|
||||||
|
const float e = 0.14;
|
||||||
|
return clamp((x * (a * x + b)) / (x * (c * x + d ) + e), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
vec2 uv = TEXCOORD.st;
|
||||||
|
vec4 src = texture2D(iChannel0, uv);
|
||||||
|
color = vec4( acesFilm(src.xyz), src.a);
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
// exposure tone mapping
|
||||||
|
// https://learnopengl.com/Advanced-Lighting/HDR
|
||||||
|
|
||||||
|
uniform float exposure = 1.0; // [0.1 .. 5]
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
vec2 uv = TEXCOORD.st;
|
||||||
|
vec4 HDR_color = texture2D(iChannel0, uv); // HDR_color, SRGB texture
|
||||||
|
vec3 mapped = vec3(1.0) - exp(-HDR_color.xyz * exposure);
|
||||||
|
color = vec4( mapped.xyz, HDR_color.a );
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
// Src: http://www.slideshare.net/ozlael/hable-john-uncharted2-hdr-lighting
|
||||||
|
// Based on Filmic Tonemapping Operators http://filmicgames.com/archives/75
|
||||||
|
|
||||||
|
vec3 tonemapFilmic(vec3 linearColor) {
|
||||||
|
vec3 x = max(vec3(0.0), linearColor - 0.004);
|
||||||
|
return (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remember final color = CustomFilmic(Linear color) / CustomFilmic(Linear white point value) : No gamma baked in
|
||||||
|
|
||||||
|
vec3 customFilmic(vec3 linearColor, float shoulderStr, float linearStr, float linearAngle, float toeStr, float toeNumer, float toeDenom) {
|
||||||
|
return ((linearColor * (shoulderStr * linearColor + linearAngle * linearStr) + toeStr * toeNumer) / (linearColor * (shoulderStr * linearColor + linearStr) + toeStr * toeDenom)) - toeNumer / toeDenom;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function applies a "film-like" tonemap to supplied
|
||||||
|
// HDR pixel. Does not apply 2.2 Gamma correction.
|
||||||
|
//
|
||||||
|
// hdr: linear colour in HDR
|
||||||
|
// whitePoint: scene white point / exposure. must be > 0.0
|
||||||
|
//
|
||||||
|
// src: https://twitter.com/jimhejl/status/841149752389558272
|
||||||
|
|
||||||
|
vec3 tonemapFilmic_hejl2015(vec3 hdr, float whitePoint) {
|
||||||
|
vec4 vh = vec4(hdr, whitePoint);
|
||||||
|
vec4 va = (1.425 * vh) + 0.05f; // evaluate filmic curve
|
||||||
|
vec4 vf = ((vh * va + 0.004f) / ((vh * (va + 0.55f) + 0.0491f))) - 0.0821f;
|
||||||
|
return vf.rgb / vf.www;
|
||||||
|
}
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
vec2 uv = TEXCOORD.st;
|
||||||
|
vec4 src = texture2D(iChannel0, uv);
|
||||||
|
color = vec4( tonemapFilmic_hejl2015(src.xyz, 0.5), src.a);
|
||||||
|
// ccolor = vec4( tonemapFilmic(src.xyz), src.a);
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
#define lerp(a,b,c) mix(a,b,c)
|
||||||
|
#define saturate(c) clamp(c, 0.0, 1.0)
|
||||||
|
|
||||||
|
// This function approximates the black and white film stock
|
||||||
|
// "Ilford FP4" pushed to 400 ISO. It is typical for noir style. This
|
||||||
|
// tonal transformation does not approximate gamma 2.2, so an explicit
|
||||||
|
// sRGB transform should be performed before display.
|
||||||
|
//
|
||||||
|
// vec3 hdr (IN): Color pixel in linear space
|
||||||
|
// vec2 uv (IN): Screen space UV for vignette
|
||||||
|
//
|
||||||
|
// returns Filmic remapped pixel in gamma 1.0 space
|
||||||
|
// src: pic.twitter.com/7ZSMM5RRMz
|
||||||
|
//
|
||||||
|
|
||||||
|
vec3 PostFilmic_IlfordFp4Push(vec3 c, vec2 uv) {
|
||||||
|
// film curve coefficients
|
||||||
|
const vec3 cb = vec3( 0.0307479, 0.00030400, -0.04458630);
|
||||||
|
const vec3 de = vec3(-0.0095000, -0.00162400, -0.01736670);
|
||||||
|
const vec3 df = vec3( 0.1493590, 0.21412400, 1.85780000);
|
||||||
|
const vec3 ef = vec3(-0.0636051, -0.00758438, -0.00934798);
|
||||||
|
|
||||||
|
c = c * c * 1.88; // quick approximation of skip bleach
|
||||||
|
|
||||||
|
// remap color channels
|
||||||
|
vec3 ax = vec3(2.36691,5.14272,0.49020)*c;
|
||||||
|
vec3 pn = (c*(ax+cb)+de);
|
||||||
|
vec3 pd = (c*(ax+vec3(0.022,0.004,-0.10543))+df);
|
||||||
|
|
||||||
|
// collapse color channels
|
||||||
|
float pr = dot(saturate(pn/pd),vec3(0.45,0.45,0.45));
|
||||||
|
|
||||||
|
// vignette
|
||||||
|
float pv = saturate(pow(1.0 - dot(uv-.5, uv-.5), -.758) + -.23);
|
||||||
|
float x = lerp(pr,pr*pr*pr,pv); // done
|
||||||
|
return vec3(x,x,x);
|
||||||
|
}
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
vec2 uv = TEXCOORD.st;
|
||||||
|
vec4 src = texture2D(iChannel0, uv);
|
||||||
|
color = vec4( PostFilmic_IlfordFp4Push(src.xyz, uv), src.a);
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
// https://www.shadertoy.com/view/lslGzl
|
||||||
|
|
||||||
|
vec3 tonemapReinhard(const vec3 color) {
|
||||||
|
// color *= toneMappingExposure;
|
||||||
|
return color / (color + vec3(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 simpleReinhardToneMapping(vec3 color)
|
||||||
|
{
|
||||||
|
float exposure = 1.5;
|
||||||
|
color *= exposure/(1. + color / exposure);
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 lumaBasedReinhardToneMapping(vec3 color)
|
||||||
|
{
|
||||||
|
float luma = dot(color, vec3(0.2126, 0.7152, 0.0722));
|
||||||
|
float toneMappedLuma = luma / (1. + luma);
|
||||||
|
color *= toneMappedLuma / luma;
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 whitePreservingLumaBasedReinhardToneMapping(vec3 color)
|
||||||
|
{
|
||||||
|
float white = 2.;
|
||||||
|
float luma = dot(color, vec3(0.2126, 0.7152, 0.0722));
|
||||||
|
float toneMappedLuma = luma * (1. + luma / (white*white)) / (1. + luma);
|
||||||
|
color *= toneMappedLuma / luma;
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
vec2 uv = TEXCOORD.st;
|
||||||
|
vec4 src = texture2D(iChannel0, uv);
|
||||||
|
color = vec4( whitePreservingLumaBasedReinhardToneMapping(src.xyz), src.a);
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
// https://www.shadertoy.com/view/lslGzl
|
||||||
|
|
||||||
|
vec3 uncharted2Tonemap(const vec3 x) {
|
||||||
|
const float A = 0.15;
|
||||||
|
const float B = 0.50;
|
||||||
|
const float C = 0.10;
|
||||||
|
const float D = 0.20;
|
||||||
|
const float E = 0.02;
|
||||||
|
const float F = 0.30;
|
||||||
|
return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 tonemapUncharted2(const vec3 color) {
|
||||||
|
const float W = 11.2;
|
||||||
|
const float exposureBias = 2.0;
|
||||||
|
vec3 curr = uncharted2Tonemap(exposureBias * color);
|
||||||
|
vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W));
|
||||||
|
return curr * whiteScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
vec2 uv = TEXCOORD.st;
|
||||||
|
vec4 src = texture2D(iChannel0, uv);
|
||||||
|
color = vec4( tonemapUncharted2(src.xyz), src.a);
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
uniform float gamma = 2.2;
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
vec2 uv = TEXCOORD.st;
|
||||||
|
vec4 src = texture2D(iChannel0, uv);
|
||||||
|
color = vec4( pow(src.xyz, vec3(1.0 / gamma)), src.a); // gamma correction
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
uniform float vignette = 0.75;
|
||||||
|
|
||||||
|
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
|
||||||
|
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||||
|
|
||||||
|
vec4 src = texture( iChannel0, uv );
|
||||||
|
vec3 color = src.rgb;
|
||||||
|
|
||||||
|
color *= (1.0 - vignette) + vignette * 16.0 * uv.x * uv.y * (1.0-uv.x) * (1.0-uv.y);
|
||||||
|
|
||||||
|
fragColor = vec4(color, src.a);
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
Kgirl Animation List
|
||||||
|
|
||||||
|
frame: 000-060 Idle (Loop)
|
||||||
|
frame: 061-065 Run Intro
|
||||||
|
frame: 066-085 Run (Loop)
|
||||||
|
frame: 086-090 Run Outro
|
||||||
|
frame: 091-101 Punch Loop
|
||||||
|
frame: 102-117 Punch Low
|
||||||
|
frame: 118-135 Punch Up
|
||||||
|
frame: 136-172 Punch Mid
|
||||||
|
frame: 173-185 Jump
|
||||||
|
frame: 186-203 Kick
|
||||||
|
frame: 204-221 Kick x3 (Loop)
|
||||||
|
frame: 228-233 Fall Loop
|
||||||
|
frame: 234-253 Land
|
||||||
|
frame: 257-270 Air attack In
|
||||||
|
frame: 271-282 Air attack Out
|
||||||
|
frame: 283-290 Dash In
|
||||||
|
frame: 289-299 Dash (loop)
|
||||||
|
frame: 300-310 Punch reverse
|
||||||
|
frame: 311-358 Punch super
|
||||||
|
frame: 359-389 Charge
|
||||||
|
frame: 390-409 Hit1
|
||||||
|
frame: 410-426 Hit2
|
||||||
|
frame: 427-456 Die
|
||||||
|
frame: 457-474 Get up
|
||||||
|
frame: 475-477 Walk intro
|
||||||
|
frame: 478-506 Walk (loop)
|
After Width: | Height: | Size: 417 KiB |
|
@ -0,0 +1,3 @@
|
||||||
|
author: nanofactory
|
||||||
|
source: https://sketchfab.com/3d-models/kgirls01-d2f946f58a8040ae993cda70c97b302c
|
||||||
|
license (CC BY-NC-ND 4.0): https://creativecommons.org/licenses/by-nc-nd/4.0/
|
After Width: | Height: | Size: 4.8 KiB |
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<map version="1.9" tiledversion="1.9.2" orientation="orthogonal" renderorder="right-down" width="37" height="38" tilewidth="16" tileheight="16" infinite="0" nextlayerid="3" nextobjectid="1">
|
||||||
|
<tileset firstgid="1" source="castle.tsx"/>
|
||||||
|
<layer id="2" name="Tile BG" width="37" height="38">
|
||||||
|
<data encoding="base64" compression="zlib">
|
||||||
|
eJztk8sKwjAQRfMb1sderYLPrd/hqnTT//8Ep9DAdXAmkb4o3AOHkpCEQ9qG8M1uJqtgw6blNxXgWtyoucI5v12/hT1x/xD3pBustl+uOlP9fZssU61jfk+5jVM2xa5/3uEUTfq+cu7SOuftNDWdQzel/rfaaGrAdv41kxV06aa9eBBP4hnGR7GEZ5z31uu93thruohX8SE+YXwT7/CM8956vdcbYxPifftjYzURQgghhBBCCMnjAxltRQI=
|
||||||
|
</data>
|
||||||
|
</layer>
|
||||||
|
<layer id="1" name="Tile FG" width="37" height="38">
|
||||||
|
<data encoding="base64" compression="zlib">
|
||||||
|
eJztlE1Lw0AQhicxoLd605taP489xsb6EZH6hYiKCIKFXvr//4Ez+A4Z102y0oMe5oWHdGd3Ju/OkBKlKwd9KhLOzANmoO/9RfBUZaAAdp2ZM0Xk3LKeTpkzcI66NqbxWCyL5GeRuO71edLeXAdxyXln1phpS33NC/On1MxU9+aIHyV4KnDO6piaOawHtUUT43Nh+DBon4i+z22U4CnHOdGj8aTaxPtWsR4yB8weYosA0RazjbsW8FIHnrokOSVTMW+IXUQ8DbAem72B+a2z0h5n5q6/9ZTjPnlA6GnDeFJfGpuY87bHI2rmW+OZ4klUom5tsN+y1Lqkn9+6xGSWu/Q1S5Htcdnhqc2X1F7Bc4i6Dy2+bjrudMvcMffU9Gls7mD/l1L6JJ4q4+OV4v3aYa6YfeaQOUFccp+YZ+aFmj5p3sx4qhI9/YXcU5r+oyeXy+VyuVwul8vlci2nTwIxM6E=
|
||||||
|
</data>
|
||||||
|
</layer>
|
||||||
|
</map>
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<tileset version="1.9" tiledversion="1.9.2" name="castle" tilewidth="16" tileheight="16" tilecount="128" columns="8">
|
||||||
|
<image source="castle-tileset-by-RottingPixels-(CC0).png" width="128" height="256"/>
|
||||||
|
</tileset>
|
|
@ -0,0 +1,95 @@
|
||||||
|
Copyright (c) 2010-2013 by tyPoland Lukasz Dziedzic with Reserved Font Name "Carlito".
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License,
|
||||||
|
Version 1.1 as shown below.
|
||||||
|
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
|
||||||
|
PREAMBLE The goals of the Open Font License (OFL) are to stimulate
|
||||||
|
worldwide development of collaborative font projects, to support the font
|
||||||
|
creation efforts of academic and linguistic communities, and to provide
|
||||||
|
a free and open framework in which fonts may be shared and improved in
|
||||||
|
partnership with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves.
|
||||||
|
The fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply to
|
||||||
|
any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such.
|
||||||
|
This may include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components
|
||||||
|
as distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting ? in part or in whole ?
|
||||||
|
any of the components of the Original Version, by changing formats or
|
||||||
|
by porting the Font Software to a new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical writer
|
||||||
|
or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,in
|
||||||
|
Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the
|
||||||
|
corresponding Copyright Holder. This restriction only applies to the
|
||||||
|
primary font name as presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole, must
|
||||||
|
be distributed entirely under this license, and must not be distributed
|
||||||
|
under any other license. The requirement for fonts to remain under
|
||||||
|
this license does not apply to any document created using the Font
|
||||||
|
Software.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are not met.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER
|
||||||
|
DEALINGS IN THE FONT SOFTWARE.
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
Copyright (c) 2010-2013 by tyPoland Lukasz Dziedzic with Reserved Font Name "Carlito".
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License,
|
||||||
|
Version 1.1 as shown below.
|
||||||
|
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
|
||||||
|
PREAMBLE The goals of the Open Font License (OFL) are to stimulate
|
||||||
|
worldwide development of collaborative font projects, to support the font
|
||||||
|
creation efforts of academic and linguistic communities, and to provide
|
||||||
|
a free and open framework in which fonts may be shared and improved in
|
||||||
|
partnership with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves.
|
||||||
|
The fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply to
|
||||||
|
any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such.
|
||||||
|
This may include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components
|
||||||
|
as distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting ? in part or in whole ?
|
||||||
|
any of the components of the Original Version, by changing formats or
|
||||||
|
by porting the Font Software to a new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical writer
|
||||||
|
or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,in
|
||||||
|
Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the
|
||||||
|
corresponding Copyright Holder. This restriction only applies to the
|
||||||
|
primary font name as presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole, must
|
||||||
|
be distributed entirely under this license, and must not be distributed
|
||||||
|
under any other license. The requirement for fonts to remain under
|
||||||
|
this license does not apply to any document created using the Font
|
||||||
|
Software.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are not met.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER
|
||||||
|
DEALINGS IN THE FONT SOFTWARE.
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
Copyright 2006 The Inconsolata Project Authors
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@ -0,0 +1,2 @@
|
||||||
|
License
|
||||||
|
We have made these icons available for you to incorporate into your products under the Apache License Version 2.0. Feel free to remix and re-share these icons and documentation in your products. We'd love attribution in your app's about screen, but it's
|
|
@ -0,0 +1,19 @@
|
||||||
|
uniform int thickness = 2;
|
||||||
|
uniform vec4 border_color = vec4(1,1,0,1);
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texel = texture(iChannel0, uv);
|
||||||
|
float outline = 0.0;
|
||||||
|
if( texel.a == 0.0 ) {
|
||||||
|
for( int x = -thickness; x <= thickness; x++ ) {
|
||||||
|
for( int y = -thickness;y <= thickness; y++ ) {
|
||||||
|
float sample = texture(iChannel0, uv+vec2(float(x)/iWidth, float(y)/iHeight)).a;
|
||||||
|
if( sample > 0.0 ) {
|
||||||
|
outline = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FRAGCOLOR = vec4(border_color.rgb, outline * border_color.a); // mix(texel, border_color, outline * border_color.a);
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
Creative Commons Legal Code
|
||||||
|
|
||||||
|
CC0 1.0 Universal
|
||||||
|
|
||||||
|
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||||
|
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||||
|
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||||
|
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||||
|
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||||
|
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||||
|
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||||
|
HEREUNDER.
|
||||||
|
|
||||||
|
Statement of Purpose
|
||||||
|
|
||||||
|
The laws of most jurisdictions throughout the world automatically confer
|
||||||
|
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||||
|
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||||
|
authorship and/or a database (each, a "Work").
|
||||||
|
|
||||||
|
Certain owners wish to permanently relinquish those rights to a Work for
|
||||||
|
the purpose of contributing to a commons of creative, cultural and
|
||||||
|
scientific works ("Commons") that the public can reliably and without fear
|
||||||
|
of later claims of infringement build upon, modify, incorporate in other
|
||||||
|
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||||
|
and for any purposes, including without limitation commercial purposes.
|
||||||
|
These owners may contribute to the Commons to promote the ideal of a free
|
||||||
|
culture and the further production of creative, cultural and scientific
|
||||||
|
works, or to gain reputation or greater distribution for their Work in
|
||||||
|
part through the use and efforts of others.
|
||||||
|
|
||||||
|
For these and/or other purposes and motivations, and without any
|
||||||
|
expectation of additional consideration or compensation, the person
|
||||||
|
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||||
|
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||||
|
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||||
|
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||||
|
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||||
|
|
||||||
|
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||||
|
protected by copyright and related or neighboring rights ("Copyright and
|
||||||
|
Related Rights"). Copyright and Related Rights include, but are not
|
||||||
|
limited to, the following:
|
||||||
|
|
||||||
|
i. the right to reproduce, adapt, distribute, perform, display,
|
||||||
|
communicate, and translate a Work;
|
||||||
|
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||||
|
iii. publicity and privacy rights pertaining to a person's image or
|
||||||
|
likeness depicted in a Work;
|
||||||
|
iv. rights protecting against unfair competition in regards to a Work,
|
||||||
|
subject to the limitations in paragraph 4(a), below;
|
||||||
|
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||||
|
in a Work;
|
||||||
|
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||||
|
European Parliament and of the Council of 11 March 1996 on the legal
|
||||||
|
protection of databases, and under any national implementation
|
||||||
|
thereof, including any amended or successor version of such
|
||||||
|
directive); and
|
||||||
|
vii. other similar, equivalent or corresponding rights throughout the
|
||||||
|
world based on applicable law or treaty, and any national
|
||||||
|
implementations thereof.
|
||||||
|
|
||||||
|
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||||
|
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||||
|
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||||
|
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||||
|
of action, whether now known or unknown (including existing as well as
|
||||||
|
future claims and causes of action), in the Work (i) in all territories
|
||||||
|
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||||
|
treaty (including future time extensions), (iii) in any current or future
|
||||||
|
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||||
|
including without limitation commercial, advertising or promotional
|
||||||
|
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||||
|
member of the public at large and to the detriment of Affirmer's heirs and
|
||||||
|
successors, fully intending that such Waiver shall not be subject to
|
||||||
|
revocation, rescission, cancellation, termination, or any other legal or
|
||||||
|
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||||
|
as contemplated by Affirmer's express Statement of Purpose.
|
||||||
|
|
||||||
|
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||||
|
be judged legally invalid or ineffective under applicable law, then the
|
||||||
|
Waiver shall be preserved to the maximum extent permitted taking into
|
||||||
|
account Affirmer's express Statement of Purpose. In addition, to the
|
||||||
|
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||||
|
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||||
|
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||||
|
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||||
|
maximum duration provided by applicable law or treaty (including future
|
||||||
|
time extensions), (iii) in any current or future medium and for any number
|
||||||
|
of copies, and (iv) for any purpose whatsoever, including without
|
||||||
|
limitation commercial, advertising or promotional purposes (the
|
||||||
|
"License"). The License shall be deemed effective as of the date CC0 was
|
||||||
|
applied by Affirmer to the Work. Should any part of the License for any
|
||||||
|
reason be judged legally invalid or ineffective under applicable law, such
|
||||||
|
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||||
|
of the License, and in such case Affirmer hereby affirms that he or she
|
||||||
|
will not (i) exercise any of his or her remaining Copyright and Related
|
||||||
|
Rights in the Work or (ii) assert any associated claims and causes of
|
||||||
|
action with respect to the Work, in either case contrary to Affirmer's
|
||||||
|
express Statement of Purpose.
|
||||||
|
|
||||||
|
4. Limitations and Disclaimers.
|
||||||
|
|
||||||
|
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||||
|
surrendered, licensed or otherwise affected by this document.
|
||||||
|
b. Affirmer offers the Work as-is and makes no representations or
|
||||||
|
warranties of any kind concerning the Work, express, implied,
|
||||||
|
statutory or otherwise, including without limitation warranties of
|
||||||
|
title, merchantability, fitness for a particular purpose, non
|
||||||
|
infringement, or the absence of latent or other defects, accuracy, or
|
||||||
|
the present or absence of errors, whether or not discoverable, all to
|
||||||
|
the greatest extent permissible under applicable law.
|
||||||
|
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||||
|
that may apply to the Work or any use thereof, including without
|
||||||
|
limitation any person's Copyright and Related Rights in the Work.
|
||||||
|
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||||
|
consents, permissions or other rights required for any use of the
|
||||||
|
Work.
|
||||||
|
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||||
|
party to this document and has no duty or obligation with respect to
|
||||||
|
this CC0 or use of the Work.
|
After Width: | Height: | Size: 104 KiB |
|
@ -0,0 +1,2 @@
|
||||||
|
Free & Open Sourced Logos
|
||||||
|
At Fairpixels, we had unused logo designs piling up on our hard drives and decided to make them available to the world, for free. The logos below can be downloaded unlimited times and used by anyone. For personal & commercial projects. No attribution required. Perfect for mvp's and mockups.
|
After Width: | Height: | Size: 31 KiB |
|
@ -0,0 +1,12 @@
|
||||||
|
This work is licenced under the terms of either the GNU GPL v3 or
|
||||||
|
Creative Commons Attribution-Share Alike 4.0 United States License.
|
||||||
|
|
||||||
|
To view a copy of the CC-BY-SA licence, visit
|
||||||
|
http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative
|
||||||
|
Commons, 171 Second Street, Suite 300, San Francisco, California 94105, USA.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program; if not, see <https://www.gnu.org/licenses/>
|
||||||
|
|
||||||
|
When attributing the artwork, using "Suru Icons" is enough.
|
||||||
|
Please link to http://snwh.org/ where available.
|
After Width: | Height: | Size: 273 KiB |
|
@ -0,0 +1,18 @@
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
After Width: | Height: | Size: 16 KiB |
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
|
||||||
|
Input Prompts Pixel 16× (1.0)
|
||||||
|
|
||||||
|
Created/distributed by Kenney (www.kenney.nl)
|
||||||
|
Creation date: 23-09-2021
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
License: (Creative Commons Zero, CC0)
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
|
||||||
|
This content is free to use in personal, educational and commercial projects.
|
||||||
|
Support us by crediting Kenney or www.kenney.nl (this is not mandatory)
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
Donate: http://support.kenney.nl
|
||||||
|
Patreon: http://patreon.com/kenney/
|
||||||
|
|
||||||
|
Follow on Twitter for updates:
|
||||||
|
http://twitter.com/KenneyNL
|
|
@ -0,0 +1,153 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
struct Light
|
||||||
|
{
|
||||||
|
vec3 direction;
|
||||||
|
vec3 color;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ColorMap
|
||||||
|
{
|
||||||
|
bool has_tex;
|
||||||
|
vec4 color;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform ColorMap map_albedo; uniform sampler2D map_albedo_tex;
|
||||||
|
uniform ColorMap map_diffuse; uniform sampler2D map_diffuse_tex;
|
||||||
|
uniform ColorMap map_specular; uniform sampler2D map_specular_tex;
|
||||||
|
uniform ColorMap map_normals; uniform sampler2D map_normals_tex;
|
||||||
|
uniform ColorMap map_roughness; uniform sampler2D map_roughness_tex;
|
||||||
|
uniform ColorMap map_metallic; uniform sampler2D map_metallic_tex;
|
||||||
|
uniform ColorMap map_ao; uniform sampler2D map_ao_tex;
|
||||||
|
uniform ColorMap map_ambient; uniform sampler2D map_ambient_tex;
|
||||||
|
uniform ColorMap map_emissive; uniform sampler2D map_emissive_tex;
|
||||||
|
|
||||||
|
#define sample_colormap(ColorMap_, uv_) \
|
||||||
|
(ColorMap_.has_tex ? texture( ColorMap_##_tex, uv_ ) : ColorMap_.color)
|
||||||
|
|
||||||
|
|
||||||
|
in vec3 out_normal;
|
||||||
|
in vec3 out_tangent;
|
||||||
|
in vec3 out_binormal;
|
||||||
|
in vec2 out_texcoord;
|
||||||
|
in vec3 out_worldpos;
|
||||||
|
in vec3 out_to_camera;
|
||||||
|
|
||||||
|
|
||||||
|
uniform float specular_shininess;
|
||||||
|
|
||||||
|
uniform float skysphere_rotation;
|
||||||
|
uniform float skysphere_mip_count;
|
||||||
|
uniform float exposure;
|
||||||
|
|
||||||
|
uniform vec3 camera_position;
|
||||||
|
uniform Light lights[3];
|
||||||
|
|
||||||
|
uniform vec4 global_ambient;
|
||||||
|
|
||||||
|
uniform bool has_tex_skysphere;
|
||||||
|
uniform bool has_tex_skyenv;
|
||||||
|
|
||||||
|
uniform sampler2D tex_skysphere;
|
||||||
|
uniform sampler2D tex_skyenv;
|
||||||
|
|
||||||
|
out vec4 frag_color;
|
||||||
|
|
||||||
|
const float PI = 3.1415926536;
|
||||||
|
|
||||||
|
vec2 sphere_to_polar( vec3 normal )
|
||||||
|
{
|
||||||
|
normal = normalize( normal );
|
||||||
|
return vec2( ( atan( normal.z, normal.x ) + skysphere_rotation ) / PI / 2.0 + 0.5, acos( normal.y ) / PI );
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 sample_irradiance_fast( vec3 normal )
|
||||||
|
{
|
||||||
|
// Sample the irradiance map if it exists, otherwise fall back to blurred reflection map.
|
||||||
|
if ( has_tex_skyenv )
|
||||||
|
{
|
||||||
|
vec2 polar = sphere_to_polar( normal );
|
||||||
|
// HACK: Sample a smaller mip here to avoid high frequency color variations on detailed normal
|
||||||
|
// mapped areas.
|
||||||
|
float miplevel = 5.5; // tweaked for a 360x180 irradiance texture
|
||||||
|
return textureLod( tex_skyenv, polar, miplevel ).rgb * exposure;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vec2 polar = sphere_to_polar( normal );
|
||||||
|
return textureLod( tex_skysphere, polar, 0.80 * skysphere_mip_count ).rgb * exposure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float calculate_specular( vec3 normal, vec3 light_direction )
|
||||||
|
{
|
||||||
|
vec3 V = normalize( out_to_camera );
|
||||||
|
vec3 L = -normalize( light_direction );
|
||||||
|
vec3 H = normalize( V + L );
|
||||||
|
float rdotv = clamp( dot( normal, H ), 0.0, 1.0 );
|
||||||
|
float total_specular = pow( rdotv, specular_shininess );
|
||||||
|
|
||||||
|
return total_specular;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
vec4 specular;
|
||||||
|
if( map_specular.has_tex ) {
|
||||||
|
specular = sample_colormap( map_specular, out_texcoord );
|
||||||
|
} else {
|
||||||
|
float roughness = 1.0;
|
||||||
|
float metallic = 0.0;
|
||||||
|
|
||||||
|
if( map_metallic.has_tex && map_roughness.has_tex ) {
|
||||||
|
metallic = sample_colormap( map_metallic, out_texcoord ).x;
|
||||||
|
roughness = sample_colormap( map_roughness, out_texcoord ).x;
|
||||||
|
}
|
||||||
|
else if( map_roughness.has_tex ) {
|
||||||
|
//< @r-lyeh, metalness B, roughness G, (@todo: self-shadowing occlusion R; for now, any of R/B are metallic)
|
||||||
|
metallic = sample_colormap( map_roughness, out_texcoord ).b + sample_colormap( map_roughness, out_texcoord ).r;
|
||||||
|
roughness = sample_colormap( map_roughness, out_texcoord ).g;
|
||||||
|
}
|
||||||
|
|
||||||
|
float gloss = metallic * (1.0 - roughness);
|
||||||
|
specular = vec4(gloss);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 baseColor_alpha;
|
||||||
|
if ( map_albedo.has_tex )
|
||||||
|
baseColor_alpha = sample_colormap( map_albedo, out_texcoord );
|
||||||
|
else
|
||||||
|
baseColor_alpha = sample_colormap( map_diffuse, out_texcoord );
|
||||||
|
|
||||||
|
vec3 diffuse = baseColor_alpha.xyz;
|
||||||
|
float alpha = baseColor_alpha.w;
|
||||||
|
vec3 ambient = sample_colormap( map_ambient, out_texcoord ).xyz;
|
||||||
|
vec3 normals = normalize(texture( map_normals_tex, out_texcoord ).xyz * vec3(2.0) - vec3(1.0));
|
||||||
|
|
||||||
|
vec3 normal = out_normal;
|
||||||
|
if ( map_normals.has_tex )
|
||||||
|
{
|
||||||
|
// Mikkelsen's tangent space normal map decoding. See http://mikktspace.com/ for rationale.
|
||||||
|
vec3 bi = cross( out_normal, out_tangent );
|
||||||
|
vec3 nmap = normals.xyz;
|
||||||
|
normal = nmap.x * out_tangent + nmap.y * bi + nmap.z * out_normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
normal = normalize( normal );
|
||||||
|
|
||||||
|
vec3 irradiance = sample_irradiance_fast( normal );
|
||||||
|
ambient *= irradiance;
|
||||||
|
|
||||||
|
vec3 color = ambient * global_ambient.rgb;
|
||||||
|
for ( int i = 0; i < lights.length(); i++ )
|
||||||
|
{
|
||||||
|
float ndotl = clamp( dot( normal, -normalize( lights[ i ].direction ) ), 0.0, 1.0 );
|
||||||
|
|
||||||
|
vec3 specular = specular.rgb * calculate_specular( normal, lights[ i ].direction ) * specular.a;
|
||||||
|
color += (diffuse + specular) * ndotl * lights[ i ].color;
|
||||||
|
}
|
||||||
|
|
||||||
|
color += sample_colormap( map_emissive, out_texcoord ).rgb;
|
||||||
|
|
||||||
|
frag_color = vec4( pow( color * exposure, vec3(1. / 2.2) ), alpha );
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 in_pos;
|
||||||
|
layout(location = 1) in vec2 in_texcoord;
|
||||||
|
layout(location = 2) in vec3 in_normal;
|
||||||
|
layout(location = 3) in vec4 in_tangent; // vec3 + bi sign
|
||||||
|
//in vec3 in_binormal;
|
||||||
|
|
||||||
|
out vec3 out_normal;
|
||||||
|
out vec3 out_tangent;
|
||||||
|
out vec3 out_binormal;
|
||||||
|
out vec2 out_texcoord;
|
||||||
|
out vec3 out_worldpos;
|
||||||
|
out vec3 out_viewpos;
|
||||||
|
out vec3 out_to_camera;
|
||||||
|
|
||||||
|
uniform mat4x4 mat_projection;
|
||||||
|
uniform mat4x4 mat_view;
|
||||||
|
uniform mat4x4 mat_view_inverse;
|
||||||
|
uniform mat4x4 mat_world;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 o = vec4( in_pos.x, in_pos.y, in_pos.z, 1.0 );
|
||||||
|
o = mat_world * o;
|
||||||
|
out_worldpos = o.xyz;
|
||||||
|
o = mat_view * o;
|
||||||
|
out_viewpos = o.xyz;
|
||||||
|
|
||||||
|
vec3 to_camera = normalize( -o.xyz );
|
||||||
|
out_to_camera = mat3( mat_view_inverse ) * to_camera;
|
||||||
|
|
||||||
|
o = mat_projection * o;
|
||||||
|
gl_Position = o;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// compute tangent T and bitangent B
|
||||||
|
vec3 Q1 = dFdx(in_pos);
|
||||||
|
vec3 Q2 = dFdy(in_pos);
|
||||||
|
vec2 st1 = dFdx(in_texcoord);
|
||||||
|
vec2 st2 = dFdy(in_texcoord);
|
||||||
|
|
||||||
|
vec3 T = normalize(Q1*st2.t - Q2*st1.t);
|
||||||
|
vec3 B = normalize(-Q1*st2.s + Q2*st1.s);
|
||||||
|
vec3 in_binormal = B;
|
||||||
|
#else
|
||||||
|
vec3 in_binormal = cross(in_normal, in_tangent.xyz) * in_tangent.w;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
out_normal = normalize( mat3( mat_world ) * in_normal );
|
||||||
|
out_tangent = normalize( mat3( mat_world ) * in_tangent.xyz );
|
||||||
|
out_binormal = normalize( mat3( mat_world ) * in_binormal );
|
||||||
|
out_texcoord = in_texcoord;
|
||||||
|
}
|
|
@ -0,0 +1,485 @@
|
||||||
|
#version 400
|
||||||
|
|
||||||
|
// original PBR shader by @seece (Public Domain). link: https://github.com/Gargaj/Foxotron/pull/12
|
||||||
|
|
||||||
|
//#define textureQueryLod(t,c) vec2(0.0,0.0) // #version 400 required
|
||||||
|
|
||||||
|
uniform vec2 resolution = vec2(640.0,480.0); // debug options below use this (USE_MAP_DEBUGGING, USE_AMBIENT_DEBUGGING)
|
||||||
|
|
||||||
|
#define USE_BRUTEFORCE_IRRADIANCE false // Samples irradiance from tex_skysphere when enabled.
|
||||||
|
#define USE_WRAPAROUND_SPECULAR true // Makes silhouettes more reflective to avoid black pixels.
|
||||||
|
#define USE_SPECULAR_AO_ATTENUATION true // Dampens IBL specular ambient with AO if enabled.
|
||||||
|
#define USE_NORMAL_VARIATION_TO_ROUGHNESS true // Increases roughness if normal map has variation and was minified.
|
||||||
|
#define USE_MAP_DEBUGGING false // Shows all ColorMaps as horizontal bars
|
||||||
|
#define USE_AMBIENT_DEBUGGING false // Splits the screen in two and shows image-based specular (left), full shading (middle), diffuse shading (right).
|
||||||
|
#define BOOST_LIGHTING 2.00f // Multiplies analytic light's color with this constant because otherwise they look really pathetic.
|
||||||
|
#define BOOST_SPECULAR 1.50f
|
||||||
|
#define BOOST_NOISE 2.50f
|
||||||
|
|
||||||
|
struct Light
|
||||||
|
{
|
||||||
|
vec3 direction;
|
||||||
|
vec3 color;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ColorMap
|
||||||
|
{
|
||||||
|
bool has_tex;
|
||||||
|
vec4 color;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform ColorMap map_albedo; uniform sampler2D map_albedo_tex;
|
||||||
|
uniform ColorMap map_diffuse; uniform sampler2D map_diffuse_tex;
|
||||||
|
uniform ColorMap map_specular; uniform sampler2D map_specular_tex; // not used
|
||||||
|
uniform ColorMap map_normals; uniform sampler2D map_normals_tex;
|
||||||
|
uniform ColorMap map_roughness; uniform sampler2D map_roughness_tex;
|
||||||
|
uniform ColorMap map_metallic; uniform sampler2D map_metallic_tex;
|
||||||
|
uniform ColorMap map_ao; uniform sampler2D map_ao_tex;
|
||||||
|
uniform ColorMap map_ambient; uniform sampler2D map_ambient_tex;
|
||||||
|
uniform ColorMap map_emissive; uniform sampler2D map_emissive_tex;
|
||||||
|
|
||||||
|
#define sample_colormap(ColorMap_, uv_) \
|
||||||
|
(ColorMap_.has_tex ? texture( ColorMap_##_tex, uv_ ) : ColorMap_.color)
|
||||||
|
|
||||||
|
in vec3 out_normal;
|
||||||
|
in vec3 out_tangent;
|
||||||
|
in vec3 out_binormal;
|
||||||
|
in vec2 out_texcoord;
|
||||||
|
in vec3 out_worldpos;
|
||||||
|
in vec3 out_to_camera;
|
||||||
|
|
||||||
|
uniform float skysphere_rotation;
|
||||||
|
uniform float skysphere_mip_count;
|
||||||
|
uniform float exposure;
|
||||||
|
uniform uint frame_count;
|
||||||
|
uniform float specular_shininess;
|
||||||
|
|
||||||
|
uniform vec3 camera_position;
|
||||||
|
uniform Light lights[3];
|
||||||
|
|
||||||
|
uniform sampler2D tex_skysphere;
|
||||||
|
uniform sampler2D tex_skyenv;
|
||||||
|
uniform sampler2D tex_brdf_lut;
|
||||||
|
|
||||||
|
uniform bool has_tex_skysphere;
|
||||||
|
uniform bool has_tex_skyenv;
|
||||||
|
|
||||||
|
out vec4 frag_color;
|
||||||
|
|
||||||
|
const float PI = 3.1415926536;
|
||||||
|
|
||||||
|
// MurMurHash 3 finalizer. Implementation is in public domain.
|
||||||
|
uint hash( uint h )
|
||||||
|
{
|
||||||
|
h ^= h >> 16;
|
||||||
|
h *= 0x85ebca6bU;
|
||||||
|
h ^= h >> 13;
|
||||||
|
h *= 0xc2b2ae35U;
|
||||||
|
h ^= h >> 16;
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Random function using the idea of StackOverflow user "Spatial" https://stackoverflow.com/a/17479300
|
||||||
|
// Creates random 23 bits and puts them into the fraction bits of an 32-bit float.
|
||||||
|
float random( uvec3 h )
|
||||||
|
{
|
||||||
|
uint m = hash(h.x ^ hash( h.y ) ^ hash( h.z ));
|
||||||
|
return uintBitsToFloat( ( m & 0x007FFFFFu ) | 0x3f800000u ) - 1.;
|
||||||
|
}
|
||||||
|
|
||||||
|
float random( vec3 v )
|
||||||
|
{
|
||||||
|
return random(floatBitsToUint( v ));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 fresnel_schlick( vec3 H, vec3 V, vec3 F0 )
|
||||||
|
{
|
||||||
|
float cosTheta = clamp( dot( H, V ), 0., 1. );
|
||||||
|
return F0 + ( vec3( 1.0 ) - F0 ) * pow( 1. - cosTheta, 5.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Fresnel term that dampens rough specular reflections.
|
||||||
|
// https://seblagarde.wordpress.com/2011/08/17/hello-world/
|
||||||
|
vec3 fresnel_schlick_roughness( vec3 H, vec3 V, vec3 F0, float roughness )
|
||||||
|
{
|
||||||
|
float cosTheta = clamp( dot( H, V ), 0., 1. );
|
||||||
|
return F0 + ( max( vec3( 1.0 - roughness ), F0 ) - F0 ) * pow( 1. - cosTheta, 5.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
float distribution_ggx( vec3 N, vec3 H, float roughness )
|
||||||
|
{
|
||||||
|
float a = roughness * roughness;
|
||||||
|
float a2 = a * a;
|
||||||
|
float NdotH = max( 0., dot( N, H ) );
|
||||||
|
float factor = NdotH * NdotH * ( a2 - 1. ) + 1.;
|
||||||
|
|
||||||
|
return a2 / ( PI * factor * factor );
|
||||||
|
}
|
||||||
|
|
||||||
|
float geometry_schlick_ggx( vec3 N, vec3 V, float k )
|
||||||
|
{
|
||||||
|
float NdotV = max( 0., dot( N, V ) );
|
||||||
|
return NdotV / (NdotV * ( 1. - k ) + k );
|
||||||
|
}
|
||||||
|
|
||||||
|
float geometry_smith( vec3 N, vec3 V, vec3 L, float roughness )
|
||||||
|
{
|
||||||
|
#if 1 // original
|
||||||
|
float r = roughness + 1.;
|
||||||
|
float k = (r * r) / 8.;
|
||||||
|
#elif 0 // vries
|
||||||
|
float a = roughness;
|
||||||
|
float k = (a * a) / 2.0;
|
||||||
|
#elif 0 // vries improved?
|
||||||
|
float a = roughness * roughness;
|
||||||
|
float k = a / 2.0;
|
||||||
|
#endif
|
||||||
|
return geometry_schlick_ggx( N, V, k ) * geometry_schlick_ggx( N, L, k );
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 sphere_to_polar( vec3 normal )
|
||||||
|
{
|
||||||
|
normal = normalize( normal );
|
||||||
|
return vec2( ( atan( normal.z, normal.x ) + skysphere_rotation ) / PI / 2.0 + 0.5, acos( normal.y ) / PI );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Our vertically GL_CLAMPed textures seem to blend towards black when sampling the half-pixel edge.
|
||||||
|
// Not sure if it has a border, or this if is a driver bug, but can repro on multiple nvidia cards.
|
||||||
|
// Knowing the texture height we can limit sampling to the centers of the top and bottom pixel rows.
|
||||||
|
vec2 sphere_to_polar_clamp_y( vec3 normal, float texture_height )
|
||||||
|
{
|
||||||
|
normal = normalize( normal );
|
||||||
|
return vec2( ( atan( normal.z, normal.x ) + skysphere_rotation ) / PI / 2.0 + 0.5, clamp(acos( normal.y ) / PI, 0.5 / texture_height, 1.0 - 0.5 / texture_height) );
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 sample_sky( vec3 normal )
|
||||||
|
{
|
||||||
|
vec2 polar = sphere_to_polar( normal );
|
||||||
|
return texture( tex_skysphere, polar ).rgb * exposure;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Takes samples around the hemisphere, converts them to radiances via weighting and
|
||||||
|
// returns a normalized sum.
|
||||||
|
vec3 sample_irradiance_slow( vec3 normal, vec3 vertex_tangent )
|
||||||
|
{
|
||||||
|
float delta = 0.10;
|
||||||
|
|
||||||
|
vec3 up = abs( normal.y ) < 0.999 ? vec3( 0., 1., 0. ) : vec3( 0., 0., 1. );
|
||||||
|
vec3 tangent_x = normalize( cross( up, normal ) );
|
||||||
|
vec3 tangent_y = cross( normal, tangent_x );
|
||||||
|
|
||||||
|
int numIrradianceSamples = 0;
|
||||||
|
|
||||||
|
vec3 irradiance = vec3(0.);
|
||||||
|
|
||||||
|
for ( float phi = 0.; phi < 2. * PI ; phi += delta )
|
||||||
|
{
|
||||||
|
for ( float theta = 0.; theta < 0.5 * PI; theta += delta )
|
||||||
|
{
|
||||||
|
vec3 tangent_space = vec3(
|
||||||
|
sin( theta ) * cos( phi ),
|
||||||
|
sin( theta ) * sin( phi ),
|
||||||
|
cos( theta ) );
|
||||||
|
|
||||||
|
vec3 world_space = tangent_space.x * tangent_x + tangent_space.y + tangent_y + tangent_space.z * normal;
|
||||||
|
|
||||||
|
vec3 color = sample_sky( world_space );
|
||||||
|
irradiance += color * cos( theta ) * sin( theta );
|
||||||
|
numIrradianceSamples++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
irradiance = PI * irradiance / float( numIrradianceSamples );
|
||||||
|
return irradiance;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 sample_irradiance_fast( vec3 normal, vec3 vertex_tangent )
|
||||||
|
{
|
||||||
|
// Sample the irradiance map if it exists, otherwise fall back to blurred reflection map.
|
||||||
|
if ( has_tex_skyenv )
|
||||||
|
{
|
||||||
|
vec2 polar = sphere_to_polar_clamp_y( normal, 180.0 );
|
||||||
|
return textureLod( tex_skyenv, polar, 0.0 ).rgb * exposure;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vec2 polar = sphere_to_polar( normal );
|
||||||
|
return textureLod( tex_skysphere, polar, 0.80 * skysphere_mip_count ).rgb * exposure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3 specular_ibl( vec3 V, vec3 N, float roughness, vec3 fresnel )
|
||||||
|
{
|
||||||
|
// What we'd like to do here is take a LOT of skybox samples around the reflection
|
||||||
|
// vector R according to the BRDF lobe.
|
||||||
|
//
|
||||||
|
// Unfortunately it's not possible in real time so we use the following UE4 style approximations:
|
||||||
|
// 1. Integrate incoming light and BRDF separately ("split sum approximation")
|
||||||
|
// 2. Assume V = R = N so that we can just blur the skybox and sample that.
|
||||||
|
// 3. Bake the BRDF integral into a lookup texture so that it can be computed in constant time.
|
||||||
|
//
|
||||||
|
// Here we also simplify approximation #2 by using bilinear mipmaps with a magic formula instead
|
||||||
|
// of properly convolving it with a GGX lobe.
|
||||||
|
//
|
||||||
|
// For details, see Brian Karis, "Real Shading in Unreal Engine 4", 2013.
|
||||||
|
|
||||||
|
vec3 R = 2. * dot( V, N ) * N - V;
|
||||||
|
|
||||||
|
vec2 polar = sphere_to_polar( R );
|
||||||
|
|
||||||
|
// Map roughness from range [0, 1] into a mip LOD [0, skysphere_mip_count].
|
||||||
|
// The magic numbers were chosen empirically.
|
||||||
|
|
||||||
|
float mip = 0.9 * skysphere_mip_count * pow(roughness, 0.25 * BOOST_SPECULAR);
|
||||||
|
|
||||||
|
vec3 prefiltered = textureLod( tex_skysphere, polar, mip ).rgb * exposure;
|
||||||
|
|
||||||
|
float NdotV = dot( N, V );
|
||||||
|
|
||||||
|
// dot( N, V ) seems to produce negative values so we can try to stretch it a bit behind the silhouette
|
||||||
|
// to avoid black pixels.
|
||||||
|
if (USE_WRAPAROUND_SPECULAR)
|
||||||
|
{
|
||||||
|
NdotV = NdotV * 0.9 + 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
NdotV = min(0.99, max(0.01, NdotV));
|
||||||
|
|
||||||
|
// A precomputed lookup table contains a scale and a bias term for specular intensity (called "fresnel" here).
|
||||||
|
// See equation (8) in Karis' course notes mentioned above.
|
||||||
|
vec2 envBRDF = texture( tex_brdf_lut, vec2(NdotV, 1.0-roughness) ).xy; // (NdotV,1-roughtness) for green top-left (NdotV,roughness) for green bottom-left
|
||||||
|
vec3 specular = prefiltered * (fresnel * envBRDF.x + vec3(envBRDF.y));
|
||||||
|
|
||||||
|
return specular;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
vec3 baseColor = vec3( 0.5, 0.5, 0.5 );
|
||||||
|
float roughness = 1.0;
|
||||||
|
float metallic = 0.0;
|
||||||
|
float ao = 1.0;
|
||||||
|
float alpha = 1.0;
|
||||||
|
|
||||||
|
vec4 baseColor_alpha;
|
||||||
|
if ( map_albedo.has_tex )
|
||||||
|
baseColor_alpha = sample_colormap( map_albedo, out_texcoord );
|
||||||
|
else
|
||||||
|
baseColor_alpha = sample_colormap( map_diffuse, out_texcoord );
|
||||||
|
baseColor = baseColor_alpha.xyz;
|
||||||
|
alpha = baseColor_alpha.w;
|
||||||
|
|
||||||
|
if( map_metallic.has_tex && map_roughness.has_tex ) {
|
||||||
|
metallic = sample_colormap( map_metallic, out_texcoord ).x;
|
||||||
|
roughness = sample_colormap( map_roughness, out_texcoord ).x;
|
||||||
|
}
|
||||||
|
else if( map_roughness.has_tex ) {
|
||||||
|
//< @r-lyeh, metalness B, roughness G, (@todo: self-shadowing occlusion R; for now, any of R/B are metallic)
|
||||||
|
metallic = sample_colormap( map_roughness, out_texcoord ).b + sample_colormap( map_roughness, out_texcoord ).r;
|
||||||
|
roughness = sample_colormap( map_roughness, out_texcoord ).g;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( map_ao.has_tex )
|
||||||
|
ao = sample_colormap( map_ao, out_texcoord ).x;
|
||||||
|
else if ( map_ambient.has_tex )
|
||||||
|
ao = sample_colormap( map_ambient, out_texcoord ).x;
|
||||||
|
|
||||||
|
vec3 emissive = sample_colormap( map_emissive, out_texcoord ).rgb;
|
||||||
|
|
||||||
|
vec3 normalmap = texture( map_normals_tex, out_texcoord ).xyz * vec3(2.0) - vec3(1.0);
|
||||||
|
float normalmap_mip = textureQueryLod( map_normals_tex, out_texcoord ).x;
|
||||||
|
float normalmap_length = length(normalmap);
|
||||||
|
normalmap /= normalmap_length;
|
||||||
|
|
||||||
|
vec3 normal = out_normal;
|
||||||
|
|
||||||
|
if ( map_normals.has_tex )
|
||||||
|
{
|
||||||
|
// Mikkelsen's tangent space normal map decoding. See http://mikktspace.com/ for rationale.
|
||||||
|
vec3 bi = cross( out_normal, out_tangent );
|
||||||
|
vec3 nmap = normalmap.xyz;
|
||||||
|
normal = nmap.x * out_tangent + nmap.y * bi + nmap.z * out_normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
normal = normalize( normal );
|
||||||
|
|
||||||
|
if( USE_MAP_DEBUGGING && !USE_AMBIENT_DEBUGGING )
|
||||||
|
{
|
||||||
|
vec3 c = vec3(1., 0., 0.);
|
||||||
|
float x = gl_FragCoord.x / resolution.x;
|
||||||
|
float y = gl_FragCoord.y / resolution.y;
|
||||||
|
if ( y < (7.0/7.0) ) c = vec3(.5) + .5*out_normal;
|
||||||
|
if ( y < (6.0/7.0) ) c = vec3(.5) + .5*normalmap;
|
||||||
|
if ( y < (5.0/7.0) ) c = vec3(ao);
|
||||||
|
if ( y < (4.0/7.0) ) c = vec3(emissive);
|
||||||
|
if ( y < (3.0/7.0) ) c = vec3(metallic);
|
||||||
|
if ( y < (2.0/7.0) ) c = vec3(roughness);
|
||||||
|
if ( y < (1.0/7.0) ) c = baseColor;
|
||||||
|
frag_color = vec4(c, 1.);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (USE_NORMAL_VARIATION_TO_ROUGHNESS)
|
||||||
|
{
|
||||||
|
// Try to reduce specular aliasing by increasing roughness when minified normal maps have high variation.
|
||||||
|
float variation = 1. - pow( normalmap_length, 8. );
|
||||||
|
float minification = clamp( normalmap_mip - 2., 0., 1. );
|
||||||
|
roughness = mix( roughness, 1.0, variation * minification );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3 N = normal;
|
||||||
|
vec3 V = normalize( out_to_camera );
|
||||||
|
|
||||||
|
vec3 Lo = vec3(0.);
|
||||||
|
vec3 F0 = vec3(0.04);
|
||||||
|
F0 = mix( F0, baseColor, metallic );
|
||||||
|
|
||||||
|
bool use_ibl = has_tex_skysphere;
|
||||||
|
|
||||||
|
// Add contributions from analytic lights only if we don't have a skybox.
|
||||||
|
|
||||||
|
{
|
||||||
|
int num_lights = use_ibl ? 1 : lights.length();
|
||||||
|
for ( int i = 0; i < num_lights; i++ )
|
||||||
|
{
|
||||||
|
vec3 radiance = lights[ i ].color * BOOST_LIGHTING;
|
||||||
|
|
||||||
|
vec3 L = -normalize( lights[ i ].direction );
|
||||||
|
vec3 H = normalize( V + L );
|
||||||
|
|
||||||
|
vec3 F = fresnel_schlick( H, V, F0 );
|
||||||
|
vec3 kS = F;
|
||||||
|
vec3 kD = vec3(1.0) - kS;
|
||||||
|
kD *= 1.0 - metallic;
|
||||||
|
|
||||||
|
// Premultiplied alpha applied to the diffuse component only
|
||||||
|
kD *= alpha;
|
||||||
|
|
||||||
|
float D = distribution_ggx( N, H, roughness );
|
||||||
|
float G = geometry_smith( N, V, L, roughness );
|
||||||
|
|
||||||
|
vec3 num = D * F * G;
|
||||||
|
float denom = 4. * max( 0., dot( N, V ) ) * max( 0., dot( N, L ) );
|
||||||
|
|
||||||
|
vec3 specular = kS * (num / max( 0.001, denom ));
|
||||||
|
|
||||||
|
float NdotL = max( 0., dot( N, L ) );
|
||||||
|
|
||||||
|
Lo += ( kD * ( baseColor / PI ) + specular ) * radiance * NdotL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 ambient = sample_colormap( map_ambient, out_texcoord ).xyz;
|
||||||
|
vec3 diffuse_ambient;
|
||||||
|
vec3 specular_ambient;
|
||||||
|
|
||||||
|
if ( use_ibl )
|
||||||
|
{
|
||||||
|
// Image based lighting.
|
||||||
|
// Based on https://learnopengl.com/PBR/IBL/Diffuse-irradiance
|
||||||
|
|
||||||
|
vec3 irradiance = vec3(0.);
|
||||||
|
|
||||||
|
if ( USE_BRUTEFORCE_IRRADIANCE )
|
||||||
|
{
|
||||||
|
irradiance = sample_irradiance_slow( normal, out_tangent );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
irradiance = sample_irradiance_fast( normal, out_tangent );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the Fresnel term for a perfect mirror reflection with L = R.
|
||||||
|
// In this case the halfway vector H = N.
|
||||||
|
//
|
||||||
|
// We use a modified Fresnel function that dampens specular reflections of very
|
||||||
|
// rough surfaces to avoid too bright pixels at grazing angles.
|
||||||
|
vec3 F = fresnel_schlick_roughness( N, V, F0, roughness );
|
||||||
|
vec3 kS = F;
|
||||||
|
|
||||||
|
// Subtract the amount of reflected light (specular) to get the energy left for
|
||||||
|
// absorbed (diffuse) light.
|
||||||
|
vec3 kD = vec3(1.) - kS;
|
||||||
|
|
||||||
|
// Metallic surfaces have only a specular reflection.
|
||||||
|
kD *= 1.0 - metallic;
|
||||||
|
|
||||||
|
// Premultiplied alpha applied to the diffuse component only
|
||||||
|
kD *= alpha;
|
||||||
|
|
||||||
|
// Modulate the incoming lighting with the diffuse color: some wavelengths get absorbed.
|
||||||
|
diffuse_ambient = irradiance * baseColor;
|
||||||
|
|
||||||
|
// Ambient light also has a specular part.
|
||||||
|
specular_ambient = specular_ibl( V, normal, roughness, F );
|
||||||
|
|
||||||
|
// Ambient occlusion tells us the fraction of sky light that reaches this point.
|
||||||
|
if (USE_SPECULAR_AO_ATTENUATION)
|
||||||
|
{
|
||||||
|
ambient = ao * (kD * diffuse_ambient + specular_ambient);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We don't attenuate specular_ambient ambient here with AO which might cause flickering in dark cavities.
|
||||||
|
ambient = ao * (kD * diffuse_ambient) + specular_ambient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 color = (ambient + Lo) + emissive;
|
||||||
|
|
||||||
|
if ( USE_AMBIENT_DEBUGGING )
|
||||||
|
{
|
||||||
|
float y = gl_FragCoord.y / resolution.y;
|
||||||
|
if( USE_MAP_DEBUGGING && y > 0.5 )
|
||||||
|
{
|
||||||
|
if ( (y-0.5) < (7.0/7.0/2.0) ) color = vec3(.5) + .5*out_normal;
|
||||||
|
if ( (y-0.5) < (6.0/7.0/2.0) ) color = vec3(.5) + .5*normalmap;
|
||||||
|
if ( (y-0.5) < (5.0/7.0/2.0) ) color = vec3(ao);
|
||||||
|
if ( (y-0.5) < (4.0/7.0/2.0) ) color = vec3(emissive);
|
||||||
|
if ( (y-0.5) < (3.0/7.0/2.0) ) color = vec3(metallic);
|
||||||
|
if ( (y-0.5) < (2.0/7.0/2.0) ) color = vec3(roughness);
|
||||||
|
if ( (y-0.5) < (1.0/7.0/2.0) ) color = baseColor;
|
||||||
|
} else {
|
||||||
|
float x = gl_FragCoord.x / resolution.x;
|
||||||
|
if ( x < 0.33 )
|
||||||
|
color = specular_ambient;
|
||||||
|
else if( x > 0.66 )
|
||||||
|
color = diffuse_ambient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 // original
|
||||||
|
// basic tonemap and gamma correction
|
||||||
|
color = color / ( vec3(1.) + color );
|
||||||
|
color = pow( color, vec3(1. / 2.2) );
|
||||||
|
#elif 0
|
||||||
|
// filmic tonemapper
|
||||||
|
vec3 linearColor = color;
|
||||||
|
vec3 x = max(vec3(0.0), linearColor - 0.004);
|
||||||
|
color = (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06);
|
||||||
|
// gamma correction
|
||||||
|
// color = pow( color, vec3(1. / 2.2) );
|
||||||
|
#elif 1
|
||||||
|
// aces film (CC0, src: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/)
|
||||||
|
vec3 x = color;
|
||||||
|
float a = 2.51f;
|
||||||
|
float b = 0.03f;
|
||||||
|
float c = 2.43f;
|
||||||
|
float d = 0.59f;
|
||||||
|
float e = 0.14f;
|
||||||
|
color = clamp((x*(a*x+b))/(x*(c*x+d)+e), 0.0, 1.0);
|
||||||
|
// gamma correction
|
||||||
|
color = pow( color, vec3(1. / 2.2) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// dither with noise.
|
||||||
|
// float dither = random( uvec3( floatBitsToUint( gl_FragCoord.xy ), frame_count ) );
|
||||||
|
// color += BOOST_NOISE * vec3( (-1.0/256.) + (2./256.) * dither );
|
||||||
|
|
||||||
|
// Technically this alpha may be too transparent, if there is a lot of reflected light we wouldn't
|
||||||
|
// see the background, maybe we can approximate it well enough by adding a fresnel term
|
||||||
|
frag_color = vec4( color, alpha );
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 in_pos;
|
||||||
|
layout(location = 1) in vec2 in_texcoord;
|
||||||
|
layout(location = 2) in vec3 in_normal;
|
||||||
|
layout(location = 3) in vec4 in_tangent; // vec3 + bi sign
|
||||||
|
//in vec3 in_binormal;
|
||||||
|
|
||||||
|
out vec3 out_normal;
|
||||||
|
out vec3 out_tangent;
|
||||||
|
out vec3 out_binormal;
|
||||||
|
out vec2 out_texcoord;
|
||||||
|
out vec3 out_worldpos;
|
||||||
|
out vec3 out_viewpos;
|
||||||
|
out vec3 out_to_camera;
|
||||||
|
|
||||||
|
uniform mat4x4 mat_projection;
|
||||||
|
uniform mat4x4 mat_view;
|
||||||
|
uniform mat4x4 mat_view_inverse;
|
||||||
|
uniform mat4x4 mat_world;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 o = vec4( in_pos.x, in_pos.y, in_pos.z, 1.0 );
|
||||||
|
o = mat_world * o;
|
||||||
|
out_worldpos = o.xyz;
|
||||||
|
o = mat_view * o;
|
||||||
|
out_viewpos = o.xyz;
|
||||||
|
|
||||||
|
vec3 to_camera = normalize( -o.xyz );
|
||||||
|
out_to_camera = mat3( mat_view_inverse ) * to_camera;
|
||||||
|
|
||||||
|
o = mat_projection * o;
|
||||||
|
gl_Position = o;
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// compute tangent T and bitangent B
|
||||||
|
vec3 Q1 = dFdx(in_pos);
|
||||||
|
vec3 Q2 = dFdy(in_pos);
|
||||||
|
vec2 st1 = dFdx(in_texcoord);
|
||||||
|
vec2 st2 = dFdy(in_texcoord);
|
||||||
|
|
||||||
|
vec3 T = normalize(Q1*st2.t - Q2*st1.t);
|
||||||
|
vec3 B = normalize(-Q1*st2.s + Q2*st1.s);
|
||||||
|
vec3 in_binormal = B;
|
||||||
|
#else
|
||||||
|
vec3 in_binormal = cross(in_normal, in_tangent.xyz) * in_tangent.w;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
out_normal = normalize( mat3( mat_world ) * in_normal );
|
||||||
|
out_tangent = normalize( mat3( mat_world ) * in_tangent.xyz );
|
||||||
|
out_binormal = normalize( mat3( mat_world ) * in_binormal );
|
||||||
|
out_texcoord = in_texcoord;
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Files:
|
||||||
|
1. webcamBig.png
|
||||||
|
2. tex10.png
|
||||||
|
3. tex11.png
|
||||||
|
4. tex12.png
|
||||||
|
5. tex12_orig.png
|
||||||
|
6. tex14.png
|
||||||
|
7. tex15.png
|
||||||
|
8. tex16.png
|
||||||
|
|
||||||
|
Downloaded from Shadertoy.com by Inigo Quilez and Pol Jeremias (http://www.beautypi.com/)
|
||||||
|
Licensed under CC NC-SA 3.0 Unported License
|
||||||
|
http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Files:
|
||||||
|
1. tex09.jpg
|
||||||
|
2. tex00.jpg
|
||||||
|
3. tex01.jpg
|
||||||
|
4. tex02.jpg
|
||||||
|
5. tex03.jpg
|
||||||
|
6. tex04.jpg
|
||||||
|
7. tex05.jpg
|
||||||
|
8. tex06.jpg
|
||||||
|
9. tex07.jpg
|
||||||
|
10. tex08.jpg
|
||||||
|
|
||||||
|
Downloaded from Shadertoy.com
|
After Width: | Height: | Size: 258 KiB |
After Width: | Height: | Size: 65 KiB |
After Width: | Height: | Size: 112 KiB |
After Width: | Height: | Size: 415 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 117 KiB |
After Width: | Height: | Size: 101 KiB |
After Width: | Height: | Size: 354 KiB |
After Width: | Height: | Size: 440 KiB |
After Width: | Height: | Size: 213 KiB |
After Width: | Height: | Size: 165 KiB |
After Width: | Height: | Size: 402 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 65 KiB |
After Width: | Height: | Size: 256 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 387 B |
After Width: | Height: | Size: 256 KiB |
After Width: | Height: | Size: 298 KiB |
After Width: | Height: | Size: 387 KiB |