wip: shadowmap

main
Dominik Madarász 2023-09-10 16:46:07 +02:00
parent 687993ef40
commit 358522ea22
29 changed files with 1663 additions and 872 deletions

246
MAKE.bat
View File

@ -1,249 +1,3 @@
#!/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 v4k.o 2> /dev/null
rm .art*.zip 2> /dev/null
rm engine/bind/.art*.zip 2> /dev/null
rm demos/html5/.art*.zip 2> /dev/null
rm engine/bind/libv4k* 2> /dev/null
rm v4k_*.* 2> /dev/null
rm 3rd_*.* 2> /dev/null
rm libv4k* 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
if [ "$1" = "prep" ]; then
sh MAKE.bat join
sh MAKE.bat amalgamation
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 [amalgamation]
echo sh MAKE.bat [prep]
echo sh MAKE.bat [cook]
echo sh MAKE.bat [proj]
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" = "proj" ]; 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 engine/bind/luajit.linux
echo build=$build, type=$dll, cc=$cc, args=$args
# framework (as dynamic library)
if [ "$dll" = "dll" ]; then
echo libv4k.so && $cc -o libv4k.so engine/v4k.c -shared -fPIC -w -lX11 -lm -ldl -lpthread $flags $args
cp libv4k.so engine/bind/
export import="libv4k.so -Wl,-rpath,./"
else
# framework (static)
echo v4k && $cc -c engine/v4k.c -w $flags $args
export import=v4k.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 05-scene && $cc -o 05-scene demos/05-scene.c -lm -ldl -lpthread -lX11 -w -Iengine/ $flags $import $args &
echo 06-controller && $cc -o 06-controller demos/06-controller.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 engine/bind/luajit.osx
echo build=$build, type=$dll, cc=$cc, args=$args
# framework (as dynamic library)
if [ "$dll" = "dll" ]; then
echo libv4k && cc -ObjC -dynamiclib -o libv4k.dylib engine/v4k.c -framework cocoa -framework iokit -framework audiotoolbox -w $flags $args
cp libv4k.dylib engine/bind
export import=libv4k.dylib
else
# framework
echo v4k && cc -c -ObjC engine/v4k.c -w $flags $args
export import=v4k.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 05-scene && cc -o 05-scene demos/05-scene.c -w -Iengine/ $import $flags $args -framework cocoa -framework iokit -framework audiotoolbox &
echo 06-controller && cc -o 06-controller demos/06-controller.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"

554
demos/99-spot.c 100644
View File

@ -0,0 +1,554 @@
// [ref] http://fabiensanglard.net/shadowmappingVSM/index.php
// [ref] http://www.opengl-tutorial.org/es/intermediate-tutorials/tutorial-16-shadow-mapping/
// [ref] https://github.com/cforfang/opengl-shadowmapping
// [ref] https://learnopengl.com/Advanced-Lighting/Shadows/Shadow-Mapping
// @todo: spotlight (cone light)
// @todo: pointlight (cubemap light)
// @todo: area light (rect or circle light)
// @todo: directional light (sunlight)
// further reading (in order):
// DPSM [3] Brabec, Annen: Shadow mapping for hemispherical and omnidirectional light sources (2002)
// DPSM* [4] Osman, Bukowski: Practical implementation of dual paraboloid shadow maps (2006)
// IPSM [5] Vanek, Herout: High-quality Shadows with Improved Paraboloid Mapping (2011)
// LiSPSMs
// CSMs
// status: CUBE(0)+BLUR(0): ok
// status: CUBE(0)+BLUR(1): ok
// status: CUBE(1)+BLUR(1): ok
// status: CUBE(1)+BLUR(0): ok
// status: CUBE(?)+BLUR(?): no {
// 003.470s|!cannot find uniform 'shadowMap' in shader program 21 |shader_uniform|fwk_render.c:772
// 001: 00007FF7AF6A3FDA callstack (C:\prj\thread\FWK\fwk_system.c:250)
// 002: 00007FF7AF8E7CBC shader_uniform (C:\prj\thread\FWK\fwk_render.c:772)
// 003: 00007FF7AF691C27 shader_int (C:\prj\thread\FWK\fwk_render.c:777)
// 004: 00007FF7AF8F54EF color_begin (C:\prj\thread\FWK\spot.c:525)
// 005: 00007FF7AF8F5BF7 main (C:\prj\thread\FWK\spot.c:607)
// }
#ifndef VSMCUBE
#define VSMCUBE 0
#endif
#ifndef VSMBLUR
#define VSMBLUR 1
#endif
#include "v4k.h"
#include "split/v4k_shaders.c"
model_t sponza;
typedef struct Mesh
{
GLuint vao;
GLuint vbo;
} Mesh;
static float quadVertices[] = {
// Front-face
// Pos // Color //Tex // Norm
-1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Top-left
1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Top-right
1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // Bottom-right
1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // Bottom-right
-1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, //Bottom-left
-1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Top-left
};
static Mesh create_mesh(float* verts, int size) {
Mesh mesh;
// Create VAO
glGenVertexArrays(1, &mesh.vao);
glBindVertexArray(mesh.vao);
// Create VBO and copy the vertex data to it
glGenBuffers(1, &mesh.vbo);
glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo);
glBufferData(GL_ARRAY_BUFFER, size, verts, GL_STATIC_DRAW);
// Enable attribs
// Position
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(float), 0);
// Color
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(float), (void*)(3 * sizeof(float)));
// Texcoords
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 11 * sizeof(float), (void*)(6 * sizeof(float)));
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(float), (void*)(8 * sizeof(float)));
return mesh;
}
Mesh create_quad() {
return create_mesh(quadVertices, sizeof(quadVertices));
}
struct shadow {
// Resources
GLuint shadowProgram, blurProgram;
Mesh quadMesh;
GLuint shadowMapFBO, shadowMapTex, shadowMapTexDepth;
GLuint blurFBO, blurTex;
// Options
bool do_blur;
bool do_debugshadow;
float BLUR_SCALE; // Amount of blurring [0..100]
GLuint SHADOWMAP_WIDTH; // 256,512,1024,2048
// State
int shadow_active;
vec3 lightPos;
vec3 lightAimPos;
// VSM cubemap
GLuint cubeTex, cubeDepthTex, cubeFBOs[6];
GLuint currentSideTex, currentSideDepthTex;
GLuint toCurrentSideFBO;
} shadow;
#define shadowProgram shadow.shadowProgram
#define blurProgram shadow.blurProgram
#define quadMesh shadow.quadMesh
#define shadowMapFBO shadow.shadowMapFBO
#define shadowMapTex shadow.shadowMapTex
#define shadowMapTexDepth shadow.shadowMapTexDepth
#define blurFBO shadow.blurFBO
#define blurTex shadow.blurTex
#define do_blur shadow.do_blur
#define do_debugshadow shadow.do_debugshadow
#define BLUR_SCALE shadow.BLUR_SCALE
#define SHADOWMAP_WIDTH shadow.SHADOWMAP_WIDTH
#define shadow_active shadow.shadow_active
#define lightPos shadow.lightPos
#define lightAimPos shadow.lightAimPos
// vsm cubemap
#define cubeTex shadow.cubeTex
#define cubeDepthTex shadow.cubeDepthTex
#define cubeFBOs shadow.cubeFBOs
#define currentSideTex shadow.currentSideTex
#define currentSideDepthTex shadow.currentSideDepthTex
#define toCurrentSideFBO shadow.toCurrentSideFBO
static GLuint cubemap_create(GLsizei size, int flags) {
GLenum texel = flags & TEXTURE_DEPTH ? GL_DEPTH_COMPONENT : GL_RGB32F;
GLenum pixel = flags & TEXTURE_DEPTH ? GL_DEPTH_COMPONENT : GL_RGB;
GLenum storage = flags & TEXTURE_DEPTH ? GL_FLOAT : GL_UNSIGNED_BYTE; // swap?
GLuint id;
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_CUBE_MAP, id);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, texel, size, size, 0, pixel, storage, NULL);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, texel, size, size, 0, pixel, storage, NULL);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, texel, size, size, 0, pixel, storage, NULL);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, texel, size, size, 0, pixel, storage, NULL);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, texel, size, size, 0, pixel, storage, NULL);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, texel, size, size, 0, pixel, storage, NULL);
if( flags & TEXTURE_DEPTH ) {
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
} else {
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
return id;
}
static void framebuffer_cube_create(GLuint cube_fbo[6], GLuint cube_texture, GLuint cube_texture_depth) {
glGenFramebuffers(6, cube_fbo);
for (int i = 0; i < 6; i++) {
glBindFramebuffer(GL_FRAMEBUFFER, cube_fbo[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cube_texture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cube_texture_depth, 0);
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (GL_FRAMEBUFFER_COMPLETE != result) {
printf("ERROR: Framebuffer is not complete.\n");
}
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
static void set_shadow_matrix_uniform(const GLuint program, int dir) {
if(dir<0) return;
mat44 P, V, PV;
perspective44(P, 90.0f, 1.0f, 0.5f, 100.0f);
/**/ if(dir == 0) lookat44(V, lightPos, add3(lightPos, vec3(+1, 0, 0)), vec3(0, -1, 0)); // +X
else if(dir == 1) lookat44(V, lightPos, add3(lightPos, vec3(-1, 0, 0)), vec3(0, -1, 0)); // -X
else if(dir == 2) lookat44(V, lightPos, add3(lightPos, vec3( 0, +1, 0)), vec3(0, 0, +1)); // +Y
else if(dir == 3) lookat44(V, lightPos, add3(lightPos, vec3( 0, -1, 0)), vec3(0, 0, -1)); // -Y
else if(dir == 4) lookat44(V, lightPos, add3(lightPos, vec3( 0, 0, +1)), vec3(0, -1, 0)); // +Z
else /*dir == 5*/ lookat44(V, lightPos, add3(lightPos, vec3( 0, 0, -1)), vec3(0, -1, 0)); // -Z
multiply44x2(PV, P, V); // -Z
shader_bind(program); shader_mat44("cameraToShadowView", V);
shader_bind(program); shader_mat44("cameraToShadowProjector", PV);
}
void shadow_create(int RESOLUTION) {
do_blur = 1;
do_debugshadow = 0;
BLUR_SCALE = 0.5; // Amount of blurring [0..1]
SHADOWMAP_WIDTH = RESOLUTION; // 256,512,1024,2048
lightPos = vec3(-2, 2.0, -2);
lightAimPos = vec3(0.0, 0, -5.0);
// Create programs
shadowProgram = shader(vs_shadow_vsm, fs_shadow_vsm, "position", "outColor");
blurProgram = shader(vs_shadow_blur, fs_shadow_blur, "position,,texcoord", "outColor");
// ShadowMap-textures and FBO // @todo: GL_RG32F+GL_RG also GL_CLAMP to remove artifacts
shadowMapTex = texture_create(SHADOWMAP_WIDTH, SHADOWMAP_WIDTH, 2, NULL, TEXTURE_FLOAT).id;
shadowMapTexDepth = texture_create(SHADOWMAP_WIDTH, SHADOWMAP_WIDTH, 0, NULL, TEXTURE_DEPTH | TEXTURE_FLOAT).id;
shadowMapFBO = fbo(shadowMapTex, shadowMapTexDepth, 0);
// Textures and FBO to perform blurring
blurTex = texture_create(SHADOWMAP_WIDTH, SHADOWMAP_WIDTH, 2, NULL, TEXTURE_FLOAT).id;
blurFBO = fbo(blurTex, 0, 0);
#if VSMCUBE
// Create cubemap
cubeTex = cubemap_create(SHADOWMAP_WIDTH, 0);
cubeDepthTex = cubemap_create(SHADOWMAP_WIDTH, TEXTURE_DEPTH);
framebuffer_cube_create(cubeFBOs, cubeTex, cubeDepthTex);
// Temporary storage
currentSideTex = texture_create(SHADOWMAP_WIDTH, SHADOWMAP_WIDTH, 2, NULL, TEXTURE_FLOAT /*| TEXTURE_EDGE*/ ).id;
currentSideDepthTex = texture_create(SHADOWMAP_WIDTH, SHADOWMAP_WIDTH, 0, NULL, TEXTURE_DEPTH | TEXTURE_FLOAT).id;
toCurrentSideFBO = fbo(currentSideTex, currentSideDepthTex, 0);
#endif
}
void shadow_destroy() {
glDeleteProgram(shadowProgram);
glDeleteProgram(blurProgram);
glDeleteTextures(1, &blurTex);
glDeleteFramebuffers(1, &blurFBO);
glDeleteTextures(1, &shadowMapTex);
glDeleteTextures(1, &shadowMapTexDepth);
glDeleteFramebuffers(1, &shadowMapFBO);
}
bool shadow_is_active() {
return shadow_active;
}
void shadow_pv_matrix(mat44 PV) {
mat44 P,V;
// perspective44(P, 45.0f, 1.0f, 2.0f, 100.0f);
perspective44(P, 45*2, window_width() / ((float)window_height()+!window_height()), 1.f, 100.f);
lookat44(V, lightPos, lightAimPos, vec3(0, 1, 0)); // Point toward object regardless of position
multiply44x2(PV, P, V);
}
void shadow_position(vec3 p) {
lightPos = p;
}
void shadow_target(vec3 p) {
lightAimPos = p;
}
void shadow_begin() {
shadow_active = 1;
// shadow_state() {
glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS);
glEnable(GL_CULL_FACE); glCullFace(GL_BACK);
glFrontFace(GL_CW);
glBlendFunc(1, 0);
#if VSMCUBE
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
#endif
// }
glBindFramebuffer(GL_FRAMEBUFFER, shadowMapFBO);
glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_WIDTH);
//glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
mat44 PV; shadow_pv_matrix(PV);
shader_bind(shadowProgram);shader_mat44("cameraToShadowProjector", PV);
}
static void draw_fullscreen_quad() {
//delete_mesh(quadMesh);
if(!quadMesh.vao) quadMesh = create_quad();
glBindVertexArray(quadMesh.vao);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
}
static void shadow_blur() {
// remap 0(min)..1(max) -> 2(min)..epsilon(max)
float blur_scale = 1.999 * (1 - BLUR_SCALE) + 0.001;
glDisable(GL_DEPTH_TEST);
// Blur shadowMapTex (horizontally) to blurTex
glBindFramebuffer(GL_FRAMEBUFFER, blurFBO);
glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_WIDTH);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, shadowMapTex); //Input-texture
shader_bind(blurProgram); shader_vec2("ScaleU", vec2(1.0 / (SHADOWMAP_WIDTH*blur_scale), 0));
shader_int("textureSource",0);
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw_fullscreen_quad();
// Blur blurTex vertically and write to shadowMapTex
glBindFramebuffer(GL_FRAMEBUFFER, shadowMapFBO);
glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_WIDTH);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, blurTex);
shader_bind(blurProgram); shader_vec2("ScaleU", vec2(0, 1.0 / (SHADOWMAP_WIDTH*blur_scale)));
shader_int("textureSource",0);
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw_fullscreen_quad();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_DEPTH_TEST);
}
void shadow_end() {
// Reset
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
if(do_blur) shadow_blur();
shadow_active = 0;
glViewport(0, 0, window_width(), window_height());
}
void shadow_ui() {
// UI
if( ui_panel("Shadow", 0) ) {
if(ui_toggle("Debug", &do_debugshadow)) {}
if(ui_toggle("Blur shadow", &do_blur)) {}
if(ui_slider("Blur amount", &BLUR_SCALE)) {}
ui_panel_end();
}
if(do_debugshadow) {
// Blur and draw to screen
shader_bind(blurProgram); shader_vec2("ScaleU", vec2(0, 0)); // ... but make sure we don't actually blur
glBindTexture(GL_TEXTURE_2D, shadowMapTex);
draw_fullscreen_quad();
glBindTexture(GL_TEXTURE_2D, 0);
}
}
#define USER_DRAWCALL(shader) do { \
model_render(sponza, camera_get_active()->proj, camera_get_active()->view, sponza.pivot, shader); \
} while(0)
static void vsm_cube_draw()
{
glViewport(0, 0, SHADOWMAP_WIDTH, SHADOWMAP_WIDTH);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
shader_bind(shadowProgram);
// For each side of cubemap
for (int i = 0; i < 6; ++i) {
#if VSMBLUR
// Draw to temp. storage
shader_bind(shadowProgram);
glBindFramebuffer(GL_FRAMEBUFFER, toCurrentSideFBO);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
set_shadow_matrix_uniform(shadowProgram, i);
USER_DRAWCALL(shadowProgram);
// Blur horizontally to blurTex
glDisable(GL_DEPTH_TEST);
shader_bind(blurProgram);
shader_vec2("ScaleU", vec2(1.0 / SHADOWMAP_WIDTH, 0));
glBindFramebuffer(GL_FRAMEBUFFER, blurFBO);
glBindTexture(GL_TEXTURE_2D, currentSideTex);
glClear(GL_COLOR_BUFFER_BIT);
draw_fullscreen_quad();
// Blur vertically to actual cubemap
glBindFramebuffer(GL_FRAMEBUFFER, cubeFBOs[i]);
glBindTexture(GL_TEXTURE_2D, blurTex);
shader_bind(blurProgram);
shader_vec2("ScaleU", vec2(0, 1.0 / SHADOWMAP_WIDTH));
draw_fullscreen_quad();
glEnable(GL_DEPTH_TEST);
#else
// Draw directly to cubemap
glBindFramebuffer(GL_FRAMEBUFFER, cubeFBOs[i]);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
set_shadow_matrix_uniform(shadowProgram, i);
USER_DRAWCALL(shadowProgram);
#endif
}
// Reset state
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
#undef shadowProgram
#undef blurProgram
#undef quadMesh
#undef shadowMapFBO
#undef shadowMapTex
#undef shadowMapTexDepth
#undef blurFBO
#undef blurTex
#undef do_blur
#undef do_debugshadow
#undef BLUR_SCALE
#undef SHADOWMAP_WIDTH
#undef shadow_active
#undef lightPos
#undef lightAimPos
// Geometry (world coordinates)
static bool do_animate = 1;
static void color_begin(const GLuint program) {
glCullFace(GL_BACK);
#if 1 // VSMCUBE
glViewport(0, 0, window_width(), window_height());
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#endif
// Upload uniforms
shader_bind(program);
shader_mat44("view", camera_get_active()->view);
// shader_mat44("proj", camera_get_active()->proj);
shader_vec3("lightPos", shadow.lightPos);
#if VSMCUBE
set_shadow_matrix_uniform(program, -1);
#else
mat44 PV; shadow_pv_matrix(PV);
shader_mat44("cameraToShadowProjector", PV);
#endif
glActiveTexture(GL_TEXTURE0+1);
#if VSMCUBE
glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex);
#else
glBindTexture(GL_TEXTURE_2D, shadow.shadowMapTex); //Input-texture
#endif
shader_int("shadowMap",1);
}
static void color_end() {
#if VSMCUBE
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
#else
glBindTexture(GL_TEXTURE_2D, 0);
#endif
}
int main(int argc, char **argv)
{
window_create(0.75f, 0);
camera_t cam = camera();
// init shadowing 384x384 // 512x512
shadow_create(argc > 1 ? atoi(argv[1]) : 384);
sponza = model("sponza.obj", 0);
translation44(sponza.pivot, 0,-1,0);
rotate44(sponza.pivot, -90,1,0,0);
scale44(sponza.pivot, 10,10,10);
model_t suzanne = model("suzanne.obj", 0);
// create geometry
GLuint vsm_program = sponza.program;
#if 1
const char *tpl[] = {
"{{include-shadowmap}}", fs_0_0_shadowmap_lit,
};
vsm_program = shader(strlerp(1,tpl,vs_323444143_16_332_model), strlerp(1,tpl,fs_32_4_model), "att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent", "fragColor");
#endif
while (window_swap())
{
// input
if (input(KEY_ESC))
break;
// fps camera
bool active = ui_active() ? 0 : input(MOUSE_L) || input(MOUSE_M) || input(MOUSE_R);
vec3 wasdec = scale3( vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-input(KEY_C),input(KEY_W)-input(KEY_S)), 0.2f);
vec2 mouse = scale2( vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active);
camera_move(&cam, wasdec.x,wasdec.y,wasdec.z);
camera_fps(&cam, mouse.x,mouse.y);
window_cursor( !active );
#if 1
// animate light
if( do_animate ) {
static vec3 lightPos;
do_once {
lightPos = cam.position;
};
vec3 offs = vec3(sin(window_time()) * 15, 0, cos(window_time()) * 15);
shadow_position(add3(lightPos, offs));
// shadow_target(vec3(0,0,0)); // good for pointlight
shadow_target(add3(add3(lightPos, offs), vec3(0,0,-1)));
}
#else
shadow_position(cam.position);
shadow_target(add3(cam.position, cam.look));
#endif
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// render
#if VSMCUBE
shadow_begin();
vsm_cube_draw();
shadow_end();
#else
shadow_begin();
model_render(sponza, camera_get_active()->proj, camera_get_active()->view, sponza.pivot, shadow.shadowProgram); //< typo!, but works!
shadow_end();
#endif
color_begin(vsm_program);
model_render(sponza, camera_get_active()->proj, camera_get_active()->view, sponza.pivot, vsm_program); // does not work without program
color_end();
// // light bulb (suzanne)
// {
// mat44 M; scaling44(M, 10,10,10); relocate44(M, shadow.lightPos.x, shadow.lightPos.y, shadow.lightPos.z );
// model_render(suzanne, camera_get_active()->proj, camera_get_active()->view, M, 0);
// }
// if( ui_panel("App", 0) ) {
// if(ui_toggle("Animate light", &do_animate)) {}
// ui_panel_end();
// }
// shadow_ui();
}
}

View File

@ -2556,6 +2556,8 @@ extern const char *const fs_32_4_model_basic;
extern const char *const fs_3_4_skybox;
extern const char *const fs_3_4_skybox_rayleigh;
extern const char *const fs_main_shadertoy;
extern const char *const fs_shadow_blur;
extern const char *const fs_shadow_vsm;
extern const char *const vs_0_2_fullscreen_quad_A;
extern const char *const vs_0_2_fullscreen_quad_B;
extern const char *const vs_0_2_fullscreen_quad_B_flipped;
@ -2563,6 +2565,8 @@ extern const char *const vs_323444143_16_332_model;
extern const char *const vs_324_24_sprite;
extern const char *const vs_332_32;
extern const char *const vs_3_3_skybox;
extern const char *const vs_shadow_blur;
extern const char *const vs_shadow_vsm;
void ddraw_color(unsigned rgb);
void ddraw_color_push(unsigned rgb);
void ddraw_color_pop();

View File

@ -16438,6 +16438,13 @@ API void fbo_destroy(unsigned id);
// -----------------------------------------------------------------------------
// shadowmaps
// #ifndef VSMCUBE
// #define VSMCUBE 0
// #endif
// #ifndef VSMBLUR
// #define VSMBLUR 1
// #endif
typedef struct shadowmap_t {
mat44 shadowmatrix;
mat44 mvp;
@ -16819,6 +16826,8 @@ extern const char *const fs_32_4_model_basic;
extern const char *const fs_3_4_skybox;
extern const char *const fs_3_4_skybox_rayleigh;
extern const char *const fs_main_shadertoy;
extern const char *const fs_shadow_blur;
extern const char *const fs_shadow_vsm;
extern const char *const vs_0_2_fullscreen_quad_A;
extern const char *const vs_0_2_fullscreen_quad_B;
extern const char *const vs_0_2_fullscreen_quad_B_flipped;
@ -16826,6 +16835,8 @@ extern const char *const vs_323444143_16_332_model;
extern const char *const vs_324_24_sprite;
extern const char *const vs_332_32;
extern const char *const vs_3_3_skybox;
extern const char *const vs_shadow_blur;
extern const char *const vs_shadow_vsm;
#line 0
#line 1 "v4k_renderdd.h"
@ -339318,107 +339329,109 @@ const char *const fs_0_0_shadowmap_lit = "//" FILELINE "\n"
"uniform sampler2D shadowMap; // !VSMCUBE\n"
#endif
"\n"
"\n"
"struct light {\n"
" vec3 position; // world-space\n"
" vec4 diffuse;\n"
" vec4 specular;\n"
" float constantAttenuation, linearAttenuation, quadraticAttenuation;\n"
"};\n"
" \n"
"light light0 = light(\n"
" };\n"
" \n"
" light light0 = light(\n"
" lightPos,\n"
" vec4(1,1,1,1), // diffuse\n"
" vec4(1,1,1,1), // specular\n"
" 1.0, 0.0, 0.0 // attenuation (const, linear, quad)\n"
");\n"
" );\n"
" \n"
"// From http://fabiensanglard.net/shadowmappingVSM/index.php\n"
#if VSMCUBE
"float chebyshevUpperBound(float distance, vec3 dir) {\n"
" distance = distance/20 ;\n"
" vec2 moments = texture(shadowMap, dir).rg;\n"
#else
"float chebyshevUpperBound(float distance, vec4 scPostW) {\n"
" vec2 moments = texture(shadowMap,scPostW.xy).rg;\n"
#endif
" // Surface is fully lit. as the current fragment is before the light occluder\n"
" if (distance <= moments.x)\n"
" return 1.0;\n"
" \n"
" // The fragment is either in shadow or penumbra. We now use chebyshev's upperBound to check\n"
" // How likely this pixel is to be lit (p_max)\n"
" float variance = moments.y - (moments.x*moments.x);\n"
" //variance = max(variance, 0.000002);\n"
" variance = max(variance, 0.00002);\n"
" \n"
" float d = distance - moments.x;\n"
" float p_max = variance / (variance + d*d);\n"
" \n"
" return p_max;\n"
"}\n"
"\n"
"vec4 shadowmap(in vec4 vpeye, in vec4 vneye, in vec2 uv, in vec4 sc) {\n"
#ifndef VSMCUBE
" return vec4(1.);\n"
#else
" vec3 fragment = vec3(vpeye);\n"
" vec3 normal = vec3(normalize(vneye));\n"
" vec3 viewDir = normalize(-fragment);\n"
" \n"
" // Lighting\n"
" // Convert to eye-space\n"
" vec3 light = vec3(view * vec4(light0.position, 1.0));\n"
" \n"
#if VSMCUBE
" // Vectors\n"
" vec3 fragmentToLight = light - fragment;\n"
" vec3 fragmentToLightDir = normalize(fragmentToLight);\n"
" \n"
" // Shadows\n"
" vec4 fragmentToLight_world = inverse(view) * vec4(fragmentToLightDir, 0.0);\n"
" float shadowFactor = chebyshevUpperBound(length(fragmentToLight), -fragmentToLight_world.xyz);\n"
#else
" // Shadows\n"
" vec4 scPostW = sc / sc.w;\n"
" scPostW = scPostW * 0.5 + 0.5;\n"
" \n"
" float shadowFactor = 1.0; // Not in shadow\n"
" \n"
" bool outsideShadowMap = sc.w <= 0.0f || (scPostW.x < 0 || scPostW.y < 0) || (scPostW.x >= 1 || scPostW.y >= 1);\n"
" if (!outsideShadowMap) {\n"
" shadowFactor = chebyshevUpperBound(scPostW.z, scPostW);\n"
" }\n"
#endif
" \n"
" vec4 diffColor = vec4(1,1,1,1);\n"
#if VSMCUBE
" if(doTexture != 0) diffColor = vec4(vec3(texture(shadowMap, -fragmentToLight_world.xyz).r), 1.0);\n"
#else
" if(doTexture != 0) diffColor = vec4(vec3(texture(shadowMap, vec2(uv.x, 1.0 - uv.y)).r), 1.0);\n"
#endif
" \n"
#if 1
" vec3 positionToLight = light - fragment;\n"
" vec3 lightDir = normalize(positionToLight);\n"
" \n"
" // Angle between fragment-normal and incoming light\n"
" float cosAngIncidence = dot(lightDir, normal);\n"
" cosAngIncidence = clamp(cosAngIncidence, 0, 1);\n"
" \n"
" float attenuation = 1.0f;\n"
" attenuation = 1.0 / (light0.constantAttenuation + light0.linearAttenuation * length(positionToLight) + light0.quadraticAttenuation * pow(length(positionToLight),2));\n"
" \n"
" vec4 diffuse = diffColor * light0.diffuse * cosAngIncidence * attenuation;\n"
" \n"
" vec4 total_lighting;\n"
" total_lighting += vec4(0.1, 0.1, 0.1, 1.0) * diffColor; // Ambient\n"
" total_lighting += diffuse * shadowFactor; // Diffuse\n"
#else
" vec4 total_lighting = diffColor;\n"
#endif
" return vec4(clamp(vec3(total_lighting), 0., 1.), 1.0);\n"
#endif
"}\n";
" // From http://fabiensanglard.net/shadowmappingVSM/index.php\n"
#if VSMCUBE
" float chebyshevUpperBound(float distance, vec3 dir) {\n"
" distance = distance/20 ;\n"
" vec2 moments = texture(shadowMap, dir).rg;\n"
#else
" float chebyshevUpperBound(float distance, vec4 scPostW) {\n"
" vec2 moments = texture(shadowMap,scPostW.xy).rg;\n"
#endif
" // Surface is fully lit. as the current fragment is before the light occluder\n"
" if (distance <= moments.x)\n"
" return 1.0;\n"
" \n"
" // The fragment is either in shadow or penumbra. We now use chebyshev's upperBound to check\n"
" // How likely this pixel is to be lit (p_max)\n"
" float variance = moments.y - (moments.x*moments.x);\n"
" //variance = max(variance, 0.000002);\n"
" variance = max(variance, 0.00002);\n"
" \n"
" float d = distance - moments.x;\n"
" float p_max = variance / (variance + d*d);\n"
" \n"
" return p_max;\n"
" }\n"
" \n"
" \n"
" vec4 shadowmap(in vec4 vpeye, in vec4 vneye, in vec2 uv, in vec4 sc) {\n"
#ifndef VSMCUBE
" return vec4(1.);\n"
#else
" vec3 fragment = vec3(vpeye);\n"
" vec3 normal = vec3(normalize(vneye));\n"
" vec3 viewDir = normalize(-fragment);\n"
" \n"
" // Lighting\n"
" // Convert to eye-space\n"
" vec3 light = vec3(view * vec4(light0.position, 1.0));\n"
" \n"
#if VSMCUBE
" // Vectors\n"
" vec3 fragmentToLight = light - fragment;\n"
" vec3 fragmentToLightDir = normalize(fragmentToLight);\n"
" \n"
" // Shadows\n"
" vec4 fragmentToLight_world = inverse(view) * vec4(fragmentToLightDir, 0.0);\n"
" float shadowFactor = chebyshevUpperBound(length(fragmentToLight), -fragmentToLight_world.xyz);\n"
#else
" // Shadows\n"
" vec4 scPostW = sc / sc.w;\n"
" scPostW = scPostW * 0.5 + 0.5;\n"
" \n"
" float shadowFactor = 1.0; // Not in shadow\n"
" \n"
" bool outsideShadowMap = sc.w <= 0.0f || (scPostW.x < 0 || scPostW.y < 0) || (scPostW.x >= 1 || scPostW.y >= 1);\n"
" if (!outsideShadowMap) {\n"
" shadowFactor = chebyshevUpperBound(scPostW.z, scPostW);\n"
" }\n"
#endif
" \n"
" vec4 diffColor = vec4(1,1,1,1);\n"
#if VSMCUBE
" if(doTexture != 0) diffColor = vec4(vec3(texture(shadowMap, -fragmentToLight_world.xyz).r), 1.0);\n"
#else
" if(doTexture != 0) diffColor = vec4(vec3(texture(shadowMap, vec2(uv.x, 1.0 - uv.y)).r), 1.0);\n"
#endif
" \n"
#if 1
" vec3 positionToLight = light - fragment;\n"
" vec3 lightDir = normalize(positionToLight);\n"
" \n"
" // Angle between fragment-normal and incoming light\n"
" float cosAngIncidence = dot(lightDir, normal);\n"
" cosAngIncidence = clamp(cosAngIncidence, 0, 1);\n"
" \n"
" float attenuation = 1.0f;\n"
" attenuation = 1.0 / (light0.constantAttenuation + light0.linearAttenuation * length(positionToLight) + light0.quadraticAttenuation * pow(length(positionToLight),2));\n"
" \n"
" vec4 diffuse = diffColor * light0.diffuse * cosAngIncidence * attenuation;\n"
" \n"
" vec4 total_lighting;\n"
" total_lighting += vec4(0.1, 0.1, 0.1, 1.0) * diffColor; // Ambient\n"
" total_lighting += diffuse * shadowFactor; // Diffuse\n"
#else
" vec4 total_lighting = diffColor;\n"
#endif
" return vec4(clamp(vec3(total_lighting), 0., 1.), 1.0);\n"
#endif
" }\n";
const char *const fs_0_0_shadowmap_unlit = "//" FILELINE "\n"
"// uniform mat4 view = mat4(1.0);\n"
@ -339426,17 +339439,20 @@ const char *const fs_0_0_shadowmap_unlit = "//" FILELINE "\n"
"uniform float doTexture = 0.;\n"
"uniform sampler2D shadowMap;\n"
"\n"
"\n"
"vec4 shadowmap(in vec4 vpeye, in vec4 vneye, in vec2 Texcoord, in vec4 sc) {\n"
" return vec4(1.);\n"
"};\n";
" };\n";
const char *const fs_24_4_sprite = "//" FILELINE "\n"
"uniform sampler2D u_texture;\n"
"\n"
"\n"
"in vec2 vTexCoord;\n"
"in vec4 vColor;\n"
"out vec4 fragColor;\n"
"\n"
"\n"
"// [src] https://www.shadertoy.com/view/MllBWf CC1.0\n"
"vec4 texture_AA(sampler2D tx, vec2 uv) {\n"
" vec2 res = vec2(textureSize(tx, 0));\n"
@ -339451,6 +339467,7 @@ const char *const fs_24_4_sprite = "//" FILELINE "\n"
" return texture(tx, uv);\n"
"}\n"
"\n"
"\n"
"// [src] https://www.shadertoy.com/view/MllBWf CC1.0\n"
"vec4 texture_AA2( sampler2D tex, vec2 uv) {\n"
" vec2 res = vec2(textureSize(tex,0));\n"
@ -339460,6 +339477,7 @@ const char *const fs_24_4_sprite = "//" FILELINE "\n"
" return texture(tex, uv/res);\n"
"}\n"
"\n"
"\n"
"// [src] https://www.shadertoy.com/view/ltBfRD\n"
"vec4 texture_AA3(sampler2D tex, vec2 uv) {\n"
" vec2 res = vec2(textureSize(tex,0));\n"
@ -339478,6 +339496,7 @@ const char *const fs_24_4_sprite = "//" FILELINE "\n"
" return texture(tex, uv);\n"
"}\n"
"\n"
"\n"
"void main() {\n"
" vec4 texColor = texture_AA2(u_texture, vTexCoord);\n"
" if(texColor.a < 0.9) discard;\n"
@ -339506,9 +339525,11 @@ const char *const fs_2_4_texel_inv_gamma = "//" FILELINE "\n"
"uniform sampler2D texture0; /*unit0*/\n"
"uniform float u_inv_gamma;\n"
"\n"
"\n"
"in vec2 uv;\n"
"out vec4 fragcolor;\n"
"\n"
"\n"
"void main() {\n"
" vec4 texel = texture( texture0, uv );\n"
" fragcolor = texel;\n"
@ -339521,9 +339542,11 @@ const char *const fs_2_4_texel_ycbr_gamma_saturation = "//" FILELINE "\n"
"uniform sampler2D u_texture_cr; /*unit2*/\n"
"uniform float u_gamma;\n"
"\n"
"\n"
"in vec2 uv;\n"
"out vec4 fragcolor;\n"
"\n"
"\n"
"void main() {\n"
" float y = texture(u_texture_y, uv).r;\n"
" float cb = texture(u_texture_cb, uv).r;\n"
@ -339550,6 +339573,7 @@ const char *const fs_2_4_texel_ycbr_gamma_saturation = "//" FILELINE "\n"
" vec3 intensity = vec3(dot(texel.rgb, W));\n"
"texel.rgb = mix(intensity, texel.rgb, saturation); }\n"
"\n"
"\n"
"fragcolor = vec4(texel.rgb, 1.0);\n"
"}\n";
@ -339562,6 +339586,7 @@ const char *const fs_32_4_model = "//" FILELINE "\n"
"uniform bool u_matcaps = false;\n"
"uniform vec4 u_diffuse = vec4(1.0,1.0,1.0,1.0);\n"
"\n"
"\n"
#ifdef RIM
"in vec3 v_position;\n"
#endif
@ -339570,60 +339595,63 @@ const char *const fs_32_4_model = "//" FILELINE "\n"
"in vec4 v_color;\n"
"out vec4 fragcolor;\n"
"\n"
"\n"
"{{include-shadowmap}}\n"
"in vec4 vpeye;\n"
"in vec4 vneye;\n"
"in vec4 sc;\n"
"vec4 shadowing() {\n"
" return shadowmap(vpeye, vneye, v_texcoord, sc);\n"
"return shadowmap(vpeye, vneye, v_texcoord, sc);\n"
"}\n"
"\n"
"\n"
"void main() {\n"
" vec3 n = /*normalize*/(v_normal);\n"
"vec3 n = /*normalize*/(v_normal);\n"
"\n"
" // SH lighting\n"
" vec4 lit = vec4(1.0, 1.0, 1.0, 1.0);\n"
" vec3 SHLightResult[9];\n"
" SHLightResult[0] = 0.282095f * u_coefficients_sh[0];\n"
" SHLightResult[1] = -0.488603f * u_coefficients_sh[1] * n.y;\n"
" SHLightResult[2] = 0.488603f * u_coefficients_sh[2] * n.z;\n"
" SHLightResult[3] = -0.488603f * u_coefficients_sh[3] * n.x;\n"
" SHLightResult[4] = 1.092548f * u_coefficients_sh[4] * n.x * n.y;\n"
" SHLightResult[5] = -1.092548f * u_coefficients_sh[5] * n.y * n.z;\n"
" SHLightResult[6] = 0.315392f * u_coefficients_sh[6] * (3.0f * n.z * n.z - 1.0f);\n"
" SHLightResult[7] = -1.092548f * u_coefficients_sh[7] * n.x * n.z;\n"
" SHLightResult[8] = 0.546274f * u_coefficients_sh[8] * (n.x * n.x - n.y * n.y);\n"
" vec3 result = vec3(0.0);\n"
" for (int i = 0; i < 9; ++i)\n"
" result += SHLightResult[i];\n"
" \n"
" if( (result.x*result.x+result.y*result.y+result.z*result.z) > 0.0 ) lit = vec4(result, 1.0);\n"
"\n"
" // base\n"
" vec4 diffuse;\n"
" if(u_matcaps) {\n"
" vec2 muv = vec2(view * vec4(v_normal_ws, 0))*0.5+vec2(0.5,0.5); // normal (model space) to view space\n"
" diffuse = texture(u_texture2d, vec2(muv.x, 1.0-muv.y));\n"
"// SH lighting\n"
"vec4 lit = vec4(1.0, 1.0, 1.0, 1.0);\n"
"vec3 SHLightResult[9];\n"
"SHLightResult[0] = 0.282095f * u_coefficients_sh[0];\n"
"SHLightResult[1] = -0.488603f * u_coefficients_sh[1] * n.y;\n"
"SHLightResult[2] = 0.488603f * u_coefficients_sh[2] * n.z;\n"
"SHLightResult[3] = -0.488603f * u_coefficients_sh[3] * n.x;\n"
"SHLightResult[4] = 1.092548f * u_coefficients_sh[4] * n.x * n.y;\n"
"SHLightResult[5] = -1.092548f * u_coefficients_sh[5] * n.y * n.z;\n"
"SHLightResult[6] = 0.315392f * u_coefficients_sh[6] * (3.0f * n.z * n.z - 1.0f);\n"
"SHLightResult[7] = -1.092548f * u_coefficients_sh[7] * n.x * n.z;\n"
"SHLightResult[8] = 0.546274f * u_coefficients_sh[8] * (n.x * n.x - n.y * n.y);\n"
"vec3 result = vec3(0.0);\n"
"for (int i = 0; i < 9; ++i)\n"
"result += SHLightResult[i];\n"
"\n"
"if( (result.x*result.x+result.y*result.y+result.z*result.z) > 0.0 ) lit = vec4(result, 1.0);\n"
"\n"
"\n"
"// base\n"
"vec4 diffuse;\n"
"if(u_matcaps) {\n"
" vec2 muv = vec2(view * vec4(v_normal_ws, 0))*0.5+vec2(0.5,0.5); // normal (model space) to view space\n"
" diffuse = texture(u_texture2d, vec2(muv.x, 1.0-muv.y));\n"
" } else if(u_textured) {\n"
" diffuse = texture(u_texture2d, v_texcoord);\n"
" } else {\n"
" diffuse = u_diffuse; // * v_color;\n"
" }\n"
" } else {\n"
" diffuse = u_diffuse; // * v_color;\n"
" }\n"
" \n"
" // lighting mix\n"
" fragcolor = diffuse * lit * shadowing();\n"
" \n"
" // rimlight\n"
#ifdef RIM
" {vec3 n = normalize(mat3(M) * v_normal); // convert normal to view space\n"
" vec3 p = (M * vec4(v_position,1.0)).xyz; // convert position to view space\n"
" vec3 v = normalize(-p); // eye vector\n"
" float rim = 1.0 - max(dot(v, n), 0.0); // rimlight\n"
" rim = smoothstep(1.0-0.01, 1.0, rim); // intensity (0.01)\n"
" fragcolor += vec4(0.0, 0.0, rim, 1.0);} // blue\n"
#endif
"}\n"
"\n";
" // lighting mix\n"
" fragcolor = diffuse * lit * shadowing();\n"
" \n"
" // rimlight\n"
#ifdef RIM
" {vec3 n = normalize(mat3(M) * v_normal); // convert normal to view space\n"
" vec3 p = (M * vec4(v_position,1.0)).xyz; // convert position to view space\n"
" vec3 v = normalize(-p); // eye vector\n"
" float rim = 1.0 - max(dot(v, n), 0.0); // rimlight\n"
" rim = smoothstep(1.0-0.01, 1.0, rim); // intensity (0.01)\n"
" fragcolor += vec4(0.0, 0.0, rim, 1.0);} // blue\n"
#endif
" }\n";
const char *const fs_32_4_model_basic = "//" FILELINE "\n"
"uniform sampler2D fsDiffTex;\n"
@ -339631,10 +339659,12 @@ const char *const fs_32_4_model_basic = "//" FILELINE "\n"
"uniform sampler2D fsPositionTex;\n"
"uniform mat4 MVP;\n"
"\n"
"\n"
"in vec3 v_normal;\n"
"in vec2 v_texcoord;\n"
"out vec4 fragColor;\n"
"\n"
"\n"
"void main() {\n"
" vec4 diff = texture(fsDiffTex, v_texcoord).rgba;\n"
" vec3 n = normalize(mat3(MVP) * v_normal); // transform normal to eye space\n"
@ -339644,9 +339674,11 @@ const char *const fs_32_4_model_basic = "//" FILELINE "\n"
const char *const fs_3_4_skybox = "//" FILELINE "\n"
"uniform samplerCube u_cubemap;\n"
"\n"
"\n"
"in vec3 v_direction;\n"
"out vec4 fragcolor;\n"
"\n"
"\n"
"void main() {\n"
" fragcolor = vec4(texture(u_cubemap, v_direction).rgb, 1.0);\n"
"}\n";
@ -339654,11 +339686,14 @@ const char *const fs_3_4_skybox = "//" FILELINE "\n"
const char *const fs_3_4_skybox_rayleigh = "//" FILELINE "\n"
"uniform vec3 uSunPos = vec3( 0, 0.1, -1 ); // = [0, Math.cos(theta) * 0.3 + 0.2, -1];\n"
"\n"
"\n"
"in vec3 v_direction;\n"
"out vec4 fragcolor;\n"
"\n"
"\n"
"vec3 atmosphere(vec3 r, vec3 r0, vec3 pSun, float iSun, float rPlanet, float rAtmos, vec3 kRlh, float kMie, float shRlh, float shMie, float g);\n"
"\n"
"\n"
"void main() {\n"
" vec3 color = atmosphere(\n"
" normalize(v_direction), // normalized ray direction\n"
@ -339680,13 +339715,16 @@ const char *const fs_3_4_skybox_rayleigh = "//" FILELINE "\n"
" fragcolor = vec4(color, 1);\n"
"}\n"
"\n"
"\n"
"// [src] https://github.com/wwwtyro/glsl-atmosphere by wwwtyro (Unlicensed)\n"
"// For more information, please refer to <http://unlicense.org>\n"
"\n"
"\n"
"#define PI 3.141592\n"
"#define iSteps 16\n"
"#define jSteps 8\n"
"\n"
"\n"
"vec2 rsi(vec3 r0, vec3 rd, float sr) {\n"
" // ray-sphere intersection that assumes\n"
" // the sphere is centered at the origin.\n"
@ -339702,6 +339740,7 @@ const char *const fs_3_4_skybox_rayleigh = "//" FILELINE "\n"
" );\n"
"}\n"
"\n"
"\n"
"vec3 atmosphere(vec3 r, vec3 r0, vec3 pSun, float iSun, float rPlanet, float rAtmos, vec3 kRlh, float kMie, float shRlh, float shMie, float g) {\n"
" // Normalize the sun and view directions.\n"
" pSun = normalize(pSun);\n"
@ -339797,9 +339836,50 @@ const char *const fs_main_shadertoy = "//" FILELINE "\n"
" mainImage(fragColor, texcoord.xy * iResolution);\n"
"}\n";
const char *const fs_shadow_blur = "//" FILELINE "\n"
"uniform sampler2D textureSource;\n"
"uniform vec2 ScaleU;\n"
"\n"
"in vec2 Texcoord;\n"
"out vec4 outColor;\n"
"\n"
"void main() {\n"
" vec4 color = vec4(0.0);\n"
" color += texture( textureSource, Texcoord.st + vec2( -3.0*ScaleU.x, -3.0*ScaleU.y ) ) * 0.015625;\n"
" color += texture( textureSource, Texcoord.st + vec2( -2.0*ScaleU.x, -2.0*ScaleU.y ) )*0.09375;\n"
" color += texture( textureSource, Texcoord.st + vec2( -1.0*ScaleU.x, -1.0*ScaleU.y ) )*0.234375;\n"
" color += texture( textureSource, Texcoord.st + vec2( 0.0 , 0.0) )*0.3125;\n"
" color += texture( textureSource, Texcoord.st + vec2( 1.0*ScaleU.x, 1.0*ScaleU.y ) )*0.234375;\n"
" color += texture( textureSource, Texcoord.st + vec2( 2.0*ScaleU.x, 2.0*ScaleU.y ) )*0.09375;\n"
" color += texture( textureSource, Texcoord.st + vec2( 3.0*ScaleU.x, -3.0*ScaleU.y ) ) * 0.015625;\n"
" outColor = vec4(color.xyz, 1.0);\n"
"}\n";
const char *const fs_shadow_vsm = "//" FILELINE "\n"
"in vec4 v_position;\n"
"out vec4 outColor;\n"
"\n"
"void main() {\n"
#if VSMCUBE
" float depth = length( vec3(v_position) ) / 20;\n"
#else
" float depth = v_position.z / v_position.w;\n"
" depth = depth * 0.5 + 0.5;\n"
#endif
" \n"
" float moment1 = depth;\n"
" float moment2 = depth * depth;\n"
" \n"
" float dx = dFdx(depth);\n"
" float dy = dFdy(depth);\n"
" moment2 += 0.25*(dx*dx+dy*dy);\n"
" outColor = vec4( moment1, moment2, 0.0, 0.0);\n"
"}\n";
const char *const vs_0_2_fullscreen_quad_A = "//" FILELINE "\n"
"out vec2 texcoord;\n"
"\n"
"\n"
"void main() {\n"
" texcoord = vec2( (gl_VertexID << 1) & 2, gl_VertexID & 2 );\n"
" gl_Position = vec4( texCoord * 2.0 - 1.0, 0.0, 1.0 );\n"
@ -339808,6 +339888,7 @@ const char *const vs_0_2_fullscreen_quad_A = "//" FILELINE "\n"
const char *const vs_0_2_fullscreen_quad_B = "//" FILELINE "\n"
"out vec2 uv;\n"
"\n"
"\n"
"void main() {\n"
" float x = float(((uint(gl_VertexID) + 2u) / 3u)%2u);\n"
" float y = float(((uint(gl_VertexID) + 1u) / 3u)%2u);\n"
@ -339818,6 +339899,7 @@ const char *const vs_0_2_fullscreen_quad_B = "//" FILELINE "\n"
const char *const vs_0_2_fullscreen_quad_B_flipped = "//" FILELINE "\n"
"out vec2 uv;\n"
"\n"
"\n"
"void main() {\n"
" float x = float(((uint(gl_VertexID) + 2u) / 3u)%2u);\n"
" float y = float(((uint(gl_VertexID) + 1u) / 3u)%2u);\n"
@ -339834,6 +339916,7 @@ const char *const vs_323444143_16_332_model = "//" FILELINE "\n"
"// uniform mat4 M; // RIM\n"
"uniform mat4 VP;\n"
"\n"
"\n"
#if 0
"// Fetch blend channels from all attached blend deformers.\n"
"for (size_t di = 0; di < mesh->blend_deformers.count; di++) {\n"
@ -339853,14 +339936,17 @@ const char *const vs_323444143_16_332_model = "//" FILELINE "\n"
" vmesh->num_blend_shapes = num_blend_shapes;\n"
"}\n"
"\n"
"\n"
"ubo.f_num_blend_shapes = (float)mesh->num_blend_shapes;\n"
"for (size_t i = 0; i < mesh->num_blend_shapes; i++) {\n"
" ubo.blend_weights[i] = view->scene.blend_channels[mesh->blend_channel_indices[i]].weight;\n"
"}\n"
"\n"
"\n"
"sg_image blend_shapes = mesh->num_blend_shapes > 0 ? mesh->blend_shape_image : view->empty_blend_shape_image;\n"
#endif
"\n"
"\n"
"// for blendshapes\n"
#ifndef MAX_BLENDSHAPES
"#define MAX_BLENDSHAPES 16\n"
@ -339869,6 +339955,7 @@ const char *const vs_323444143_16_332_model = "//" FILELINE "\n"
"uniform float f_num_blend_shapes; // @todo: implement me\n"
"uniform sampler2DArray blend_shapes; // @todo: implement me\n"
"\n"
"\n"
"in vec3 att_position; // @todo: reorder ass2iqe to emit p3 n3 u2 t3 b3 c4B i4 w4 instead\n"
"in vec2 att_texcoord;\n"
"in vec3 att_normal;\n"
@ -339885,6 +339972,8 @@ const char *const vs_323444143_16_332_model = "//" FILELINE "\n"
"out vec2 v_texcoord;\n"
"\n"
"\n"
"\n"
"\n"
"// shadow\n"
"uniform mat4 model, view;\n"
"uniform mat4 cameraToShadowProjector;\n"
@ -339897,6 +339986,7 @@ const char *const vs_323444143_16_332_model = "//" FILELINE "\n"
" sc = cameraToShadowProjector * model * vec4(att_position, 1.0f);\n"
"}\n"
"\n"
"\n"
"// blendshapes\n"
"vec3 evaluate_blend_shape(int vertex_index) {\n"
" ivec2 coord = ivec2(vertex_index & (2048 - 1), vertex_index >> 11);\n"
@ -339910,47 +340000,49 @@ const char *const vs_323444143_16_332_model = "//" FILELINE "\n"
" return offset;\n"
"}\n"
"\n"
"\n"
"void main() {\n"
" vec3 objPos;\n"
" if(!SKINNED) {\n"
" objPos = att_position;\n"
" v_normal = att_normal;\n"
" } else {\n"
" mat3x4 m = vsBoneMatrix[int(att_indexes.x)] * att_weights.x;\n"
" m += vsBoneMatrix[int(att_indexes.y)] * att_weights.y;\n"
" m += vsBoneMatrix[int(att_indexes.z)] * att_weights.z;\n"
" m += vsBoneMatrix[int(att_indexes.w)] * att_weights.w;\n"
" objPos = vec4(att_position, 1.0) * m;\n"
" } else {\n"
" mat3x4 m = vsBoneMatrix[int(att_indexes.x)] * att_weights.x;\n"
" m += vsBoneMatrix[int(att_indexes.y)] * att_weights.y;\n"
" m += vsBoneMatrix[int(att_indexes.z)] * att_weights.z;\n"
" m += vsBoneMatrix[int(att_indexes.w)] * att_weights.w;\n"
" objPos = vec4(att_position, 1.0) * m;\n"
" \n"
" // blendshapes\n"
" // objPos += evaluate_blend_shape(int(att_vertexindex));\n"
" \n"
" v_normal = vec4(att_normal, 0.0) * m;\n"
" //@todo: tangents\n"
" }\n"
" \n"
" // blendshapes\n"
" // objPos += evaluate_blend_shape(int(att_vertexindex));\n"
" // vec3 tangent = att_tangent.xyz;\n"
" // vec3 bitangent = cross(att_normal, att_tangent.xyz) * att_tangent.w;\n"
" \n"
" v_normal = vec4(att_normal, 0.0) * m;\n"
" //@todo: tangents\n"
" }\n"
" \n"
" // vec3 tangent = att_tangent.xyz;\n"
" // vec3 bitangent = cross(att_normal, att_tangent.xyz) * att_tangent.w;\n"
" \n"
" v_normal_ws = normalize(vec3(model * vec4(v_normal, 0.))); // normal to world/model space\n"
" v_normal = normalize(v_normal);\n"
" v_position = att_position;\n"
" v_texcoord = att_texcoord;\n"
" v_color = att_color;\n"
" gl_Position = VP * att_instanced_matrix * vec4( objPos, 1.0 );\n"
" do_shadow();\n"
"}\n"
"\n";
" v_normal_ws = normalize(vec3(model * vec4(v_normal, 0.))); // normal to world/model space\n"
" v_normal = normalize(v_normal);\n"
" v_position = att_position;\n"
" v_texcoord = att_texcoord;\n"
" v_color = att_color;\n"
" gl_Position = VP * att_instanced_matrix * vec4( objPos, 1.0 );\n"
" do_shadow();\n"
" }\n";
const char *const vs_324_24_sprite = "//" FILELINE "\n"
"uniform mat4 u_mvp;\n"
"\n"
"\n"
"in vec3 att_Position;\n"
"in vec2 att_TexCoord;\n"
"in vec4 att_Color;\n"
"out vec2 vTexCoord;\n"
"out vec4 vColor;\n"
"\n"
"\n"
"void main() {\n"
" vColor = att_Color;\n"
" vTexCoord = att_TexCoord;\n"
@ -339960,6 +340052,7 @@ const char *const vs_324_24_sprite = "//" FILELINE "\n"
const char *const vs_332_32 = "//" FILELINE "\n"
"uniform mat4 u_mvp;\n"
"\n"
"\n"
"in vec3 att_position;\n"
"in vec3 att_normal;\n"
"in vec2 att_texcoord;\n"
@ -339969,6 +340062,7 @@ const char *const vs_332_32 = "//" FILELINE "\n"
"out vec3 v_normal_ws;\n"
"out vec2 v_texcoord;\n"
"\n"
"\n"
"// shadow\n"
"uniform mat4 model, view, proj;\n"
"uniform mat4 cameraToShadowProjector; // !VSMCUBE\n"
@ -339981,6 +340075,7 @@ const char *const vs_332_32 = "//" FILELINE "\n"
" sc = cameraToShadowProjector * model * vec4(att_position, 1.0f);\n"
"}\n"
"\n"
"\n"
"void main() {\n"
" gl_Position = u_mvp * vec4(att_position, 1.0);\n"
" v_normal = normalize(att_normal);\n"
@ -339993,15 +340088,44 @@ const char *const vs_332_32 = "//" FILELINE "\n"
const char *const vs_3_3_skybox = "//" FILELINE "\n"
"uniform mat4 u_mvp;\n"
"\n"
"\n"
"in vec3 att_position;\n"
"out vec3 v_direction;\n"
"\n"
"\n"
"void main() {\n"
" vec4 position = u_mvp * vec4(att_position, 0.0);\n"
" gl_Position = position.xyww;\n"
" v_direction = att_position;\n"
"}\n";
const char *const vs_shadow_blur = "//" FILELINE "\n"
"in vec3 position;\n"
"in vec2 texcoord;\n"
"out vec2 Texcoord;\n"
"\n"
"void main() {\n"
" gl_Position = vec4(position, 1.0);\n"
" Texcoord = texcoord;\n"
"}\n";
const char *const vs_shadow_vsm = "//" FILELINE "\n"
"uniform mat4 model;\n"
"uniform mat4 cameraToShadowView;\n"
"uniform mat4 cameraToShadowProjector;\n"
"\n"
"in vec3 position;\n"
"out vec4 v_position;\n"
"\n"
"void main() {\n"
" gl_Position = cameraToShadowProjector * model * vec4(position, 1.0);\n"
#if VSMCUBE
" v_position = cameraToShadowView * model * vec4(position, 1.0);\n"
#else
" v_position = gl_Position;\n"
#endif
"}\n";
#line 0
#line 1 "v4k_render.c"

View File

@ -7,104 +7,106 @@ uniform samplerCube shadowMap; // VSMCUBE
uniform sampler2D shadowMap; // !VSMCUBE
#endif
struct light {
vec3 position; // world-space
vec4 diffuse;
vec4 specular;
float constantAttenuation, linearAttenuation, quadraticAttenuation;
};
light light0 = light(
};
light light0 = light(
lightPos,
vec4(1,1,1,1), // diffuse
vec4(1,1,1,1), // specular
1.0, 0.0, 0.0 // attenuation (const, linear, quad)
);
);
// From http://fabiensanglard.net/shadowmappingVSM/index.php
#if VSMCUBE
float chebyshevUpperBound(float distance, vec3 dir) {
distance = distance/20 ;
vec2 moments = texture(shadowMap, dir).rg;
#else
float chebyshevUpperBound(float distance, vec4 scPostW) {
vec2 moments = texture(shadowMap,scPostW.xy).rg;
#endif
// Surface is fully lit. as the current fragment is before the light occluder
if (distance <= moments.x)
return 1.0;
// The fragment is either in shadow or penumbra. We now use chebyshev's upperBound to check
// How likely this pixel is to be lit (p_max)
float variance = moments.y - (moments.x*moments.x);
//variance = max(variance, 0.000002);
variance = max(variance, 0.00002);
float d = distance - moments.x;
float p_max = variance / (variance + d*d);
return p_max;
}
vec4 shadowmap(in vec4 vpeye, in vec4 vneye, in vec2 uv, in vec4 sc) {
#ifndef VSMCUBE
return vec4(1.);
#else
vec3 fragment = vec3(vpeye);
vec3 normal = vec3(normalize(vneye));
vec3 viewDir = normalize(-fragment);
// Lighting
// Convert to eye-space
vec3 light = vec3(view * vec4(light0.position, 1.0));
#if VSMCUBE
// Vectors
vec3 fragmentToLight = light - fragment;
vec3 fragmentToLightDir = normalize(fragmentToLight);
// Shadows
vec4 fragmentToLight_world = inverse(view) * vec4(fragmentToLightDir, 0.0);
float shadowFactor = chebyshevUpperBound(length(fragmentToLight), -fragmentToLight_world.xyz);
#else
// Shadows
vec4 scPostW = sc / sc.w;
scPostW = scPostW * 0.5 + 0.5;
float shadowFactor = 1.0; // Not in shadow
bool outsideShadowMap = sc.w <= 0.0f || (scPostW.x < 0 || scPostW.y < 0) || (scPostW.x >= 1 || scPostW.y >= 1);
if (!outsideShadowMap) {
shadowFactor = chebyshevUpperBound(scPostW.z, scPostW);
}
#endif
vec4 diffColor = vec4(1,1,1,1);
#if VSMCUBE
if(doTexture != 0) diffColor = vec4(vec3(texture(shadowMap, -fragmentToLight_world.xyz).r), 1.0);
#else
if(doTexture != 0) diffColor = vec4(vec3(texture(shadowMap, vec2(uv.x, 1.0 - uv.y)).r), 1.0);
#endif
#if 1
vec3 positionToLight = light - fragment;
vec3 lightDir = normalize(positionToLight);
// Angle between fragment-normal and incoming light
float cosAngIncidence = dot(lightDir, normal);
cosAngIncidence = clamp(cosAngIncidence, 0, 1);
float attenuation = 1.0f;
attenuation = 1.0 / (light0.constantAttenuation + light0.linearAttenuation * length(positionToLight) + light0.quadraticAttenuation * pow(length(positionToLight),2));
vec4 diffuse = diffColor * light0.diffuse * cosAngIncidence * attenuation;
vec4 total_lighting;
total_lighting += vec4(0.1, 0.1, 0.1, 1.0) * diffColor; // Ambient
total_lighting += diffuse * shadowFactor; // Diffuse
#else
vec4 total_lighting = diffColor;
#endif
return vec4(clamp(vec3(total_lighting), 0., 1.), 1.0);
#endif
}
// From http://fabiensanglard.net/shadowmappingVSM/index.php
#if VSMCUBE
float chebyshevUpperBound(float distance, vec3 dir) {
distance = distance/20 ;
vec2 moments = texture(shadowMap, dir).rg;
#else
float chebyshevUpperBound(float distance, vec4 scPostW) {
vec2 moments = texture(shadowMap,scPostW.xy).rg;
#endif
// Surface is fully lit. as the current fragment is before the light occluder
if (distance <= moments.x)
return 1.0;
// The fragment is either in shadow or penumbra. We now use chebyshev's upperBound to check
// How likely this pixel is to be lit (p_max)
float variance = moments.y - (moments.x*moments.x);
//variance = max(variance, 0.000002);
variance = max(variance, 0.00002);
float d = distance - moments.x;
float p_max = variance / (variance + d*d);
return p_max;
}
vec4 shadowmap(in vec4 vpeye, in vec4 vneye, in vec2 uv, in vec4 sc) {
#ifndef VSMCUBE
return vec4(1.);
#else
vec3 fragment = vec3(vpeye);
vec3 normal = vec3(normalize(vneye));
vec3 viewDir = normalize(-fragment);
// Lighting
// Convert to eye-space
vec3 light = vec3(view * vec4(light0.position, 1.0));
#if VSMCUBE
// Vectors
vec3 fragmentToLight = light - fragment;
vec3 fragmentToLightDir = normalize(fragmentToLight);
// Shadows
vec4 fragmentToLight_world = inverse(view) * vec4(fragmentToLightDir, 0.0);
float shadowFactor = chebyshevUpperBound(length(fragmentToLight), -fragmentToLight_world.xyz);
#else
// Shadows
vec4 scPostW = sc / sc.w;
scPostW = scPostW * 0.5 + 0.5;
float shadowFactor = 1.0; // Not in shadow
bool outsideShadowMap = sc.w <= 0.0f || (scPostW.x < 0 || scPostW.y < 0) || (scPostW.x >= 1 || scPostW.y >= 1);
if (!outsideShadowMap) {
shadowFactor = chebyshevUpperBound(scPostW.z, scPostW);
}
#endif
vec4 diffColor = vec4(1,1,1,1);
#if VSMCUBE
if(doTexture != 0) diffColor = vec4(vec3(texture(shadowMap, -fragmentToLight_world.xyz).r), 1.0);
#else
if(doTexture != 0) diffColor = vec4(vec3(texture(shadowMap, vec2(uv.x, 1.0 - uv.y)).r), 1.0);
#endif
#if 1
vec3 positionToLight = light - fragment;
vec3 lightDir = normalize(positionToLight);
// Angle between fragment-normal and incoming light
float cosAngIncidence = dot(lightDir, normal);
cosAngIncidence = clamp(cosAngIncidence, 0, 1);
float attenuation = 1.0f;
attenuation = 1.0 / (light0.constantAttenuation + light0.linearAttenuation * length(positionToLight) + light0.quadraticAttenuation * pow(length(positionToLight),2));
vec4 diffuse = diffColor * light0.diffuse * cosAngIncidence * attenuation;
vec4 total_lighting;
total_lighting += vec4(0.1, 0.1, 0.1, 1.0) * diffColor; // Ambient
total_lighting += diffuse * shadowFactor; // Diffuse
#else
vec4 total_lighting = diffColor;
#endif
return vec4(clamp(vec3(total_lighting), 0., 1.), 1.0);
#endif
}

View File

@ -3,6 +3,7 @@ uniform vec3 lightPos = vec3(1.0);
uniform float doTexture = 0.;
uniform sampler2D shadowMap;
vec4 shadowmap(in vec4 vpeye, in vec4 vneye, in vec2 Texcoord, in vec4 sc) {
return vec4(1.);
};
};

View File

@ -1,9 +1,11 @@
uniform sampler2D u_texture;
in vec2 vTexCoord;
in vec4 vColor;
out vec4 fragColor;
// [src] https://www.shadertoy.com/view/MllBWf CC1.0
vec4 texture_AA(sampler2D tx, vec2 uv) {
vec2 res = vec2(textureSize(tx, 0));
@ -18,6 +20,7 @@ vec4 texture_AA(sampler2D tx, vec2 uv) {
return texture(tx, uv);
}
// [src] https://www.shadertoy.com/view/MllBWf CC1.0
vec4 texture_AA2( sampler2D tex, vec2 uv) {
vec2 res = vec2(textureSize(tex,0));
@ -27,6 +30,7 @@ vec4 texture_AA2( sampler2D tex, vec2 uv) {
return texture(tex, uv/res);
}
// [src] https://www.shadertoy.com/view/ltBfRD
vec4 texture_AA3(sampler2D tex, vec2 uv) {
vec2 res = vec2(textureSize(tex,0));
@ -45,6 +49,7 @@ vec4 texture_AA3(sampler2D tex, vec2 uv) {
return texture(tex, uv);
}
void main() {
vec4 texColor = texture_AA2(u_texture, vTexCoord);
if(texColor.a < 0.9) discard;

View File

@ -1,9 +1,11 @@
uniform sampler2D texture0; /*unit0*/
uniform float u_inv_gamma;
in vec2 uv;
out vec4 fragcolor;
void main() {
vec4 texel = texture( texture0, uv );
fragcolor = texel;

View File

@ -3,9 +3,11 @@ uniform sampler2D u_texture_cb; /*unit1*/
uniform sampler2D u_texture_cr; /*unit2*/
uniform float u_gamma;
in vec2 uv;
out vec4 fragcolor;
void main() {
float y = texture(u_texture_y, uv).r;
float cb = texture(u_texture_cb, uv).r;
@ -32,5 +34,6 @@ void main() {
vec3 intensity = vec3(dot(texel.rgb, W));
texel.rgb = mix(intensity, texel.rgb, saturation); }
fragcolor = vec4(texel.rgb, 1.0);
}

View File

@ -6,6 +6,7 @@ uniform bool u_lit = false;
uniform bool u_matcaps = false;
uniform vec4 u_diffuse = vec4(1.0,1.0,1.0,1.0);
#ifdef RIM
in vec3 v_position;
#endif
@ -14,56 +15,60 @@ in vec2 v_texcoord;
in vec4 v_color;
out vec4 fragcolor;
{{include-shadowmap}}
in vec4 vpeye;
in vec4 vneye;
in vec4 sc;
vec4 shadowing() {
return shadowmap(vpeye, vneye, v_texcoord, sc);
return shadowmap(vpeye, vneye, v_texcoord, sc);
}
void main() {
vec3 n = /*normalize*/(v_normal);
vec3 n = /*normalize*/(v_normal);
// SH lighting
vec4 lit = vec4(1.0, 1.0, 1.0, 1.0);
vec3 SHLightResult[9];
SHLightResult[0] = 0.282095f * u_coefficients_sh[0];
SHLightResult[1] = -0.488603f * u_coefficients_sh[1] * n.y;
SHLightResult[2] = 0.488603f * u_coefficients_sh[2] * n.z;
SHLightResult[3] = -0.488603f * u_coefficients_sh[3] * n.x;
SHLightResult[4] = 1.092548f * u_coefficients_sh[4] * n.x * n.y;
SHLightResult[5] = -1.092548f * u_coefficients_sh[5] * n.y * n.z;
SHLightResult[6] = 0.315392f * u_coefficients_sh[6] * (3.0f * n.z * n.z - 1.0f);
SHLightResult[7] = -1.092548f * u_coefficients_sh[7] * n.x * n.z;
SHLightResult[8] = 0.546274f * u_coefficients_sh[8] * (n.x * n.x - n.y * n.y);
vec3 result = vec3(0.0);
for (int i = 0; i < 9; ++i)
result += SHLightResult[i];
if( (result.x*result.x+result.y*result.y+result.z*result.z) > 0.0 ) lit = vec4(result, 1.0);
// base
vec4 diffuse;
if(u_matcaps) {
vec2 muv = vec2(view * vec4(v_normal_ws, 0))*0.5+vec2(0.5,0.5); // normal (model space) to view space
diffuse = texture(u_texture2d, vec2(muv.x, 1.0-muv.y));
// SH lighting
vec4 lit = vec4(1.0, 1.0, 1.0, 1.0);
vec3 SHLightResult[9];
SHLightResult[0] = 0.282095f * u_coefficients_sh[0];
SHLightResult[1] = -0.488603f * u_coefficients_sh[1] * n.y;
SHLightResult[2] = 0.488603f * u_coefficients_sh[2] * n.z;
SHLightResult[3] = -0.488603f * u_coefficients_sh[3] * n.x;
SHLightResult[4] = 1.092548f * u_coefficients_sh[4] * n.x * n.y;
SHLightResult[5] = -1.092548f * u_coefficients_sh[5] * n.y * n.z;
SHLightResult[6] = 0.315392f * u_coefficients_sh[6] * (3.0f * n.z * n.z - 1.0f);
SHLightResult[7] = -1.092548f * u_coefficients_sh[7] * n.x * n.z;
SHLightResult[8] = 0.546274f * u_coefficients_sh[8] * (n.x * n.x - n.y * n.y);
vec3 result = vec3(0.0);
for (int i = 0; i < 9; ++i)
result += SHLightResult[i];
if( (result.x*result.x+result.y*result.y+result.z*result.z) > 0.0 ) lit = vec4(result, 1.0);
// base
vec4 diffuse;
if(u_matcaps) {
vec2 muv = vec2(view * vec4(v_normal_ws, 0))*0.5+vec2(0.5,0.5); // normal (model space) to view space
diffuse = texture(u_texture2d, vec2(muv.x, 1.0-muv.y));
} else if(u_textured) {
diffuse = texture(u_texture2d, v_texcoord);
} else {
diffuse = u_diffuse; // * v_color;
}
} else {
diffuse = u_diffuse; // * v_color;
}
// lighting mix
fragcolor = diffuse * lit * shadowing();
// rimlight
#ifdef RIM
{vec3 n = normalize(mat3(M) * v_normal); // convert normal to view space
vec3 p = (M * vec4(v_position,1.0)).xyz; // convert position to view space
vec3 v = normalize(-p); // eye vector
float rim = 1.0 - max(dot(v, n), 0.0); // rimlight
rim = smoothstep(1.0-0.01, 1.0, rim); // intensity (0.01)
fragcolor += vec4(0.0, 0.0, rim, 1.0);} // blue
#endif
}
// lighting mix
fragcolor = diffuse * lit * shadowing();
// rimlight
#ifdef RIM
{vec3 n = normalize(mat3(M) * v_normal); // convert normal to view space
vec3 p = (M * vec4(v_position,1.0)).xyz; // convert position to view space
vec3 v = normalize(-p); // eye vector
float rim = 1.0 - max(dot(v, n), 0.0); // rimlight
rim = smoothstep(1.0-0.01, 1.0, rim); // intensity (0.01)
fragcolor += vec4(0.0, 0.0, rim, 1.0);} // blue
#endif
}

View File

@ -3,10 +3,12 @@ uniform sampler2D fsNormalTex;
uniform sampler2D fsPositionTex;
uniform mat4 MVP;
in vec3 v_normal;
in vec2 v_texcoord;
out vec4 fragColor;
void main() {
vec4 diff = texture(fsDiffTex, v_texcoord).rgba;
vec3 n = normalize(mat3(MVP) * v_normal); // transform normal to eye space

View File

@ -1,8 +1,10 @@
uniform samplerCube u_cubemap;
in vec3 v_direction;
out vec4 fragcolor;
void main() {
fragcolor = vec4(texture(u_cubemap, v_direction).rgb, 1.0);
}

View File

@ -1,10 +1,13 @@
uniform vec3 uSunPos = vec3( 0, 0.1, -1 ); // = [0, Math.cos(theta) * 0.3 + 0.2, -1];
in vec3 v_direction;
out vec4 fragcolor;
vec3 atmosphere(vec3 r, vec3 r0, vec3 pSun, float iSun, float rPlanet, float rAtmos, vec3 kRlh, float kMie, float shRlh, float shMie, float g);
void main() {
vec3 color = atmosphere(
normalize(v_direction), // normalized ray direction
@ -26,13 +29,16 @@ void main() {
fragcolor = vec4(color, 1);
}
// [src] https://github.com/wwwtyro/glsl-atmosphere by wwwtyro (Unlicensed)
// For more information, please refer to <http://unlicense.org>
#define PI 3.141592
#define iSteps 16
#define jSteps 8
vec2 rsi(vec3 r0, vec3 rd, float sr) {
// ray-sphere intersection that assumes
// the sphere is centered at the origin.
@ -48,6 +54,7 @@ vec2 rsi(vec3 r0, vec3 rd, float sr) {
);
}
vec3 atmosphere(vec3 r, vec3 r0, vec3 pSun, float iSun, float rPlanet, float rAtmos, vec3 kRlh, float kMie, float shRlh, float shMie, float g) {
// Normalize the sun and view directions.
pSun = normalize(pSun);

View File

@ -0,0 +1,17 @@
uniform sampler2D textureSource;
uniform vec2 ScaleU;
in vec2 Texcoord;
out vec4 outColor;
void main() {
vec4 color = vec4(0.0);
color += texture( textureSource, Texcoord.st + vec2( -3.0*ScaleU.x, -3.0*ScaleU.y ) ) * 0.015625;
color += texture( textureSource, Texcoord.st + vec2( -2.0*ScaleU.x, -2.0*ScaleU.y ) )*0.09375;
color += texture( textureSource, Texcoord.st + vec2( -1.0*ScaleU.x, -1.0*ScaleU.y ) )*0.234375;
color += texture( textureSource, Texcoord.st + vec2( 0.0 , 0.0) )*0.3125;
color += texture( textureSource, Texcoord.st + vec2( 1.0*ScaleU.x, 1.0*ScaleU.y ) )*0.234375;
color += texture( textureSource, Texcoord.st + vec2( 2.0*ScaleU.x, 2.0*ScaleU.y ) )*0.09375;
color += texture( textureSource, Texcoord.st + vec2( 3.0*ScaleU.x, -3.0*ScaleU.y ) ) * 0.015625;
outColor = vec4(color.xyz, 1.0);
}

View File

@ -0,0 +1,19 @@
in vec4 v_position;
out vec4 outColor;
void main() {
#if VSMCUBE
float depth = length( vec3(v_position) ) / 20;
#else
float depth = v_position.z / v_position.w;
depth = depth * 0.5 + 0.5;
#endif
float moment1 = depth;
float moment2 = depth * depth;
float dx = dFdx(depth);
float dy = dFdy(depth);
moment2 += 0.25*(dx*dx+dy*dy);
outColor = vec4( moment1, moment2, 0.0, 0.0);
}

View File

@ -1,5 +1,6 @@
out vec2 texcoord;
void main() {
texcoord = vec2( (gl_VertexID << 1) & 2, gl_VertexID & 2 );
gl_Position = vec4( texCoord * 2.0 - 1.0, 0.0, 1.0 );

View File

@ -1,5 +1,6 @@
out vec2 uv;
void main() {
float x = float(((uint(gl_VertexID) + 2u) / 3u)%2u);
float y = float(((uint(gl_VertexID) + 1u) / 3u)%2u);

View File

@ -1,5 +1,6 @@
out vec2 uv;
void main() {
float x = float(((uint(gl_VertexID) + 2u) / 3u)%2u);
float y = float(((uint(gl_VertexID) + 1u) / 3u)%2u);

View File

@ -6,6 +6,7 @@ uniform bool SKINNED = false;
// uniform mat4 M; // RIM
uniform mat4 VP;
#if 0
// Fetch blend channels from all attached blend deformers.
for (size_t di = 0; di < mesh->blend_deformers.count; di++) {
@ -25,14 +26,17 @@ if (num_blend_shapes > 0) {
vmesh->num_blend_shapes = num_blend_shapes;
}
ubo.f_num_blend_shapes = (float)mesh->num_blend_shapes;
for (size_t i = 0; i < mesh->num_blend_shapes; i++) {
ubo.blend_weights[i] = view->scene.blend_channels[mesh->blend_channel_indices[i]].weight;
}
sg_image blend_shapes = mesh->num_blend_shapes > 0 ? mesh->blend_shape_image : view->empty_blend_shape_image;
#endif
// for blendshapes
#ifndef MAX_BLENDSHAPES
#define MAX_BLENDSHAPES 16
@ -41,6 +45,7 @@ uniform vec4 blend_weights[MAX_BLENDSHAPES]; // @todo: implement me
uniform float f_num_blend_shapes; // @todo: implement me
uniform sampler2DArray blend_shapes; // @todo: implement me
in vec3 att_position; // @todo: reorder ass2iqe to emit p3 n3 u2 t3 b3 c4B i4 w4 instead
in vec2 att_texcoord;
in vec3 att_normal;
@ -57,6 +62,8 @@ out vec3 v_normal, v_normal_ws;
out vec2 v_texcoord;
// shadow
uniform mat4 model, view;
uniform mat4 cameraToShadowProjector;
@ -69,6 +76,7 @@ void do_shadow() {
sc = cameraToShadowProjector * model * vec4(att_position, 1.0f);
}
// blendshapes
vec3 evaluate_blend_shape(int vertex_index) {
ivec2 coord = ivec2(vertex_index & (2048 - 1), vertex_index >> 11);
@ -82,33 +90,34 @@ vec3 evaluate_blend_shape(int vertex_index) {
return offset;
}
void main() {
vec3 objPos;
if(!SKINNED) {
objPos = att_position;
v_normal = att_normal;
} else {
mat3x4 m = vsBoneMatrix[int(att_indexes.x)] * att_weights.x;
m += vsBoneMatrix[int(att_indexes.y)] * att_weights.y;
m += vsBoneMatrix[int(att_indexes.z)] * att_weights.z;
m += vsBoneMatrix[int(att_indexes.w)] * att_weights.w;
objPos = vec4(att_position, 1.0) * m;
} else {
mat3x4 m = vsBoneMatrix[int(att_indexes.x)] * att_weights.x;
m += vsBoneMatrix[int(att_indexes.y)] * att_weights.y;
m += vsBoneMatrix[int(att_indexes.z)] * att_weights.z;
m += vsBoneMatrix[int(att_indexes.w)] * att_weights.w;
objPos = vec4(att_position, 1.0) * m;
// blendshapes
// objPos += evaluate_blend_shape(int(att_vertexindex));
v_normal = vec4(att_normal, 0.0) * m;
//@todo: tangents
}
// blendshapes
// objPos += evaluate_blend_shape(int(att_vertexindex));
// vec3 tangent = att_tangent.xyz;
// vec3 bitangent = cross(att_normal, att_tangent.xyz) * att_tangent.w;
v_normal = vec4(att_normal, 0.0) * m;
//@todo: tangents
}
// vec3 tangent = att_tangent.xyz;
// vec3 bitangent = cross(att_normal, att_tangent.xyz) * att_tangent.w;
v_normal_ws = normalize(vec3(model * vec4(v_normal, 0.))); // normal to world/model space
v_normal = normalize(v_normal);
v_position = att_position;
v_texcoord = att_texcoord;
v_color = att_color;
gl_Position = VP * att_instanced_matrix * vec4( objPos, 1.0 );
do_shadow();
}
v_normal_ws = normalize(vec3(model * vec4(v_normal, 0.))); // normal to world/model space
v_normal = normalize(v_normal);
v_position = att_position;
v_texcoord = att_texcoord;
v_color = att_color;
gl_Position = VP * att_instanced_matrix * vec4( objPos, 1.0 );
do_shadow();
}

View File

@ -1,11 +1,13 @@
uniform mat4 u_mvp;
in vec3 att_Position;
in vec2 att_TexCoord;
in vec4 att_Color;
out vec2 vTexCoord;
out vec4 vColor;
void main() {
vColor = att_Color;
vTexCoord = att_TexCoord;

View File

@ -1,5 +1,6 @@
uniform mat4 u_mvp;
in vec3 att_position;
in vec3 att_normal;
in vec2 att_texcoord;
@ -9,6 +10,7 @@ out vec3 v_normal;
out vec3 v_normal_ws;
out vec2 v_texcoord;
// shadow
uniform mat4 model, view, proj;
uniform mat4 cameraToShadowProjector; // !VSMCUBE
@ -21,6 +23,7 @@ void do_shadow() {
sc = cameraToShadowProjector * model * vec4(att_position, 1.0f);
}
void main() {
gl_Position = u_mvp * vec4(att_position, 1.0);
v_normal = normalize(att_normal);

View File

@ -1,8 +1,10 @@
uniform mat4 u_mvp;
in vec3 att_position;
out vec3 v_direction;
void main() {
vec4 position = u_mvp * vec4(att_position, 0.0);
gl_Position = position.xyww;

View File

@ -0,0 +1,8 @@
in vec3 position;
in vec2 texcoord;
out vec2 Texcoord;
void main() {
gl_Position = vec4(position, 1.0);
Texcoord = texcoord;
}

View File

@ -0,0 +1,15 @@
uniform mat4 model;
uniform mat4 cameraToShadowView;
uniform mat4 cameraToShadowProjector;
in vec3 position;
out vec4 v_position;
void main() {
gl_Position = cameraToShadowProjector * model * vec4(position, 1.0);
#if VSMCUBE
v_position = cameraToShadowView * model * vec4(position, 1.0);
#else
v_position = gl_Position;
#endif
}

View File

@ -283,6 +283,13 @@ API void fbo_destroy(unsigned id);
// -----------------------------------------------------------------------------
// shadowmaps
// #ifndef VSMCUBE
// #define VSMCUBE 0
// #endif
// #ifndef VSMBLUR
// #define VSMBLUR 1
// #endif
typedef struct shadowmap_t {
mat44 shadowmatrix;
mat44 mvp;

View File

@ -8,107 +8,109 @@ const char *const fs_0_0_shadowmap_lit = "//" FILELINE "\n"
"uniform sampler2D shadowMap; // !VSMCUBE\n"
#endif
"\n"
"\n"
"struct light {\n"
" vec3 position; // world-space\n"
" vec4 diffuse;\n"
" vec4 specular;\n"
" float constantAttenuation, linearAttenuation, quadraticAttenuation;\n"
"};\n"
" \n"
"light light0 = light(\n"
" };\n"
" \n"
" light light0 = light(\n"
" lightPos,\n"
" vec4(1,1,1,1), // diffuse\n"
" vec4(1,1,1,1), // specular\n"
" 1.0, 0.0, 0.0 // attenuation (const, linear, quad)\n"
");\n"
" );\n"
" \n"
"// From http://fabiensanglard.net/shadowmappingVSM/index.php\n"
#if VSMCUBE
"float chebyshevUpperBound(float distance, vec3 dir) {\n"
" distance = distance/20 ;\n"
" vec2 moments = texture(shadowMap, dir).rg;\n"
#else
"float chebyshevUpperBound(float distance, vec4 scPostW) {\n"
" vec2 moments = texture(shadowMap,scPostW.xy).rg;\n"
#endif
" // Surface is fully lit. as the current fragment is before the light occluder\n"
" if (distance <= moments.x)\n"
" return 1.0;\n"
" \n"
" // The fragment is either in shadow or penumbra. We now use chebyshev's upperBound to check\n"
" // How likely this pixel is to be lit (p_max)\n"
" float variance = moments.y - (moments.x*moments.x);\n"
" //variance = max(variance, 0.000002);\n"
" variance = max(variance, 0.00002);\n"
" \n"
" float d = distance - moments.x;\n"
" float p_max = variance / (variance + d*d);\n"
" \n"
" return p_max;\n"
"}\n"
"\n"
"vec4 shadowmap(in vec4 vpeye, in vec4 vneye, in vec2 uv, in vec4 sc) {\n"
#ifndef VSMCUBE
" return vec4(1.);\n"
#else
" vec3 fragment = vec3(vpeye);\n"
" vec3 normal = vec3(normalize(vneye));\n"
" vec3 viewDir = normalize(-fragment);\n"
" \n"
" // Lighting\n"
" // Convert to eye-space\n"
" vec3 light = vec3(view * vec4(light0.position, 1.0));\n"
" \n"
#if VSMCUBE
" // Vectors\n"
" vec3 fragmentToLight = light - fragment;\n"
" vec3 fragmentToLightDir = normalize(fragmentToLight);\n"
" \n"
" // Shadows\n"
" vec4 fragmentToLight_world = inverse(view) * vec4(fragmentToLightDir, 0.0);\n"
" float shadowFactor = chebyshevUpperBound(length(fragmentToLight), -fragmentToLight_world.xyz);\n"
#else
" // Shadows\n"
" vec4 scPostW = sc / sc.w;\n"
" scPostW = scPostW * 0.5 + 0.5;\n"
" \n"
" float shadowFactor = 1.0; // Not in shadow\n"
" \n"
" bool outsideShadowMap = sc.w <= 0.0f || (scPostW.x < 0 || scPostW.y < 0) || (scPostW.x >= 1 || scPostW.y >= 1);\n"
" if (!outsideShadowMap) {\n"
" shadowFactor = chebyshevUpperBound(scPostW.z, scPostW);\n"
" }\n"
#endif
" \n"
" vec4 diffColor = vec4(1,1,1,1);\n"
#if VSMCUBE
" if(doTexture != 0) diffColor = vec4(vec3(texture(shadowMap, -fragmentToLight_world.xyz).r), 1.0);\n"
#else
" if(doTexture != 0) diffColor = vec4(vec3(texture(shadowMap, vec2(uv.x, 1.0 - uv.y)).r), 1.0);\n"
#endif
" \n"
#if 1
" vec3 positionToLight = light - fragment;\n"
" vec3 lightDir = normalize(positionToLight);\n"
" \n"
" // Angle between fragment-normal and incoming light\n"
" float cosAngIncidence = dot(lightDir, normal);\n"
" cosAngIncidence = clamp(cosAngIncidence, 0, 1);\n"
" \n"
" float attenuation = 1.0f;\n"
" attenuation = 1.0 / (light0.constantAttenuation + light0.linearAttenuation * length(positionToLight) + light0.quadraticAttenuation * pow(length(positionToLight),2));\n"
" \n"
" vec4 diffuse = diffColor * light0.diffuse * cosAngIncidence * attenuation;\n"
" \n"
" vec4 total_lighting;\n"
" total_lighting += vec4(0.1, 0.1, 0.1, 1.0) * diffColor; // Ambient\n"
" total_lighting += diffuse * shadowFactor; // Diffuse\n"
#else
" vec4 total_lighting = diffColor;\n"
#endif
" return vec4(clamp(vec3(total_lighting), 0., 1.), 1.0);\n"
#endif
"}\n";
" // From http://fabiensanglard.net/shadowmappingVSM/index.php\n"
#if VSMCUBE
" float chebyshevUpperBound(float distance, vec3 dir) {\n"
" distance = distance/20 ;\n"
" vec2 moments = texture(shadowMap, dir).rg;\n"
#else
" float chebyshevUpperBound(float distance, vec4 scPostW) {\n"
" vec2 moments = texture(shadowMap,scPostW.xy).rg;\n"
#endif
" // Surface is fully lit. as the current fragment is before the light occluder\n"
" if (distance <= moments.x)\n"
" return 1.0;\n"
" \n"
" // The fragment is either in shadow or penumbra. We now use chebyshev's upperBound to check\n"
" // How likely this pixel is to be lit (p_max)\n"
" float variance = moments.y - (moments.x*moments.x);\n"
" //variance = max(variance, 0.000002);\n"
" variance = max(variance, 0.00002);\n"
" \n"
" float d = distance - moments.x;\n"
" float p_max = variance / (variance + d*d);\n"
" \n"
" return p_max;\n"
" }\n"
" \n"
" \n"
" vec4 shadowmap(in vec4 vpeye, in vec4 vneye, in vec2 uv, in vec4 sc) {\n"
#ifndef VSMCUBE
" return vec4(1.);\n"
#else
" vec3 fragment = vec3(vpeye);\n"
" vec3 normal = vec3(normalize(vneye));\n"
" vec3 viewDir = normalize(-fragment);\n"
" \n"
" // Lighting\n"
" // Convert to eye-space\n"
" vec3 light = vec3(view * vec4(light0.position, 1.0));\n"
" \n"
#if VSMCUBE
" // Vectors\n"
" vec3 fragmentToLight = light - fragment;\n"
" vec3 fragmentToLightDir = normalize(fragmentToLight);\n"
" \n"
" // Shadows\n"
" vec4 fragmentToLight_world = inverse(view) * vec4(fragmentToLightDir, 0.0);\n"
" float shadowFactor = chebyshevUpperBound(length(fragmentToLight), -fragmentToLight_world.xyz);\n"
#else
" // Shadows\n"
" vec4 scPostW = sc / sc.w;\n"
" scPostW = scPostW * 0.5 + 0.5;\n"
" \n"
" float shadowFactor = 1.0; // Not in shadow\n"
" \n"
" bool outsideShadowMap = sc.w <= 0.0f || (scPostW.x < 0 || scPostW.y < 0) || (scPostW.x >= 1 || scPostW.y >= 1);\n"
" if (!outsideShadowMap) {\n"
" shadowFactor = chebyshevUpperBound(scPostW.z, scPostW);\n"
" }\n"
#endif
" \n"
" vec4 diffColor = vec4(1,1,1,1);\n"
#if VSMCUBE
" if(doTexture != 0) diffColor = vec4(vec3(texture(shadowMap, -fragmentToLight_world.xyz).r), 1.0);\n"
#else
" if(doTexture != 0) diffColor = vec4(vec3(texture(shadowMap, vec2(uv.x, 1.0 - uv.y)).r), 1.0);\n"
#endif
" \n"
#if 1
" vec3 positionToLight = light - fragment;\n"
" vec3 lightDir = normalize(positionToLight);\n"
" \n"
" // Angle between fragment-normal and incoming light\n"
" float cosAngIncidence = dot(lightDir, normal);\n"
" cosAngIncidence = clamp(cosAngIncidence, 0, 1);\n"
" \n"
" float attenuation = 1.0f;\n"
" attenuation = 1.0 / (light0.constantAttenuation + light0.linearAttenuation * length(positionToLight) + light0.quadraticAttenuation * pow(length(positionToLight),2));\n"
" \n"
" vec4 diffuse = diffColor * light0.diffuse * cosAngIncidence * attenuation;\n"
" \n"
" vec4 total_lighting;\n"
" total_lighting += vec4(0.1, 0.1, 0.1, 1.0) * diffColor; // Ambient\n"
" total_lighting += diffuse * shadowFactor; // Diffuse\n"
#else
" vec4 total_lighting = diffColor;\n"
#endif
" return vec4(clamp(vec3(total_lighting), 0., 1.), 1.0);\n"
#endif
" }\n";
const char *const fs_0_0_shadowmap_unlit = "//" FILELINE "\n"
"// uniform mat4 view = mat4(1.0);\n"
@ -116,17 +118,20 @@ const char *const fs_0_0_shadowmap_unlit = "//" FILELINE "\n"
"uniform float doTexture = 0.;\n"
"uniform sampler2D shadowMap;\n"
"\n"
"\n"
"vec4 shadowmap(in vec4 vpeye, in vec4 vneye, in vec2 Texcoord, in vec4 sc) {\n"
" return vec4(1.);\n"
"};\n";
" };\n";
const char *const fs_24_4_sprite = "//" FILELINE "\n"
"uniform sampler2D u_texture;\n"
"\n"
"\n"
"in vec2 vTexCoord;\n"
"in vec4 vColor;\n"
"out vec4 fragColor;\n"
"\n"
"\n"
"// [src] https://www.shadertoy.com/view/MllBWf CC1.0\n"
"vec4 texture_AA(sampler2D tx, vec2 uv) {\n"
" vec2 res = vec2(textureSize(tx, 0));\n"
@ -141,6 +146,7 @@ const char *const fs_24_4_sprite = "//" FILELINE "\n"
" return texture(tx, uv);\n"
"}\n"
"\n"
"\n"
"// [src] https://www.shadertoy.com/view/MllBWf CC1.0\n"
"vec4 texture_AA2( sampler2D tex, vec2 uv) {\n"
" vec2 res = vec2(textureSize(tex,0));\n"
@ -150,6 +156,7 @@ const char *const fs_24_4_sprite = "//" FILELINE "\n"
" return texture(tex, uv/res);\n"
"}\n"
"\n"
"\n"
"// [src] https://www.shadertoy.com/view/ltBfRD\n"
"vec4 texture_AA3(sampler2D tex, vec2 uv) {\n"
" vec2 res = vec2(textureSize(tex,0));\n"
@ -168,6 +175,7 @@ const char *const fs_24_4_sprite = "//" FILELINE "\n"
" return texture(tex, uv);\n"
"}\n"
"\n"
"\n"
"void main() {\n"
" vec4 texColor = texture_AA2(u_texture, vTexCoord);\n"
" if(texColor.a < 0.9) discard;\n"
@ -196,9 +204,11 @@ const char *const fs_2_4_texel_inv_gamma = "//" FILELINE "\n"
"uniform sampler2D texture0; /*unit0*/\n"
"uniform float u_inv_gamma;\n"
"\n"
"\n"
"in vec2 uv;\n"
"out vec4 fragcolor;\n"
"\n"
"\n"
"void main() {\n"
" vec4 texel = texture( texture0, uv );\n"
" fragcolor = texel;\n"
@ -211,9 +221,11 @@ const char *const fs_2_4_texel_ycbr_gamma_saturation = "//" FILELINE "\n"
"uniform sampler2D u_texture_cr; /*unit2*/\n"
"uniform float u_gamma;\n"
"\n"
"\n"
"in vec2 uv;\n"
"out vec4 fragcolor;\n"
"\n"
"\n"
"void main() {\n"
" float y = texture(u_texture_y, uv).r;\n"
" float cb = texture(u_texture_cb, uv).r;\n"
@ -240,6 +252,7 @@ const char *const fs_2_4_texel_ycbr_gamma_saturation = "//" FILELINE "\n"
" vec3 intensity = vec3(dot(texel.rgb, W));\n"
"texel.rgb = mix(intensity, texel.rgb, saturation); }\n"
"\n"
"\n"
"fragcolor = vec4(texel.rgb, 1.0);\n"
"}\n";
@ -252,6 +265,7 @@ const char *const fs_32_4_model = "//" FILELINE "\n"
"uniform bool u_matcaps = false;\n"
"uniform vec4 u_diffuse = vec4(1.0,1.0,1.0,1.0);\n"
"\n"
"\n"
#ifdef RIM
"in vec3 v_position;\n"
#endif
@ -260,60 +274,63 @@ const char *const fs_32_4_model = "//" FILELINE "\n"
"in vec4 v_color;\n"
"out vec4 fragcolor;\n"
"\n"
"\n"
"{{include-shadowmap}}\n"
"in vec4 vpeye;\n"
"in vec4 vneye;\n"
"in vec4 sc;\n"
"vec4 shadowing() {\n"
" return shadowmap(vpeye, vneye, v_texcoord, sc);\n"
"return shadowmap(vpeye, vneye, v_texcoord, sc);\n"
"}\n"
"\n"
"\n"
"void main() {\n"
" vec3 n = /*normalize*/(v_normal);\n"
"vec3 n = /*normalize*/(v_normal);\n"
"\n"
" // SH lighting\n"
" vec4 lit = vec4(1.0, 1.0, 1.0, 1.0);\n"
" vec3 SHLightResult[9];\n"
" SHLightResult[0] = 0.282095f * u_coefficients_sh[0];\n"
" SHLightResult[1] = -0.488603f * u_coefficients_sh[1] * n.y;\n"
" SHLightResult[2] = 0.488603f * u_coefficients_sh[2] * n.z;\n"
" SHLightResult[3] = -0.488603f * u_coefficients_sh[3] * n.x;\n"
" SHLightResult[4] = 1.092548f * u_coefficients_sh[4] * n.x * n.y;\n"
" SHLightResult[5] = -1.092548f * u_coefficients_sh[5] * n.y * n.z;\n"
" SHLightResult[6] = 0.315392f * u_coefficients_sh[6] * (3.0f * n.z * n.z - 1.0f);\n"
" SHLightResult[7] = -1.092548f * u_coefficients_sh[7] * n.x * n.z;\n"
" SHLightResult[8] = 0.546274f * u_coefficients_sh[8] * (n.x * n.x - n.y * n.y);\n"
" vec3 result = vec3(0.0);\n"
" for (int i = 0; i < 9; ++i)\n"
" result += SHLightResult[i];\n"
" \n"
" if( (result.x*result.x+result.y*result.y+result.z*result.z) > 0.0 ) lit = vec4(result, 1.0);\n"
"\n"
" // base\n"
" vec4 diffuse;\n"
" if(u_matcaps) {\n"
" vec2 muv = vec2(view * vec4(v_normal_ws, 0))*0.5+vec2(0.5,0.5); // normal (model space) to view space\n"
" diffuse = texture(u_texture2d, vec2(muv.x, 1.0-muv.y));\n"
"// SH lighting\n"
"vec4 lit = vec4(1.0, 1.0, 1.0, 1.0);\n"
"vec3 SHLightResult[9];\n"
"SHLightResult[0] = 0.282095f * u_coefficients_sh[0];\n"
"SHLightResult[1] = -0.488603f * u_coefficients_sh[1] * n.y;\n"
"SHLightResult[2] = 0.488603f * u_coefficients_sh[2] * n.z;\n"
"SHLightResult[3] = -0.488603f * u_coefficients_sh[3] * n.x;\n"
"SHLightResult[4] = 1.092548f * u_coefficients_sh[4] * n.x * n.y;\n"
"SHLightResult[5] = -1.092548f * u_coefficients_sh[5] * n.y * n.z;\n"
"SHLightResult[6] = 0.315392f * u_coefficients_sh[6] * (3.0f * n.z * n.z - 1.0f);\n"
"SHLightResult[7] = -1.092548f * u_coefficients_sh[7] * n.x * n.z;\n"
"SHLightResult[8] = 0.546274f * u_coefficients_sh[8] * (n.x * n.x - n.y * n.y);\n"
"vec3 result = vec3(0.0);\n"
"for (int i = 0; i < 9; ++i)\n"
"result += SHLightResult[i];\n"
"\n"
"if( (result.x*result.x+result.y*result.y+result.z*result.z) > 0.0 ) lit = vec4(result, 1.0);\n"
"\n"
"\n"
"// base\n"
"vec4 diffuse;\n"
"if(u_matcaps) {\n"
" vec2 muv = vec2(view * vec4(v_normal_ws, 0))*0.5+vec2(0.5,0.5); // normal (model space) to view space\n"
" diffuse = texture(u_texture2d, vec2(muv.x, 1.0-muv.y));\n"
" } else if(u_textured) {\n"
" diffuse = texture(u_texture2d, v_texcoord);\n"
" } else {\n"
" diffuse = u_diffuse; // * v_color;\n"
" }\n"
" } else {\n"
" diffuse = u_diffuse; // * v_color;\n"
" }\n"
" \n"
" // lighting mix\n"
" fragcolor = diffuse * lit * shadowing();\n"
" \n"
" // rimlight\n"
#ifdef RIM
" {vec3 n = normalize(mat3(M) * v_normal); // convert normal to view space\n"
" vec3 p = (M * vec4(v_position,1.0)).xyz; // convert position to view space\n"
" vec3 v = normalize(-p); // eye vector\n"
" float rim = 1.0 - max(dot(v, n), 0.0); // rimlight\n"
" rim = smoothstep(1.0-0.01, 1.0, rim); // intensity (0.01)\n"
" fragcolor += vec4(0.0, 0.0, rim, 1.0);} // blue\n"
#endif
"}\n"
"\n";
" // lighting mix\n"
" fragcolor = diffuse * lit * shadowing();\n"
" \n"
" // rimlight\n"
#ifdef RIM
" {vec3 n = normalize(mat3(M) * v_normal); // convert normal to view space\n"
" vec3 p = (M * vec4(v_position,1.0)).xyz; // convert position to view space\n"
" vec3 v = normalize(-p); // eye vector\n"
" float rim = 1.0 - max(dot(v, n), 0.0); // rimlight\n"
" rim = smoothstep(1.0-0.01, 1.0, rim); // intensity (0.01)\n"
" fragcolor += vec4(0.0, 0.0, rim, 1.0);} // blue\n"
#endif
" }\n";
const char *const fs_32_4_model_basic = "//" FILELINE "\n"
"uniform sampler2D fsDiffTex;\n"
@ -321,10 +338,12 @@ const char *const fs_32_4_model_basic = "//" FILELINE "\n"
"uniform sampler2D fsPositionTex;\n"
"uniform mat4 MVP;\n"
"\n"
"\n"
"in vec3 v_normal;\n"
"in vec2 v_texcoord;\n"
"out vec4 fragColor;\n"
"\n"
"\n"
"void main() {\n"
" vec4 diff = texture(fsDiffTex, v_texcoord).rgba;\n"
" vec3 n = normalize(mat3(MVP) * v_normal); // transform normal to eye space\n"
@ -334,9 +353,11 @@ const char *const fs_32_4_model_basic = "//" FILELINE "\n"
const char *const fs_3_4_skybox = "//" FILELINE "\n"
"uniform samplerCube u_cubemap;\n"
"\n"
"\n"
"in vec3 v_direction;\n"
"out vec4 fragcolor;\n"
"\n"
"\n"
"void main() {\n"
" fragcolor = vec4(texture(u_cubemap, v_direction).rgb, 1.0);\n"
"}\n";
@ -344,11 +365,14 @@ const char *const fs_3_4_skybox = "//" FILELINE "\n"
const char *const fs_3_4_skybox_rayleigh = "//" FILELINE "\n"
"uniform vec3 uSunPos = vec3( 0, 0.1, -1 ); // = [0, Math.cos(theta) * 0.3 + 0.2, -1];\n"
"\n"
"\n"
"in vec3 v_direction;\n"
"out vec4 fragcolor;\n"
"\n"
"\n"
"vec3 atmosphere(vec3 r, vec3 r0, vec3 pSun, float iSun, float rPlanet, float rAtmos, vec3 kRlh, float kMie, float shRlh, float shMie, float g);\n"
"\n"
"\n"
"void main() {\n"
" vec3 color = atmosphere(\n"
" normalize(v_direction), // normalized ray direction\n"
@ -370,13 +394,16 @@ const char *const fs_3_4_skybox_rayleigh = "//" FILELINE "\n"
" fragcolor = vec4(color, 1);\n"
"}\n"
"\n"
"\n"
"// [src] https://github.com/wwwtyro/glsl-atmosphere by wwwtyro (Unlicensed)\n"
"// For more information, please refer to <http://unlicense.org>\n"
"\n"
"\n"
"#define PI 3.141592\n"
"#define iSteps 16\n"
"#define jSteps 8\n"
"\n"
"\n"
"vec2 rsi(vec3 r0, vec3 rd, float sr) {\n"
" // ray-sphere intersection that assumes\n"
" // the sphere is centered at the origin.\n"
@ -392,6 +419,7 @@ const char *const fs_3_4_skybox_rayleigh = "//" FILELINE "\n"
" );\n"
"}\n"
"\n"
"\n"
"vec3 atmosphere(vec3 r, vec3 r0, vec3 pSun, float iSun, float rPlanet, float rAtmos, vec3 kRlh, float kMie, float shRlh, float shMie, float g) {\n"
" // Normalize the sun and view directions.\n"
" pSun = normalize(pSun);\n"
@ -487,9 +515,50 @@ const char *const fs_main_shadertoy = "//" FILELINE "\n"
" mainImage(fragColor, texcoord.xy * iResolution);\n"
"}\n";
const char *const fs_shadow_blur = "//" FILELINE "\n"
"uniform sampler2D textureSource;\n"
"uniform vec2 ScaleU;\n"
"\n"
"in vec2 Texcoord;\n"
"out vec4 outColor;\n"
"\n"
"void main() {\n"
" vec4 color = vec4(0.0);\n"
" color += texture( textureSource, Texcoord.st + vec2( -3.0*ScaleU.x, -3.0*ScaleU.y ) ) * 0.015625;\n"
" color += texture( textureSource, Texcoord.st + vec2( -2.0*ScaleU.x, -2.0*ScaleU.y ) )*0.09375;\n"
" color += texture( textureSource, Texcoord.st + vec2( -1.0*ScaleU.x, -1.0*ScaleU.y ) )*0.234375;\n"
" color += texture( textureSource, Texcoord.st + vec2( 0.0 , 0.0) )*0.3125;\n"
" color += texture( textureSource, Texcoord.st + vec2( 1.0*ScaleU.x, 1.0*ScaleU.y ) )*0.234375;\n"
" color += texture( textureSource, Texcoord.st + vec2( 2.0*ScaleU.x, 2.0*ScaleU.y ) )*0.09375;\n"
" color += texture( textureSource, Texcoord.st + vec2( 3.0*ScaleU.x, -3.0*ScaleU.y ) ) * 0.015625;\n"
" outColor = vec4(color.xyz, 1.0);\n"
"}\n";
const char *const fs_shadow_vsm = "//" FILELINE "\n"
"in vec4 v_position;\n"
"out vec4 outColor;\n"
"\n"
"void main() {\n"
#if VSMCUBE
" float depth = length( vec3(v_position) ) / 20;\n"
#else
" float depth = v_position.z / v_position.w;\n"
" depth = depth * 0.5 + 0.5;\n"
#endif
" \n"
" float moment1 = depth;\n"
" float moment2 = depth * depth;\n"
" \n"
" float dx = dFdx(depth);\n"
" float dy = dFdy(depth);\n"
" moment2 += 0.25*(dx*dx+dy*dy);\n"
" outColor = vec4( moment1, moment2, 0.0, 0.0);\n"
"}\n";
const char *const vs_0_2_fullscreen_quad_A = "//" FILELINE "\n"
"out vec2 texcoord;\n"
"\n"
"\n"
"void main() {\n"
" texcoord = vec2( (gl_VertexID << 1) & 2, gl_VertexID & 2 );\n"
" gl_Position = vec4( texCoord * 2.0 - 1.0, 0.0, 1.0 );\n"
@ -498,6 +567,7 @@ const char *const vs_0_2_fullscreen_quad_A = "//" FILELINE "\n"
const char *const vs_0_2_fullscreen_quad_B = "//" FILELINE "\n"
"out vec2 uv;\n"
"\n"
"\n"
"void main() {\n"
" float x = float(((uint(gl_VertexID) + 2u) / 3u)%2u);\n"
" float y = float(((uint(gl_VertexID) + 1u) / 3u)%2u);\n"
@ -508,6 +578,7 @@ const char *const vs_0_2_fullscreen_quad_B = "//" FILELINE "\n"
const char *const vs_0_2_fullscreen_quad_B_flipped = "//" FILELINE "\n"
"out vec2 uv;\n"
"\n"
"\n"
"void main() {\n"
" float x = float(((uint(gl_VertexID) + 2u) / 3u)%2u);\n"
" float y = float(((uint(gl_VertexID) + 1u) / 3u)%2u);\n"
@ -524,6 +595,7 @@ const char *const vs_323444143_16_332_model = "//" FILELINE "\n"
"// uniform mat4 M; // RIM\n"
"uniform mat4 VP;\n"
"\n"
"\n"
#if 0
"// Fetch blend channels from all attached blend deformers.\n"
"for (size_t di = 0; di < mesh->blend_deformers.count; di++) {\n"
@ -543,14 +615,17 @@ const char *const vs_323444143_16_332_model = "//" FILELINE "\n"
" vmesh->num_blend_shapes = num_blend_shapes;\n"
"}\n"
"\n"
"\n"
"ubo.f_num_blend_shapes = (float)mesh->num_blend_shapes;\n"
"for (size_t i = 0; i < mesh->num_blend_shapes; i++) {\n"
" ubo.blend_weights[i] = view->scene.blend_channels[mesh->blend_channel_indices[i]].weight;\n"
"}\n"
"\n"
"\n"
"sg_image blend_shapes = mesh->num_blend_shapes > 0 ? mesh->blend_shape_image : view->empty_blend_shape_image;\n"
#endif
"\n"
"\n"
"// for blendshapes\n"
#ifndef MAX_BLENDSHAPES
"#define MAX_BLENDSHAPES 16\n"
@ -559,6 +634,7 @@ const char *const vs_323444143_16_332_model = "//" FILELINE "\n"
"uniform float f_num_blend_shapes; // @todo: implement me\n"
"uniform sampler2DArray blend_shapes; // @todo: implement me\n"
"\n"
"\n"
"in vec3 att_position; // @todo: reorder ass2iqe to emit p3 n3 u2 t3 b3 c4B i4 w4 instead\n"
"in vec2 att_texcoord;\n"
"in vec3 att_normal;\n"
@ -575,6 +651,8 @@ const char *const vs_323444143_16_332_model = "//" FILELINE "\n"
"out vec2 v_texcoord;\n"
"\n"
"\n"
"\n"
"\n"
"// shadow\n"
"uniform mat4 model, view;\n"
"uniform mat4 cameraToShadowProjector;\n"
@ -587,6 +665,7 @@ const char *const vs_323444143_16_332_model = "//" FILELINE "\n"
" sc = cameraToShadowProjector * model * vec4(att_position, 1.0f);\n"
"}\n"
"\n"
"\n"
"// blendshapes\n"
"vec3 evaluate_blend_shape(int vertex_index) {\n"
" ivec2 coord = ivec2(vertex_index & (2048 - 1), vertex_index >> 11);\n"
@ -600,47 +679,49 @@ const char *const vs_323444143_16_332_model = "//" FILELINE "\n"
" return offset;\n"
"}\n"
"\n"
"\n"
"void main() {\n"
" vec3 objPos;\n"
" if(!SKINNED) {\n"
" objPos = att_position;\n"
" v_normal = att_normal;\n"
" } else {\n"
" mat3x4 m = vsBoneMatrix[int(att_indexes.x)] * att_weights.x;\n"
" m += vsBoneMatrix[int(att_indexes.y)] * att_weights.y;\n"
" m += vsBoneMatrix[int(att_indexes.z)] * att_weights.z;\n"
" m += vsBoneMatrix[int(att_indexes.w)] * att_weights.w;\n"
" objPos = vec4(att_position, 1.0) * m;\n"
" } else {\n"
" mat3x4 m = vsBoneMatrix[int(att_indexes.x)] * att_weights.x;\n"
" m += vsBoneMatrix[int(att_indexes.y)] * att_weights.y;\n"
" m += vsBoneMatrix[int(att_indexes.z)] * att_weights.z;\n"
" m += vsBoneMatrix[int(att_indexes.w)] * att_weights.w;\n"
" objPos = vec4(att_position, 1.0) * m;\n"
" \n"
" // blendshapes\n"
" // objPos += evaluate_blend_shape(int(att_vertexindex));\n"
" \n"
" v_normal = vec4(att_normal, 0.0) * m;\n"
" //@todo: tangents\n"
" }\n"
" \n"
" // blendshapes\n"
" // objPos += evaluate_blend_shape(int(att_vertexindex));\n"
" // vec3 tangent = att_tangent.xyz;\n"
" // vec3 bitangent = cross(att_normal, att_tangent.xyz) * att_tangent.w;\n"
" \n"
" v_normal = vec4(att_normal, 0.0) * m;\n"
" //@todo: tangents\n"
" }\n"
" \n"
" // vec3 tangent = att_tangent.xyz;\n"
" // vec3 bitangent = cross(att_normal, att_tangent.xyz) * att_tangent.w;\n"
" \n"
" v_normal_ws = normalize(vec3(model * vec4(v_normal, 0.))); // normal to world/model space\n"
" v_normal = normalize(v_normal);\n"
" v_position = att_position;\n"
" v_texcoord = att_texcoord;\n"
" v_color = att_color;\n"
" gl_Position = VP * att_instanced_matrix * vec4( objPos, 1.0 );\n"
" do_shadow();\n"
"}\n"
"\n";
" v_normal_ws = normalize(vec3(model * vec4(v_normal, 0.))); // normal to world/model space\n"
" v_normal = normalize(v_normal);\n"
" v_position = att_position;\n"
" v_texcoord = att_texcoord;\n"
" v_color = att_color;\n"
" gl_Position = VP * att_instanced_matrix * vec4( objPos, 1.0 );\n"
" do_shadow();\n"
" }\n";
const char *const vs_324_24_sprite = "//" FILELINE "\n"
"uniform mat4 u_mvp;\n"
"\n"
"\n"
"in vec3 att_Position;\n"
"in vec2 att_TexCoord;\n"
"in vec4 att_Color;\n"
"out vec2 vTexCoord;\n"
"out vec4 vColor;\n"
"\n"
"\n"
"void main() {\n"
" vColor = att_Color;\n"
" vTexCoord = att_TexCoord;\n"
@ -650,6 +731,7 @@ const char *const vs_324_24_sprite = "//" FILELINE "\n"
const char *const vs_332_32 = "//" FILELINE "\n"
"uniform mat4 u_mvp;\n"
"\n"
"\n"
"in vec3 att_position;\n"
"in vec3 att_normal;\n"
"in vec2 att_texcoord;\n"
@ -659,6 +741,7 @@ const char *const vs_332_32 = "//" FILELINE "\n"
"out vec3 v_normal_ws;\n"
"out vec2 v_texcoord;\n"
"\n"
"\n"
"// shadow\n"
"uniform mat4 model, view, proj;\n"
"uniform mat4 cameraToShadowProjector; // !VSMCUBE\n"
@ -671,6 +754,7 @@ const char *const vs_332_32 = "//" FILELINE "\n"
" sc = cameraToShadowProjector * model * vec4(att_position, 1.0f);\n"
"}\n"
"\n"
"\n"
"void main() {\n"
" gl_Position = u_mvp * vec4(att_position, 1.0);\n"
" v_normal = normalize(att_normal);\n"
@ -683,12 +767,41 @@ const char *const vs_332_32 = "//" FILELINE "\n"
const char *const vs_3_3_skybox = "//" FILELINE "\n"
"uniform mat4 u_mvp;\n"
"\n"
"\n"
"in vec3 att_position;\n"
"out vec3 v_direction;\n"
"\n"
"\n"
"void main() {\n"
" vec4 position = u_mvp * vec4(att_position, 0.0);\n"
" gl_Position = position.xyww;\n"
" v_direction = att_position;\n"
"}\n";
const char *const vs_shadow_blur = "//" FILELINE "\n"
"in vec3 position;\n"
"in vec2 texcoord;\n"
"out vec2 Texcoord;\n"
"\n"
"void main() {\n"
" gl_Position = vec4(position, 1.0);\n"
" Texcoord = texcoord;\n"
"}\n";
const char *const vs_shadow_vsm = "//" FILELINE "\n"
"uniform mat4 model;\n"
"uniform mat4 cameraToShadowView;\n"
"uniform mat4 cameraToShadowProjector;\n"
"\n"
"in vec3 position;\n"
"out vec4 v_position;\n"
"\n"
"void main() {\n"
" gl_Position = cameraToShadowProjector * model * vec4(position, 1.0);\n"
#if VSMCUBE
" v_position = cameraToShadowView * model * vec4(position, 1.0);\n"
#else
" v_position = gl_Position;\n"
#endif
"}\n";

View File

@ -9,6 +9,8 @@ extern const char *const fs_32_4_model_basic;
extern const char *const fs_3_4_skybox;
extern const char *const fs_3_4_skybox_rayleigh;
extern const char *const fs_main_shadertoy;
extern const char *const fs_shadow_blur;
extern const char *const fs_shadow_vsm;
extern const char *const vs_0_2_fullscreen_quad_A;
extern const char *const vs_0_2_fullscreen_quad_B;
extern const char *const vs_0_2_fullscreen_quad_B_flipped;
@ -16,3 +18,5 @@ extern const char *const vs_323444143_16_332_model;
extern const char *const vs_324_24_sprite;
extern const char *const vs_332_32;
extern const char *const vs_3_3_skybox;
extern const char *const vs_shadow_blur;
extern const char *const vs_shadow_vsm;

View File

@ -10220,107 +10220,109 @@ const char *const fs_0_0_shadowmap_lit = "//" FILELINE "\n"
"uniform sampler2D shadowMap; // !VSMCUBE\n"
#endif
"\n"
"\n"
"struct light {\n"
" vec3 position; // world-space\n"
" vec4 diffuse;\n"
" vec4 specular;\n"
" float constantAttenuation, linearAttenuation, quadraticAttenuation;\n"
"};\n"
" \n"
"light light0 = light(\n"
" };\n"
" \n"
" light light0 = light(\n"
" lightPos,\n"
" vec4(1,1,1,1), // diffuse\n"
" vec4(1,1,1,1), // specular\n"
" 1.0, 0.0, 0.0 // attenuation (const, linear, quad)\n"
");\n"
" );\n"
" \n"
"// From http://fabiensanglard.net/shadowmappingVSM/index.php\n"
#if VSMCUBE
"float chebyshevUpperBound(float distance, vec3 dir) {\n"
" distance = distance/20 ;\n"
" vec2 moments = texture(shadowMap, dir).rg;\n"
#else
"float chebyshevUpperBound(float distance, vec4 scPostW) {\n"
" vec2 moments = texture(shadowMap,scPostW.xy).rg;\n"
#endif
" // Surface is fully lit. as the current fragment is before the light occluder\n"
" if (distance <= moments.x)\n"
" return 1.0;\n"
" \n"
" // The fragment is either in shadow or penumbra. We now use chebyshev's upperBound to check\n"
" // How likely this pixel is to be lit (p_max)\n"
" float variance = moments.y - (moments.x*moments.x);\n"
" //variance = max(variance, 0.000002);\n"
" variance = max(variance, 0.00002);\n"
" \n"
" float d = distance - moments.x;\n"
" float p_max = variance / (variance + d*d);\n"
" \n"
" return p_max;\n"
"}\n"
"\n"
"vec4 shadowmap(in vec4 vpeye, in vec4 vneye, in vec2 uv, in vec4 sc) {\n"
#ifndef VSMCUBE
" return vec4(1.);\n"
#else
" vec3 fragment = vec3(vpeye);\n"
" vec3 normal = vec3(normalize(vneye));\n"
" vec3 viewDir = normalize(-fragment);\n"
" \n"
" // Lighting\n"
" // Convert to eye-space\n"
" vec3 light = vec3(view * vec4(light0.position, 1.0));\n"
" \n"
#if VSMCUBE
" // Vectors\n"
" vec3 fragmentToLight = light - fragment;\n"
" vec3 fragmentToLightDir = normalize(fragmentToLight);\n"
" \n"
" // Shadows\n"
" vec4 fragmentToLight_world = inverse(view) * vec4(fragmentToLightDir, 0.0);\n"
" float shadowFactor = chebyshevUpperBound(length(fragmentToLight), -fragmentToLight_world.xyz);\n"
#else
" // Shadows\n"
" vec4 scPostW = sc / sc.w;\n"
" scPostW = scPostW * 0.5 + 0.5;\n"
" \n"
" float shadowFactor = 1.0; // Not in shadow\n"
" \n"
" bool outsideShadowMap = sc.w <= 0.0f || (scPostW.x < 0 || scPostW.y < 0) || (scPostW.x >= 1 || scPostW.y >= 1);\n"
" if (!outsideShadowMap) {\n"
" shadowFactor = chebyshevUpperBound(scPostW.z, scPostW);\n"
" }\n"
#endif
" \n"
" vec4 diffColor = vec4(1,1,1,1);\n"
#if VSMCUBE
" if(doTexture != 0) diffColor = vec4(vec3(texture(shadowMap, -fragmentToLight_world.xyz).r), 1.0);\n"
#else
" if(doTexture != 0) diffColor = vec4(vec3(texture(shadowMap, vec2(uv.x, 1.0 - uv.y)).r), 1.0);\n"
#endif
" \n"
#if 1
" vec3 positionToLight = light - fragment;\n"
" vec3 lightDir = normalize(positionToLight);\n"
" \n"
" // Angle between fragment-normal and incoming light\n"
" float cosAngIncidence = dot(lightDir, normal);\n"
" cosAngIncidence = clamp(cosAngIncidence, 0, 1);\n"
" \n"
" float attenuation = 1.0f;\n"
" attenuation = 1.0 / (light0.constantAttenuation + light0.linearAttenuation * length(positionToLight) + light0.quadraticAttenuation * pow(length(positionToLight),2));\n"
" \n"
" vec4 diffuse = diffColor * light0.diffuse * cosAngIncidence * attenuation;\n"
" \n"
" vec4 total_lighting;\n"
" total_lighting += vec4(0.1, 0.1, 0.1, 1.0) * diffColor; // Ambient\n"
" total_lighting += diffuse * shadowFactor; // Diffuse\n"
#else
" vec4 total_lighting = diffColor;\n"
#endif
" return vec4(clamp(vec3(total_lighting), 0., 1.), 1.0);\n"
#endif
"}\n";
" // From http://fabiensanglard.net/shadowmappingVSM/index.php\n"
#if VSMCUBE
" float chebyshevUpperBound(float distance, vec3 dir) {\n"
" distance = distance/20 ;\n"
" vec2 moments = texture(shadowMap, dir).rg;\n"
#else
" float chebyshevUpperBound(float distance, vec4 scPostW) {\n"
" vec2 moments = texture(shadowMap,scPostW.xy).rg;\n"
#endif
" // Surface is fully lit. as the current fragment is before the light occluder\n"
" if (distance <= moments.x)\n"
" return 1.0;\n"
" \n"
" // The fragment is either in shadow or penumbra. We now use chebyshev's upperBound to check\n"
" // How likely this pixel is to be lit (p_max)\n"
" float variance = moments.y - (moments.x*moments.x);\n"
" //variance = max(variance, 0.000002);\n"
" variance = max(variance, 0.00002);\n"
" \n"
" float d = distance - moments.x;\n"
" float p_max = variance / (variance + d*d);\n"
" \n"
" return p_max;\n"
" }\n"
" \n"
" \n"
" vec4 shadowmap(in vec4 vpeye, in vec4 vneye, in vec2 uv, in vec4 sc) {\n"
#ifndef VSMCUBE
" return vec4(1.);\n"
#else
" vec3 fragment = vec3(vpeye);\n"
" vec3 normal = vec3(normalize(vneye));\n"
" vec3 viewDir = normalize(-fragment);\n"
" \n"
" // Lighting\n"
" // Convert to eye-space\n"
" vec3 light = vec3(view * vec4(light0.position, 1.0));\n"
" \n"
#if VSMCUBE
" // Vectors\n"
" vec3 fragmentToLight = light - fragment;\n"
" vec3 fragmentToLightDir = normalize(fragmentToLight);\n"
" \n"
" // Shadows\n"
" vec4 fragmentToLight_world = inverse(view) * vec4(fragmentToLightDir, 0.0);\n"
" float shadowFactor = chebyshevUpperBound(length(fragmentToLight), -fragmentToLight_world.xyz);\n"
#else
" // Shadows\n"
" vec4 scPostW = sc / sc.w;\n"
" scPostW = scPostW * 0.5 + 0.5;\n"
" \n"
" float shadowFactor = 1.0; // Not in shadow\n"
" \n"
" bool outsideShadowMap = sc.w <= 0.0f || (scPostW.x < 0 || scPostW.y < 0) || (scPostW.x >= 1 || scPostW.y >= 1);\n"
" if (!outsideShadowMap) {\n"
" shadowFactor = chebyshevUpperBound(scPostW.z, scPostW);\n"
" }\n"
#endif
" \n"
" vec4 diffColor = vec4(1,1,1,1);\n"
#if VSMCUBE
" if(doTexture != 0) diffColor = vec4(vec3(texture(shadowMap, -fragmentToLight_world.xyz).r), 1.0);\n"
#else
" if(doTexture != 0) diffColor = vec4(vec3(texture(shadowMap, vec2(uv.x, 1.0 - uv.y)).r), 1.0);\n"
#endif
" \n"
#if 1
" vec3 positionToLight = light - fragment;\n"
" vec3 lightDir = normalize(positionToLight);\n"
" \n"
" // Angle between fragment-normal and incoming light\n"
" float cosAngIncidence = dot(lightDir, normal);\n"
" cosAngIncidence = clamp(cosAngIncidence, 0, 1);\n"
" \n"
" float attenuation = 1.0f;\n"
" attenuation = 1.0 / (light0.constantAttenuation + light0.linearAttenuation * length(positionToLight) + light0.quadraticAttenuation * pow(length(positionToLight),2));\n"
" \n"
" vec4 diffuse = diffColor * light0.diffuse * cosAngIncidence * attenuation;\n"
" \n"
" vec4 total_lighting;\n"
" total_lighting += vec4(0.1, 0.1, 0.1, 1.0) * diffColor; // Ambient\n"
" total_lighting += diffuse * shadowFactor; // Diffuse\n"
#else
" vec4 total_lighting = diffColor;\n"
#endif
" return vec4(clamp(vec3(total_lighting), 0., 1.), 1.0);\n"
#endif
" }\n";
const char *const fs_0_0_shadowmap_unlit = "//" FILELINE "\n"
"// uniform mat4 view = mat4(1.0);\n"
@ -10328,17 +10330,20 @@ const char *const fs_0_0_shadowmap_unlit = "//" FILELINE "\n"
"uniform float doTexture = 0.;\n"
"uniform sampler2D shadowMap;\n"
"\n"
"\n"
"vec4 shadowmap(in vec4 vpeye, in vec4 vneye, in vec2 Texcoord, in vec4 sc) {\n"
" return vec4(1.);\n"
"};\n";
" };\n";
const char *const fs_24_4_sprite = "//" FILELINE "\n"
"uniform sampler2D u_texture;\n"
"\n"
"\n"
"in vec2 vTexCoord;\n"
"in vec4 vColor;\n"
"out vec4 fragColor;\n"
"\n"
"\n"
"// [src] https://www.shadertoy.com/view/MllBWf CC1.0\n"
"vec4 texture_AA(sampler2D tx, vec2 uv) {\n"
" vec2 res = vec2(textureSize(tx, 0));\n"
@ -10353,6 +10358,7 @@ const char *const fs_24_4_sprite = "//" FILELINE "\n"
" return texture(tx, uv);\n"
"}\n"
"\n"
"\n"
"// [src] https://www.shadertoy.com/view/MllBWf CC1.0\n"
"vec4 texture_AA2( sampler2D tex, vec2 uv) {\n"
" vec2 res = vec2(textureSize(tex,0));\n"
@ -10362,6 +10368,7 @@ const char *const fs_24_4_sprite = "//" FILELINE "\n"
" return texture(tex, uv/res);\n"
"}\n"
"\n"
"\n"
"// [src] https://www.shadertoy.com/view/ltBfRD\n"
"vec4 texture_AA3(sampler2D tex, vec2 uv) {\n"
" vec2 res = vec2(textureSize(tex,0));\n"
@ -10380,6 +10387,7 @@ const char *const fs_24_4_sprite = "//" FILELINE "\n"
" return texture(tex, uv);\n"
"}\n"
"\n"
"\n"
"void main() {\n"
" vec4 texColor = texture_AA2(u_texture, vTexCoord);\n"
" if(texColor.a < 0.9) discard;\n"
@ -10408,9 +10416,11 @@ const char *const fs_2_4_texel_inv_gamma = "//" FILELINE "\n"
"uniform sampler2D texture0; /*unit0*/\n"
"uniform float u_inv_gamma;\n"
"\n"
"\n"
"in vec2 uv;\n"
"out vec4 fragcolor;\n"
"\n"
"\n"
"void main() {\n"
" vec4 texel = texture( texture0, uv );\n"
" fragcolor = texel;\n"
@ -10423,9 +10433,11 @@ const char *const fs_2_4_texel_ycbr_gamma_saturation = "//" FILELINE "\n"
"uniform sampler2D u_texture_cr; /*unit2*/\n"
"uniform float u_gamma;\n"
"\n"
"\n"
"in vec2 uv;\n"
"out vec4 fragcolor;\n"
"\n"
"\n"
"void main() {\n"
" float y = texture(u_texture_y, uv).r;\n"
" float cb = texture(u_texture_cb, uv).r;\n"
@ -10452,6 +10464,7 @@ const char *const fs_2_4_texel_ycbr_gamma_saturation = "//" FILELINE "\n"
" vec3 intensity = vec3(dot(texel.rgb, W));\n"
"texel.rgb = mix(intensity, texel.rgb, saturation); }\n"
"\n"
"\n"
"fragcolor = vec4(texel.rgb, 1.0);\n"
"}\n";
@ -10464,6 +10477,7 @@ const char *const fs_32_4_model = "//" FILELINE "\n"
"uniform bool u_matcaps = false;\n"
"uniform vec4 u_diffuse = vec4(1.0,1.0,1.0,1.0);\n"
"\n"
"\n"
#ifdef RIM
"in vec3 v_position;\n"
#endif
@ -10472,60 +10486,63 @@ const char *const fs_32_4_model = "//" FILELINE "\n"
"in vec4 v_color;\n"
"out vec4 fragcolor;\n"
"\n"
"\n"
"{{include-shadowmap}}\n"
"in vec4 vpeye;\n"
"in vec4 vneye;\n"
"in vec4 sc;\n"
"vec4 shadowing() {\n"
" return shadowmap(vpeye, vneye, v_texcoord, sc);\n"
"return shadowmap(vpeye, vneye, v_texcoord, sc);\n"
"}\n"
"\n"
"\n"
"void main() {\n"
" vec3 n = /*normalize*/(v_normal);\n"
"vec3 n = /*normalize*/(v_normal);\n"
"\n"
" // SH lighting\n"
" vec4 lit = vec4(1.0, 1.0, 1.0, 1.0);\n"
" vec3 SHLightResult[9];\n"
" SHLightResult[0] = 0.282095f * u_coefficients_sh[0];\n"
" SHLightResult[1] = -0.488603f * u_coefficients_sh[1] * n.y;\n"
" SHLightResult[2] = 0.488603f * u_coefficients_sh[2] * n.z;\n"
" SHLightResult[3] = -0.488603f * u_coefficients_sh[3] * n.x;\n"
" SHLightResult[4] = 1.092548f * u_coefficients_sh[4] * n.x * n.y;\n"
" SHLightResult[5] = -1.092548f * u_coefficients_sh[5] * n.y * n.z;\n"
" SHLightResult[6] = 0.315392f * u_coefficients_sh[6] * (3.0f * n.z * n.z - 1.0f);\n"
" SHLightResult[7] = -1.092548f * u_coefficients_sh[7] * n.x * n.z;\n"
" SHLightResult[8] = 0.546274f * u_coefficients_sh[8] * (n.x * n.x - n.y * n.y);\n"
" vec3 result = vec3(0.0);\n"
" for (int i = 0; i < 9; ++i)\n"
" result += SHLightResult[i];\n"
" \n"
" if( (result.x*result.x+result.y*result.y+result.z*result.z) > 0.0 ) lit = vec4(result, 1.0);\n"
"\n"
" // base\n"
" vec4 diffuse;\n"
" if(u_matcaps) {\n"
" vec2 muv = vec2(view * vec4(v_normal_ws, 0))*0.5+vec2(0.5,0.5); // normal (model space) to view space\n"
" diffuse = texture(u_texture2d, vec2(muv.x, 1.0-muv.y));\n"
"// SH lighting\n"
"vec4 lit = vec4(1.0, 1.0, 1.0, 1.0);\n"
"vec3 SHLightResult[9];\n"
"SHLightResult[0] = 0.282095f * u_coefficients_sh[0];\n"
"SHLightResult[1] = -0.488603f * u_coefficients_sh[1] * n.y;\n"
"SHLightResult[2] = 0.488603f * u_coefficients_sh[2] * n.z;\n"
"SHLightResult[3] = -0.488603f * u_coefficients_sh[3] * n.x;\n"
"SHLightResult[4] = 1.092548f * u_coefficients_sh[4] * n.x * n.y;\n"
"SHLightResult[5] = -1.092548f * u_coefficients_sh[5] * n.y * n.z;\n"
"SHLightResult[6] = 0.315392f * u_coefficients_sh[6] * (3.0f * n.z * n.z - 1.0f);\n"
"SHLightResult[7] = -1.092548f * u_coefficients_sh[7] * n.x * n.z;\n"
"SHLightResult[8] = 0.546274f * u_coefficients_sh[8] * (n.x * n.x - n.y * n.y);\n"
"vec3 result = vec3(0.0);\n"
"for (int i = 0; i < 9; ++i)\n"
"result += SHLightResult[i];\n"
"\n"
"if( (result.x*result.x+result.y*result.y+result.z*result.z) > 0.0 ) lit = vec4(result, 1.0);\n"
"\n"
"\n"
"// base\n"
"vec4 diffuse;\n"
"if(u_matcaps) {\n"
" vec2 muv = vec2(view * vec4(v_normal_ws, 0))*0.5+vec2(0.5,0.5); // normal (model space) to view space\n"
" diffuse = texture(u_texture2d, vec2(muv.x, 1.0-muv.y));\n"
" } else if(u_textured) {\n"
" diffuse = texture(u_texture2d, v_texcoord);\n"
" } else {\n"
" diffuse = u_diffuse; // * v_color;\n"
" }\n"
" } else {\n"
" diffuse = u_diffuse; // * v_color;\n"
" }\n"
" \n"
" // lighting mix\n"
" fragcolor = diffuse * lit * shadowing();\n"
" \n"
" // rimlight\n"
#ifdef RIM
" {vec3 n = normalize(mat3(M) * v_normal); // convert normal to view space\n"
" vec3 p = (M * vec4(v_position,1.0)).xyz; // convert position to view space\n"
" vec3 v = normalize(-p); // eye vector\n"
" float rim = 1.0 - max(dot(v, n), 0.0); // rimlight\n"
" rim = smoothstep(1.0-0.01, 1.0, rim); // intensity (0.01)\n"
" fragcolor += vec4(0.0, 0.0, rim, 1.0);} // blue\n"
#endif
"}\n"
"\n";
" // lighting mix\n"
" fragcolor = diffuse * lit * shadowing();\n"
" \n"
" // rimlight\n"
#ifdef RIM
" {vec3 n = normalize(mat3(M) * v_normal); // convert normal to view space\n"
" vec3 p = (M * vec4(v_position,1.0)).xyz; // convert position to view space\n"
" vec3 v = normalize(-p); // eye vector\n"
" float rim = 1.0 - max(dot(v, n), 0.0); // rimlight\n"
" rim = smoothstep(1.0-0.01, 1.0, rim); // intensity (0.01)\n"
" fragcolor += vec4(0.0, 0.0, rim, 1.0);} // blue\n"
#endif
" }\n";
const char *const fs_32_4_model_basic = "//" FILELINE "\n"
"uniform sampler2D fsDiffTex;\n"
@ -10533,10 +10550,12 @@ const char *const fs_32_4_model_basic = "//" FILELINE "\n"
"uniform sampler2D fsPositionTex;\n"
"uniform mat4 MVP;\n"
"\n"
"\n"
"in vec3 v_normal;\n"
"in vec2 v_texcoord;\n"
"out vec4 fragColor;\n"
"\n"
"\n"
"void main() {\n"
" vec4 diff = texture(fsDiffTex, v_texcoord).rgba;\n"
" vec3 n = normalize(mat3(MVP) * v_normal); // transform normal to eye space\n"
@ -10546,9 +10565,11 @@ const char *const fs_32_4_model_basic = "//" FILELINE "\n"
const char *const fs_3_4_skybox = "//" FILELINE "\n"
"uniform samplerCube u_cubemap;\n"
"\n"
"\n"
"in vec3 v_direction;\n"
"out vec4 fragcolor;\n"
"\n"
"\n"
"void main() {\n"
" fragcolor = vec4(texture(u_cubemap, v_direction).rgb, 1.0);\n"
"}\n";
@ -10556,11 +10577,14 @@ const char *const fs_3_4_skybox = "//" FILELINE "\n"
const char *const fs_3_4_skybox_rayleigh = "//" FILELINE "\n"
"uniform vec3 uSunPos = vec3( 0, 0.1, -1 ); // = [0, Math.cos(theta) * 0.3 + 0.2, -1];\n"
"\n"
"\n"
"in vec3 v_direction;\n"
"out vec4 fragcolor;\n"
"\n"
"\n"
"vec3 atmosphere(vec3 r, vec3 r0, vec3 pSun, float iSun, float rPlanet, float rAtmos, vec3 kRlh, float kMie, float shRlh, float shMie, float g);\n"
"\n"
"\n"
"void main() {\n"
" vec3 color = atmosphere(\n"
" normalize(v_direction), // normalized ray direction\n"
@ -10582,13 +10606,16 @@ const char *const fs_3_4_skybox_rayleigh = "//" FILELINE "\n"
" fragcolor = vec4(color, 1);\n"
"}\n"
"\n"
"\n"
"// [src] https://github.com/wwwtyro/glsl-atmosphere by wwwtyro (Unlicensed)\n"
"// For more information, please refer to <http://unlicense.org>\n"
"\n"
"\n"
"#define PI 3.141592\n"
"#define iSteps 16\n"
"#define jSteps 8\n"
"\n"
"\n"
"vec2 rsi(vec3 r0, vec3 rd, float sr) {\n"
" // ray-sphere intersection that assumes\n"
" // the sphere is centered at the origin.\n"
@ -10604,6 +10631,7 @@ const char *const fs_3_4_skybox_rayleigh = "//" FILELINE "\n"
" );\n"
"}\n"
"\n"
"\n"
"vec3 atmosphere(vec3 r, vec3 r0, vec3 pSun, float iSun, float rPlanet, float rAtmos, vec3 kRlh, float kMie, float shRlh, float shMie, float g) {\n"
" // Normalize the sun and view directions.\n"
" pSun = normalize(pSun);\n"
@ -10699,9 +10727,50 @@ const char *const fs_main_shadertoy = "//" FILELINE "\n"
" mainImage(fragColor, texcoord.xy * iResolution);\n"
"}\n";
const char *const fs_shadow_blur = "//" FILELINE "\n"
"uniform sampler2D textureSource;\n"
"uniform vec2 ScaleU;\n"
"\n"
"in vec2 Texcoord;\n"
"out vec4 outColor;\n"
"\n"
"void main() {\n"
" vec4 color = vec4(0.0);\n"
" color += texture( textureSource, Texcoord.st + vec2( -3.0*ScaleU.x, -3.0*ScaleU.y ) ) * 0.015625;\n"
" color += texture( textureSource, Texcoord.st + vec2( -2.0*ScaleU.x, -2.0*ScaleU.y ) )*0.09375;\n"
" color += texture( textureSource, Texcoord.st + vec2( -1.0*ScaleU.x, -1.0*ScaleU.y ) )*0.234375;\n"
" color += texture( textureSource, Texcoord.st + vec2( 0.0 , 0.0) )*0.3125;\n"
" color += texture( textureSource, Texcoord.st + vec2( 1.0*ScaleU.x, 1.0*ScaleU.y ) )*0.234375;\n"
" color += texture( textureSource, Texcoord.st + vec2( 2.0*ScaleU.x, 2.0*ScaleU.y ) )*0.09375;\n"
" color += texture( textureSource, Texcoord.st + vec2( 3.0*ScaleU.x, -3.0*ScaleU.y ) ) * 0.015625;\n"
" outColor = vec4(color.xyz, 1.0);\n"
"}\n";
const char *const fs_shadow_vsm = "//" FILELINE "\n"
"in vec4 v_position;\n"
"out vec4 outColor;\n"
"\n"
"void main() {\n"
#if VSMCUBE
" float depth = length( vec3(v_position) ) / 20;\n"
#else
" float depth = v_position.z / v_position.w;\n"
" depth = depth * 0.5 + 0.5;\n"
#endif
" \n"
" float moment1 = depth;\n"
" float moment2 = depth * depth;\n"
" \n"
" float dx = dFdx(depth);\n"
" float dy = dFdy(depth);\n"
" moment2 += 0.25*(dx*dx+dy*dy);\n"
" outColor = vec4( moment1, moment2, 0.0, 0.0);\n"
"}\n";
const char *const vs_0_2_fullscreen_quad_A = "//" FILELINE "\n"
"out vec2 texcoord;\n"
"\n"
"\n"
"void main() {\n"
" texcoord = vec2( (gl_VertexID << 1) & 2, gl_VertexID & 2 );\n"
" gl_Position = vec4( texCoord * 2.0 - 1.0, 0.0, 1.0 );\n"
@ -10710,6 +10779,7 @@ const char *const vs_0_2_fullscreen_quad_A = "//" FILELINE "\n"
const char *const vs_0_2_fullscreen_quad_B = "//" FILELINE "\n"
"out vec2 uv;\n"
"\n"
"\n"
"void main() {\n"
" float x = float(((uint(gl_VertexID) + 2u) / 3u)%2u);\n"
" float y = float(((uint(gl_VertexID) + 1u) / 3u)%2u);\n"
@ -10720,6 +10790,7 @@ const char *const vs_0_2_fullscreen_quad_B = "//" FILELINE "\n"
const char *const vs_0_2_fullscreen_quad_B_flipped = "//" FILELINE "\n"
"out vec2 uv;\n"
"\n"
"\n"
"void main() {\n"
" float x = float(((uint(gl_VertexID) + 2u) / 3u)%2u);\n"
" float y = float(((uint(gl_VertexID) + 1u) / 3u)%2u);\n"
@ -10736,6 +10807,7 @@ const char *const vs_323444143_16_332_model = "//" FILELINE "\n"
"// uniform mat4 M; // RIM\n"
"uniform mat4 VP;\n"
"\n"
"\n"
#if 0
"// Fetch blend channels from all attached blend deformers.\n"
"for (size_t di = 0; di < mesh->blend_deformers.count; di++) {\n"
@ -10755,14 +10827,17 @@ const char *const vs_323444143_16_332_model = "//" FILELINE "\n"
" vmesh->num_blend_shapes = num_blend_shapes;\n"
"}\n"
"\n"
"\n"
"ubo.f_num_blend_shapes = (float)mesh->num_blend_shapes;\n"
"for (size_t i = 0; i < mesh->num_blend_shapes; i++) {\n"
" ubo.blend_weights[i] = view->scene.blend_channels[mesh->blend_channel_indices[i]].weight;\n"
"}\n"
"\n"
"\n"
"sg_image blend_shapes = mesh->num_blend_shapes > 0 ? mesh->blend_shape_image : view->empty_blend_shape_image;\n"
#endif
"\n"
"\n"
"// for blendshapes\n"
#ifndef MAX_BLENDSHAPES
"#define MAX_BLENDSHAPES 16\n"
@ -10771,6 +10846,7 @@ const char *const vs_323444143_16_332_model = "//" FILELINE "\n"
"uniform float f_num_blend_shapes; // @todo: implement me\n"
"uniform sampler2DArray blend_shapes; // @todo: implement me\n"
"\n"
"\n"
"in vec3 att_position; // @todo: reorder ass2iqe to emit p3 n3 u2 t3 b3 c4B i4 w4 instead\n"
"in vec2 att_texcoord;\n"
"in vec3 att_normal;\n"
@ -10787,6 +10863,8 @@ const char *const vs_323444143_16_332_model = "//" FILELINE "\n"
"out vec2 v_texcoord;\n"
"\n"
"\n"
"\n"
"\n"
"// shadow\n"
"uniform mat4 model, view;\n"
"uniform mat4 cameraToShadowProjector;\n"
@ -10799,6 +10877,7 @@ const char *const vs_323444143_16_332_model = "//" FILELINE "\n"
" sc = cameraToShadowProjector * model * vec4(att_position, 1.0f);\n"
"}\n"
"\n"
"\n"
"// blendshapes\n"
"vec3 evaluate_blend_shape(int vertex_index) {\n"
" ivec2 coord = ivec2(vertex_index & (2048 - 1), vertex_index >> 11);\n"
@ -10812,47 +10891,49 @@ const char *const vs_323444143_16_332_model = "//" FILELINE "\n"
" return offset;\n"
"}\n"
"\n"
"\n"
"void main() {\n"
" vec3 objPos;\n"
" if(!SKINNED) {\n"
" objPos = att_position;\n"
" v_normal = att_normal;\n"
" } else {\n"
" mat3x4 m = vsBoneMatrix[int(att_indexes.x)] * att_weights.x;\n"
" m += vsBoneMatrix[int(att_indexes.y)] * att_weights.y;\n"
" m += vsBoneMatrix[int(att_indexes.z)] * att_weights.z;\n"
" m += vsBoneMatrix[int(att_indexes.w)] * att_weights.w;\n"
" objPos = vec4(att_position, 1.0) * m;\n"
" } else {\n"
" mat3x4 m = vsBoneMatrix[int(att_indexes.x)] * att_weights.x;\n"
" m += vsBoneMatrix[int(att_indexes.y)] * att_weights.y;\n"
" m += vsBoneMatrix[int(att_indexes.z)] * att_weights.z;\n"
" m += vsBoneMatrix[int(att_indexes.w)] * att_weights.w;\n"
" objPos = vec4(att_position, 1.0) * m;\n"
" \n"
" // blendshapes\n"
" // objPos += evaluate_blend_shape(int(att_vertexindex));\n"
" \n"
" v_normal = vec4(att_normal, 0.0) * m;\n"
" //@todo: tangents\n"
" }\n"
" \n"
" // blendshapes\n"
" // objPos += evaluate_blend_shape(int(att_vertexindex));\n"
" // vec3 tangent = att_tangent.xyz;\n"
" // vec3 bitangent = cross(att_normal, att_tangent.xyz) * att_tangent.w;\n"
" \n"
" v_normal = vec4(att_normal, 0.0) * m;\n"
" //@todo: tangents\n"
" }\n"
" \n"
" // vec3 tangent = att_tangent.xyz;\n"
" // vec3 bitangent = cross(att_normal, att_tangent.xyz) * att_tangent.w;\n"
" \n"
" v_normal_ws = normalize(vec3(model * vec4(v_normal, 0.))); // normal to world/model space\n"
" v_normal = normalize(v_normal);\n"
" v_position = att_position;\n"
" v_texcoord = att_texcoord;\n"
" v_color = att_color;\n"
" gl_Position = VP * att_instanced_matrix * vec4( objPos, 1.0 );\n"
" do_shadow();\n"
"}\n"
"\n";
" v_normal_ws = normalize(vec3(model * vec4(v_normal, 0.))); // normal to world/model space\n"
" v_normal = normalize(v_normal);\n"
" v_position = att_position;\n"
" v_texcoord = att_texcoord;\n"
" v_color = att_color;\n"
" gl_Position = VP * att_instanced_matrix * vec4( objPos, 1.0 );\n"
" do_shadow();\n"
" }\n";
const char *const vs_324_24_sprite = "//" FILELINE "\n"
"uniform mat4 u_mvp;\n"
"\n"
"\n"
"in vec3 att_Position;\n"
"in vec2 att_TexCoord;\n"
"in vec4 att_Color;\n"
"out vec2 vTexCoord;\n"
"out vec4 vColor;\n"
"\n"
"\n"
"void main() {\n"
" vColor = att_Color;\n"
" vTexCoord = att_TexCoord;\n"
@ -10862,6 +10943,7 @@ const char *const vs_324_24_sprite = "//" FILELINE "\n"
const char *const vs_332_32 = "//" FILELINE "\n"
"uniform mat4 u_mvp;\n"
"\n"
"\n"
"in vec3 att_position;\n"
"in vec3 att_normal;\n"
"in vec2 att_texcoord;\n"
@ -10871,6 +10953,7 @@ const char *const vs_332_32 = "//" FILELINE "\n"
"out vec3 v_normal_ws;\n"
"out vec2 v_texcoord;\n"
"\n"
"\n"
"// shadow\n"
"uniform mat4 model, view, proj;\n"
"uniform mat4 cameraToShadowProjector; // !VSMCUBE\n"
@ -10883,6 +10966,7 @@ const char *const vs_332_32 = "//" FILELINE "\n"
" sc = cameraToShadowProjector * model * vec4(att_position, 1.0f);\n"
"}\n"
"\n"
"\n"
"void main() {\n"
" gl_Position = u_mvp * vec4(att_position, 1.0);\n"
" v_normal = normalize(att_normal);\n"
@ -10895,15 +10979,44 @@ const char *const vs_332_32 = "//" FILELINE "\n"
const char *const vs_3_3_skybox = "//" FILELINE "\n"
"uniform mat4 u_mvp;\n"
"\n"
"\n"
"in vec3 att_position;\n"
"out vec3 v_direction;\n"
"\n"
"\n"
"void main() {\n"
" vec4 position = u_mvp * vec4(att_position, 0.0);\n"
" gl_Position = position.xyww;\n"
" v_direction = att_position;\n"
"}\n";
const char *const vs_shadow_blur = "//" FILELINE "\n"
"in vec3 position;\n"
"in vec2 texcoord;\n"
"out vec2 Texcoord;\n"
"\n"
"void main() {\n"
" gl_Position = vec4(position, 1.0);\n"
" Texcoord = texcoord;\n"
"}\n";
const char *const vs_shadow_vsm = "//" FILELINE "\n"
"uniform mat4 model;\n"
"uniform mat4 cameraToShadowView;\n"
"uniform mat4 cameraToShadowProjector;\n"
"\n"
"in vec3 position;\n"
"out vec4 v_position;\n"
"\n"
"void main() {\n"
" gl_Position = cameraToShadowProjector * model * vec4(position, 1.0);\n"
#if VSMCUBE
" v_position = cameraToShadowView * model * vec4(position, 1.0);\n"
#else
" v_position = gl_Position;\n"
#endif
"}\n";
#line 0
#line 1 "v4k_render.c"

View File

@ -2521,6 +2521,13 @@ API void fbo_destroy(unsigned id);
// -----------------------------------------------------------------------------
// shadowmaps
// #ifndef VSMCUBE
// #define VSMCUBE 0
// #endif
// #ifndef VSMBLUR
// #define VSMBLUR 1
// #endif
typedef struct shadowmap_t {
mat44 shadowmatrix;
mat44 mvp;
@ -2902,6 +2909,8 @@ extern const char *const fs_32_4_model_basic;
extern const char *const fs_3_4_skybox;
extern const char *const fs_3_4_skybox_rayleigh;
extern const char *const fs_main_shadertoy;
extern const char *const fs_shadow_blur;
extern const char *const fs_shadow_vsm;
extern const char *const vs_0_2_fullscreen_quad_A;
extern const char *const vs_0_2_fullscreen_quad_B;
extern const char *const vs_0_2_fullscreen_quad_B_flipped;
@ -2909,6 +2918,8 @@ extern const char *const vs_323444143_16_332_model;
extern const char *const vs_324_24_sprite;
extern const char *const vs_332_32;
extern const char *const vs_3_3_skybox;
extern const char *const vs_shadow_blur;
extern const char *const vs_shadow_vsm;
#line 0
#line 1 "v4k_renderdd.h"