Commit for 2021.03.01.7z
278
Makefile
Normal file
@ -0,0 +1,278 @@
|
||||
ARCH = win64
|
||||
PREFIX = gcc
|
||||
TARGET_NAME = program
|
||||
TARGET_EXTENSION = exe
|
||||
TARGET_LIB_EXTENSION = dll
|
||||
|
||||
include makefiles/$(ARCH).$(PREFIX).make
|
||||
|
||||
.PHONY: $(ARCH)-$(PREFIX)
|
||||
|
||||
BIN_DIR += ./bin
|
||||
|
||||
ENGINE_SRC_DIR += ./engine/src
|
||||
ENGINE_INC_DIR += ./engine/inc
|
||||
ENGINE_LIB_DIR += ./engine/lib
|
||||
|
||||
EXT_SRC_DIR += ./ext
|
||||
CLIENT_SRC_DIR += ./client
|
||||
|
||||
UF_LIBS +=
|
||||
EXT_LIBS +=
|
||||
FLAGS += -Wno-pointer-arith
|
||||
LIB_NAME += uf
|
||||
EXT_LIB_NAME += ext
|
||||
|
||||
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.154.0/
|
||||
VULKAN_SDK_PATH += /c/VulkanSDK/1.2.162.0/
|
||||
GLSL_VALIDATOR += $(VULKAN_SDK_PATH)/Bin32/glslangValidator
|
||||
# Base Engine's DLL
|
||||
INC_DIR += $(ENGINE_INC_DIR)/$(ARCH)/$(PREFIX)
|
||||
DEPS +=
|
||||
|
||||
ifneq (,$(findstring win64,$(ARCH)))
|
||||
REQ_DEPS += vulkan json:nlohmann png openal ogg freetype ncurses curl luajit bullet meshoptimizer # draco discord
|
||||
FLAGS +=
|
||||
DEPS += -lgdi32
|
||||
else ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
REQ_DEPS += opengl gldc json:nlohmann png meshoptimizer bullet freetype # lua ogg openal draco luajit ultralight-ux ncurses curl openvr discord
|
||||
FLAGS += $(KOS_CPPFLAGS) -frtti -DUF_NO_EXCEPTIONS
|
||||
INCS += $(KOS_INC_PATHS) -I/opt/dreamcast/sh-elf/sh-elf/include
|
||||
LIBS += $(KOS_LIB_PATHS) -L/opt/dreamcast/sh-elf/sh-elf/lib
|
||||
endif
|
||||
ifneq (,$(findstring vulkan,$(REQ_DEPS)))
|
||||
FLAGS += -DVK_USE_PLATFORM_WIN32_KHR -DUF_USE_VULKAN
|
||||
DEPS += -lvulkan -lspirv-cross
|
||||
endif
|
||||
ifneq (,$(findstring opengl,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_OPENGL -DUF_USE_GLEW -DUF_USE_OPENGL_FIXED_FUNCTION
|
||||
ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
ifneq (,$(findstring gldc,$(REQ_DEPS)))
|
||||
DEPS += -lGLdc
|
||||
FLAGS += -DUF_USE_OPENGL_GLDC
|
||||
else
|
||||
DEPS += -lGL #-lGLdc
|
||||
endif
|
||||
else
|
||||
DEPS += -lglew32 -lopengl32 -lglu32
|
||||
endif
|
||||
endif
|
||||
ifneq (,$(findstring json,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_JSON
|
||||
DEPS +=
|
||||
ifneq (,$(findstring nlohmann,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_JSON_USE_NLOHMANN
|
||||
endif
|
||||
endif
|
||||
ifneq (,$(findstring png,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_PNG
|
||||
DEPS += -lpng -lz -lbz2
|
||||
endif
|
||||
ifneq (,$(findstring openal,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_OPENAL
|
||||
ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
DEPS += -lAL
|
||||
else
|
||||
FLAGS += -DUF_USE_ALUT
|
||||
DEPS += -lopenal -lalut
|
||||
endif
|
||||
endif
|
||||
ifneq (,$(findstring ogg,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_VORBIS
|
||||
ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
DEPS += -lvorbis -logg
|
||||
else
|
||||
DEPS += -lvorbis -lvorbisfile -logg
|
||||
endif
|
||||
endif
|
||||
ifneq (,$(findstring freetype,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_FREETYPE
|
||||
DEPS += -lfreetype
|
||||
ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
DEPS += -lbrotlicommon-static -lbrotlidec-static
|
||||
endif
|
||||
endif
|
||||
ifneq (,$(findstring ncurses,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_NCURSES
|
||||
DEPS += -lncursesw
|
||||
endif
|
||||
ifneq (,$(findstring curl,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_CURL
|
||||
DEPS += -lcurl
|
||||
endif
|
||||
ifneq (,$(findstring discord,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_DISCORD
|
||||
DEPS += -ldiscord_game_sdk
|
||||
endif
|
||||
ifneq (,$(findstring openvr,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_OPENVR -DUSE_OPENVR_MINGW
|
||||
DEPS += -lopenvr_api
|
||||
endif
|
||||
ifneq (,$(findstring lua,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_LUA
|
||||
ifneq (,$(findstring luajit,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_LUAJIT
|
||||
DEPS += -lluajit-5.1
|
||||
INCS += -I/mingw64/include/luajit-2.1
|
||||
else
|
||||
ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
DEPS += -llua
|
||||
INCS += -I/opt/dreamcast/kos-ports/include/lua
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifneq (,$(findstring ultralight-ux,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_ULTRALIGHT_UX
|
||||
DEPS += -lUltralight -lUltralightCore -lWebCore -lAppCore
|
||||
endif
|
||||
ifneq (,$(findstring bullet,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_BULLET
|
||||
ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
DEPS += -lbulletdynamics -lbulletcollision -lbulletlinearmath
|
||||
else
|
||||
DEPS += -lBulletDynamics -lBulletCollision -lLinearMath
|
||||
INCS += -I$(ENGINE_INC_DIR)/bullet/
|
||||
endif
|
||||
endif
|
||||
ifneq (,$(findstring simd,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_SIMD #-march=native
|
||||
|
||||
endif
|
||||
ifneq (,$(findstring meshoptimizer,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_MESHOPTIMIZER
|
||||
DEPS += -lmeshoptimizer
|
||||
endif
|
||||
ifneq (,$(findstring draco,$(REQ_DEPS)))
|
||||
FLAGS += -DUF_USE_DRACO
|
||||
DEPS += -ldraco
|
||||
endif
|
||||
|
||||
#DEPS += -lvulkan -lncursesw
|
||||
LINKS += $(UF_LIBS) $(EXT_LIBS) $(DEPS)
|
||||
#-Wl,-subsystem,windows
|
||||
|
||||
LIB_DIR += $(ENGINE_LIB_DIR)/$(ARCH)
|
||||
INCS += -I$(ENGINE_INC_DIR) -I$(INC_DIR) -I$(VULKAN_SDK_PATH)/include -I/mingw64/include
|
||||
LIBS += -L$(ENGINE_LIB_DIR) -L$(LIB_DIR) -L$(LIB_DIR)/$(PREFIX) -L$(VULKAN_SDK_PATH)/Lib
|
||||
|
||||
SRCS_DLL += $(wildcard $(ENGINE_SRC_DIR)/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*/*/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*/*/*/*.cpp)
|
||||
OBJS_DLL += $(patsubst %.cpp,%.$(ARCH).$(PREFIX).o,$(SRCS_DLL))
|
||||
BASE_DLL += lib$(LIB_NAME)
|
||||
IM_DLL += $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_DLL).$(TARGET_LIB_EXTENSION).a
|
||||
EX_DLL += $(BIN_DIR)/exe/lib/$(ARCH)/$(PREFIX)/$(BASE_DLL).$(TARGET_LIB_EXTENSION)
|
||||
# External Engine's DLL
|
||||
EXT_INC_DIR += $(INC_DIR)
|
||||
EXT_LB_FLAGS += $(LIB_DIR)
|
||||
EXT_DEPS += -l$(LIB_NAME) $(DEPS)
|
||||
EXT_LINKS += $(UF_LIBS) $(EXT_LIBS) $(EXT_DEPS)
|
||||
#-Wl,-subsystem,windows
|
||||
|
||||
EXT_LIB_DIR += $(ENGINE_LIB_DIR)/$(ARCH)
|
||||
EXT_INCS += -I$(ENGINE_INC_DIR) -I$(EXT_INC_DIR) -I$(VULKAN_SDK_PATH)/include -I/mingw64/include
|
||||
EXT_LIBS += -L$(ENGINE_LIB_DIR) -L$(EXT_LIB_DIR) -L$(EXT_LIB_DIR)/$(PREFIX) -L$(VULKAN_SDK_PATH)/Lib -L/mingw64/lib
|
||||
|
||||
SRCS_EXT_DLL += $(wildcard $(EXT_SRC_DIR)/*.cpp) $(wildcard $(EXT_SRC_DIR)/*/*.cpp) $(wildcard $(EXT_SRC_DIR)/*/*/*.cpp) $(wildcard $(EXT_SRC_DIR)/*/*/*/*.cpp) $(wildcard $(EXT_SRC_DIR)/*/*/*/*/*.cpp)
|
||||
OBJS_EXT_DLL += $(patsubst %.cpp,%.$(ARCH).$(PREFIX).o,$(SRCS_EXT_DLL))
|
||||
BASE_EXT_DLL += lib$(EXT_LIB_NAME)
|
||||
EXT_IM_DLL += $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_EXT_DLL).$(TARGET_LIB_EXTENSION).a
|
||||
EXT_EX_DLL += $(BIN_DIR)/exe/lib/$(ARCH)/$(PREFIX)/$(BASE_EXT_DLL).$(TARGET_LIB_EXTENSION)
|
||||
# Client EXE
|
||||
SRCS += $(wildcard $(CLIENT_SRC_DIR)/*.cpp) $(wildcard $(CLIENT_SRC_DIR)/*/*.cpp)
|
||||
OBJS += $(patsubst %.cpp,%.$(ARCH).$(PREFIX).o,$(SRCS))
|
||||
TARGET += $(BIN_DIR)/exe/$(TARGET_NAME).$(PREFIX).$(TARGET_EXTENSION)
|
||||
# Shaders
|
||||
SRCS_SHADERS += $(wildcard bin/data/shaders/*.glsl) $(wildcard bin/data/shaders/*/*.glsl)
|
||||
TARGET_SHADERS += $(patsubst %.glsl,%.spv,$(SRCS_SHADERS))
|
||||
|
||||
ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
$(ARCH): $(EX_DLL) $(EXT_EX_DLL) $(TARGET) ./bin/dreamcast/$(TARGET_NAME).cdi
|
||||
#$(ARCH): $(TARGET) ./bin/dreamcast/$(TARGET_NAME).cdi
|
||||
OBJS = $(patsubst %.cpp,%.$(ARCH).$(PREFIX).o,$(SRCS_DLL)) $(patsubst %.cpp,%.$(ARCH).$(PREFIX).o,$(SRCS_EXT_DLL)) $(patsubst %.cpp,%.$(ARCH).$(PREFIX).o,$(SRCS))
|
||||
|
||||
DEPS += -lkallisti -lc -lm -lgcc -lstdc++ # -l$(LIB_NAME) -l$(EXT_LIB_NAME)
|
||||
|
||||
%.$(ARCH).$(PREFIX).o: %.cpp
|
||||
$(CC) $(FLAGS) $(INCS) -c $< -o $@
|
||||
|
||||
$(EX_DLL): FLAGS += -DUF_EXPORTS -DJSON_DLL_BUILD
|
||||
$(EX_DLL): $(OBJS_DLL)
|
||||
$(KOS_AR) cru $@ $^
|
||||
$(KOS_RANLIB) $@
|
||||
cp $@ $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_DLL).a
|
||||
|
||||
$(EXT_EX_DLL): FLAGS += -DEXT_EXPORTS -DJSON_DLL_BUILD
|
||||
$(EXT_EX_DLL): $(OBJS_EXT_DLL)
|
||||
$(KOS_AR) cru $@ $^
|
||||
$(KOS_RANLIB) $@
|
||||
cp $@ $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_EXT_DLL).a
|
||||
|
||||
./bin/dreamcast/romdisk.img:
|
||||
$(KOS_GENROMFS) -f ./bin/dreamcast/romdisk.img -d ./bin/dreamcast/romdisk/ -v
|
||||
|
||||
./bin/dreamcast/romdisk.o: ./bin/dreamcast/romdisk.img
|
||||
$(KOS_BASE)/utils/bin2o/bin2o ./bin/dreamcast/romdisk.img romdisk ./bin/dreamcast/romdisk.o
|
||||
|
||||
$(TARGET): $(OBJS) ./bin/dreamcast/romdisk.o
|
||||
$(CC) -O2 -fomit-frame-pointer -ml -m4-single-only -ffunction-sections -fdata-sections $(KOS_INC_PATHS) $(INCS) -D_arch_dreamcast -D_arch_sub_pristine -Wall -g -fno-builtin -ml -m4-single-only -Wl,-Ttext=0x8c010000 -Wl,--gc-sections -T/opt/dreamcast/kos/utils/ldscripts/shlelf.xc -nodefaultlibs $(KOS_LIB_PATHS) $(LIBS) -o $(TARGET) $(OBJS) ./bin/dreamcast/romdisk.o -Wl,--start-group $(DEPS) -Wl,--end-group
|
||||
|
||||
./bin/dreamcast/$(TARGET_NAME).cdi: $(TARGET)
|
||||
cd ./bin/dreamcast/; ./elf2cdi.sh $(TARGET_NAME)
|
||||
|
||||
else
|
||||
$(ARCH): $(EX_DLL) $(EXT_EX_DLL) $(TARGET) $(TARGET_SHADERS)
|
||||
|
||||
%.$(ARCH).$(PREFIX).o: %.cpp
|
||||
$(CC) $(FLAGS) $(INCS) -c $< -o $@
|
||||
|
||||
$(EX_DLL): FLAGS += -DUF_EXPORTS -DJSON_DLL_BUILD
|
||||
$(EX_DLL): $(OBJS_DLL)
|
||||
$(CC) -shared -o $(EX_DLL) -g -Wl,--out-implib=$(IM_DLL) $(OBJS_DLL) $(LIBS) $(INCS) $(LINKS)
|
||||
cp $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_DLL).$(TARGET_LIB_EXTENSION).a $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_DLL).a
|
||||
|
||||
$(EXT_EX_DLL): FLAGS += -DEXT_EXPORTS -DJSON_DLL_BUILD
|
||||
$(EXT_EX_DLL): $(OBJS_EXT_DLL)
|
||||
$(CC) -shared -o $(EXT_EX_DLL) -g -Wl,--out-implib=$(EXT_IM_DLL) $(OBJS_EXT_DLL) $(EXT_LIBS) $(EXT_INCS) $(EXT_LINKS)
|
||||
cp $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_EXT_DLL).$(TARGET_LIB_EXTENSION).a $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_EXT_DLL).a
|
||||
|
||||
$(TARGET): $(OBJS)
|
||||
$(CC) $(FLAGS) $(OBJS) $(LIBS) $(INCS) $(LINKS) -l$(LIB_NAME) -l$(EXT_LIB_NAME) -o $(TARGET)
|
||||
endif
|
||||
|
||||
%.spv: %.glsl
|
||||
$(GLSL_VALIDATOR) -V $< -o $@
|
||||
ifneq (,$(findstring dreamcast,$(ARCH)))
|
||||
clean:
|
||||
@-rm $(EX_DLL)
|
||||
@-rm $(EXT_EX_DLL)
|
||||
@-rm $(TARGET)
|
||||
|
||||
@-rm -f $(OBJS_DLL)
|
||||
@-rm -f $(OBJS_EXT_DLL)
|
||||
@-rm -f $(OBJS)
|
||||
|
||||
@-rm ./bin/dreamcast/build/*
|
||||
@-rm ./bin/dreamcast/romdisk.*
|
||||
@-rm ./bin/dreamcast/$(TARGET_NAME).*
|
||||
else
|
||||
clean:
|
||||
@-rm $(EX_DLL)
|
||||
@-rm $(EXT_EX_DLL)
|
||||
@-rm $(TARGET)
|
||||
|
||||
@-rm -f $(OBJS_DLL)
|
||||
@-rm -f $(OBJS_EXT_DLL)
|
||||
@-rm -f $(OBJS)
|
||||
endif
|
||||
clean-uf:
|
||||
@-rm $(EX_DLL)
|
||||
@-rm -f $(OBJS_DLL)
|
||||
|
||||
clean-exf:
|
||||
@-rm $(EXT_EX_DLL)
|
||||
@-rm -f $(OBJS_EXT_DLL)
|
||||
|
||||
clean-exe:
|
||||
-rm $(EX_DLL)
|
||||
-rm $(EXT_EX_DLL)
|
||||
-rm $(TARGET)
|
||||
-rm $(TARGET_SHADERS)
|
||||
44
bin/data/shaders/base/colored.vert.glsl
Normal file
@ -0,0 +1,44 @@
|
||||
#version 450
|
||||
|
||||
layout (constant_id = 0) const uint PASSES = 6;
|
||||
layout (location = 0) in vec3 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
layout (location = 2) in vec3 inNormal;
|
||||
layout (location = 3) in vec4 inColor;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
struct Matrices {
|
||||
mat4 model;
|
||||
mat4 view[PASSES];
|
||||
mat4 projection[PASSES];
|
||||
};
|
||||
|
||||
layout (binding = 0) uniform UBO {
|
||||
Matrices matrices;
|
||||
vec4 color;
|
||||
} ubo;
|
||||
|
||||
layout (location = 0) out vec2 outUv;
|
||||
layout (location = 1) out vec4 outColor;
|
||||
layout (location = 2) out vec3 outNormal;
|
||||
layout (location = 3) out vec3 outPosition;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
|
||||
void main() {
|
||||
outUv = inUv;
|
||||
outColor = inColor.rgba;
|
||||
|
||||
outPosition = vec3(ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inPos.xyz, 1.0));
|
||||
outNormal = vec3(ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inNormal.xyz, 0.0));
|
||||
outNormal = normalize(outNormal);
|
||||
|
||||
gl_Position = ubo.matrices.projection[PushConstant.pass] * ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inPos.xyz, 1.0);
|
||||
}
|
||||
49
bin/data/shaders/base/frag.glsl
Normal file
@ -0,0 +1,49 @@
|
||||
#version 450
|
||||
|
||||
#define UF_DEFERRED_SAMPLING 0
|
||||
#define UF_CAN_DISCARD 1
|
||||
|
||||
layout (binding = 1) uniform sampler2D samplerTexture;
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) in vec4 inColor;
|
||||
layout (location = 2) in vec3 inNormal;
|
||||
layout (location = 3) in vec3 inPosition;
|
||||
|
||||
layout (location = 0) out uvec2 outId;
|
||||
layout (location = 1) out vec2 outNormals;
|
||||
#if UF_DEFERRED_SAMPLING
|
||||
layout (location = 2) out vec2 outUvs;
|
||||
#else
|
||||
layout (location = 2) out vec4 outAlbedo;
|
||||
#endif
|
||||
|
||||
vec2 encodeNormals( vec3 n ) {
|
||||
float p = sqrt(n.z*8+8);
|
||||
return n.xy/p + 0.5;
|
||||
}
|
||||
float mipLevel( in vec2 uv ) {
|
||||
vec2 dx_vtc = dFdx(uv);
|
||||
vec2 dy_vtc = dFdy(uv);
|
||||
return 0.5 * log2(max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc)));
|
||||
}
|
||||
|
||||
void main() {
|
||||
float mip = mipLevel(inUv.xy);
|
||||
vec2 uv = inUv.xy;
|
||||
vec4 C = vec4(1, 1, 1, 1);
|
||||
vec3 P = inPosition;
|
||||
vec3 N = inNormal;
|
||||
#if UF_DEFERRED_SAMPLING
|
||||
outUvs = wrap(inUv.xy);
|
||||
vec4 outAlbedo = vec4(0,0,0,0);
|
||||
#endif
|
||||
#if !UF_DEFERRED_SAMPLING || UF_CAN_DISCARD
|
||||
C = textureLod( samplerTexture, uv, mip );
|
||||
#endif
|
||||
#if !UF_DEFERRED_SAMPLING
|
||||
outAlbedo = C * inColor;
|
||||
#endif
|
||||
outNormals = encodeNormals( N );
|
||||
//outId = ivec2(0, 0);
|
||||
}
|
||||
43
bin/data/shaders/base/vert.glsl
Normal file
@ -0,0 +1,43 @@
|
||||
#version 450
|
||||
|
||||
layout (constant_id = 0) const uint PASSES = 6;
|
||||
layout (location = 0) in vec3 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
layout (location = 2) in vec3 inNormal;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
struct Matrices {
|
||||
mat4 model;
|
||||
mat4 view[PASSES];
|
||||
mat4 projection[PASSES];
|
||||
};
|
||||
|
||||
layout (binding = 0) uniform UBO {
|
||||
Matrices matrices;
|
||||
vec4 color;
|
||||
} ubo;
|
||||
|
||||
layout (location = 0) out vec2 outUv;
|
||||
layout (location = 1) out vec4 outColor;
|
||||
layout (location = 2) out vec3 outNormal;
|
||||
layout (location = 3) out vec3 outPosition;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
|
||||
void main() {
|
||||
outUv = inUv;
|
||||
outColor = ubo.color;
|
||||
|
||||
outPosition = vec3(ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inPos.xyz, 1.0));
|
||||
outNormal = vec3(ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inNormal.xyz, 0.0));
|
||||
outNormal = normalize(outNormal);
|
||||
|
||||
gl_Position = ubo.matrices.projection[PushConstant.pass] * ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inPos.xyz, 1.0);
|
||||
}
|
||||
23
bin/data/shaders/display/blit.frag.glsl
Normal file
@ -0,0 +1,23 @@
|
||||
#version 450
|
||||
#extension GL_EXT_samplerless_texture_functions : require
|
||||
|
||||
layout (binding = 1) uniform sampler samp;
|
||||
layout (binding = 2) uniform texture2D albedoLeftTexture;
|
||||
layout (binding = 3) uniform texture2D albedoRightTexture;
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
|
||||
layout (location = 0) out vec4 outAlbedoSpecular;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
} PushConstant;
|
||||
|
||||
void main() {
|
||||
if ( PushConstant.pass == 0 ) {
|
||||
outAlbedoSpecular.rgb = texture(sampler2D(albedoLeftTexture, samp), inUv).rgb;
|
||||
} else {
|
||||
outAlbedoSpecular.rgb = texture(sampler2D(albedoRightTexture, samp), inUv).rgb;
|
||||
}
|
||||
outAlbedoSpecular.a = 1;
|
||||
}
|
||||
16
bin/data/shaders/display/blit.vert.glsl
Normal file
@ -0,0 +1,16 @@
|
||||
#version 450
|
||||
|
||||
layout (location = 0) in vec2 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
|
||||
layout (location = 0) out vec2 outUv;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
void main() {
|
||||
outUv = inUv;
|
||||
|
||||
gl_Position = vec4(inPos.xy, 0.0, 1.0);
|
||||
}
|
||||
75
bin/data/shaders/display/rendertarget.frag.glsl
Normal file
@ -0,0 +1,75 @@
|
||||
#version 450
|
||||
#extension GL_EXT_samplerless_texture_functions : require
|
||||
|
||||
#define MULTISAMPLING 1
|
||||
#define UF_DEFERRED_SAMPLING 0
|
||||
#define UF_CAN_DISCARD 1
|
||||
|
||||
#if !MULTISAMPLING
|
||||
layout (binding = 1) uniform usampler2D textureId;
|
||||
layout (binding = 2) uniform sampler2D textureNormals;
|
||||
#if UF_DEFERRED_SAMPLING
|
||||
layout (binding = 3) uniform sampler2D textureUvs;
|
||||
#else
|
||||
layout (binding = 3) uniform sampler2D textureAlbedo;
|
||||
#endif
|
||||
#else
|
||||
layout (binding = 1) uniform usampler2DMS textureId;
|
||||
layout (binding = 2) uniform sampler2DMS textureNormals;
|
||||
#if UF_DEFERRED_SAMPLING
|
||||
layout (binding = 3) uniform sampler2DMS textureUvs;
|
||||
#else
|
||||
layout (binding = 3) uniform sampler2DMS textureAlbedo;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct Cursor {
|
||||
vec2 position;
|
||||
vec2 radius;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
vec4 resolve( sampler2DMS t, ivec2 uv ) {
|
||||
vec4 resolved = vec4(0);
|
||||
int samples = textureSamples(t);
|
||||
for ( int i = 0; i < samples; ++i ) {
|
||||
resolved += texelFetch(t, uv, i);
|
||||
}
|
||||
resolved /= float(samples);
|
||||
return resolved;
|
||||
}
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) in float inAlpha;
|
||||
layout (location = 2) in Cursor inCursor;
|
||||
|
||||
layout (location = 0) out vec4 outAlbedo;
|
||||
void main() {
|
||||
#if !MULTISAMPLING
|
||||
ivec2 screenSize = textureSize(textureId, 0);
|
||||
#else
|
||||
ivec2 screenSize = textureSize(textureId);
|
||||
#endif
|
||||
ivec2 uv = ivec2(inUv * screenSize);
|
||||
if ( inCursor.radius.x <= 0 || inCursor.radius.y <= 0 ) {
|
||||
#if !MULTISAMPLING
|
||||
outAlbedo = texture(textureAlbedo, uv).rgba;
|
||||
#else
|
||||
outAlbedo = resolve( textureAlbedo, uv );
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
float dist = pow(inUv.x - inCursor.position.x, 2) / pow(inCursor.radius.x, 2) + pow(inUv.y - inCursor.position.y, 2) / pow(inCursor.radius.y, 2);
|
||||
|
||||
#if !MULTISAMPLING
|
||||
outAlbedo = texture(textureAlbedo, inUv);
|
||||
#else
|
||||
outAlbedo = resolve( textureAlbedo, uv );
|
||||
#endif
|
||||
|
||||
if ( dist <= 1 ) {
|
||||
float attenuation = dist;
|
||||
outAlbedo.rgb = mix( inCursor.color.rgb * inCursor.color.a, outAlbedo.rgb, attenuation );
|
||||
}
|
||||
if ( inAlpha < 1.0 ) outAlbedo.a = inAlpha;
|
||||
}
|
||||
41
bin/data/shaders/display/rendertarget.vert.glsl
Normal file
@ -0,0 +1,41 @@
|
||||
#version 450
|
||||
|
||||
layout (location = 0) in vec2 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
|
||||
struct Cursor {
|
||||
vec2 position;
|
||||
vec2 radius;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
layout (location = 0) out vec2 outUv;
|
||||
layout (location = 1) out float outAlpha;
|
||||
layout (location = 2) out flat Cursor outCursor;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
struct Matrices {
|
||||
mat4 model[2];
|
||||
};
|
||||
layout (binding = 0) uniform UBO {
|
||||
Matrices matrices;
|
||||
Cursor cursor;
|
||||
// float alpha;
|
||||
// float padding;
|
||||
} ubo;
|
||||
|
||||
void main() {
|
||||
outUv = inUv;
|
||||
outCursor = ubo.cursor;
|
||||
outAlpha = 1;
|
||||
|
||||
gl_Position = ubo.matrices.model[PushConstant.pass] * vec4(inPos.xy, 0.0, 1.0);
|
||||
}
|
||||
741
bin/data/shaders/display/subpass.frag.glsl
Normal file
@ -0,0 +1,741 @@
|
||||
#version 450
|
||||
#extension GL_EXT_samplerless_texture_functions : require
|
||||
|
||||
#define MULTISAMPLING 1
|
||||
#define RAY_MARCH_FOG 1
|
||||
#define UF_DEFERRED_SAMPLING 0
|
||||
|
||||
layout (constant_id = 0) const uint TEXTURES = 256;
|
||||
|
||||
struct Matrices {
|
||||
mat4 view[2];
|
||||
mat4 projection[2];
|
||||
mat4 iView[2];
|
||||
mat4 iProjection[2];
|
||||
mat4 iProjectionView[2];
|
||||
};
|
||||
|
||||
struct Space {
|
||||
vec3 eye;
|
||||
vec3 world;
|
||||
} position, normal, view;
|
||||
|
||||
struct Fog {
|
||||
vec3 color;
|
||||
float stepScale;
|
||||
|
||||
vec3 offset;
|
||||
float densityScale;
|
||||
|
||||
float densityThreshold;
|
||||
float densityMultiplier;
|
||||
float absorbtion;
|
||||
float padding1;
|
||||
|
||||
vec2 range;
|
||||
float padding2;
|
||||
float padding3;
|
||||
};
|
||||
|
||||
struct Mode {
|
||||
uint type;
|
||||
uint scalar;
|
||||
vec2 padding;
|
||||
vec4 parameters;
|
||||
};
|
||||
|
||||
struct Light {
|
||||
vec3 position;
|
||||
float radius;
|
||||
|
||||
vec3 color;
|
||||
float power;
|
||||
|
||||
int type;
|
||||
int mapIndex;
|
||||
float depthBias;
|
||||
float padding;
|
||||
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
};
|
||||
|
||||
struct Material {
|
||||
vec4 colorBase;
|
||||
vec4 colorEmissive;
|
||||
|
||||
float factorMetallic;
|
||||
float factorRoughness;
|
||||
float factorOcclusion;
|
||||
float factorAlphaCutoff;
|
||||
|
||||
int indexAlbedo;
|
||||
int indexNormal;
|
||||
int indexEmissive;
|
||||
int indexOcclusion;
|
||||
|
||||
int indexMetallicRoughness;
|
||||
int modeAlpha;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
struct Texture {
|
||||
int index;
|
||||
int samp;
|
||||
int remap;
|
||||
float blend;
|
||||
|
||||
vec4 lerp;
|
||||
};
|
||||
struct DrawCall {
|
||||
int materialIndex;
|
||||
uint materials;
|
||||
int textureIndex;
|
||||
uint textures;
|
||||
};
|
||||
|
||||
#if !MULTISAMPLING
|
||||
layout (input_attachment_index = 0, binding = 0) uniform usubpassInput samplerId;
|
||||
layout (input_attachment_index = 1, binding = 1) uniform subpassInput samplerNormal;
|
||||
#if UF_DEFERRED_SAMPLING
|
||||
layout (input_attachment_index = 2, binding = 2) uniform subpassInput samplerUv;
|
||||
#else
|
||||
layout (input_attachment_index = 2, binding = 2) uniform subpassInput samplerAlbedo;
|
||||
#endif
|
||||
layout (input_attachment_index = 3, binding = 3) uniform subpassInput samplerDepth;
|
||||
#else
|
||||
layout (input_attachment_index = 0, binding = 0) uniform usubpassInputMS samplerId;
|
||||
layout (input_attachment_index = 1, binding = 1) uniform subpassInputMS samplerNormal;
|
||||
#if UF_DEFERRED_SAMPLING
|
||||
layout (input_attachment_index = 2, binding = 2) uniform subpassInputMS samplerUv;
|
||||
#else
|
||||
layout (input_attachment_index = 2, binding = 2) uniform subpassInputMS samplerAlbedo;
|
||||
#endif
|
||||
layout (input_attachment_index = 3, binding = 3) uniform subpassInputMS samplerDepth;
|
||||
#endif
|
||||
layout (binding = 4) uniform sampler3D samplerNoise;
|
||||
layout (binding = 5) uniform samplerCube samplerSkybox;
|
||||
layout (binding = 6) uniform sampler2D samplerTextures[TEXTURES];
|
||||
|
||||
layout (binding = 7) uniform UBO {
|
||||
Matrices matrices;
|
||||
|
||||
Mode mode;
|
||||
Fog fog;
|
||||
|
||||
uint lights;
|
||||
uint materials;
|
||||
uint textures;
|
||||
uint drawCalls;
|
||||
|
||||
vec3 ambient;
|
||||
float kexp;
|
||||
|
||||
uint msaa;
|
||||
uint poissonSamples;
|
||||
uint padding1;
|
||||
uint padding2;
|
||||
} ubo;
|
||||
|
||||
layout (std140, binding = 8) readonly buffer Lights {
|
||||
Light lights[];
|
||||
};
|
||||
layout (std140, binding = 9) readonly buffer Materials {
|
||||
Material materials[];
|
||||
};
|
||||
layout (std140, binding = 10) readonly buffer Textures {
|
||||
Texture textures[];
|
||||
};
|
||||
layout (std140, binding = 11) readonly buffer DrawCalls {
|
||||
DrawCall drawCalls[];
|
||||
};
|
||||
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) in flat uint inPushConstantPass;
|
||||
|
||||
layout (location = 0) out vec4 outFragColor;
|
||||
|
||||
vec2 poissonDisk[16] = vec2[](
|
||||
vec2( -0.94201624, -0.39906216 ),
|
||||
vec2( 0.94558609, -0.76890725 ),
|
||||
vec2( -0.094184101, -0.92938870 ),
|
||||
vec2( 0.34495938, 0.29387760 ),
|
||||
vec2( -0.91588581, 0.45771432 ),
|
||||
vec2( -0.81544232, -0.87912464 ),
|
||||
vec2( -0.38277543, 0.27676845 ),
|
||||
vec2( 0.97484398, 0.75648379 ),
|
||||
vec2( 0.44323325, -0.97511554 ),
|
||||
vec2( 0.53742981, -0.47373420 ),
|
||||
vec2( -0.26496911, -0.41893023 ),
|
||||
vec2( 0.79197514, 0.19090188 ),
|
||||
vec2( -0.24188840, 0.99706507 ),
|
||||
vec2( -0.81409955, 0.91437590 ),
|
||||
vec2( 0.19984126, 0.78641367 ),
|
||||
vec2( 0.14383161, -0.14100790 )
|
||||
);
|
||||
|
||||
void phong( Light light, vec4 albedoSpecular, inout vec3 i ) {
|
||||
vec3 Ls = vec3(1.0, 1.0, 1.0); // light specular
|
||||
vec3 Ld = light.color; // light color
|
||||
vec3 La = vec3(1.0, 1.0, 1.0);
|
||||
|
||||
vec3 Ks = vec3(albedoSpecular.a); // material specular
|
||||
vec3 Kd = albedoSpecular.rgb; // material diffuse
|
||||
vec3 Ka = vec3(1.0, 1.0, 1.0);
|
||||
|
||||
float Kexp = ubo.kexp;
|
||||
|
||||
vec3 V = position.eye;
|
||||
vec3 N = normal.eye;
|
||||
vec3 L = light.position.xyz - V;
|
||||
float dist = length(L);
|
||||
// if ( light.radius > 0.001 && light.radius < dist ) return;
|
||||
|
||||
vec3 D = normalize(L);
|
||||
float d_dot = max(dot( D, N ), 0.0);
|
||||
|
||||
vec3 R = reflect( -D, N );
|
||||
vec3 S = normalize(-V);
|
||||
float s_factor = pow( max(dot( R, S ), 0.0), Kexp );
|
||||
if ( Kexp < 0.0001 ) s_factor = 0;
|
||||
|
||||
float radiance = light.power / (dist * dist);
|
||||
|
||||
vec3 Ia = La * Ka;
|
||||
vec3 Id = Ld * Kd * d_dot * radiance;
|
||||
vec3 Is = Ls * Ks * s_factor * radiance;
|
||||
|
||||
i += Id + Is;
|
||||
}
|
||||
|
||||
const float PI = 3.14159265359;
|
||||
float DistributionGGX(vec3 N, vec3 H, float roughness) {
|
||||
float a = roughness*roughness;
|
||||
float a2 = a*a;
|
||||
float NdotH = max(dot(N, H), 0.0);
|
||||
float NdotH2 = NdotH*NdotH;
|
||||
|
||||
float num = a2;
|
||||
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
|
||||
denom = PI * denom * denom;
|
||||
|
||||
return num / denom;
|
||||
}
|
||||
|
||||
float GeometrySchlickGGX(float NdotV, float roughness) {
|
||||
float r = (roughness + 1.0);
|
||||
float k = (r*r) / 8.0;
|
||||
|
||||
float num = NdotV;
|
||||
float denom = NdotV * (1.0 - k) + k;
|
||||
|
||||
return num / denom;
|
||||
}
|
||||
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) {
|
||||
float NdotV = max(dot(N, V), 0.0);
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
float ggx2 = GeometrySchlickGGX(NdotV, roughness);
|
||||
float ggx1 = GeometrySchlickGGX(NdotL, roughness);
|
||||
|
||||
return ggx1 * ggx2;
|
||||
}
|
||||
vec3 fresnelSchlick(float cosTheta, vec3 F0) {
|
||||
return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
|
||||
}
|
||||
|
||||
float random(vec3 seed, int i){
|
||||
vec4 seed4 = vec4(seed,i);
|
||||
float dot_product = dot(seed4, vec4(12.9898,78.233,45.164,94.673));
|
||||
return fract(sin(dot_product) * 43758.5453);
|
||||
}
|
||||
|
||||
float shadowFactor( Light light, uint shadowMap ) {
|
||||
vec4 positionClip = light.projection * light.view * vec4(position.world, 1.0);
|
||||
positionClip.xyz /= positionClip.w;
|
||||
|
||||
if ( positionClip.x < -1 || positionClip.x >= 1 ) return 0.0;
|
||||
if ( positionClip.y < -1 || positionClip.y >= 1 ) return 0.0;
|
||||
if ( positionClip.z <= 0 || positionClip.z >= 1 ) return 0.0;
|
||||
|
||||
float factor = 1.0;
|
||||
|
||||
// spot light
|
||||
if ( light.type == 2 || light.type == 3 ) {
|
||||
float dist = length( positionClip.xy );
|
||||
if ( dist > 0.5 ) return 0.0;
|
||||
|
||||
// spot light with attenuation
|
||||
if ( light.type == 3 ) {
|
||||
factor = 1.0 - (pow(dist * 2,2.0));
|
||||
}
|
||||
}
|
||||
|
||||
vec2 uv = positionClip.xy * 0.5 + 0.5;
|
||||
float bias = light.depthBias;
|
||||
/*
|
||||
if ( true ) {
|
||||
float cosTheta = clamp(dot(normal.eye, normalize(light.position.xyz - position.eye)), 0, 1);
|
||||
bias = clamp(bias * tan(acos(cosTheta)), 0, 0.01);
|
||||
} else if ( true ) {
|
||||
bias = max(bias * 10 * (1.0 - dot(normal.eye, normalize(light.position.xyz - position.eye))), bias);
|
||||
}
|
||||
*/
|
||||
|
||||
float eyeDepth = positionClip.z;
|
||||
|
||||
int samples = int(ubo.poissonSamples);
|
||||
if ( samples <= 1 ) {
|
||||
return eyeDepth < texture(samplerTextures[shadowMap], uv).r - bias ? 0.0 : factor;
|
||||
}
|
||||
for ( int i = 0; i < samples; ++i ) {
|
||||
// int index = i;
|
||||
// int index = int( float(samples) * random(gl_FragCoord.xyy, i) ) % samples;
|
||||
int index = int( float(samples) * random(floor(position.world.xyz * 1000.0), i)) % samples;
|
||||
float lightDepth = texture(samplerTextures[shadowMap], uv + poissonDisk[index] / 700.0 ).r;
|
||||
if ( eyeDepth < lightDepth - bias ) factor -= 1.0 / samples;
|
||||
}
|
||||
return factor;
|
||||
}
|
||||
vec3 hslToRgb(vec3 HSL) {
|
||||
vec3 RGB; {
|
||||
float H = HSL.x;
|
||||
float R = abs(H * 6 - 3) - 1;
|
||||
float G = 2 - abs(H * 6 - 2);
|
||||
float B = 2 - abs(H * 6 - 4);
|
||||
RGB = clamp(vec3(R,G,B), 0, 1);
|
||||
}
|
||||
float C = (1 - abs(2 * HSL.z - 1)) * HSL.y;
|
||||
return (RGB - 0.5) * C + HSL.z;
|
||||
}
|
||||
vec3 rgbToHsl(vec3 RGB) {
|
||||
float Epsilon = 1e-10;
|
||||
vec3 HCV; {
|
||||
vec4 P = (RGB.g < RGB.b) ? vec4(RGB.bg, -1.0, 2.0/3.0) : vec4(RGB.gb, 0.0, -1.0/3.0);
|
||||
vec4 Q = (RGB.r < P.x) ? vec4(P.xyw, RGB.r) : vec4(RGB.r, P.yzx);
|
||||
float C = Q.x - min(Q.w, Q.y);
|
||||
float H = abs((Q.w - Q.y) / (6 * C + Epsilon) + Q.z);
|
||||
HCV = vec3(H, C, Q.x);
|
||||
}
|
||||
float L = HCV.z - HCV.y * 0.5;
|
||||
float S = HCV.y / (1 - abs(L * 2 - 1) + Epsilon);
|
||||
return vec3(HCV.x, S, L);
|
||||
}
|
||||
|
||||
float hueDistance(float h1, float h2) {
|
||||
float diff = abs((h1 - h2));
|
||||
return min(abs((1.0 - diff)), diff);
|
||||
}
|
||||
const float lightnessSteps = 4.0;
|
||||
float lightnessStep(float l) {
|
||||
return floor((0.5 + l * lightnessSteps)) / lightnessSteps;
|
||||
}
|
||||
const int indexMatrix16x16[256] = int[](0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255,
|
||||
128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127,
|
||||
32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223,
|
||||
160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95,
|
||||
8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247,
|
||||
136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119,
|
||||
40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215,
|
||||
168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87,
|
||||
2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253,
|
||||
130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125,
|
||||
34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221,
|
||||
162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93,
|
||||
10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245,
|
||||
138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117,
|
||||
42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213,
|
||||
170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85);
|
||||
float indexValue16x16( float scale ) {
|
||||
int x = int(mod(gl_FragCoord.x * scale, 16));
|
||||
int y = int(mod(gl_FragCoord.y * scale, 16));
|
||||
return indexMatrix16x16[(x + y * 16)] / 256.0;
|
||||
}
|
||||
const int indexMatrix8x8[64] = int[](0, 32, 8, 40, 2, 34, 10, 42,
|
||||
48, 16, 56, 24, 50, 18, 58, 26,
|
||||
12, 44, 4, 36, 14, 46, 6, 38,
|
||||
60, 28, 52, 20, 62, 30, 54, 22,
|
||||
3, 35, 11, 43, 1, 33, 9, 41,
|
||||
51, 19, 59, 27, 49, 17, 57, 25,
|
||||
15, 47, 7, 39, 13, 45, 5, 37,
|
||||
63, 31, 55, 23, 61, 29, 53, 21);
|
||||
float indexValue8x8( float scale ) {
|
||||
int x = int(mod(gl_FragCoord.x * scale, 8));
|
||||
int y = int(mod(gl_FragCoord.y * scale, 8));
|
||||
return indexMatrix8x8[(x + y * 8)] / 64.0;
|
||||
}
|
||||
const int indexMatrix4x4[16] = int[](0, 8, 2, 10,
|
||||
12, 4, 14, 6,
|
||||
3, 11, 1, 9,
|
||||
15, 7, 13, 5);
|
||||
float indexValue4x4( float scale ) {
|
||||
int x = int(mod(gl_FragCoord.x * scale, 4));
|
||||
int y = int(mod(gl_FragCoord.y * scale, 4));
|
||||
return indexMatrix4x4[(x + y * 4)] / 16.0;
|
||||
}
|
||||
vec3[2] closestColors(float hue) {
|
||||
vec3 ret[2];
|
||||
vec3 closest = vec3(-2, 0, 0);
|
||||
vec3 secondClosest = vec3(-2, 0, 0);
|
||||
vec3 temp;
|
||||
/*
|
||||
for (int i = 0; i < palette.length(); ++i) {
|
||||
temp = rgbToHsl(palette[i].rgb);
|
||||
float tempDistance = hueDistance(temp.x, hue);
|
||||
if (tempDistance < hueDistance(closest.x, hue)) {
|
||||
secondClosest = closest;
|
||||
closest = temp;
|
||||
} else {
|
||||
if (tempDistance < hueDistance(secondClosest.x, hue)) {
|
||||
secondClosest = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
ret[0] = closest;
|
||||
ret[1] = secondClosest;
|
||||
return ret;
|
||||
}
|
||||
float dither(float color) {
|
||||
float closestColor = (color < 0.5) ? 0 : 1;
|
||||
float secondClosestColor = 1 - closestColor;
|
||||
float d = 1; // -0.5 - fract(ubo.mode.parameters.w / 8.0);
|
||||
if ( ubo.mode.scalar == 16 ) {
|
||||
d = indexValue16x16(1);
|
||||
} else if ( ubo.mode.scalar == 8 ) {
|
||||
d = indexValue8x8(1);
|
||||
} else if ( ubo.mode.scalar == 4 ) {
|
||||
d = indexValue4x4(1);
|
||||
}
|
||||
float distance = abs(closestColor - color);
|
||||
return (distance < d) ? closestColor : secondClosestColor;
|
||||
}
|
||||
void dither(inout vec3 color) {
|
||||
vec3 hsl = rgbToHsl(color);
|
||||
hsl.x = dither(hsl.x);
|
||||
color = hslToRgb(hsl);
|
||||
}
|
||||
void dither1(inout vec3 color) {
|
||||
vec3 hsl = rgbToHsl(color);
|
||||
|
||||
float d = 0;
|
||||
vec3 cs[2] = { hsl, hsl }; // closestColors(hsl.x);
|
||||
float scale = 1;
|
||||
if ( ubo.mode.scalar == 16 ) {
|
||||
d = indexValue16x16(scale);
|
||||
} else if ( ubo.mode.scalar == 8 ) {
|
||||
d = indexValue8x8(scale);
|
||||
} else if ( ubo.mode.scalar == 4 ) {
|
||||
d = indexValue4x4(scale);
|
||||
}
|
||||
float hueDiff = hueDistance(hsl.x, cs[0].x) / hueDistance(cs[1].x, cs[0].x);
|
||||
float l1 = lightnessStep(max((hsl.z - 0.125), 0.0));
|
||||
float l2 = lightnessStep(min((hsl.z + 0.124), 1.0));
|
||||
float lightnessDiff = (hsl.z - l1) / (l2 - l1);
|
||||
|
||||
vec3 resultColor = (hueDiff < d) ? cs[0] : cs[1];
|
||||
resultColor.z = (lightnessDiff < d) ? l1 : l2;
|
||||
color = hslToRgb(resultColor);
|
||||
}
|
||||
vec3 dither2() {
|
||||
vec3 vDither = dot( vec2( 171.0, 231.0 ), inUv.xy + ubo.mode.parameters.w ).xxx;
|
||||
vDither.rgb = fract( vDither.rgb / vec3( 103.0, 71.0, 97.0 ) ) - vec3( 0.5, 0.5, 0.5 );
|
||||
return ( vDither.rgb / 255.0 ) * 0.375;
|
||||
}
|
||||
|
||||
float rand2(vec2 co){
|
||||
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 143758.5453);
|
||||
}
|
||||
float rand3(vec3 co){
|
||||
return fract(sin(dot(co.xyz ,vec3(12.9898,78.233, 37.719))) * 143758.5453);
|
||||
}
|
||||
void whitenoise(inout vec3 color) {
|
||||
float flicker = ubo.mode.parameters.x;
|
||||
float pieces = ubo.mode.parameters.y;
|
||||
float blend = ubo.mode.parameters.z;
|
||||
float time = ubo.mode.parameters.w;
|
||||
if ( blend < 0.0001 ) return;
|
||||
float freq = sin(pow(mod(time, flicker) + flicker, 1.9));
|
||||
// float whiteNoise = rand3( floor(position.world / pieces) + floor(time * 2) );
|
||||
float whiteNoise = rand2( floor(gl_FragCoord.xy / pieces) + mod(time, freq) );
|
||||
color = mix( color, vec3(whiteNoise), blend );
|
||||
}
|
||||
|
||||
void pbr( Light light, vec3 albedo, float metallic, float roughness, vec3 lightPositionWorld, inout vec3 i ) {
|
||||
vec3 F0 = vec3(0.04);
|
||||
F0 = mix(F0, albedo, metallic);
|
||||
|
||||
vec3 N = normalize(normal.eye);
|
||||
vec3 L = light.position.xyz - position.eye;
|
||||
float dist = length(L);
|
||||
|
||||
L = normalize(L);
|
||||
vec3 V = normalize(-position.eye);
|
||||
vec3 H = normalize(V + L);
|
||||
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
float NdotV = max(dot(N, V), 0.0);
|
||||
float attenuation = light.power / (dist * dist);
|
||||
vec3 radiance = light.color.rgb * attenuation;
|
||||
|
||||
// cook-torrance brdf
|
||||
float NDF = DistributionGGX(N, H, roughness);
|
||||
float G = GeometrySmith(N, V, L, roughness);
|
||||
vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
|
||||
|
||||
vec3 kD = vec3(1.0) - F;
|
||||
kD *= 1.0 - metallic;
|
||||
|
||||
vec3 numerator = NDF * G * F;
|
||||
float denominator = 4.0 * NdotV * NdotL;
|
||||
vec3 specular = numerator / max(denominator, 0.001);
|
||||
|
||||
// add to outgoing radiance Lo
|
||||
i += (kD * albedo / PI + specular) * radiance * NdotL;
|
||||
}
|
||||
|
||||
vec2 rayBoxDst( vec3 boundsMin, vec3 boundsMax, vec3 rayO, vec3 rayD ) {
|
||||
vec3 t0 = (boundsMin - rayO) / rayD;
|
||||
vec3 t1 = (boundsMax - rayO) / rayD;
|
||||
vec3 tmin = min(t0, t1);
|
||||
vec3 tmax = max(t0, t1);
|
||||
float dstA = max( max(tmin.x, tmin.y), tmin.z );
|
||||
float dstB = min( tmax.x, min(tmax.y, tmax.z) );
|
||||
float dstToBox = max(0, dstA);
|
||||
float dstInsideBox = max(0, dstB - dstToBox);
|
||||
return vec2(dstToBox, dstInsideBox);
|
||||
}
|
||||
|
||||
float sampleDensity( vec3 position ) {
|
||||
vec3 uvw = position * ubo.fog.densityScale * 0.001 + ubo.fog.offset * 0.01;
|
||||
return max(0, texture(samplerNoise, uvw).r - ubo.fog.densityThreshold) * ubo.fog.densityMultiplier;
|
||||
}
|
||||
|
||||
void fog( vec3 rayO, vec3 rayD, inout vec3 i, float scale ) {
|
||||
if ( ubo.fog.stepScale <= 0 ) return;
|
||||
if ( ubo.fog.range.x == 0 || ubo.fog.range.y == 0 ) return;
|
||||
|
||||
#if RAY_MARCH_FOG
|
||||
float range = ubo.fog.range.y;
|
||||
vec3 boundsMin = vec3(-range,-range,-range) + rayO;
|
||||
vec3 boundsMax = vec3(range,range,range) + rayO;
|
||||
int numSteps = int(length(boundsMax - boundsMin) * ubo.fog.stepScale );
|
||||
|
||||
vec2 rayBoxInfo = rayBoxDst( boundsMin, boundsMax, rayO, rayD );
|
||||
float dstToBox = rayBoxInfo.x;
|
||||
float dstInsideBox = rayBoxInfo.y;
|
||||
float depth = position.eye.z;
|
||||
|
||||
float lightEnergy = 0;
|
||||
// march
|
||||
if ( 0 <= dstInsideBox && dstToBox <= depth ) {
|
||||
float dstTravelled = 0;
|
||||
float stepSize = dstInsideBox / numSteps;
|
||||
float dstLimit = min( depth - dstToBox, dstInsideBox );
|
||||
float totalDensity = 0;
|
||||
float transmittance = 1;
|
||||
while ( dstTravelled < dstLimit ) {
|
||||
vec3 rayPos = rayO + rayD * (dstToBox + dstTravelled);
|
||||
float density = sampleDensity(rayPos);
|
||||
if ( density > 0 ) {
|
||||
transmittance *= exp(-density * stepSize * ubo.fog.absorbtion);
|
||||
if ( transmittance < 0.01 ) break;
|
||||
}
|
||||
dstTravelled += stepSize;
|
||||
}
|
||||
i.rgb = mix(ubo.fog.color.rgb, i.rgb, transmittance);
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 color = ubo.fog.color.rgb;
|
||||
float inner = ubo.fog.range.x;
|
||||
float outer = ubo.fog.range.y * scale;
|
||||
float distance = length(-position.eye);
|
||||
float factor = (distance - inner) / (outer - inner);
|
||||
factor = clamp( factor, 0.0, 1.0 );
|
||||
|
||||
i.rgb = mix(i.rgb, color, factor);
|
||||
}
|
||||
|
||||
vec3 decodeNormals( vec2 enc ) {
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return normalize(n);
|
||||
}
|
||||
float wrap( float i ) {
|
||||
return fract(i);
|
||||
}
|
||||
vec2 wrap( vec2 uv ) {
|
||||
return vec2( wrap( uv.x ), wrap( uv.y ) );
|
||||
}
|
||||
float mipLevel( in vec2 uv ) {
|
||||
vec2 dx_vtc = dFdx(uv);
|
||||
vec2 dy_vtc = dFdy(uv);
|
||||
return 0.5 * log2(max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc)));
|
||||
}
|
||||
bool validTextureIndex( int textureIndex ) {
|
||||
return 0 <= textureIndex && textureIndex < ubo.textures;
|
||||
}
|
||||
vec4 sampleTexture( uint drawId, int textureIndex, in vec2 uv, vec4 base ) {
|
||||
if ( !validTextureIndex( textureIndex ) ) return base;
|
||||
Texture t = textures[textureIndex+1];
|
||||
float mip = mipLevel( uv );
|
||||
return texture( samplerTextures[drawId], mix( t.lerp.xy, t.lerp.zw, wrap( uv ) ), mip );
|
||||
}
|
||||
|
||||
vec4 resolve( subpassInputMS t ) {
|
||||
int samples = int(ubo.msaa);
|
||||
vec4 resolved = vec4(0);
|
||||
for ( int i = 0; i < samples; ++i ) {
|
||||
resolved += subpassLoad(t, i);
|
||||
}
|
||||
resolved /= vec4(samples);
|
||||
return resolved;
|
||||
}
|
||||
uvec4 resolve( usubpassInputMS t ) {
|
||||
int samples = int(ubo.msaa);
|
||||
uvec4 resolved = uvec4(0);
|
||||
for ( int i = 0; i < samples; ++i ) {
|
||||
resolved += subpassLoad(t, i);
|
||||
}
|
||||
resolved /= uvec4(samples);
|
||||
return resolved;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec3 rayO = vec3(0);
|
||||
vec3 rayD = vec3(0);
|
||||
vec3 fragColor = vec3(0);
|
||||
|
||||
{
|
||||
#if !MULTISAMPLING
|
||||
float depth = subpassLoad(samplerDepth).r;
|
||||
#else
|
||||
float depth = resolve( samplerDepth ).r;
|
||||
#endif
|
||||
|
||||
vec4 positionClip = vec4(inUv * 2.0 - 1.0, depth, 1.0);
|
||||
vec4 positionEye = ubo.matrices.iProjection[inPushConstantPass] * positionClip;
|
||||
positionEye /= positionEye.w;
|
||||
position.eye = positionEye.xyz;
|
||||
|
||||
vec4 positionWorld = ubo.matrices.iView[inPushConstantPass] * positionEye;
|
||||
position.world = positionWorld.xyz;
|
||||
}
|
||||
{
|
||||
vec4 near4 = ubo.matrices.iProjectionView[inPushConstantPass] * (vec4(2.0 * inUv - 1.0, -1.0, 1.0));
|
||||
vec4 far4 = ubo.matrices.iProjectionView[inPushConstantPass] * (vec4(2.0 * inUv - 1.0, 1.0, 1.0));
|
||||
vec3 near3 = near4.xyz / near4.w;
|
||||
vec3 far3 = far4.xyz / far4.w;
|
||||
|
||||
rayO = near3;
|
||||
}
|
||||
{
|
||||
mat4 iProjectionView = inverse( ubo.matrices.projection[inPushConstantPass] * mat4(mat3(ubo.matrices.view[inPushConstantPass])) );
|
||||
vec4 near4 = iProjectionView * (vec4(2.0 * inUv - 1.0, -1.0, 1.0));
|
||||
vec4 far4 = iProjectionView * (vec4(2.0 * inUv - 1.0, 1.0, 1.0));
|
||||
vec3 near3 = near4.xyz / near4.w;
|
||||
vec3 far3 = far4.xyz / far4.w;
|
||||
|
||||
rayD = normalize( far3 - near3 );
|
||||
}
|
||||
#if !MULTISAMPLING
|
||||
normal.eye = decodeNormals( subpassLoad(samplerNormal).xy );
|
||||
uvec2 ID = subpassLoad(samplerId).xy;
|
||||
#else
|
||||
normal.eye = decodeNormals( resolve(samplerNormal).xy );
|
||||
uvec2 ID = resolve(samplerId).xy;
|
||||
#endif
|
||||
uint drawId = ID.x;
|
||||
uint materialId = ID.y;
|
||||
if ( drawId == 0 || materialId == 0 ) {
|
||||
fragColor.rgb = texture( samplerSkybox, rayD ).rgb;
|
||||
fog(rayO, rayD, fragColor, 0.0);
|
||||
outFragColor = vec4(fragColor,1);
|
||||
return;
|
||||
}
|
||||
--drawId;
|
||||
--materialId;
|
||||
|
||||
DrawCall drawCall = drawCalls[drawId];
|
||||
materialId += drawCall.materialIndex;
|
||||
|
||||
Material material = materials[materialId];
|
||||
vec4 C = material.colorBase;
|
||||
|
||||
#if UF_DEFERRED_SAMPLING
|
||||
#if !MULTISAMPLING
|
||||
vec2 uv = subpassLoad(samplerUv).xy;
|
||||
#else
|
||||
vec2 uv = resolve(samplerUv).xy;
|
||||
#endif
|
||||
C = sampleTexture( drawId, drawCall.textureIndex + material.indexAlbedo, uv, C );
|
||||
// OPAQUE
|
||||
if ( material.modeAlpha == 0 ) {
|
||||
C.a = 1;
|
||||
// BLEND
|
||||
} else if ( material.modeAlpha == 1 ) {
|
||||
|
||||
// MASK
|
||||
} else if ( material.modeAlpha == 2 ) {
|
||||
|
||||
}
|
||||
#else
|
||||
#if !MULTISAMPLING
|
||||
C = subpassLoad(samplerAlbedo);
|
||||
#else
|
||||
C = resolve(samplerAlbedo);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
float M = material.factorMetallic;
|
||||
float R = material.factorRoughness * 4.0;
|
||||
float AO = material.factorOcclusion;
|
||||
|
||||
bool usePbr = true;
|
||||
bool gammaCorrect = false;
|
||||
float litFactor = 1.0;
|
||||
fragColor = C.rgb * ubo.ambient.rgb * AO;
|
||||
for ( uint i = 0; i < ubo.lights; ++i ) {
|
||||
Light light = lights[i];
|
||||
|
||||
if ( light.power <= 0.001 ) continue;
|
||||
|
||||
vec3 lightPositionWorld = light.position.xyz;
|
||||
light.position.xyz = vec3(ubo.matrices.view[inPushConstantPass] * vec4(light.position.xyz, 1));
|
||||
|
||||
if ( 0 <= light.mapIndex && light.mapIndex < TEXTURES ) {
|
||||
float factor = shadowFactor( light, light.mapIndex );
|
||||
// if ( factor <= 0.0001 ) continue;
|
||||
light.power *= factor;
|
||||
litFactor += light.power;
|
||||
}
|
||||
if ( light.power <= 0.0001 ) continue;
|
||||
|
||||
if ( usePbr ) {
|
||||
pbr( light, C.rgb, M, R, lightPositionWorld, fragColor );
|
||||
} else
|
||||
phong( light, C, fragColor );
|
||||
}
|
||||
if ( gammaCorrect ) {
|
||||
fragColor = fragColor / (fragColor + vec3(1.0));
|
||||
fragColor = pow(fragColor, vec3(1.0/2.2));
|
||||
}
|
||||
|
||||
fog(rayO, rayD, fragColor, litFactor);
|
||||
|
||||
/*
|
||||
if ( (ubo.mode.type & (0x1 << 0)) == (0x1 << 0) ) {
|
||||
//dither1(fragColor);
|
||||
fragColor += dither2();
|
||||
}
|
||||
*/
|
||||
if ( (ubo.mode.type & (0x1 << 1)) == (0x1 << 1) ) {
|
||||
whitenoise(fragColor);
|
||||
}
|
||||
outFragColor = vec4(fragColor,1);
|
||||
}
|
||||
559
bin/data/shaders/display/subpass.old.frag.glsl
Normal file
@ -0,0 +1,559 @@
|
||||
#version 450
|
||||
#extension GL_EXT_samplerless_texture_functions : require
|
||||
|
||||
layout (constant_id = 0) const uint LIGHTS = 256;
|
||||
|
||||
layout (input_attachment_index = 0, binding = 1) uniform subpassInput samplerAlbedoMetallic;
|
||||
layout (input_attachment_index = 0, binding = 2) uniform subpassInput samplerNormalRoughness;
|
||||
layout (input_attachment_index = 0, binding = 3) uniform subpassInput samplerDepth;
|
||||
|
||||
layout (binding = 5) uniform sampler3D samplerNoise;
|
||||
layout (binding = 6) uniform sampler2D samplerShadows[LIGHTS];
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) in flat uint inPushConstantPass;
|
||||
|
||||
layout (location = 0) out vec4 outFragColor;
|
||||
|
||||
/*
|
||||
const vec2 poissonDisk[4] = vec2[](
|
||||
vec2( -0.94201624, -0.39906216 ),
|
||||
vec2( 0.94558609, -0.76890725 ),
|
||||
vec2( -0.094184101, -0.92938870 ),
|
||||
vec2( 0.34495938, 0.29387760 )
|
||||
);
|
||||
*/
|
||||
vec2 poissonDisk[16] = vec2[](
|
||||
vec2( -0.94201624, -0.39906216 ),
|
||||
vec2( 0.94558609, -0.76890725 ),
|
||||
vec2( -0.094184101, -0.92938870 ),
|
||||
vec2( 0.34495938, 0.29387760 ),
|
||||
vec2( -0.91588581, 0.45771432 ),
|
||||
vec2( -0.81544232, -0.87912464 ),
|
||||
vec2( -0.38277543, 0.27676845 ),
|
||||
vec2( 0.97484398, 0.75648379 ),
|
||||
vec2( 0.44323325, -0.97511554 ),
|
||||
vec2( 0.53742981, -0.47373420 ),
|
||||
vec2( -0.26496911, -0.41893023 ),
|
||||
vec2( 0.79197514, 0.19090188 ),
|
||||
vec2( -0.24188840, 0.99706507 ),
|
||||
vec2( -0.81409955, 0.91437590 ),
|
||||
vec2( 0.19984126, 0.78641367 ),
|
||||
vec2( 0.14383161, -0.14100790 )
|
||||
);
|
||||
|
||||
struct Light {
|
||||
vec3 position;
|
||||
float radius;
|
||||
|
||||
vec3 color;
|
||||
float power;
|
||||
|
||||
int type;
|
||||
float depthBias;
|
||||
float padding1;
|
||||
float padding2;
|
||||
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
};
|
||||
|
||||
struct Matrices {
|
||||
mat4 view[2];
|
||||
mat4 projection[2];
|
||||
};
|
||||
|
||||
struct Space {
|
||||
vec3 eye;
|
||||
vec3 world;
|
||||
} position, normal, view;
|
||||
|
||||
struct Fog {
|
||||
vec3 color;
|
||||
float stepScale;
|
||||
|
||||
vec3 offset;
|
||||
float densityScale;
|
||||
|
||||
float densityThreshold;
|
||||
float densityMultiplier;
|
||||
float absorbtion;
|
||||
float padding1;
|
||||
|
||||
vec2 range;
|
||||
float padding2;
|
||||
float padding3;
|
||||
};
|
||||
|
||||
struct Mode {
|
||||
uint type;
|
||||
uint scalar;
|
||||
vec2 padding;
|
||||
vec4 parameters;
|
||||
};
|
||||
|
||||
layout (binding = 0) uniform UBO {
|
||||
Matrices matrices;
|
||||
vec3 ambient;
|
||||
float kexp;
|
||||
Mode mode;
|
||||
Fog fog;
|
||||
Light lights[LIGHTS];
|
||||
} ubo;
|
||||
|
||||
void phong( Light light, vec4 albedoSpecular, inout vec3 i ) {
|
||||
vec3 Ls = vec3(1.0, 1.0, 1.0); // light specular
|
||||
vec3 Ld = light.color; // light color
|
||||
vec3 La = vec3(1.0, 1.0, 1.0);
|
||||
|
||||
vec3 Ks = vec3(albedoSpecular.a); // material specular
|
||||
vec3 Kd = albedoSpecular.rgb; // material diffuse
|
||||
vec3 Ka = vec3(1.0, 1.0, 1.0);
|
||||
|
||||
float Kexp = ubo.kexp;
|
||||
|
||||
vec3 V = position.eye;
|
||||
vec3 N = normal.eye;
|
||||
vec3 L = light.position.xyz - V;
|
||||
float dist = length(L);
|
||||
// if ( light.radius > 0.001 && light.radius < dist ) return;
|
||||
|
||||
vec3 D = normalize(L);
|
||||
float d_dot = max(dot( D, N ), 0.0);
|
||||
|
||||
vec3 R = reflect( -D, N );
|
||||
vec3 S = normalize(-V);
|
||||
float s_factor = pow( max(dot( R, S ), 0.0), Kexp );
|
||||
if ( Kexp < 0.0001 ) s_factor = 0;
|
||||
|
||||
float radiance = light.power / (dist * dist);
|
||||
|
||||
vec3 Ia = La * Ka;
|
||||
vec3 Id = Ld * Kd * d_dot * radiance;
|
||||
vec3 Is = Ls * Ks * s_factor * radiance;
|
||||
|
||||
i += Id + Is;
|
||||
}
|
||||
|
||||
const float PI = 3.14159265359;
|
||||
float DistributionGGX(vec3 N, vec3 H, float roughness) {
|
||||
float a = roughness*roughness;
|
||||
float a2 = a*a;
|
||||
float NdotH = max(dot(N, H), 0.0);
|
||||
float NdotH2 = NdotH*NdotH;
|
||||
|
||||
float num = a2;
|
||||
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
|
||||
denom = PI * denom * denom;
|
||||
|
||||
return num / denom;
|
||||
}
|
||||
|
||||
float GeometrySchlickGGX(float NdotV, float roughness) {
|
||||
float r = (roughness + 1.0);
|
||||
float k = (r*r) / 8.0;
|
||||
|
||||
float num = NdotV;
|
||||
float denom = NdotV * (1.0 - k) + k;
|
||||
|
||||
return num / denom;
|
||||
}
|
||||
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) {
|
||||
float NdotV = max(dot(N, V), 0.0);
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
float ggx2 = GeometrySchlickGGX(NdotV, roughness);
|
||||
float ggx1 = GeometrySchlickGGX(NdotL, roughness);
|
||||
|
||||
return ggx1 * ggx2;
|
||||
}
|
||||
vec3 fresnelSchlick(float cosTheta, vec3 F0) {
|
||||
return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
|
||||
}
|
||||
|
||||
float random(vec3 seed, int i){
|
||||
vec4 seed4 = vec4(seed,i);
|
||||
float dot_product = dot(seed4, vec4(12.9898,78.233,45.164,94.673));
|
||||
return fract(sin(dot_product) * 43758.5453);
|
||||
}
|
||||
|
||||
float shadowFactor( Light light, uint shadowMap ) {
|
||||
vec4 positionClip = light.projection * light.view * vec4(position.world, 1.0);
|
||||
positionClip.xyz /= positionClip.w;
|
||||
|
||||
if ( positionClip.x < -1 || positionClip.x >= 1 ) return 0.0;
|
||||
if ( positionClip.y < -1 || positionClip.y >= 1 ) return 0.0;
|
||||
if ( positionClip.z <= 0 || positionClip.z >= 1 ) return 0.0;
|
||||
|
||||
float factor = 1.0;
|
||||
|
||||
// spot light
|
||||
if ( light.type == -2 || light.type == -3 ) {
|
||||
float dist = length( positionClip.xy );
|
||||
if ( dist > 0.5 ) return 0.0;
|
||||
|
||||
// spot light with attenuation
|
||||
if ( light.type == -3 ) {
|
||||
factor = 1.0 - (pow(dist * 2,2.0));
|
||||
}
|
||||
}
|
||||
|
||||
vec2 uv = positionClip.xy * 0.5 + 0.5;
|
||||
float bias = light.depthBias;
|
||||
if ( !true ) {
|
||||
float cosTheta = clamp(dot(normal.eye, normalize(light.position.xyz - position.eye)), 0, 1);
|
||||
bias = clamp(bias * tan(acos(cosTheta)), 0, 0.01);
|
||||
} else if ( true ) {
|
||||
bias = max(bias * 10 * (1.0 - dot(normal.eye, normalize(light.position.xyz - position.eye))), bias);
|
||||
}
|
||||
|
||||
float eyeDepth = positionClip.z;
|
||||
int samples = poissonDisk.length();
|
||||
if ( samples <= 1 ) {
|
||||
return eyeDepth < texture(samplerShadows[shadowMap], uv).r - bias ? 0.0 : factor;
|
||||
}
|
||||
for ( int i = 0; i < samples; ++i ) {
|
||||
// int index = i;
|
||||
// int index = int( float(samples) * random(gl_FragCoord.xyy, i) ) % samples;
|
||||
int index = int( float(samples) * random(floor(position.world.xyz * 1000.0), i)) % samples;
|
||||
float lightDepth = texture(samplerShadows[shadowMap], uv + poissonDisk[index] / 700.0 ).r;
|
||||
if ( eyeDepth < lightDepth - bias ) factor -= 1.0 / samples;
|
||||
}
|
||||
return factor;
|
||||
}
|
||||
vec3 hslToRgb(vec3 HSL) {
|
||||
vec3 RGB; {
|
||||
float H = HSL.x;
|
||||
float R = abs(H * 6 - 3) - 1;
|
||||
float G = 2 - abs(H * 6 - 2);
|
||||
float B = 2 - abs(H * 6 - 4);
|
||||
RGB = clamp(vec3(R,G,B), 0, 1);
|
||||
}
|
||||
float C = (1 - abs(2 * HSL.z - 1)) * HSL.y;
|
||||
return (RGB - 0.5) * C + HSL.z;
|
||||
}
|
||||
vec3 rgbToHsl(vec3 RGB) {
|
||||
float Epsilon = 1e-10;
|
||||
vec3 HCV; {
|
||||
vec4 P = (RGB.g < RGB.b) ? vec4(RGB.bg, -1.0, 2.0/3.0) : vec4(RGB.gb, 0.0, -1.0/3.0);
|
||||
vec4 Q = (RGB.r < P.x) ? vec4(P.xyw, RGB.r) : vec4(RGB.r, P.yzx);
|
||||
float C = Q.x - min(Q.w, Q.y);
|
||||
float H = abs((Q.w - Q.y) / (6 * C + Epsilon) + Q.z);
|
||||
HCV = vec3(H, C, Q.x);
|
||||
}
|
||||
float L = HCV.z - HCV.y * 0.5;
|
||||
float S = HCV.y / (1 - abs(L * 2 - 1) + Epsilon);
|
||||
return vec3(HCV.x, S, L);
|
||||
}
|
||||
|
||||
float hueDistance(float h1, float h2) {
|
||||
float diff = abs((h1 - h2));
|
||||
return min(abs((1.0 - diff)), diff);
|
||||
}
|
||||
const float lightnessSteps = 4.0;
|
||||
float lightnessStep(float l) {
|
||||
return floor((0.5 + l * lightnessSteps)) / lightnessSteps;
|
||||
}
|
||||
const int indexMatrix16x16[256] = int[](0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255,
|
||||
128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127,
|
||||
32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223,
|
||||
160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95,
|
||||
8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247,
|
||||
136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119,
|
||||
40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215,
|
||||
168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87,
|
||||
2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253,
|
||||
130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125,
|
||||
34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221,
|
||||
162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93,
|
||||
10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245,
|
||||
138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117,
|
||||
42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213,
|
||||
170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85);
|
||||
float indexValue16x16( float scale ) {
|
||||
int x = int(mod(gl_FragCoord.x * scale, 16));
|
||||
int y = int(mod(gl_FragCoord.y * scale, 16));
|
||||
return indexMatrix16x16[(x + y * 16)] / 256.0;
|
||||
}
|
||||
const int indexMatrix8x8[64] = int[](0, 32, 8, 40, 2, 34, 10, 42,
|
||||
48, 16, 56, 24, 50, 18, 58, 26,
|
||||
12, 44, 4, 36, 14, 46, 6, 38,
|
||||
60, 28, 52, 20, 62, 30, 54, 22,
|
||||
3, 35, 11, 43, 1, 33, 9, 41,
|
||||
51, 19, 59, 27, 49, 17, 57, 25,
|
||||
15, 47, 7, 39, 13, 45, 5, 37,
|
||||
63, 31, 55, 23, 61, 29, 53, 21);
|
||||
float indexValue8x8( float scale ) {
|
||||
int x = int(mod(gl_FragCoord.x * scale, 8));
|
||||
int y = int(mod(gl_FragCoord.y * scale, 8));
|
||||
return indexMatrix8x8[(x + y * 8)] / 64.0;
|
||||
}
|
||||
const int indexMatrix4x4[16] = int[](0, 8, 2, 10,
|
||||
12, 4, 14, 6,
|
||||
3, 11, 1, 9,
|
||||
15, 7, 13, 5);
|
||||
float indexValue4x4( float scale ) {
|
||||
int x = int(mod(gl_FragCoord.x * scale, 4));
|
||||
int y = int(mod(gl_FragCoord.y * scale, 4));
|
||||
return indexMatrix4x4[(x + y * 4)] / 16.0;
|
||||
}
|
||||
vec3[2] closestColors(float hue) {
|
||||
vec3 ret[2];
|
||||
vec3 closest = vec3(-2, 0, 0);
|
||||
vec3 secondClosest = vec3(-2, 0, 0);
|
||||
vec3 temp;
|
||||
/*
|
||||
for (int i = 0; i < palette.length(); ++i) {
|
||||
temp = rgbToHsl(palette[i].rgb);
|
||||
float tempDistance = hueDistance(temp.x, hue);
|
||||
if (tempDistance < hueDistance(closest.x, hue)) {
|
||||
secondClosest = closest;
|
||||
closest = temp;
|
||||
} else {
|
||||
if (tempDistance < hueDistance(secondClosest.x, hue)) {
|
||||
secondClosest = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
ret[0] = closest;
|
||||
ret[1] = secondClosest;
|
||||
return ret;
|
||||
}
|
||||
float dither(float color) {
|
||||
float closestColor = (color < 0.5) ? 0 : 1;
|
||||
float secondClosestColor = 1 - closestColor;
|
||||
float d = 1; // -0.5 - fract(ubo.mode.parameters.w / 8.0);
|
||||
if ( ubo.mode.scalar == 16 ) {
|
||||
d = indexValue16x16(1);
|
||||
} else if ( ubo.mode.scalar == 8 ) {
|
||||
d = indexValue8x8(1);
|
||||
} else if ( ubo.mode.scalar == 4 ) {
|
||||
d = indexValue4x4(1);
|
||||
}
|
||||
float distance = abs(closestColor - color);
|
||||
return (distance < d) ? closestColor : secondClosestColor;
|
||||
}
|
||||
void dither(inout vec3 color) {
|
||||
vec3 hsl = rgbToHsl(color);
|
||||
hsl.x = dither(hsl.x);
|
||||
color = hslToRgb(hsl);
|
||||
}
|
||||
void dither1(inout vec3 color) {
|
||||
vec3 hsl = rgbToHsl(color);
|
||||
|
||||
float d = 0;
|
||||
vec3 cs[2] = { hsl, hsl }; // closestColors(hsl.x);
|
||||
float scale = 1;
|
||||
if ( ubo.mode.scalar == 16 ) {
|
||||
d = indexValue16x16(scale);
|
||||
} else if ( ubo.mode.scalar == 8 ) {
|
||||
d = indexValue8x8(scale);
|
||||
} else if ( ubo.mode.scalar == 4 ) {
|
||||
d = indexValue4x4(scale);
|
||||
}
|
||||
float hueDiff = hueDistance(hsl.x, cs[0].x) / hueDistance(cs[1].x, cs[0].x);
|
||||
float l1 = lightnessStep(max((hsl.z - 0.125), 0.0));
|
||||
float l2 = lightnessStep(min((hsl.z + 0.124), 1.0));
|
||||
float lightnessDiff = (hsl.z - l1) / (l2 - l1);
|
||||
|
||||
vec3 resultColor = (hueDiff < d) ? cs[0] : cs[1];
|
||||
resultColor.z = (lightnessDiff < d) ? l1 : l2;
|
||||
color = hslToRgb(resultColor);
|
||||
}
|
||||
vec3 dither2() {
|
||||
vec3 vDither = dot( vec2( 171.0, 231.0 ), inUv.xy + ubo.mode.parameters.w ).xxx;
|
||||
vDither.rgb = fract( vDither.rgb / vec3( 103.0, 71.0, 97.0 ) ) - vec3( 0.5, 0.5, 0.5 );
|
||||
return ( vDither.rgb / 255.0 ) * 0.375;
|
||||
}
|
||||
|
||||
float rand2(vec2 co){
|
||||
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 143758.5453);
|
||||
}
|
||||
float rand3(vec3 co){
|
||||
return fract(sin(dot(co.xyz ,vec3(12.9898,78.233, 37.719))) * 143758.5453);
|
||||
}
|
||||
void whitenoise(inout vec3 color) {
|
||||
float flicker = ubo.mode.parameters.x;
|
||||
float pieces = ubo.mode.parameters.y;
|
||||
float blend = ubo.mode.parameters.z;
|
||||
float time = ubo.mode.parameters.w;
|
||||
if ( blend < 0.0001 ) return;
|
||||
float freq = sin(pow(mod(time, flicker) + flicker, 1.9));
|
||||
// float whiteNoise = rand3( floor(position.world / pieces) + floor(time * 2) );
|
||||
float whiteNoise = rand2( floor(gl_FragCoord.xy / pieces) + mod(time, freq) );
|
||||
color = mix( color, vec3(whiteNoise), blend );
|
||||
}
|
||||
|
||||
void pbr( Light light, vec3 albedo, float metallic, float roughness, vec3 lightPositionWorld, inout vec3 i ) {
|
||||
vec3 F0 = vec3(0.04);
|
||||
F0 = mix(F0, albedo, metallic);
|
||||
|
||||
vec3 N = normalize(normal.eye);
|
||||
vec3 L = light.position.xyz - position.eye;
|
||||
float dist = length(L);
|
||||
// if ( light.radius > 0.001 && light.radius < dist ) return;
|
||||
|
||||
vec3 D = normalize(L);
|
||||
vec3 V = normalize(-position.eye);
|
||||
vec3 H = normalize(V + D);
|
||||
|
||||
float NdotD = max(dot(N, D), 0.0);
|
||||
float NdotV = max(dot(N, V), 0.0);
|
||||
|
||||
vec3 radiance = light.color.rgb * light.power / (dist * dist);
|
||||
/*
|
||||
if ( light.radius > 0.0001 ) {
|
||||
radiance *= clamp( light.radius / (pow(dist, 2.0) + 1.0), 0.0, 1.0 );
|
||||
} else if ( false ) {
|
||||
radiance /= dist * dist;
|
||||
}
|
||||
*/
|
||||
|
||||
// cook-torrance brdf
|
||||
float NDF = DistributionGGX(N, H, roughness);
|
||||
float G = GeometrySmith(N, V, D, roughness);
|
||||
vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
|
||||
|
||||
vec3 kS = F;
|
||||
vec3 kD = vec3(1.0) - kS;
|
||||
kD *= 1.0 - metallic;
|
||||
|
||||
vec3 numerator = NDF * G * F;
|
||||
float denominator = 4.0 * NdotV * NdotD;
|
||||
vec3 specular = numerator / max(denominator, 0.001);
|
||||
|
||||
// add to outgoing radiance Lo
|
||||
i += (kD * albedo / PI + specular) * radiance * NdotD;
|
||||
}
|
||||
|
||||
vec2 rayBoxDst( vec3 boundsMin, vec3 boundsMax, vec3 rayOrigin, vec3 rayDir ) {
|
||||
vec3 t0 = (boundsMin - rayOrigin) / rayDir;
|
||||
vec3 t1 = (boundsMax - rayOrigin) / rayDir;
|
||||
vec3 tmin = min(t0, t1);
|
||||
vec3 tmax = max(t0, t1);
|
||||
float dstA = max( max(tmin.x, tmin.y), tmin.z );
|
||||
float dstB = min( tmax.x, min(tmax.y, tmax.z) );
|
||||
float dstToBox = max(0, dstA);
|
||||
float dstInsideBox = max(0, dstB - dstToBox);
|
||||
return vec2(dstToBox, dstInsideBox);
|
||||
}
|
||||
|
||||
float sampleDensity( vec3 position ) {
|
||||
vec3 uvw = position * ubo.fog.densityScale * 0.001 + ubo.fog.offset * 0.01;
|
||||
return max(0, texture(samplerNoise, uvw).r - ubo.fog.densityThreshold) * ubo.fog.densityMultiplier;
|
||||
}
|
||||
|
||||
void fog( inout vec3 i, float scale ) {
|
||||
if ( ubo.fog.stepScale <= 0 ) return;
|
||||
if ( ubo.fog.range.x == 0 || ubo.fog.range.y == 0 ) return;
|
||||
|
||||
mat4 iProjView = inverse( ubo.matrices.projection[inPushConstantPass] * ubo.matrices.view[inPushConstantPass] );
|
||||
vec4 near4 = iProjView * (vec4(2.0 * inUv - 1.0, -1.0, 1.0));
|
||||
vec4 far4 = iProjView * (vec4(2.0 * inUv - 1.0, 1.0, 1.0));
|
||||
vec3 near3 = near4.xyz / near4.w;
|
||||
vec3 far3 = far4.xyz / far4.w;
|
||||
|
||||
vec3 rayOrigin = near3;
|
||||
vec3 rayDir = normalize( far3 - near3 );
|
||||
|
||||
float range = ubo.fog.range.y;
|
||||
vec3 boundsMin = vec3(-range,-range,-range) + rayOrigin;
|
||||
vec3 boundsMax = vec3(range,range,range) + rayOrigin;
|
||||
int numSteps = int(length(boundsMax - boundsMin) * ubo.fog.stepScale );
|
||||
|
||||
vec2 rayBoxInfo = rayBoxDst( boundsMin, boundsMax, rayOrigin, rayDir );
|
||||
float dstToBox = rayBoxInfo.x;
|
||||
float dstInsideBox = rayBoxInfo.y;
|
||||
float depth = position.eye.z;
|
||||
|
||||
float lightEnergy = 0;
|
||||
// march
|
||||
if ( 0 <= dstInsideBox && dstToBox <= depth ) {
|
||||
float dstTravelled = 0;
|
||||
float stepSize = dstInsideBox / numSteps;
|
||||
float dstLimit = min( depth - dstToBox, dstInsideBox );
|
||||
float totalDensity = 0;
|
||||
float transmittance = 1;
|
||||
while ( dstTravelled < dstLimit ) {
|
||||
vec3 rayPos = rayOrigin + rayDir * (dstToBox + dstTravelled);
|
||||
float density = sampleDensity(rayPos);
|
||||
if ( density > 0 ) {
|
||||
transmittance *= exp(-density * stepSize * ubo.fog.absorbtion);
|
||||
if ( transmittance < 0.01 ) break;
|
||||
}
|
||||
dstTravelled += stepSize;
|
||||
}
|
||||
i.rgb = mix(ubo.fog.color.rgb, i.rgb, transmittance);
|
||||
}
|
||||
|
||||
vec3 color = ubo.fog.color.rgb;
|
||||
float inner = ubo.fog.range.x;
|
||||
float outer = ubo.fog.range.y * scale;
|
||||
float distance = length(-position.eye);
|
||||
float factor = (distance - inner) / (outer - inner);
|
||||
factor = clamp( factor, 0.0, 1.0 );
|
||||
|
||||
i.rgb = mix(i.rgb, color, factor);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 albedoMetallic = subpassLoad(samplerAlbedoMetallic);
|
||||
vec4 normalRoughness = subpassLoad(samplerNormalRoughness);
|
||||
// vec4 positionAO = subpassLoad(samplerPositionAO);
|
||||
|
||||
normal.eye = normalRoughness.rgb;
|
||||
{
|
||||
mat4 iProj = inverse( ubo.matrices.projection[inPushConstantPass] );
|
||||
mat4 iView = inverse( ubo.matrices.view[inPushConstantPass] );
|
||||
float depth = subpassLoad(samplerDepth).r;
|
||||
|
||||
vec4 positionClip = vec4(inUv * 2.0 - 1.0, depth, 1.0);
|
||||
vec4 positionEye = iProj * positionClip;
|
||||
positionEye /= positionEye.w;
|
||||
position.eye = positionEye.xyz;
|
||||
|
||||
vec4 positionWorld = iView * positionEye;
|
||||
position.world = positionWorld.xyz;
|
||||
}
|
||||
|
||||
bool usePbr = true;
|
||||
bool gammaCorrect = false;
|
||||
float litFactor = 1.0;
|
||||
float ao = 1; // positionAO.a;
|
||||
vec3 fragColor = albedoMetallic.rgb * ubo.ambient.rgb * ao;
|
||||
for ( uint i = 0; i < LIGHTS; ++i ) {
|
||||
Light light = ubo.lights[i];
|
||||
|
||||
if ( light.power <= 0.001 ) continue;
|
||||
vec3 lightPositionWorld = light.position.xyz;
|
||||
light.position.xyz = vec3(ubo.matrices.view[inPushConstantPass] * vec4(light.position.xyz, 1));
|
||||
if ( light.type < 0 ) {
|
||||
float factor = shadowFactor( light, i );
|
||||
if ( factor <= 0.0001 ) continue;
|
||||
light.power *= factor;
|
||||
litFactor += light.power;
|
||||
}
|
||||
if ( usePbr ) {
|
||||
pbr( light, albedoMetallic.rgb, albedoMetallic.a, normalRoughness.a, lightPositionWorld, fragColor );
|
||||
} else
|
||||
phong( light, albedoMetallic, fragColor );
|
||||
}
|
||||
|
||||
if ( gammaCorrect ) {
|
||||
fragColor = fragColor / (fragColor + vec3(1.0));
|
||||
fragColor = pow(fragColor, vec3(1.0/2.2));
|
||||
}
|
||||
|
||||
fog(fragColor, litFactor);
|
||||
|
||||
/*
|
||||
if ( (ubo.mode.type & (0x1 << 0)) == (0x1 << 0) ) {
|
||||
//dither1(fragColor);
|
||||
fragColor += dither2();
|
||||
}
|
||||
if ( (ubo.mode.type & (0x1 << 1)) == (0x1 << 1) ) {
|
||||
whitenoise(fragColor);
|
||||
}
|
||||
*/
|
||||
outFragColor = vec4(fragColor,1);
|
||||
}
|
||||
24
bin/data/shaders/display/subpass.vert.glsl
Normal file
@ -0,0 +1,24 @@
|
||||
#version 450
|
||||
|
||||
layout (location = 0) in vec2 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
|
||||
layout (location = 0) out vec2 outUv;
|
||||
layout (location = 1) out flat uint outPushConstantPass;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
|
||||
void main() {
|
||||
outUv = inUv;
|
||||
outPushConstantPass = PushConstant.pass;
|
||||
|
||||
gl_Position = vec4(inPos.xy, 0.0, 1.0);
|
||||
}
|
||||
17
bin/data/shaders/display/vert.glsl
Normal file
@ -0,0 +1,17 @@
|
||||
#version 450
|
||||
|
||||
layout (location = 0) in vec2 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
|
||||
layout (location = 0) out vec2 outUv;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
|
||||
void main() {
|
||||
outUv = inUv;
|
||||
|
||||
gl_Position = vec4(inPos.xy, 0.0, 1.0);
|
||||
}
|
||||
138
bin/data/shaders/gltf/frag.glsl
Normal file
@ -0,0 +1,138 @@
|
||||
#version 450
|
||||
|
||||
#define UF_DEFERRED_SAMPLING 0
|
||||
#define UF_CAN_DISCARD 1
|
||||
|
||||
layout (constant_id = 0) const uint TEXTURES = 1;
|
||||
layout (binding = 0) uniform sampler2D samplerTextures[TEXTURES];
|
||||
|
||||
struct Material {
|
||||
vec4 colorBase;
|
||||
vec4 colorEmissive;
|
||||
|
||||
float factorMetallic;
|
||||
float factorRoughness;
|
||||
float factorOcclusion;
|
||||
float factorAlphaCutoff;
|
||||
|
||||
int indexAlbedo;
|
||||
int indexNormal;
|
||||
int indexEmissive;
|
||||
int indexOcclusion;
|
||||
|
||||
int indexMetallicRoughness;
|
||||
int modeAlpha;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
struct Texture {
|
||||
int index;
|
||||
int samp;
|
||||
int remap;
|
||||
float blend;
|
||||
|
||||
vec4 lerp;
|
||||
};
|
||||
layout (std140, binding = 1) readonly buffer Materials {
|
||||
Material materials[];
|
||||
};
|
||||
layout (std140, binding = 2) readonly buffer Textures {
|
||||
Texture textures[];
|
||||
};
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) in vec4 inColor;
|
||||
layout (location = 2) in vec3 inNormal;
|
||||
layout (location = 3) in mat3 inTBN;
|
||||
layout (location = 6) in vec3 inPosition;
|
||||
layout (location = 7) flat in ivec4 inId;
|
||||
|
||||
layout (location = 0) out uvec2 outId;
|
||||
layout (location = 1) out vec2 outNormals;
|
||||
#if UF_DEFERRED_SAMPLING
|
||||
layout (location = 2) out vec2 outUvs;
|
||||
#else
|
||||
layout (location = 2) out vec4 outAlbedo;
|
||||
#endif
|
||||
|
||||
vec2 encodeNormals( vec3 n ) {
|
||||
float p = sqrt(n.z*8+8);
|
||||
return n.xy/p + 0.5;
|
||||
}
|
||||
|
||||
float wrap( float i ) {
|
||||
return fract(i);
|
||||
}
|
||||
vec2 wrap( vec2 uv ) {
|
||||
return vec2( wrap( uv.x ), wrap( uv.y ) );
|
||||
}
|
||||
float mipLevel( in vec2 uv ) {
|
||||
vec2 dx_vtc = dFdx(uv);
|
||||
vec2 dy_vtc = dFdy(uv);
|
||||
return 0.5 * log2(max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc)));
|
||||
}
|
||||
bool validTextureIndex( int textureIndex ) {
|
||||
return 0 <= textureIndex && textureIndex < TEXTURES;
|
||||
}
|
||||
void main() {
|
||||
float mip = mipLevel(inUv.xy);
|
||||
vec2 uv = wrap(inUv.xy);
|
||||
vec4 C = vec4(0, 0, 0, 0);
|
||||
vec3 P = inPosition;
|
||||
vec3 N = inNormal;
|
||||
#if UF_DEFERRED_SAMPLING
|
||||
outUvs = wrap(inUv.xy);
|
||||
vec4 outAlbedo = vec4(0,0,0,0);
|
||||
#endif
|
||||
#if !UF_DEFERRED_SAMPLING || UF_CAN_DISCARD
|
||||
int materialId = int(inId.y);
|
||||
Material material = materials[materialId];
|
||||
|
||||
float M = material.factorMetallic;
|
||||
float R = material.factorRoughness;
|
||||
float AO = material.factorOcclusion;
|
||||
|
||||
// sample albedo
|
||||
if ( !validTextureIndex( material.indexAlbedo ) ) discard; {
|
||||
Texture t = textures[material.indexAlbedo + 1];
|
||||
C = textureLod( samplerTextures[0], mix( t.lerp.xy, t.lerp.zw, uv ), mip );
|
||||
// alpha mode OPAQUE
|
||||
if ( material.modeAlpha == 0 ) {
|
||||
C.a = 1;
|
||||
// alpha mode BLEND
|
||||
} else if ( material.modeAlpha == 1 ) {
|
||||
|
||||
// alpha mode MASK
|
||||
} else if ( material.modeAlpha == 2 ) {
|
||||
if ( C.a < abs(material.factorAlphaCutoff) ) discard;
|
||||
C.a = 1;
|
||||
}
|
||||
if ( C.a == 0 ) discard;
|
||||
}
|
||||
#endif
|
||||
#if !UF_DEFERRED_SAMPLING
|
||||
// sample normal
|
||||
if ( validTextureIndex( material.indexNormal ) ) {
|
||||
Texture t = textures[material.indexNormal + 1];
|
||||
N = inTBN * normalize( textureLod( samplerTextures[0], mix( t.lerp.xy, t.lerp.zw, uv ), mip ).xyz * 2.0 - vec3(1.0));
|
||||
}
|
||||
#if 0
|
||||
// sample metallic/roughness
|
||||
if ( validTextureIndex( material.indexMetallicRoughness ) ) {
|
||||
Texture t = textures[material.indexMetallicRoughness + 1];
|
||||
vec4 sampled = texture( samplerTextures[0], mix( t.lerp.xy, t.lerp.zw, uv ), mip );
|
||||
M = sampled.b;
|
||||
R = sampled.g;
|
||||
}
|
||||
// sample ao
|
||||
AO = material.factorOcclusion;
|
||||
if ( validTextureIndex( material.indexOcclusion ) ) {
|
||||
Texture t = textures[material.indexMetallicRoughness + 1];
|
||||
AO = texture( samplerTextures[0], mix( t.lerp.xy, t.lerp.zw, uv ) ).r;
|
||||
}
|
||||
#endif
|
||||
outAlbedo = C * inColor;
|
||||
#endif
|
||||
outNormals = encodeNormals( N );
|
||||
outId = ivec2(inId.w+1, inId.y+1);
|
||||
}
|
||||
62
bin/data/shaders/gltf/instanced.vert.glsl
Normal file
@ -0,0 +1,62 @@
|
||||
#version 450
|
||||
|
||||
layout (constant_id = 0) const uint PASSES = 6;
|
||||
layout (location = 0) in vec3 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
layout (location = 2) in vec3 inNormal;
|
||||
layout (location = 3) in vec4 inTangent;
|
||||
layout (location = 4) in ivec2 inId;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
layout (binding = 3) uniform UBO {
|
||||
mat4 view[PASSES];
|
||||
mat4 projection[PASSES];
|
||||
} ubo;
|
||||
|
||||
layout (std140, binding = 4) readonly buffer Models {
|
||||
mat4 models[];
|
||||
};
|
||||
|
||||
layout (location = 0) out vec2 outUv;
|
||||
layout (location = 1) out vec4 outColor;
|
||||
layout (location = 2) out vec3 outNormal;
|
||||
layout (location = 3) out mat3 outTBN;
|
||||
layout (location = 6) out vec3 outPosition;
|
||||
layout (location = 7) out ivec4 outId;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
vec4 snap(vec4 vertex, vec2 resolution) {
|
||||
vec4 snappedPos = vertex;
|
||||
snappedPos.xyz = vertex.xyz / vertex.w;
|
||||
snappedPos.xy = floor(resolution * snappedPos.xy) / resolution;
|
||||
snappedPos.xyz *= vertex.w;
|
||||
return snappedPos;
|
||||
}
|
||||
|
||||
void main() {
|
||||
outUv = inUv;
|
||||
outColor = vec4(1.0);
|
||||
outId = ivec4(inId, PushConstant.pass, PushConstant.draw);
|
||||
|
||||
mat4 model = models.length() <= 0 ? mat4(1.0) : models[int(inId.x)];
|
||||
outPosition = vec3(ubo.view[PushConstant.pass] * model * vec4(inPos.xyz, 1.0));
|
||||
outNormal = vec3(ubo.view[PushConstant.pass] * model * vec4(inNormal.xyz, 0.0));
|
||||
outNormal = normalize(outNormal);
|
||||
|
||||
{
|
||||
vec3 T = vec3(ubo.view[PushConstant.pass] * model * vec4(inTangent.xyz, 0.0));
|
||||
vec3 N = outNormal;
|
||||
vec3 B = cross(N, T) * inTangent.w;
|
||||
outTBN = mat3( T, B, N );
|
||||
}
|
||||
|
||||
gl_Position = ubo.projection[PushConstant.pass] * ubo.view[PushConstant.pass] * model * vec4(inPos.xyz, 1.0);
|
||||
// gl_Position = snap( gl_Position, vec2(256.0, 224.0) );
|
||||
}
|
||||
74
bin/data/shaders/gltf/skinned.instanced.vert.glsl
Normal file
@ -0,0 +1,74 @@
|
||||
#version 450
|
||||
|
||||
layout (constant_id = 0) const uint PASSES = 6;
|
||||
layout (location = 0) in vec3 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
layout (location = 2) in vec3 inNormal;
|
||||
layout (location = 3) in vec4 inTangent;
|
||||
layout (location = 4) in ivec2 inId;
|
||||
layout (location = 5) in ivec4 inJoints;
|
||||
layout (location = 6) in vec4 inWeights;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
layout (binding = 3) uniform UBO {
|
||||
mat4 view[PASSES];
|
||||
mat4 projection[PASSES];
|
||||
} ubo;
|
||||
|
||||
layout (std140, binding = 4) readonly buffer Models {
|
||||
mat4 models[];
|
||||
};
|
||||
|
||||
layout (std140, binding = 5) readonly buffer Joints {
|
||||
mat4 joints[];
|
||||
};
|
||||
|
||||
layout (location = 0) out vec2 outUv;
|
||||
layout (location = 1) out vec4 outColor;
|
||||
layout (location = 2) out vec3 outNormal;
|
||||
layout (location = 3) out mat3 outTBN;
|
||||
layout (location = 6) out vec3 outPosition;
|
||||
layout (location = 7) out ivec4 outId;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
vec4 snap(vec4 vertex, vec2 resolution) {
|
||||
vec4 snappedPos = vertex;
|
||||
snappedPos.xyz = vertex.xyz / vertex.w;
|
||||
snappedPos.xy = floor(resolution * snappedPos.xy) / resolution;
|
||||
snappedPos.xyz *= vertex.w;
|
||||
return snappedPos;
|
||||
}
|
||||
|
||||
void main() {
|
||||
outUv = inUv;
|
||||
outColor = vec4(1.0);
|
||||
outId = ivec4(inId, PushConstant.pass, PushConstant.draw);
|
||||
|
||||
mat4 model = models.length() <= 0 ? mat4(1.0) : models[int(inId.x)];
|
||||
mat4 skinnedMatrix = joints.length() <= 0 ? mat4(1.0) :
|
||||
inWeights.x * joints[int(inJoints.x)] +
|
||||
inWeights.y * joints[int(inJoints.y)] +
|
||||
inWeights.z * joints[int(inJoints.z)] +
|
||||
inWeights.w * joints[int(inJoints.w)];
|
||||
|
||||
outPosition = vec3(ubo.view[PushConstant.pass] * model * skinnedMatrix * vec4(inPos.xyz, 1.0));
|
||||
outNormal = vec3(ubo.view[PushConstant.pass] * model * vec4(inNormal.xyz, 0.0));
|
||||
outNormal = normalize(outNormal);
|
||||
|
||||
|
||||
{
|
||||
vec3 T = vec3(ubo.view[PushConstant.pass] * model * vec4(inTangent.xyz, 0.0));
|
||||
vec3 N = outNormal;
|
||||
vec3 B = cross(N, T) * inTangent.w;
|
||||
outTBN = mat3( T, B, N );
|
||||
}
|
||||
|
||||
gl_Position = ubo.projection[PushConstant.pass] * ubo.view[PushConstant.pass] * model * skinnedMatrix * vec4(inPos.xyz, 1.0);
|
||||
}
|
||||
78
bin/data/shaders/gltf/skinned.vert.glsl
Normal file
@ -0,0 +1,78 @@
|
||||
#version 450
|
||||
|
||||
layout (constant_id = 0) const uint PASSES = 6;
|
||||
layout (location = 0) in vec3 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
layout (location = 2) in vec3 inNormal;
|
||||
layout (location = 3) in vec4 inTangent;
|
||||
layout (location = 4) in ivec2 inId;
|
||||
layout (location = 5) in ivec4 inJoints;
|
||||
layout (location = 6) in vec4 inWeights;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
struct Matrices {
|
||||
mat4 model;
|
||||
mat4 view[PASSES];
|
||||
mat4 projection[PASSES];
|
||||
};
|
||||
layout (binding = 3) uniform UBO {
|
||||
Matrices matrices;
|
||||
vec4 color;
|
||||
} ubo;
|
||||
|
||||
layout (std140, binding = 4) readonly buffer Joints {
|
||||
mat4 joints[];
|
||||
};
|
||||
|
||||
|
||||
layout (location = 0) out vec2 outUv;
|
||||
layout (location = 1) out vec4 outColor;
|
||||
layout (location = 2) out vec3 outNormal;
|
||||
layout (location = 3) out mat3 outTBN;
|
||||
layout (location = 6) out vec3 outPosition;
|
||||
layout (location = 7) out ivec4 outId;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
vec4 snap(vec4 vertex, vec2 resolution) {
|
||||
vec4 snappedPos = vertex;
|
||||
snappedPos.xyz = vertex.xyz / vertex.w;
|
||||
snappedPos.xy = floor(resolution * snappedPos.xy) / resolution;
|
||||
snappedPos.xyz *= vertex.w;
|
||||
return snappedPos;
|
||||
}
|
||||
|
||||
void main() {
|
||||
outUv = inUv;
|
||||
outColor = ubo.color;
|
||||
outId = ivec4(inId, PushConstant.pass, PushConstant.draw);
|
||||
|
||||
mat4 skinnedMatrix = joints.length() <= 0 ? mat4(1.0) :
|
||||
inWeights.x * joints[int(inJoints.x)] +
|
||||
inWeights.y * joints[int(inJoints.y)] +
|
||||
inWeights.z * joints[int(inJoints.z)] +
|
||||
inWeights.w * joints[int(inJoints.w)];
|
||||
|
||||
outPosition = vec3(ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * skinnedMatrix * vec4(inPos.xyz, 1.0));
|
||||
outNormal = vec3(ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inNormal.xyz, 0.0));
|
||||
outNormal = normalize(outNormal);
|
||||
|
||||
|
||||
{
|
||||
vec3 T = vec3(ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inTangent.xyz, 0.0));
|
||||
vec3 N = outNormal;
|
||||
vec3 B = cross(N, T) * inTangent.w;
|
||||
outTBN = mat3( T, B, N );
|
||||
}
|
||||
|
||||
gl_Position = ubo.matrices.projection[PushConstant.pass] * ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * skinnedMatrix * vec4(inPos.xyz, 1.0);
|
||||
// gl_Position = snap( gl_Position, vec2(320.0, 240.0) );
|
||||
// gl_Position = snap( gl_Position, vec2(480.0, 270.0) );
|
||||
// gl_Position = snap( gl_Position, vec2(640.0, 480.0) );
|
||||
}
|
||||
64
bin/data/shaders/gltf/vert.glsl
Normal file
@ -0,0 +1,64 @@
|
||||
#version 450
|
||||
|
||||
layout (constant_id = 0) const uint PASSES = 6;
|
||||
layout (location = 0) in vec3 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
layout (location = 2) in vec3 inNormal;
|
||||
layout (location = 3) in vec4 inTangent;
|
||||
layout (location = 4) in ivec2 inId;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
struct Matrices {
|
||||
mat4 model;
|
||||
mat4 view[PASSES];
|
||||
mat4 projection[PASSES];
|
||||
};
|
||||
|
||||
layout (binding = 3) uniform UBO {
|
||||
Matrices matrices;
|
||||
vec4 color;
|
||||
} ubo;
|
||||
|
||||
layout (location = 0) out vec2 outUv;
|
||||
layout (location = 1) out vec4 outColor;
|
||||
layout (location = 2) out vec3 outNormal;
|
||||
layout (location = 3) out mat3 outTBN;
|
||||
layout (location = 6) out vec3 outPosition;
|
||||
layout (location = 7) out ivec4 outId;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
vec4 snap(vec4 vertex, vec2 resolution) {
|
||||
vec4 snappedPos = vertex;
|
||||
snappedPos.xyz = vertex.xyz / vertex.w;
|
||||
snappedPos.xy = floor(resolution * snappedPos.xy) / resolution;
|
||||
snappedPos.xyz *= vertex.w;
|
||||
return snappedPos;
|
||||
}
|
||||
|
||||
void main() {
|
||||
outUv = inUv;
|
||||
outColor = ubo.color;
|
||||
outId = ivec4(inId, PushConstant.pass, PushConstant.draw);
|
||||
|
||||
outPosition = vec3(ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inPos.xyz, 1.0));
|
||||
outNormal = vec3(ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inNormal.xyz, 0.0));
|
||||
outNormal = normalize(outNormal);
|
||||
|
||||
|
||||
{
|
||||
vec3 T = vec3(ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inTangent.xyz, 0.0));
|
||||
vec3 N = outNormal;
|
||||
vec3 B = cross(N, T) * inTangent.w;
|
||||
outTBN = mat3( T, B, N );
|
||||
}
|
||||
|
||||
gl_Position = ubo.matrices.projection[PushConstant.pass] * ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inPos.xyz, 1.0);
|
||||
// gl_Position = snap( gl_Position, vec2(320.0, 240.0) );
|
||||
}
|
||||
66
bin/data/shaders/gui/frag.glsl
Normal file
@ -0,0 +1,66 @@
|
||||
#version 450
|
||||
|
||||
#define UF_DEFERRED_SAMPLING 0
|
||||
#define UF_CAN_DISCARD 1
|
||||
|
||||
layout (binding = 1) uniform sampler2D samplerTexture;
|
||||
|
||||
struct Gui {
|
||||
vec4 offset;
|
||||
vec4 color;
|
||||
int mode;
|
||||
float depth;
|
||||
vec2 padding;
|
||||
};
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) in flat Gui inGui;
|
||||
|
||||
layout (location = 0) out uvec2 outId;
|
||||
layout (location = 1) out vec2 outNormals;
|
||||
#if UF_DEFERRED_SAMPLING
|
||||
layout (location = 2) out vec2 outUvs;
|
||||
#else
|
||||
layout (location = 2) out vec4 outAlbedo;
|
||||
#endif
|
||||
|
||||
vec2 encodeNormals( vec3 n ) {
|
||||
float p = sqrt(n.z*8+8);
|
||||
return n.xy/p + 0.5;
|
||||
}
|
||||
float mipLevel( in vec2 uv ) {
|
||||
vec2 dx_vtc = dFdx(uv);
|
||||
vec2 dy_vtc = dFdy(uv);
|
||||
return 0.5 * log2(max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc)));
|
||||
}
|
||||
|
||||
void main() {
|
||||
if ( inUv.x < inGui.offset.x ) discard;
|
||||
if ( inUv.y < inGui.offset.y ) discard;
|
||||
if ( inUv.x > inGui.offset.z ) discard;
|
||||
if ( inUv.y > inGui.offset.w ) discard;
|
||||
|
||||
float mip = mipLevel(inUv.xy);
|
||||
vec2 uv = inUv.xy;
|
||||
vec4 C = vec4(1, 1, 1, 1);
|
||||
//vec3 N = inNormal;
|
||||
#if UF_DEFERRED_SAMPLING
|
||||
outUvs = wrap(inUv.xy);
|
||||
vec4 outAlbedo = vec4(0,0,0,0);
|
||||
#endif
|
||||
#if !UF_DEFERRED_SAMPLING || UF_CAN_DISCARD
|
||||
C = textureLod( samplerTexture, uv, mip );
|
||||
#endif
|
||||
#if !UF_DEFERRED_SAMPLING
|
||||
if ( inGui.mode == 1 ) {
|
||||
C = inGui.color;
|
||||
} else {
|
||||
C *= inGui.color;
|
||||
}
|
||||
outAlbedo = C;
|
||||
#endif
|
||||
/*
|
||||
outNormals = encodeNormals( N );
|
||||
outId = ivec2(0, 0);
|
||||
*/
|
||||
}
|
||||
62
bin/data/shaders/gui/text.frag.glsl
Normal file
@ -0,0 +1,62 @@
|
||||
#version 450
|
||||
|
||||
#define UF_DEFERRED_SAMPLING 0
|
||||
#define UF_CAN_DISCARD 1
|
||||
|
||||
layout (binding = 1) uniform sampler2D samplerTexture;
|
||||
|
||||
struct Gui {
|
||||
vec4 offset;
|
||||
vec4 color;
|
||||
int mode;
|
||||
float depth;
|
||||
int sdf;
|
||||
int shadowbox;
|
||||
vec4 stroke;
|
||||
float weight;
|
||||
int spread;
|
||||
float scale;
|
||||
float padding;
|
||||
};
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) in flat Gui inGui;
|
||||
|
||||
layout (location = 0) out uvec2 outId;
|
||||
layout (location = 1) out vec2 outNormals;
|
||||
#if UF_DEFERRED_SAMPLING
|
||||
layout (location = 2) out vec2 outUvs;
|
||||
#else
|
||||
layout (location = 2) out vec4 outAlbedo;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
if ( inUv.x < inGui.offset.x ) discard;
|
||||
if ( inUv.y < inGui.offset.y ) discard;
|
||||
if ( inUv.x > inGui.offset.z ) discard;
|
||||
if ( inUv.y > inGui.offset.w ) discard;
|
||||
|
||||
#if UF_DEFERRED_SAMPLING
|
||||
vec4 outAlbedo = vec4(0,0,0,0);
|
||||
#endif
|
||||
|
||||
if ( inGui.shadowbox == 1 ) {
|
||||
outAlbedo = inGui.color;
|
||||
return;
|
||||
}
|
||||
float dist = texture(samplerTexture, inUv).r;
|
||||
if ( inGui.sdf == 1 ) {
|
||||
float smoothing = ( inGui.spread > 0 && inGui.scale > 0 ) ? 0.25 / (inGui.spread * inGui.scale) : 0.25 / (4 * 1.5);
|
||||
float outlining = smoothstep(0.5 - smoothing, 0.5 + smoothing, dist);
|
||||
float alpha = smoothstep(inGui.weight - smoothing, inGui.weight + smoothing, dist);
|
||||
vec4 c = inGui.color;
|
||||
outAlbedo = mix(inGui.stroke, c, outlining);
|
||||
outAlbedo.a = inGui.color.a * alpha;
|
||||
if ( alpha < 0.001 ) discard;
|
||||
if ( alpha > 1 ) discard;
|
||||
} else {
|
||||
outAlbedo = vec4(inGui.color) * dist;
|
||||
if ( dist < 0.001 ) discard;
|
||||
if ( dist > 1 ) discard;
|
||||
}
|
||||
}
|
||||
47
bin/data/shaders/gui/text.vert.glsl
Normal file
@ -0,0 +1,47 @@
|
||||
#version 450
|
||||
|
||||
layout (constant_id = 0) const uint PASSES = 6;
|
||||
layout (location = 0) in vec2 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
struct Matrices {
|
||||
mat4 model[PASSES];
|
||||
};
|
||||
struct Gui {
|
||||
vec4 offset;
|
||||
vec4 color;
|
||||
int mode;
|
||||
float depth;
|
||||
int sdf;
|
||||
int shadowbox;
|
||||
vec4 stroke;
|
||||
float weight;
|
||||
int spread;
|
||||
float scale;
|
||||
float padding;
|
||||
};
|
||||
|
||||
layout (binding = 0) uniform UBO {
|
||||
Matrices matrices;
|
||||
Gui gui;
|
||||
} ubo;
|
||||
|
||||
layout (location = 0) out vec2 outUv;
|
||||
layout (location = 1) out flat Gui outGui;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
|
||||
void main() {
|
||||
outUv = inUv;
|
||||
outGui = ubo.gui;
|
||||
|
||||
gl_Position = ubo.matrices.model[PushConstant.pass] * vec4(inPos.xy, ubo.gui.depth, 1.0);
|
||||
}
|
||||
41
bin/data/shaders/gui/vert.glsl
Normal file
@ -0,0 +1,41 @@
|
||||
#version 450
|
||||
|
||||
layout (constant_id = 0) const uint PASSES = 6;
|
||||
layout (location = 0) in vec2 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
struct Matrices {
|
||||
mat4 model[PASSES];
|
||||
};
|
||||
struct Gui {
|
||||
vec4 offset;
|
||||
vec4 color;
|
||||
int mode;
|
||||
float depth;
|
||||
vec2 padding;
|
||||
};
|
||||
|
||||
layout (binding = 0) uniform UBO {
|
||||
Matrices matrices;
|
||||
Gui gui;
|
||||
} ubo;
|
||||
|
||||
layout (location = 0) out vec2 outUv;
|
||||
layout (location = 1) out flat Gui outGui;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
|
||||
void main() {
|
||||
outUv = inUv;
|
||||
outGui = ubo.gui;
|
||||
|
||||
gl_Position = ubo.matrices.model[PushConstant.pass] * vec4(inPos.xy, ubo.gui.depth, 1.0);
|
||||
}
|
||||
19
bin/data/shaders/heightmap/frag.glsl
Normal file
@ -0,0 +1,19 @@
|
||||
#version 450
|
||||
|
||||
layout (binding = 1) uniform sampler2D samplerColor;
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) in vec3 inNormal;
|
||||
layout (location = 2) in vec4 inColor;
|
||||
|
||||
layout (location = 0) out vec4 outAlbedoSpecular;
|
||||
layout (location = 1) out vec4 outNormal;
|
||||
|
||||
void main() {
|
||||
outAlbedoSpecular = texture(samplerColor, inUv);
|
||||
outAlbedoSpecular = vec4(1,1,1,1);
|
||||
outAlbedoSpecular.rgb *= inColor.rgb;
|
||||
outAlbedoSpecular.a = 1;
|
||||
// outPosition = vec4(inPosition, 1.0);
|
||||
outNormal = vec4(normalize(inNormal), 1.0);
|
||||
}
|
||||
52
bin/data/shaders/heightmap/vert.glsl
Normal file
@ -0,0 +1,52 @@
|
||||
#version 450
|
||||
|
||||
layout (constant_id = 0) const uint PASSES = 6;
|
||||
layout (location = 0) in vec3 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
layout (location = 2) in vec3 inNormal;
|
||||
layout (location = 3) in uint inColor;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
struct Matrices {
|
||||
mat4 model;
|
||||
mat4 view[PASSES];
|
||||
mat4 projection[PASSES];
|
||||
};
|
||||
|
||||
layout (binding = 0) uniform UBO {
|
||||
Matrices matrices;
|
||||
vec4 color;
|
||||
} ubo;
|
||||
|
||||
layout (location = 0) out vec2 outUv;
|
||||
layout (location = 1) out vec3 outNormal;
|
||||
layout (location = 2) out vec4 outColor;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
|
||||
void main() {
|
||||
outUv = inUv;
|
||||
// outColor = ubo.color;
|
||||
|
||||
// outPosition = vec3(ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inPos.xyz, 1.0));
|
||||
outNormal = vec3(ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inNormal.xyz, 0.0));
|
||||
|
||||
// outPosition = vec3(ubo.matrices.model * vec4(inPos.xyz, 1.0));
|
||||
// outNormal = vec3(ubo.matrices.model * vec4(inNormal.xyz, 0.0));
|
||||
|
||||
outColor.a = (inColor >> 24u) & 0xFF;
|
||||
outColor.b = (inColor >> 16u) & 0xFF;
|
||||
outColor.g = (inColor >> 8u) & 0xFF;
|
||||
outColor.r = (inColor ) & 0xFF;
|
||||
outColor.rgb /= 256.0;
|
||||
outColor.a = 0.5;
|
||||
|
||||
gl_Position = ubo.matrices.projection[PushConstant.pass] * ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inPos.xyz, 1.0);
|
||||
}
|
||||
10
bin/data/shaders/line/frag.glsl
Normal file
@ -0,0 +1,10 @@
|
||||
#version 450
|
||||
|
||||
layout (location = 0) in vec3 inColor;
|
||||
|
||||
layout (location = 0) out vec4 outAlbedoSpecular;
|
||||
|
||||
void main() {
|
||||
outAlbedoSpecular.rgb *= inColor.rgb;
|
||||
outAlbedoSpecular.a = 1;
|
||||
}
|
||||
35
bin/data/shaders/line/vert.glsl
Normal file
@ -0,0 +1,35 @@
|
||||
#version 450
|
||||
|
||||
layout (constant_id = 0) const uint PASSES = 6;
|
||||
layout (location = 0) in vec3 inPos;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
struct Matrices {
|
||||
mat4 model;
|
||||
mat4 view[PASSES];
|
||||
mat4 projection[PASSES];
|
||||
};
|
||||
|
||||
layout (binding = 0) uniform UBO {
|
||||
Matrices matrices;
|
||||
vec4 color;
|
||||
} ubo;
|
||||
|
||||
layout (location = 0) out vec4 outColor;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
|
||||
void main() {
|
||||
outColor = ubo.color;
|
||||
|
||||
// outPosition = vec3(ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inPos.xyz, 1.0));
|
||||
|
||||
gl_Position = ubo.matrices.projection[PushConstant.pass] * ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inPos.xyz, 1.0);
|
||||
}
|
||||
23
bin/data/shaders/noise/frag.glsl
Normal file
@ -0,0 +1,23 @@
|
||||
#version 450
|
||||
|
||||
layout (binding = 1) uniform sampler3D samplerColor;
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) in vec4 inColor;
|
||||
layout (location = 2) in vec3 inNormal;
|
||||
layout (location = 3) in vec3 inPosition;
|
||||
|
||||
layout (location = 0) out vec4 outAlbedoSpecular;
|
||||
layout (location = 1) out vec4 outNormal;
|
||||
layout (location = 2) out vec4 outPosition;
|
||||
|
||||
layout (binding = 2) uniform UBO {
|
||||
float slice;
|
||||
} ubo;
|
||||
|
||||
void main() {
|
||||
outAlbedoSpecular.rgb = vec3(texture(samplerColor, vec3(inUv,ubo.slice)).r);
|
||||
outAlbedoSpecular.a = 1;
|
||||
outNormal = vec4(inNormal,1);
|
||||
outPosition = vec4(inPosition,1);
|
||||
}
|
||||
295
bin/data/shaders/raytracing/comp.glsl
Normal file
@ -0,0 +1,295 @@
|
||||
#version 450
|
||||
|
||||
layout (local_size_x = 32, local_size_y = 32) in;
|
||||
|
||||
layout (constant_id = 0) const uint LIGHTS = 16;
|
||||
layout (constant_id = 1) const uint EYES = 2;
|
||||
layout (binding = 0, rgba8) uniform writeonly image2D resultImage[EYES];
|
||||
|
||||
#define EPSILON 0.0001
|
||||
#define MAXLEN 1000.0
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint marchingSteps;
|
||||
uint rayBounces;
|
||||
float shadowFactor;
|
||||
float reflectionStrength;
|
||||
float reflectionFalloff;
|
||||
} PushConstant;
|
||||
|
||||
struct Ray {
|
||||
vec3 origin;
|
||||
vec3 direction;
|
||||
};
|
||||
struct Result {
|
||||
vec3 color;
|
||||
float t;
|
||||
int id;
|
||||
};
|
||||
struct Light {
|
||||
vec3 position;
|
||||
float radius;
|
||||
vec3 color;
|
||||
float power;
|
||||
vec2 type;
|
||||
vec2 padding;
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
};
|
||||
|
||||
struct State {
|
||||
vec3 viewPosition;
|
||||
Ray ray;
|
||||
Result result;
|
||||
} state;
|
||||
|
||||
struct Fog {
|
||||
vec2 range;
|
||||
vec2 padding;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
layout (binding = 1) uniform UBO {
|
||||
mat4 matrices[2];
|
||||
vec4 ambient;
|
||||
Fog fog;
|
||||
Light lights[LIGHTS];
|
||||
} ubo;
|
||||
|
||||
struct Shape {
|
||||
vec4 values;
|
||||
vec4 albedoSpecular;
|
||||
int type;
|
||||
};
|
||||
layout (std140, binding = 2) buffer Shapes {
|
||||
Shape shapes[];
|
||||
};
|
||||
|
||||
void reflectRay(inout vec3 rayD, in vec3 normal) {
|
||||
rayD = rayD + 2.0 * -dot(normal, rayD) * normal;
|
||||
}
|
||||
// Lighting =========================================================
|
||||
float lightDiffuse(vec3 normal, vec3 lightDir) {
|
||||
return clamp(dot(normal, lightDir), 0.1, 1.0);
|
||||
}
|
||||
float lightSpecular(vec3 normal, vec3 lightDir, float specularFactor) {
|
||||
vec3 viewVec = normalize(state.viewPosition);
|
||||
vec3 halfVec = normalize(lightDir + viewVec);
|
||||
return pow(clamp(dot(normal, halfVec), 0.0, 1.0), specularFactor);
|
||||
}
|
||||
|
||||
// Sphere ===========================================================
|
||||
float sphereIntersect(in vec3 rayO, in vec3 rayD, in Shape shape ) {
|
||||
vec3 oc = rayO - shape.values.xyz;
|
||||
float b = 2.0 * dot(oc, rayD);
|
||||
float c = dot(oc, oc) - shape.values.w * shape.values.w;
|
||||
float h = b*b - 4.0*c;
|
||||
if (h < 0.0) return -1.0;
|
||||
float t = (-b - sqrt(h)) / 2.0;
|
||||
return t;
|
||||
}
|
||||
vec3 sphereNormal(in vec3 position, in Shape shape) {
|
||||
return (position - shape.values.xyz) / shape.values.w;
|
||||
}
|
||||
float sphereSDF( vec3 position, in Shape shape ) {
|
||||
return length(position - shape.values.xyz) - shape.values.w;
|
||||
}
|
||||
// Plane ===========================================================
|
||||
float planeIntersect(in vec3 rayO, in vec3 rayD, in Shape shape) {
|
||||
float d = dot(rayD, shape.values.xyz);
|
||||
if (d == 0.0) return 0.0;
|
||||
float t = -(shape.values.w + dot(rayO, shape.values.xyz)) / d;
|
||||
return t < 0.0 ? 0.0 : t;
|
||||
}
|
||||
vec3 planeNormal(in vec3 position, in Shape shape) {
|
||||
return shape.values.xyz;
|
||||
}
|
||||
float planeSDF( vec3 position, in Shape shape ) {
|
||||
return dot( position, shape.values.xyz ) + shape.values.w;
|
||||
}
|
||||
// Generic =========================================================
|
||||
float shapeIntersect(in vec3 rayO, in vec3 rayD, in Shape shape) {
|
||||
if ( shape.type == 1 ) return sphereIntersect( rayO, rayD, shape );
|
||||
if ( shape.type == 2 ) return planeIntersect( rayO, rayD, shape );
|
||||
return 0.0;
|
||||
}
|
||||
vec3 shapeNormal( vec3 position, in Shape shape ) {
|
||||
if ( shape.type == 1 ) return sphereNormal(position, shape);
|
||||
if ( shape.type == 2 ) return planeNormal(position, shape);
|
||||
return vec3(0.0);
|
||||
}
|
||||
float shapeSDF( vec3 position, in Shape shape ) {
|
||||
if ( shape.type == 1 ) return sphereSDF(position, shape);
|
||||
if ( shape.type == 2 ) return planeSDF(position, shape);
|
||||
return MAXLEN;
|
||||
}
|
||||
// Intersect =======================================================
|
||||
int intersect(in vec3 rayO, in vec3 rayD, inout float resT) {
|
||||
int id = -1;
|
||||
for (int i = 0; i < shapes.length(); i++) {
|
||||
Shape shape = shapes[i];
|
||||
float tShape = shapeIntersect(rayO, rayD, shape);
|
||||
if ((tShape > EPSILON) && (tShape < resT)) {
|
||||
id = i;
|
||||
resT = tShape;
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
float calcShadow(in vec3 rayO, in vec3 rayD, in int objectID, inout float resT) {
|
||||
for (int i = 0; i < shapes.length(); i++) {
|
||||
if ( i == objectID ) continue;
|
||||
Shape shape = shapes[i];
|
||||
float tShape = shapeIntersect(rayO, rayD, shape);
|
||||
if ((tShape > EPSILON) && (tShape < resT)) {
|
||||
resT = tShape;
|
||||
return PushConstant.shadowFactor;
|
||||
}
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
// Marching ========================================
|
||||
int intersectMarch( in vec3 rayO, in vec3 rayD, inout float resT ) {
|
||||
resT = 0;
|
||||
for (int i = 0; i < PushConstant.marchingSteps; ++i) {
|
||||
vec3 position = resT * rayD + rayO;
|
||||
float tNearest = MAXLEN;
|
||||
int objectID = -1;
|
||||
for ( int j = 0; j < shapes.length(); ++j ) {
|
||||
Shape shape = shapes[j];
|
||||
float tShape = shapeSDF(position, shape);
|
||||
// if ((tShape > EPSILON) && (tShape < tNearest)) {
|
||||
if ( tShape < tNearest ) {
|
||||
objectID = j;
|
||||
tNearest = tShape;
|
||||
}
|
||||
}
|
||||
if (tNearest < EPSILON) {
|
||||
return objectID;
|
||||
}
|
||||
if (resT > MAXLEN) break;
|
||||
resT += tNearest;
|
||||
}
|
||||
resT = MAXLEN;
|
||||
return -1;
|
||||
}
|
||||
float calcShadowMarch( in vec3 rayO, in vec3 rayD, in int objectID, inout float resT ) {
|
||||
float distance = resT;
|
||||
resT = 0;
|
||||
for (int i = 0; i < PushConstant.marchingSteps; ++i) {
|
||||
vec3 position = resT * rayD + rayO;
|
||||
float tNearest = distance;
|
||||
int objectID = -1;
|
||||
for ( int j = 0; j < shapes.length(); ++j ) {
|
||||
if ( j == objectID ) continue;
|
||||
Shape shape = shapes[j];
|
||||
float tShape = shapeSDF(position, shape);
|
||||
// if ((tShape > EPSILON) && (tShape < tNearest)) {
|
||||
if ( tShape < tNearest ) {
|
||||
objectID = j;
|
||||
tNearest = tShape;
|
||||
}
|
||||
}
|
||||
if (tNearest < EPSILON) {
|
||||
return PushConstant.shadowFactor;
|
||||
}
|
||||
if (resT > distance) break;
|
||||
resT += tNearest;
|
||||
}
|
||||
resT = distance;
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
void fog(inout vec3 i, in float t ) {
|
||||
/*
|
||||
vec3 fogColor = ubo.ambient.rgb;
|
||||
i = mix(i, fogColor.rgb, clamp(sqrt(t*t)/20.0, 0.0, 1.0));
|
||||
*/
|
||||
if ( ubo.fog.range.x == 0 || ubo.fog.range.y == 0 ) return;
|
||||
|
||||
vec3 color = ubo.fog.color.rgb;
|
||||
float inner = ubo.fog.range.x, outer = ubo.fog.range.y;
|
||||
float factor = (t - inner) / (outer - inner);
|
||||
factor = clamp( factor, 0.0, 1.0 );
|
||||
|
||||
i = mix(i.rgb, color, factor);
|
||||
}
|
||||
|
||||
Result renderScene(inout vec3 rayO, inout vec3 rayD ) {
|
||||
Result result;
|
||||
result.color = vec3(0.0);
|
||||
result.t = MAXLEN;
|
||||
result.id = PushConstant.marchingSteps > 0 ? intersectMarch(rayO, rayD, result.t) : intersect(rayO, rayD, result.t);
|
||||
if (result.id == -1) return result;
|
||||
|
||||
Shape shape = shapes[result.id];
|
||||
vec3 position = rayO + result.t * rayD;
|
||||
vec3 normal = shapeNormal( position, shape );
|
||||
|
||||
for ( uint i = 0; i < LIGHTS; ++i ) {
|
||||
Light light = ubo.lights[i];
|
||||
if ( light.radius <= EPSILON ) continue;
|
||||
if ( light.power <= EPSILON ) continue;
|
||||
|
||||
vec3 L = light.position - position;
|
||||
float dist = length(L);
|
||||
vec3 D = normalize(L);
|
||||
float attenuation = light.radius / (pow(dist, 2.0) + 1.0);;
|
||||
attenuation = 1;
|
||||
// if ( dist > light.radius ) continue;
|
||||
|
||||
vec4 albedoSpecular = shape.albedoSpecular;
|
||||
|
||||
float d_dot = lightDiffuse(normal, D);
|
||||
float s_factor = lightSpecular(normal, D, albedoSpecular.a);
|
||||
vec3 color = (light.color * albedoSpecular.rgb) * d_dot + s_factor;
|
||||
|
||||
// Shadows
|
||||
float tShadow = dist;
|
||||
float shadowed = 1;
|
||||
if ( PushConstant.shadowFactor < 1.0 )
|
||||
shadowed = PushConstant.marchingSteps > 0 ? calcShadowMarch(position, D, result.id, tShadow) : calcShadow(position, D, result.id, tShadow);
|
||||
result.color += color * light.power * attenuation * shadowed;
|
||||
}
|
||||
|
||||
// Fog
|
||||
// fog(t, result.color);
|
||||
|
||||
// Reflect ray for next render pass
|
||||
reflectRay(rayD, normal);
|
||||
rayO = position;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void main() {
|
||||
for ( int pass = 0; pass < EYES; ++pass ) {
|
||||
{
|
||||
vec2 uv = vec2(gl_GlobalInvocationID.xy) / imageSize(resultImage[pass]);
|
||||
vec4 near4 = ubo.matrices[pass] * (vec4(2.0 * uv - 1.0, -1.0, 1.0));
|
||||
vec4 far4 = ubo.matrices[pass] * (vec4(2.0 * uv - 1.0, 1.0, 1.0));
|
||||
vec3 near3 = near4.xyz / near4.w;
|
||||
vec3 far3 = far4.xyz / far4.w;
|
||||
|
||||
state.viewPosition = near3;
|
||||
state.ray.origin = near3;
|
||||
state.ray.direction = normalize( far3 - near3 );
|
||||
}
|
||||
|
||||
// Basic color path
|
||||
state.result = renderScene(state.ray.origin, state.ray.direction);
|
||||
vec3 finalColor = state.result.color;
|
||||
|
||||
// Reflection
|
||||
float reflectionStrength = PushConstant.reflectionStrength;
|
||||
for (int i = 0; i < PushConstant.rayBounces; i++) {
|
||||
Result result = renderScene(state.ray.origin, state.ray.direction);
|
||||
vec3 reflectionColor = result.color;
|
||||
|
||||
finalColor = (1.0 - reflectionStrength) * finalColor + reflectionStrength * mix(reflectionColor, finalColor, 1.0 - reflectionStrength);
|
||||
reflectionStrength *= PushConstant.reflectionFalloff;
|
||||
}
|
||||
|
||||
imageStore(resultImage[pass], ivec2(gl_GlobalInvocationID.xy), vec4(finalColor, 1.0));
|
||||
}
|
||||
}
|
||||
20
bin/data/shaders/terrain/frag.glsl
Normal file
@ -0,0 +1,20 @@
|
||||
#version 450
|
||||
|
||||
layout (binding = 1) uniform sampler2D samplerColor;
|
||||
|
||||
layout (location = 0) in vec2 inUv;
|
||||
layout (location = 1) in vec4 inColor;
|
||||
layout (location = 2) in vec3 inNormal;
|
||||
layout (location = 3) in vec3 inPosition;
|
||||
|
||||
layout (location = 0) out vec4 outAlbedoSpecular;
|
||||
layout (location = 1) out vec4 outNormal;
|
||||
layout (location = 2) out vec4 outPosition;
|
||||
|
||||
void main() {
|
||||
outAlbedoSpecular = texture(samplerColor, inUv);
|
||||
// outAlbedoSpecular.rgb *= inColor.rgb;
|
||||
outAlbedoSpecular.a = 1;
|
||||
outNormal = vec4(inNormal,1);
|
||||
outPosition = vec4(inPosition,1);
|
||||
}
|
||||
51
bin/data/shaders/terrain/vert.glsl
Normal file
@ -0,0 +1,51 @@
|
||||
#version 450
|
||||
|
||||
layout (constant_id = 0) const uint PASSES = 6;
|
||||
layout (location = 0) in vec3 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
layout (location = 2) in vec3 inNormal;
|
||||
layout (location = 3) in uint inColor;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
struct Matrices {
|
||||
mat4 model;
|
||||
mat4 view[PASSES];
|
||||
mat4 projection[PASSES];
|
||||
};
|
||||
|
||||
layout (binding = 0) uniform UBO {
|
||||
Matrices matrices;
|
||||
vec4 color;
|
||||
} ubo;
|
||||
|
||||
layout (location = 0) out vec2 outUv;
|
||||
layout (location = 1) out vec4 outColor;
|
||||
layout (location = 2) out vec3 outNormal;
|
||||
layout (location = 3) out vec3 outPosition;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
|
||||
void main() {
|
||||
outUv = inUv;
|
||||
// outColor = ubo.color;
|
||||
|
||||
outPosition = vec3(ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inPos.xyz, 1.0));
|
||||
outNormal = vec3(ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inNormal.xyz, 0.0));
|
||||
outNormal = normalize(outNormal);
|
||||
|
||||
outColor.a = (inColor >> 24u) & 0xFF;
|
||||
outColor.b = (inColor >> 16u) & 0xFF;
|
||||
outColor.g = (inColor >> 8u) & 0xFF;
|
||||
outColor.r = (inColor ) & 0xFF;
|
||||
outColor.rgb /= 256.0;
|
||||
outColor.a = 0.5;
|
||||
|
||||
gl_Position = ubo.matrices.projection[PushConstant.pass] * ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inPos.xyz, 1.0);
|
||||
}
|
||||
11
bin/data/shaders/texture/frag.glsl
Normal file
@ -0,0 +1,11 @@
|
||||
#version 450
|
||||
|
||||
layout (binding = 0) uniform sampler2D samplerColor;
|
||||
layout (location = 0) in vec2 inUV;
|
||||
layout (location = 0) out vec4 outFragColor;
|
||||
|
||||
void main() {
|
||||
vec4 sampledColor = texture(samplerColor, inUV);
|
||||
if ( sampledColor.r <= 0.000001 && sampledColor.g <= 0.000001 && sampledColor.b <= 0.000001 ) discard;
|
||||
outFragColor = sampledColor;
|
||||
}
|
||||
14
bin/data/shaders/texture/vert.glsl
Normal file
@ -0,0 +1,14 @@
|
||||
#version 450
|
||||
|
||||
layout (location = 0) out vec2 outUV;
|
||||
|
||||
out gl_PerVertex
|
||||
{
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||
gl_Position = vec4(outUV * 2.0f + -1.0f, 0.0f, 1.0f);
|
||||
}
|
||||
266
client/client/ext.cpp
Normal file
@ -0,0 +1,266 @@
|
||||
#include "../main.h"
|
||||
|
||||
#include <uf/utils/window/window.h>
|
||||
#include <uf/utils/io/iostream.h>
|
||||
#include <uf/utils/image/image.h>
|
||||
#include <uf/utils/audio/audio.h>
|
||||
#include <uf/spec/terminal/terminal.h>
|
||||
#include <uf/utils/hook/hook.h>
|
||||
#include <uf/utils/thread/thread.h>
|
||||
#include <uf/utils/renderer/renderer.h>
|
||||
|
||||
bool client::ready = false;
|
||||
bool client::terminated = false;
|
||||
uf::Window client::window;
|
||||
uf::Serializer client::config;
|
||||
|
||||
void client::initialize() {
|
||||
uf::IoStream::ncurses = true;
|
||||
uf::renderer::device.window = &client::window;
|
||||
|
||||
ext::load();
|
||||
#if 1
|
||||
client::config = ext::config;
|
||||
#else
|
||||
/* Initialize config */ {
|
||||
struct {
|
||||
uf::Serializer ext;
|
||||
uf::Serializer fallback;
|
||||
} config;
|
||||
/* Get configuration */ {
|
||||
config.ext = ext::config.serialize();
|
||||
}
|
||||
/* Merge */ {
|
||||
client::config = config.ext;
|
||||
client::config.merge( config.fallback, true );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Initialize window */ {
|
||||
// Window size
|
||||
pod::Vector2i size; {
|
||||
size.x = client::config["window"]["size"]["x"].as<size_t>();
|
||||
size.y = client::config["window"]["size"]["y"].as<size_t>();
|
||||
// request system size
|
||||
if ( size.x <= 0 && size.y <= 0 ) {
|
||||
auto resolution = client::window.getResolution();
|
||||
client::config["window"]["size"]["x"] = (size.x = resolution.x);
|
||||
client::config["window"]["size"]["y"] = (size.y = resolution.y);
|
||||
}
|
||||
}
|
||||
// Window title
|
||||
uf::String title; {
|
||||
title = client::config["window"]["title"].as<std::string>();
|
||||
}
|
||||
// Terminal window;
|
||||
spec::terminal.setVisible( client::config["window"]["terminal"]["visible"].as<bool>() );
|
||||
// Ncurses
|
||||
uf::IoStream::ncurses = client::config["window"]["terminal"]["ncurses"].as<bool>();
|
||||
// Window's context settings
|
||||
uf::renderer::settings::width = size.x;
|
||||
uf::renderer::settings::height = size.y;
|
||||
client::window.create( size, title );
|
||||
#if !UF_ENV_DREAMCAST
|
||||
// Set refresh rate
|
||||
ext::config["window"]["refresh rate"] = client::window.getRefreshRate();
|
||||
// Miscellaneous
|
||||
client::window.setVisible(client::config["window"]["visible"].as<bool>());
|
||||
client::window.setCursorVisible(client::config["window"]["cursor"]["visible"].as<bool>());
|
||||
client::window.setKeyRepeatEnabled(client::config["window"]["keyboard"]["repeat"].as<bool>());
|
||||
// client::window.centerWindow();
|
||||
// client::window.setPosition({0, 0});
|
||||
// client::window.setMouseGrabbed(true);
|
||||
|
||||
/* Set Icon */ if ( client::config["window"]["icon"].is<std::string>() ) {
|
||||
uf::Image icon;
|
||||
icon.open(client::config["window"]["icon"].as<std::string>());
|
||||
client::window.setIcon({(int) icon.getDimensions().x, (int) icon.getDimensions().y}, ((uint8_t*)icon.getPixelsPtr()));
|
||||
}
|
||||
client::window.setTitle(title); {
|
||||
uf::Serializer json;
|
||||
std::string hook = "window:Title.Changed";
|
||||
json["type"] = hook;
|
||||
json["invoker"] = "os";
|
||||
json["window"]["title"] = std::string(title);
|
||||
uf::hooks.call( hook, json );
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
uf::hooks.shouldPreferReadable();
|
||||
if ( client::config["engine"]["hook"]["mode"] == "Readable" ) {
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
#if UF_USE_OPENAL
|
||||
/* Initialize OpenAL */ {
|
||||
if ( !ext::oal.initialize() ) {
|
||||
std::cerr << "[ERROR] AL failed to initialize!" << std::endl;
|
||||
std::exit(EXIT_SUCCESS);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize hooks */ {
|
||||
// if ( client::config["engine"]["hook"]["mode"] == "Both" || client::config["engine"]["hook"]["mode"] == "Readable" ) {
|
||||
uf::hooks.addHook( "window:Mouse.CursorVisibility", [&](const ext::json::Value& json){
|
||||
client::window.setCursorVisible(json["state"].as<bool>());
|
||||
client::window.setMouseGrabbed(!json["state"].as<bool>());
|
||||
client::config["mouse"]["visible"] = json["state"].as<bool>();
|
||||
client::config["window"]["mouse"]["center"] = !json["state"].as<bool>();
|
||||
});
|
||||
uf::hooks.addHook( "window:Mouse.Lock", [&](const ext::json::Value& json){
|
||||
if ( client::window.hasFocus() ) {
|
||||
client::window.setMousePosition(client::window.getSize()/2);
|
||||
}
|
||||
});
|
||||
uf::hooks.addHook( "window:Closed", [&](const ext::json::Value& json){
|
||||
client::ready = false;
|
||||
// std::exit(EXIT_SUCCESS);
|
||||
} );
|
||||
uf::hooks.addHook( "window:Title.Changed", [&](const ext::json::Value& json){
|
||||
if ( json["invoker"] != "os" ) {
|
||||
if ( !ext::json::isObject( json["window"] ) ) return;
|
||||
uf::String title = json["window"]["title"].as<std::string>();
|
||||
client::window.setTitle(title);
|
||||
}
|
||||
} );
|
||||
uf::hooks.addHook( "window:Resized", [&](const ext::json::Value& json){
|
||||
pod::Vector2i size; {
|
||||
size.x = json["window"]["size"]["x"].as<size_t>();
|
||||
size.y = json["window"]["size"]["y"].as<size_t>();
|
||||
}
|
||||
if ( json["invoker"] != "os" ) {
|
||||
client::window.setSize(size);
|
||||
}
|
||||
// Update viewport
|
||||
if ( !ext::json::isArray( client::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"] ) ) {
|
||||
float scale = client::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"].is<double>() ? client::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"].as<float>() : 1;
|
||||
uf::renderer::settings::width = size.x * scale;
|
||||
uf::renderer::settings::height = size.y * scale;
|
||||
}
|
||||
|
||||
uf::renderer::states::resized = true;
|
||||
} );
|
||||
/*
|
||||
}
|
||||
else if ( client::config["engine"]["hook"]["mode"] == "Both" || client::config["engine"]["hook"]["mode"] == "Optimal" ) {
|
||||
uf::hooks.addHook( "window:Closed", [&](const uf::OptimalHook::argument_t& userdata)->uf::OptimalHook::return_t{
|
||||
client::ready = false;
|
||||
std::exit(EXIT_SUCCESS);
|
||||
return NULL;
|
||||
} );
|
||||
uf::hooks.addHook( "window:Title.Changed", [&](const uf::OptimalHook::argument_t& userdata)->uf::OptimalHook::return_t{
|
||||
// Hook information
|
||||
struct Hook {
|
||||
std::string type;
|
||||
std::string invoker;
|
||||
|
||||
struct {
|
||||
std::string title;
|
||||
} window;
|
||||
};
|
||||
const Hook& hook = uf::userdata::get<Hook>(userdata);
|
||||
if ( hook.invoker != "os" ) {
|
||||
uf::String title = hook.window.title;
|
||||
client::window.setTitle(title);
|
||||
}
|
||||
return NULL;
|
||||
} );
|
||||
uf::hooks.addHook( "window:Resized", [&](const uf::OptimalHook::argument_t& userdata)->uf::OptimalHook::return_t{
|
||||
// Hook information
|
||||
struct Hook {
|
||||
std::string type;
|
||||
std::string invoker;
|
||||
|
||||
struct {
|
||||
pod::Vector2i size;
|
||||
} window;
|
||||
};
|
||||
const Hook& hook = uf::userdata::get<Hook>(userdata);
|
||||
if ( hook.invoker != "os" ) {
|
||||
client::window.setSize(hook.window.size);
|
||||
}
|
||||
// Update viewport
|
||||
return NULL;
|
||||
} );
|
||||
}
|
||||
*/
|
||||
}
|
||||
#if !UF_ENV_DREAMCAST
|
||||
if ( client::config["window"]["mode"].as<std::string>() == "fullscreen" ) client::window.switchToFullscreen();
|
||||
if ( client::config["window"]["mode"].as<std::string>() == "borderless" ) client::window.switchToFullscreen( true );
|
||||
#endif
|
||||
client::ready = true;
|
||||
}
|
||||
void client::tick() {
|
||||
// uf::hooks.call("system:Tick");
|
||||
client::window.pollEvents();
|
||||
// call mouse move
|
||||
// query lock
|
||||
if ( client::window.hasFocus() && client::config["window"]["mouse"]["center"].as<bool>() ) {
|
||||
auto previous = client::window.getMousePosition();
|
||||
client::window.setMousePosition(client::window.getSize()/2);
|
||||
auto current = client::window.getMousePosition();
|
||||
|
||||
auto size = client::window.getSize();
|
||||
uf::Serializer payload;
|
||||
payload["invoker"] = "client";
|
||||
payload["mouse"]["delta"]["x"] = previous.x - current.x;
|
||||
payload["mouse"]["delta"]["y"] = previous.y - current.y;
|
||||
payload["mouse"]["position"]["x"] = current.x;
|
||||
payload["mouse"]["position"]["y"] = current.y;
|
||||
payload["mouse"]["size"]["x"] = size.x;
|
||||
payload["mouse"]["size"]["y"] = size.y;
|
||||
payload["mouse"]["state"] = "???";
|
||||
payload["type"] = "window:Mouse.Moved";
|
||||
uf::hooks.call("window:Mouse.Moved", payload);
|
||||
}
|
||||
/*
|
||||
{
|
||||
"invoker" : "os",
|
||||
"mouse" :
|
||||
{
|
||||
"delta" :
|
||||
{
|
||||
"x" : -17,
|
||||
"y" : -12
|
||||
},
|
||||
"position" :
|
||||
{
|
||||
"x" : 371,
|
||||
"y" : 276
|
||||
},
|
||||
"size" :
|
||||
{
|
||||
"x" : 800,
|
||||
"y" : 600
|
||||
},
|
||||
"state" : "???"
|
||||
},
|
||||
"type" : "window:Mouse.Moved"
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void client::render() {
|
||||
client::window.display();
|
||||
}
|
||||
|
||||
void client::terminate() {
|
||||
/* Close Threads */ {
|
||||
uf::thread::terminate();
|
||||
}
|
||||
|
||||
client::window.terminate();
|
||||
|
||||
#if UF_USE_OPENAL
|
||||
if ( !ext::oal.terminate() ) {
|
||||
std::cerr << "[ERROR] AL failed to terminate!" << std::endl;
|
||||
std::exit(EXIT_SUCCESS);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
87
client/dreamcast.gldc.inl
Normal file
@ -0,0 +1,87 @@
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <GL/glkos.h>
|
||||
|
||||
/* A general OpenGL initialization function. Sets all of the initial parameters. */
|
||||
void InitGL(int Width, int Height) // We call this right after our OpenGL window is created.
|
||||
{
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black
|
||||
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
|
||||
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
|
||||
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
|
||||
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex arrays
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity(); // Reset The Projection Matrix
|
||||
|
||||
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f); // Calculate The Aspect Ratio Of The Window
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
/* The function called when our window is resized (which shouldn't happen, because we're fullscreen) */
|
||||
void ReSizeGLScene(int Width, int Height)
|
||||
{
|
||||
if (Height == 0) // Prevent A Divide By Zero If The Window Is Too Small
|
||||
Height = 1;
|
||||
|
||||
glViewport(0, 0, Width, Height); // Reset The Current Viewport And Perspective Transformation
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
|
||||
/* The main drawing function. */
|
||||
void DrawGLScene()
|
||||
{
|
||||
|
||||
const GLfloat triangle [] = {
|
||||
0.0f, 1.0f, 0.0f,
|
||||
1.0f, -1.0f, 0.0f,
|
||||
-1.0f, -1.0f, 0.0f
|
||||
};
|
||||
|
||||
const GLfloat square [] = {
|
||||
-1.0f, 1.0f, 0.0f,
|
||||
1.0f, 1.0f, 0.0f,
|
||||
1.0f, -1.0f, 0.0f,
|
||||
-1.0f, -1.0f, 0.0f
|
||||
};
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
|
||||
glLoadIdentity(); // Reset The View
|
||||
|
||||
glTranslatef(-1.5f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, triangle);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
|
||||
glTranslatef(3.0f,0.0f,0.0f); // Move Right 3 Units
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, square);
|
||||
glDrawArrays(GL_QUADS, 0, 4);
|
||||
|
||||
// swap buffers to display, since we're double buffered.
|
||||
glKosSwapBuffers();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
glKosInit();
|
||||
|
||||
InitGL(640, 480);
|
||||
ReSizeGLScene(640, 480);
|
||||
|
||||
while(1) {
|
||||
UF_DEBUG_PRINT_MARKER();
|
||||
DrawGLScene();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
82
client/dreamcast.inl
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
KallistiOS 2.0.0
|
||||
|
||||
nehe02.c
|
||||
(c)2014 Josh Pearson
|
||||
(c)2001 Benoit Miller
|
||||
(c)2000 Jeff Molofee
|
||||
*/
|
||||
|
||||
#include <kos.h>
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <GL/glut.h>
|
||||
|
||||
/*
|
||||
The simplest OpenGL example ever!
|
||||
|
||||
Essentially the same thing as NeHe's lesson02 code.
|
||||
To learn more, go to http://nehe.gamedev.net/.
|
||||
*/
|
||||
|
||||
void draw_gl(void) {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glLoadIdentity();
|
||||
glTranslatef(-1.5f, 0.0f, -6.0f);
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
glVertex3f(0.0f, 1.0f, 0.0f);
|
||||
glVertex3f(-1.0f, -1.0f, 0.0f);
|
||||
glVertex3f(1.0f, -1.0f, 0.0f);
|
||||
glEnd();
|
||||
|
||||
glTranslatef(3.0f, 0.0f, 0.0f);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glVertex3f(-1.0f, 1.0f, 0.0f);
|
||||
glVertex3f(1.0f, 1.0f, 0.0f);
|
||||
glVertex3f(1.0f, -1.0f, 0.0f);
|
||||
glVertex3f(-1.0f, -1.0f, 0.0f);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
maple_device_t *cont;
|
||||
cont_state_t *state;
|
||||
|
||||
/* Get basic stuff initialized */
|
||||
printf("nehe02 beginning\n");
|
||||
/* Notice we do not init the PVR here, that is handled by OpenGL */
|
||||
glKosInit();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(45.0f, 640.0f / 480.0f, 0.1f, 100.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
while(1) {
|
||||
cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER);
|
||||
|
||||
/* Check key status */
|
||||
state = (cont_state_t *)maple_dev_status(cont);
|
||||
|
||||
if(!state) {
|
||||
printf("Error reading controller\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if(state->buttons & CONT_START)
|
||||
break;
|
||||
|
||||
/* Draw the "scene" */
|
||||
draw_gl();
|
||||
|
||||
/* Finish the frame - Notice there is no glKosBegin/FinshFrame */
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
78
client/main.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
#include "main.h"
|
||||
|
||||
#include <uf/utils/io/iostream.h>
|
||||
#include <uf/utils/time/time.h>
|
||||
|
||||
#include <uf/utils/mempool/mempool.h>
|
||||
|
||||
#if UF_NO_EXCEPTIONS
|
||||
#define HANDLE_EXCEPTIONS 0
|
||||
#else
|
||||
#define HANDLE_EXCEPTIONS 0
|
||||
#endif
|
||||
|
||||
int main(int argc, char** argv){
|
||||
for ( size_t i = 0; i < argc; ++i ) {
|
||||
char* c_str = argv[i];
|
||||
std::string string(argv[i]);
|
||||
ext::arguments.emplace_back(string);
|
||||
}
|
||||
|
||||
std::atexit([]{
|
||||
uf::iostream << "Termination via std::atexit()!" << "\n";
|
||||
client::terminated = !(client::ready = ext::ready = false);
|
||||
});
|
||||
|
||||
client::initialize();
|
||||
ext::initialize();
|
||||
|
||||
// For Multithreaded initialization
|
||||
while ( !client::ready || !ext::ready ) {
|
||||
static uf::Timer<long long> timer(false);
|
||||
static double next = 1;
|
||||
if ( !timer.running() ) timer.start();
|
||||
|
||||
if ( timer.elapsed().asDouble() >= next ) {
|
||||
uf::iostream << "Waiting for " << ( client::ready ? "client" : "extension / engine" ) << " to initialize... Retrying in " << next << " seconds." << "\n";
|
||||
next *= 2;
|
||||
}
|
||||
}
|
||||
while ( client::ready && ext::ready ) {
|
||||
#if HANDLE_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
static bool first = false; if ( !first ) { first = true;
|
||||
uf::Serializer json;
|
||||
std::string hook = "window:Resized";
|
||||
json["type"] = hook;
|
||||
json["invoker"] = "ext";
|
||||
|
||||
json["window"]["size"]["x"] = client::config["window"]["size"]["x"];
|
||||
json["window"]["size"]["y"] = client::config["window"]["size"]["y"];
|
||||
uf::hooks.call(hook, json);
|
||||
}
|
||||
client::tick();
|
||||
ext::tick();
|
||||
client::render();
|
||||
ext::render();
|
||||
#if HANDLE_EXCEPTIONS
|
||||
} catch ( std::runtime_error& e ) {
|
||||
uf::iostream << "RUNTIME ERROR: " << e.what() << "\n";
|
||||
break;
|
||||
} catch ( std::exception& e ) {
|
||||
uf::iostream << "EXCEPTION ERROR: " << e.what() << "\n";
|
||||
throw e;
|
||||
} catch ( bool handled ) {
|
||||
if (!handled) uf::iostream << "UNHANDLED ERROR: " << "???" << "\n";
|
||||
} catch ( ... ) {
|
||||
uf::iostream << "UNKNOWN ERROR: " << "???" << "\n";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if ( !client::terminated ) {
|
||||
uf::iostream << "Natural termination!" << "\n";
|
||||
}
|
||||
ext::terminate();
|
||||
client::terminate();
|
||||
return 0;
|
||||
}
|
||||
18
client/main.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <uf/ext/ext.h>
|
||||
|
||||
#include <uf/utils/window/window.h>
|
||||
#include <uf/utils/serialize/serializer.h>
|
||||
#include <uf/utils/thread/thread.h>
|
||||
|
||||
namespace client {
|
||||
extern bool ready;
|
||||
extern bool terminated;
|
||||
extern uf::Window window;
|
||||
extern uf::Serializer config;
|
||||
|
||||
void initialize();
|
||||
void tick();
|
||||
void render();
|
||||
void terminate();
|
||||
}
|
||||
|
Before Width: | Height: | Size: 304 KiB |
|
Before Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 170 KiB |
|
Before Width: | Height: | Size: 73 KiB |
166
data/config.json
@ -1,166 +0,0 @@
|
||||
{
|
||||
"engine": {
|
||||
"scenes": {
|
||||
"start": "McDonalds",
|
||||
"lights": {
|
||||
"max": 256,
|
||||
"update threshold": 6,
|
||||
"shadow threshold": 20
|
||||
},
|
||||
"textures": {
|
||||
"max": 256
|
||||
}
|
||||
},
|
||||
"ext": {
|
||||
"vulkan": {
|
||||
"validation": {
|
||||
"enabled": false,
|
||||
"filters": [
|
||||
"MessageID = 0x4dae5635", // UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout (false positive for cubemaps)
|
||||
"MessageID = 0x71500fba", // VUID-vkDestroyDevice-device-00378 (don't care about a clean cleanup)
|
||||
"MessageID = 0x609a13b", // UNASSIGNED-CoreValidation-Shader-OutputNotConsumed (from depth-only calls)
|
||||
"MessageID = 0x23e43bb7" // UNASSIGNED-CoreValidation-Shader-InputNotProduced (from depth-only calls)
|
||||
// "MessageID = 0xe91b58a0" // VUID-vkCmdDrawIndexed-None-02686 (?)
|
||||
]
|
||||
},
|
||||
"framebuffer": {
|
||||
"size": 0.8,
|
||||
// "size": [ 640, 480, "NEAREST" ],
|
||||
// "size": [ 256, 224, "NEAREST" ],
|
||||
// "msaa": 16
|
||||
"msaa": 4
|
||||
},
|
||||
"experimental": {
|
||||
"rebuild on tick begin": false,
|
||||
"wait on render end": false,
|
||||
"individual pipelines": true,
|
||||
"multithreaded command recording": true,
|
||||
"deferred mode": "",
|
||||
// "deferred mode": "deferredSampling",
|
||||
"deferred reconstruct position": true,
|
||||
"deferred alias output to swapchain": true,
|
||||
"hdr": false
|
||||
},
|
||||
"formats": {
|
||||
"depth": "D32_SFLOAT",
|
||||
"color": "R8G8B8A8_UNORM", // "R32G32B32A32_SFLOAT",
|
||||
"normal": "R16G16B16A16_SFLOAT",
|
||||
"position": "R16G16B16A16_SFLOAT"
|
||||
},
|
||||
"features": [
|
||||
"independentBlend",
|
||||
"deviceCoherentMemory",
|
||||
"robustBufferAccess",
|
||||
"samplerAnisotropy",
|
||||
"sampleRateShading",
|
||||
"nullDescriptor"
|
||||
],
|
||||
"extensions": {
|
||||
"instance": [
|
||||
"VK_KHR_get_physical_device_properties2",
|
||||
"VK_KHR_get_surface_capabilities2"
|
||||
],
|
||||
"device": [
|
||||
]
|
||||
}
|
||||
},
|
||||
"lua": {
|
||||
"main": "/main.lua",
|
||||
"modules": {
|
||||
"json": "/json.lua"
|
||||
}
|
||||
},
|
||||
"vr" : {
|
||||
"enable" : false,
|
||||
"manifest": "./data/openvr_manifest.json",
|
||||
"swap eyes": false,
|
||||
"dominant eye": 0,
|
||||
"scale": 1
|
||||
},
|
||||
"ultralight": {
|
||||
"enabled": true,
|
||||
"scale": 1.5
|
||||
},
|
||||
"bullet": {
|
||||
"iterations": 1,
|
||||
"substeps": 12,
|
||||
"timescale": 1,
|
||||
"multithreaded": false,
|
||||
"debug draw": {
|
||||
"enabled": false,
|
||||
"rate": 1.0
|
||||
}
|
||||
},
|
||||
"discord": {
|
||||
"enabled": false
|
||||
}
|
||||
},
|
||||
"audio": {
|
||||
"mute": false
|
||||
},
|
||||
"memory pool": {
|
||||
"globalOverride": false,
|
||||
"subPools": true,
|
||||
"size": "512 MiB",
|
||||
"pools": {
|
||||
"entity": "128 MiB",
|
||||
"userdata": "128 MiB",
|
||||
"component": "128 MiB"
|
||||
}
|
||||
},
|
||||
"hook" : {
|
||||
"mode" : "Readable"
|
||||
},
|
||||
"render modes": {
|
||||
"gui": true,
|
||||
"deferred": true,
|
||||
"stereo deferred": false,
|
||||
"multiview stereo deferred": false
|
||||
},
|
||||
"limiters": {
|
||||
"deltaTime": 10,
|
||||
"framerate": "auto"
|
||||
},
|
||||
"threads": {
|
||||
"workers" : "auto",
|
||||
"frame limiter": "auto"
|
||||
},
|
||||
"debug": {
|
||||
"framerate": {
|
||||
"print": false,
|
||||
"every": 1
|
||||
},
|
||||
"garbage collection": {
|
||||
"enabled": true,
|
||||
"mode": 1,
|
||||
"rate": 16,
|
||||
"announce": true
|
||||
},
|
||||
"entity": {
|
||||
"delete children on destroy": false,
|
||||
"delete components on destroy": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"window" : {
|
||||
"terminal" : {
|
||||
"ncurses" : false,
|
||||
"visible" : true
|
||||
},
|
||||
"keyboard" : {
|
||||
"repeat" : false
|
||||
},
|
||||
"cursor" : {
|
||||
"visible" : true,
|
||||
"center" : false
|
||||
},
|
||||
"mode" : "windowed", // fullscreen, borderless, windowed
|
||||
"icon" : "./data/textures/icon.png",
|
||||
"size" : {
|
||||
"x" : 960,
|
||||
"y" : 540
|
||||
},
|
||||
"title" : "Grimgram",
|
||||
"visible" : true
|
||||
}
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
{
|
||||
"name": "Gui Manager",
|
||||
"type": "Object",
|
||||
"behaviors": [
|
||||
"GuiManagerBehavior"
|
||||
],
|
||||
"ignore": false
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
{
|
||||
"name": "HUD",
|
||||
"type": "Gui",
|
||||
"ignore": false,
|
||||
"assets": [
|
||||
"./scripts/hud.lua"
|
||||
],
|
||||
"system": {
|
||||
"clickable": false,
|
||||
"hoverable": false
|
||||
},
|
||||
"transform": {
|
||||
"position": [ 0, 0, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 0, 1 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 16, 16, 16 ]
|
||||
},
|
||||
"metadata": {
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
{
|
||||
"name": "HUD Overlay",
|
||||
"type": "Gui",
|
||||
"ignore": false,
|
||||
"assets": [
|
||||
{ "filename": "./textures/mp.png", "hash": "68e7c459f9aecd6815ff7df1e2eefa82db60a23713b0134f0bfc15d82f55453d" }
|
||||
// { "filename": "./textures/ss2.png" }
|
||||
],
|
||||
"system": {
|
||||
"clickable": false,
|
||||
"hoverable": false
|
||||
},
|
||||
"transform": {
|
||||
"position": [ 0, 0, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 0, 1 ],
|
||||
"angle": 0
|
||||
},
|
||||
// "scale": [ 1.7776, -1, -1 ]
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
// "color": [ 0.8, 0.8, 1, 1 ],
|
||||
// "color": [ 0.416, 0.573, 0.667, 1 ],
|
||||
"color": [ 1, 1, 1, 1 ],
|
||||
"location": "",
|
||||
"scaling": "relative",
|
||||
// "depth": 0.1,
|
||||
// "alpha": 0.5,
|
||||
"alpha": 0.75,
|
||||
"mode": 1,
|
||||
"gui layer": true,
|
||||
"only model": true
|
||||
}
|
||||
}
|
||||
@ -1,154 +0,0 @@
|
||||
local scene = entities.currentScene()
|
||||
local controller = entities.controller()
|
||||
local metadata = ent:getComponent("Metadata")
|
||||
local masterdata = scene:getComponent("Metadata")
|
||||
|
||||
local visorLayers = 5
|
||||
local children = {}
|
||||
for i=1, visorLayers do
|
||||
children[i] = ent:loadChild("./overlay.json",true)
|
||||
end
|
||||
|
||||
local soundEmitter = ent:loadChild("./sound.json",true)
|
||||
|
||||
local timer = Timer.new()
|
||||
if not timer:running() then timer:start() end
|
||||
|
||||
Static = {
|
||||
values = {},
|
||||
get = function( obj )
|
||||
if obj == nil then
|
||||
obj = scene
|
||||
end
|
||||
if Static.values[""..obj:uid()] == nil then
|
||||
Static.values[""..obj:uid()] = {}
|
||||
end
|
||||
return Static.values[""..obj:uid()]
|
||||
end
|
||||
}
|
||||
|
||||
local lerper = {
|
||||
to = Quaternion(0,0,0,1),
|
||||
from = Quaternion(0,0,0,1),
|
||||
a = 0
|
||||
}
|
||||
|
||||
local rotate = function( delta )
|
||||
delta.x = delta.x * 0.1
|
||||
delta.y = delta.y * 0.1
|
||||
|
||||
local transform = ent:getComponent("Transform")
|
||||
local rotation = {
|
||||
x = Quaternion.axisAngle( Vector3f(0, 1, 0), delta.x ),
|
||||
y = Quaternion.axisAngle( Vector3f(1, 0, 0), delta.y )
|
||||
}
|
||||
|
||||
lerper.a = 0
|
||||
lerper.from = Quaternion.multiply( transform.orientation, rotation.x:multiply(rotation.y) )
|
||||
transform.orientation = lerper.from
|
||||
for k, obj in pairs(children) do
|
||||
obj:getComponent("Transform").orientation = transform.orientation
|
||||
end
|
||||
end
|
||||
|
||||
local windowSize = masterdata["system"]["config"]["window"]["size"];
|
||||
local entTransform = ent:getComponent("Transform")
|
||||
entTransform.scale.x = entTransform.scale.x * windowSize.x / windowSize.y;
|
||||
|
||||
for k, obj in pairs(children) do
|
||||
local transform = obj:getComponent("Transform")
|
||||
transform.scale = entTransform.scale;
|
||||
transform.position.z = -0.5 + ((k-1) * 0.005)
|
||||
end
|
||||
|
||||
ent:addHook( "window:Resized", function( payload )
|
||||
if entTransform.scale.y == entTransform.scale.z then
|
||||
entTransform.scale.x = entTransform.scale.y * payload["window"]["size"]["x"] / payload["window"]["size"]["y"];
|
||||
end
|
||||
|
||||
for k, obj in pairs(children) do
|
||||
local transform = obj:getComponent("Transform")
|
||||
transform.scale = entTransform.scale;
|
||||
end
|
||||
end )
|
||||
|
||||
ent:addHook( "controller:Camera.Rotated", function( payload )
|
||||
rotate( {
|
||||
x = -payload.angle.yaw,
|
||||
y = -payload.angle.pitch
|
||||
})
|
||||
--[[
|
||||
local transform = ent:getComponent("Transform")
|
||||
lerper.a = 0
|
||||
local counterOrientation = Quaternion( payload.delta[1], payload.delta[2], payload.delta[3], payload.delta[4] ):inverse()
|
||||
lerper.from = Quaternion.multiply( transform.orientation, counterOrientation )
|
||||
transform.orientation = lerper.from
|
||||
for k, obj in pairs(children) do
|
||||
obj:getComponent("Transform").orientation = transform.orientation
|
||||
end
|
||||
]]
|
||||
end )
|
||||
--[[
|
||||
ent:addHook( "window:Mouse.Moved", function( payload )
|
||||
if payload.invoker ~= "client" then return end
|
||||
|
||||
local delta = payload.mouse.delta
|
||||
local size = payload.mouse.size
|
||||
|
||||
if delta == nil or size == nil then return end
|
||||
if delta.x == 0 or delta.y == 0 then return end
|
||||
|
||||
delta.x = -delta.x / size.x
|
||||
delta.y = -delta.y / size.y
|
||||
|
||||
rotate( delta )
|
||||
end )
|
||||
]]
|
||||
|
||||
ent:bind( "tick", function(self)
|
||||
for k, obj in pairs(children) do
|
||||
local metadata = obj:getComponent("Metadata")
|
||||
local glow = math.sin(time.current()) * 0.5 + 0.5 -- constrained to [0,1]
|
||||
glow = glow * 0.2 + 0.65 -- constrained to [0.65, 0.85]
|
||||
metadata["alpha"] = glow
|
||||
obj:setComponent("Metadata", metadata)
|
||||
end
|
||||
|
||||
local controllerTransform = controller:getComponent("Transform")
|
||||
local controllerCamera = controller:getComponent("Camera")
|
||||
local controllerCameraTransform = controllerCamera:getTransform()
|
||||
local transform = ent:getComponent("Transform")
|
||||
|
||||
local speed = 2.5
|
||||
if lerper.a == 1 then return end
|
||||
lerper.a = lerper.a + time.delta() * speed
|
||||
if lerper.a > 1 then lerper.a = 1 end
|
||||
|
||||
transform.orientation = lerper.from:slerp( lerper.to, lerper.a )
|
||||
local orientation = transform.orientation
|
||||
for k, obj in pairs(children) do
|
||||
local transform = obj:getComponent("Transform")
|
||||
transform.orientation = orientation
|
||||
transform.model = controllerCamera:getProjection() * Matrix4f.translate( transform.position ) * transform.orientation:matrix() * Matrix4f.scale( transform.scale ) --Matrix4f.scale( Vector3f( 1.7776 * 2, 2, 2 ) )
|
||||
end
|
||||
end )
|
||||
|
||||
--[[
|
||||
controller:callHook( "object:UpdateMetadata.%UID%", {
|
||||
path = "overlay.position",
|
||||
value = {
|
||||
[1] = position.x,
|
||||
[2] = position.y,
|
||||
[3] = position.z
|
||||
}
|
||||
} )
|
||||
controller:callHook( "object:UpdateMetadata.%UID%", {
|
||||
path = "overlay.orientation",
|
||||
value = {
|
||||
[1] = orientation.x,
|
||||
[2] = orientation.y,
|
||||
[3] = orientation.z,
|
||||
[4] = orientation.w
|
||||
}
|
||||
} )
|
||||
]]
|
||||
@ -1,38 +0,0 @@
|
||||
{
|
||||
"type": "Object",
|
||||
"name": "Sound Emitter",
|
||||
"ignore": false,
|
||||
"assets": [
|
||||
],
|
||||
"behaviors": [
|
||||
"SoundEmitterBehavior"
|
||||
],
|
||||
"transform": {
|
||||
"position": [ 0, 0, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 1, 0 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"system": {
|
||||
"hot reload": {
|
||||
"enabled": true
|
||||
},
|
||||
"defaults": {
|
||||
"render": true,
|
||||
"asset load": true
|
||||
},
|
||||
"load": {
|
||||
"ignore": true
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"audio": {
|
||||
"spatial": false,
|
||||
"loop": false,
|
||||
"volume": "sfx",
|
||||
"rolloffFactor": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
{
|
||||
"name": "Menu: Circle Inner",
|
||||
"type": "Gui",
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ 0.86, 0.86, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 1, 0, 0 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"clickable": false,
|
||||
"hoverable": false,
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"color": [ 1, 1, 1, 0.8 ],
|
||||
"location": "",
|
||||
"scaling": [ 0.64, 1 ],
|
||||
"mode": "flat"
|
||||
},
|
||||
"assets": [
|
||||
"https://cdn..xyz//unity/Android/sprite/sprite_magiccircle_in2.png"
|
||||
]
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
{
|
||||
"name": "Menu: Circle Outer",
|
||||
"type": "Gui",
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ 0.86, 0.86, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 1, 0, 0 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"clickable": false,
|
||||
"hoverable": true,
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"color": [ 1, 1, 1, 0.8 ],
|
||||
"location": "",
|
||||
"scaling": [ 0.64, 1 ],
|
||||
"mode": "flat"
|
||||
},
|
||||
"assets": [
|
||||
"https://cdn..xyz//unity/Android/sprite/sprite_magiccircle_out2.png"
|
||||
]
|
||||
}
|
||||
@ -1,26 +0,0 @@
|
||||
{
|
||||
"name": "Menu: Main Text",
|
||||
"type": "Gui",
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ -0.922623, -0.854923, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 0, 1 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"location": "",
|
||||
"scaling": "relative",
|
||||
"debug": {
|
||||
"moveable": false
|
||||
},
|
||||
"text settings": {
|
||||
"scale": 2,
|
||||
"font": "Coolvetica.ttf",
|
||||
"string": "Grimgram"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
{
|
||||
"name": "Gui: Menu",
|
||||
"type": "Gui",
|
||||
"ignore": false,
|
||||
"assets": [
|
||||
"./textures/menu.png",
|
||||
"./scripts/menu.lua"
|
||||
],
|
||||
"system": {
|
||||
"clickable": true,
|
||||
"hoverable": true
|
||||
},
|
||||
"transform": {
|
||||
"position": [ 0, 0, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 0, 1 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"metadata": {
|
||||
"experimental": true,
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"color": [ 1, 1, 1, 1 ],
|
||||
"location": "",
|
||||
"scaling": "relative",
|
||||
"depth": 0.2,
|
||||
"mode": "flat"
|
||||
}
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
{
|
||||
"name": "Menu: Close Option",
|
||||
"type": "Gui",
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ -0.75622, 0.638136, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 0, 1 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"clickable": true,
|
||||
"hoverable": true,
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"location": "",
|
||||
"scaling": "relative",
|
||||
"debug": {
|
||||
"moveable": false
|
||||
},
|
||||
"events": {
|
||||
"click": {
|
||||
"name": "system:Quit",
|
||||
"payload": {
|
||||
"scene": "StartMenu"
|
||||
}
|
||||
}
|
||||
},
|
||||
"text settings": {
|
||||
"legacy": false,
|
||||
"string": "Quit"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,142 +0,0 @@
|
||||
Static = {
|
||||
values = {},
|
||||
get = function( obj )
|
||||
if Static.values[""..obj:uid()] == nil then
|
||||
Static.values[""..obj:uid()] = {}
|
||||
end
|
||||
return Static.values[""..obj:uid()]
|
||||
end
|
||||
}
|
||||
|
||||
local scene = entities.currentScene()
|
||||
local controller = entities.controller()
|
||||
local camera = controller:getComponent("Camera")
|
||||
local metadata = ent:getComponent("Metadata")
|
||||
local masterdata = scene:getComponent("Metadata")
|
||||
|
||||
local children = {
|
||||
mainText = ent:loadChild("./main-text.json",true),
|
||||
circleOut = ent:loadChild("./circle-out.json",true),
|
||||
circleIn = ent:loadChild("./circle-in.json",true),
|
||||
start = ent:loadChild("./start.json",true),
|
||||
quit = ent:loadChild("./quit.json",true),
|
||||
}
|
||||
|
||||
local timer = Timer.new()
|
||||
if not timer:running() then timer:start() end
|
||||
|
||||
local playSound = function( key )
|
||||
local url = "/ui/" .. key .. ".ogg"
|
||||
local assetLoader = scene:getComponent("Asset")
|
||||
assetLoader:cache(string.resolveURI(url), ent:formatHookName("asset:Load.%UID%"))
|
||||
end
|
||||
local destination = function( obj, x, y, z )
|
||||
local static = Static.get(obj)
|
||||
local transform = obj:getComponent("Transform")
|
||||
static.from = Vector3f(x or transform.position.x, y or transform.position.y, z or transform.position.z)
|
||||
end
|
||||
|
||||
pcall( function()
|
||||
local metadata = controller:getComponent("Metadata")
|
||||
local json = json.readFromFile("./data/entities/player.json");
|
||||
controller:callHook("object:UpdateMetadata.%UID%", {
|
||||
overlay = json["metadata"]["overlay"]
|
||||
})
|
||||
camera:update(true);
|
||||
end )
|
||||
|
||||
destination(children.mainText, nil, -2, 0)
|
||||
destination(children.circleOut, nil, -2, 0)
|
||||
destination(children.circleIn, nil, 2, 0)
|
||||
destination(children.start, -1.5, nil, 0)
|
||||
destination(children.quit, -1.5, nil, 0)
|
||||
|
||||
ent:addHook("asset:Load.%UID%", function( json )
|
||||
local filename = json["filename"]
|
||||
if filename == "" or string.extension( filename ) ~= "ogg" then return false end
|
||||
|
||||
local sfx = ent:getComponent("Audio")
|
||||
if not sfx:playing() then sfx:stop() end
|
||||
sfx:load( filename )
|
||||
sfx:setVolume( masterdata["volumes"]["sfx"] )
|
||||
sfx:play()
|
||||
|
||||
return true
|
||||
end )
|
||||
|
||||
ent:bind( "tick", function(self)
|
||||
local static = Static.get(self)
|
||||
if not static.alpha then
|
||||
static.alpha = 0
|
||||
end
|
||||
|
||||
metadata["initialized"] = true;
|
||||
if static.alpha >= 1.0 then
|
||||
static.alpha = 1.0
|
||||
else
|
||||
static.alpha = static.alpha + time.delta() * 1.5
|
||||
end
|
||||
|
||||
-- make background glow
|
||||
local glow = 1 + math.sin(1.25 * time.current()) * 0.125
|
||||
metadata["color"][1] = glow
|
||||
metadata["color"][2] = glow
|
||||
metadata["color"][3] = glow
|
||||
metadata["alpha"] = static.alpha;
|
||||
self:setComponent("Metadata", metadata)
|
||||
|
||||
camera:update(true);
|
||||
|
||||
-- iterate children in batch
|
||||
for k, v in pairs(children) do
|
||||
if v:uid() <= 0 then goto continue end
|
||||
|
||||
-- set alpha
|
||||
local metadata = v:getComponent("Metadata")
|
||||
metadata["alpha"] = static.alpha
|
||||
v:setComponent("Metadata", metadata)
|
||||
|
||||
local transform = v:getComponent("Transform")
|
||||
local static = Static.get(v)
|
||||
-- translation
|
||||
if not static.from then goto continue end
|
||||
if not static.to then static.to = Vector3f(transform.position) end
|
||||
if not static.delta then static.delta = 0 end
|
||||
|
||||
if static.delta >= 1 then
|
||||
static.delta = 1
|
||||
else
|
||||
static.delta = static.delta + time.delta() * 1.5
|
||||
transform.position = Vector3f.lerp( static.from, static.to, static.delta )
|
||||
end
|
||||
|
||||
::continue::
|
||||
end
|
||||
|
||||
-- circle in
|
||||
child = children.circleIn
|
||||
if child:uid() > 0 then
|
||||
local static = Static.get( child )
|
||||
|
||||
local transform = child:getComponent("Transform")
|
||||
local metadata = child:getComponent("Metadata")
|
||||
|
||||
-- rotation
|
||||
local speed = metadata["hovered"] and 0.25 or 0.0125
|
||||
static.time = (static.time or 0) + time.delta() * -speed
|
||||
transform.orientation = Quaternion.axisAngle( Vector3f(0, 0, 1), static.time )
|
||||
end
|
||||
-- circle out
|
||||
child = children.circleOut
|
||||
if child:uid() > 0 then
|
||||
local static = Static.get( child )
|
||||
|
||||
local transform = child:getComponent("Transform")
|
||||
local metadata = child:getComponent("Metadata")
|
||||
|
||||
-- rotation
|
||||
local speed = metadata["hovered"] and 0.25 or 0.0125
|
||||
static.time = (static.time or 0) + time.delta() * speed
|
||||
transform.orientation = Quaternion.axisAngle( Vector3f(0, 0, 1), static.time )
|
||||
end
|
||||
end )
|
||||
@ -1,35 +0,0 @@
|
||||
{
|
||||
"name": "Menu: Start Option",
|
||||
"type": "Gui",
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ -0.75622, 0.446468, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 0, 1 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"clickable": true,
|
||||
"hoverable": true,
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"location": "",
|
||||
"scaling": "relative",
|
||||
"debug": {
|
||||
"moveable": false
|
||||
},
|
||||
"events": {
|
||||
"click": {
|
||||
"name": "game:Scene.Load",
|
||||
"payload": {
|
||||
"scene": "SS2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"text settings": {
|
||||
"string": "Start",
|
||||
"string1": "スタート"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 425 KiB |
|
Before Width: | Height: | Size: 225 B |
@ -1,23 +0,0 @@
|
||||
{
|
||||
"name": "Menu: Circle Inner",
|
||||
"type": "Gui",
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ -0.86, 0.86, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 1, 0, 0 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"color": [ 1, 1, 1, 0.8 ],
|
||||
"location": "",
|
||||
"scaling": [ 0.64, 1 ],
|
||||
"mode": "flat"
|
||||
},
|
||||
"assets": [
|
||||
"https://cdn..xyz//unity/Android/sprite/sprite_magiccircle_in.png"
|
||||
]
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
{
|
||||
"name": "Menu: Circle Outer",
|
||||
"type": "Gui",
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ -0.86, 0.86, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 1, 0, 0 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"clickable": false,
|
||||
"hoverable": true,
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"color": [ 1, 1, 1, 0.8 ],
|
||||
"location": "",
|
||||
"scaling": [ 0.64, 1 ],
|
||||
"mode": "flat"
|
||||
},
|
||||
"assets": [
|
||||
"https://cdn..xyz//unity/Android/sprite/sprite_magiccircle_out.png"
|
||||
]
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
{
|
||||
"name": "Menu: Close Option",
|
||||
"type": "Gui",
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ -0.65544, -0.339642, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 0, 1 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 0.156407, 0.0788377, 1 ]
|
||||
},
|
||||
"clickable": true,
|
||||
"hoverable": true,
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"location": "",
|
||||
"scaling": "relative",
|
||||
"events": {
|
||||
"click": {
|
||||
"name": "menu:Close.%P-UID%",
|
||||
"payload": {}
|
||||
}
|
||||
},
|
||||
"text settings": {
|
||||
"string": "Close",
|
||||
"string1": "クローズ"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
{
|
||||
"name": "Menu: Command Text",
|
||||
"type": "Gui",
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ -0.830591, -0.699509, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 1, 0, 0 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 0.258737, 0.115371, 1 ]
|
||||
},
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"location": "",
|
||||
"scaling": "relative",
|
||||
"text settings": {
|
||||
"stroke": [ 1, 0.749, 0.368, 1 ],
|
||||
"color": [ 1, 0.749, 0.368, 1 ],
|
||||
|
||||
"string": "Menu",
|
||||
"string1": "コマンド"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
{
|
||||
"name": "Gui: Icon",
|
||||
"type": "Gui",
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ 0, 0, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 0, 1 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"metadata": {
|
||||
"gui": {
|
||||
"position": [ -0.875, -0.775, 0 ],
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"color": [ 1, 1, 1, 1 ],
|
||||
"location": "",
|
||||
"scaling": "fixed"
|
||||
}
|
||||
},
|
||||
"assets": [
|
||||
"https://cdn..xyz//unity/Android/icon/icon_agyou01_skin1.png"
|
||||
]
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
{
|
||||
"name": "Menu: Main Scroller",
|
||||
"type": "Gui",
|
||||
"ignore": true,
|
||||
"transform": {
|
||||
"position": [ 0.98, -2, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 0, 1 ],
|
||||
"angle": 1.5707963
|
||||
},
|
||||
"scale": [ 0.16, 1, 1 ]
|
||||
},
|
||||
"hoverable": true,
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"color": [ 0.113, 0.756, 0.988, 0.4 ],
|
||||
"location": "",
|
||||
"scaling": "relative"
|
||||
},
|
||||
"assets": [
|
||||
"./textures/main.png"
|
||||
]
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
{
|
||||
"name": "Gui: Menu",
|
||||
"type": "Gui",
|
||||
"behaviors": [
|
||||
"GuiBehavior"
|
||||
],
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ 0, 0, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 0, 1 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"color": [ 0.1, 0.05, 0.1, 0.5 ],
|
||||
"location": "",
|
||||
"scaling": "relative",
|
||||
// "depth": 0.2,
|
||||
"alpha": 1,
|
||||
"mode": 1
|
||||
},
|
||||
"assets": [
|
||||
// "./textures/menu.png",
|
||||
"./scripts/menu.lua"
|
||||
]
|
||||
}
|
||||
@ -1,43 +0,0 @@
|
||||
{
|
||||
"name": "Menu: Close Option",
|
||||
"type": "Gui",
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ -0.65544, -0.157698, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 0, 1 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 0.156407, 0.0788377, 1 ]
|
||||
},
|
||||
"clickable": true,
|
||||
"hoverable": true,
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"location": "",
|
||||
"scaling": "relative",
|
||||
"debug": {
|
||||
"moveable": true
|
||||
},
|
||||
"events": {
|
||||
"click": [
|
||||
{
|
||||
"name": "menu:Close.%P-UID%",
|
||||
"payload": {
|
||||
"callback": {
|
||||
"name": "game:Scene.Load",
|
||||
"payload": {
|
||||
"scene": "StartMenu"
|
||||
},
|
||||
"scope": "scene"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"text settings": {
|
||||
"string": "Quit",
|
||||
"string1": "終了する"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,194 +0,0 @@
|
||||
local scene = entities.currentScene()
|
||||
local metadata = ent:getComponent("Metadata")
|
||||
local masterdata = scene:getComponent("Metadata")
|
||||
|
||||
local children = {
|
||||
mainText = ent:loadChild("./main-text.json",true),
|
||||
circleOut = ent:loadChild("./circle-out.json",true),
|
||||
circleIn = ent:loadChild("./circle-in.json",true),
|
||||
coverBar = ent:loadChild("./yellow-box.json",true),
|
||||
commandText = ent:loadChild("./command-text.json",true),
|
||||
tenkouseiOption = ent:loadChild("./tenkousei.json",true),
|
||||
closeOption = ent:loadChild("./close.json",true),
|
||||
quit = ent:loadChild("./quit.json",true),
|
||||
}
|
||||
|
||||
local soundEmitter = ent:loadChild("./sound.json",true)
|
||||
|
||||
local timer = Timer.new()
|
||||
if not timer:running() then timer:start() end
|
||||
|
||||
Static = {
|
||||
values = {},
|
||||
get = function( obj )
|
||||
if obj == nil then
|
||||
obj = scene
|
||||
end
|
||||
if Static.values[""..obj:uid()] == nil then
|
||||
Static.values[""..obj:uid()] = {}
|
||||
end
|
||||
return Static.values[""..obj:uid()]
|
||||
end
|
||||
}
|
||||
|
||||
local destination = function( obj, x, y, z )
|
||||
local static = Static.get(obj)
|
||||
local transform = obj:getComponent("Transform")
|
||||
static.from = Vector3f(x or transform.position.x, y or transform.position.y, z or transform.position.z)
|
||||
end
|
||||
-- circleOut
|
||||
destination(children.circleOut, nil, -2, 0)
|
||||
destination(children.circleIn, nil, 2, 0)
|
||||
destination(children.coverBar, -1.5, nil, 0)
|
||||
destination(children.commandText, -1.5, nil, 0)
|
||||
destination(children.tenkouseiOption, -1.5, nil, 0)
|
||||
destination(children.closeOption, -1.5, nil, 0)
|
||||
destination(children.quit, -1.5, nil, 0)
|
||||
|
||||
local playSound = function( key )
|
||||
local url = "/ui/" .. key .. ".ogg"
|
||||
local assetLoader = scene:getComponent("Asset")
|
||||
assetLoader:cache(string.resolveURI(url), soundEmitter:formatHookName("asset:Load.%UID%"), "")
|
||||
end
|
||||
|
||||
ent:addHook("menu:Close.%UID%", function( json )
|
||||
playSound("menu close")
|
||||
|
||||
metadata["system"]["hooks"]["onClose"] = json["callback"];
|
||||
metadata["system"]["closing"] = true;
|
||||
ent:setComponent("Metadata", metadata)
|
||||
end )
|
||||
|
||||
--[[
|
||||
ent:addHook("asset:Load.%UID%", function( json )
|
||||
local filename = json["filename"]
|
||||
if filename == "" or string.extension( filename ) ~= "ogg" then return false end
|
||||
local sfx = ent:getComponent("Audio")
|
||||
if not sfx:playing() then sfx:stop() end
|
||||
sfx:load( filename )
|
||||
sfx:setVolume( masterdata["volumes"]["sfx"] )
|
||||
sfx:play()
|
||||
return true
|
||||
end )
|
||||
]]
|
||||
playSound("menu open")
|
||||
|
||||
ent:bind( "tick", function(self)
|
||||
local static = Static.get(self)
|
||||
if not static.alpha then
|
||||
static.alpha = 0
|
||||
end
|
||||
|
||||
-- handle closing
|
||||
if metadata["system"]["closing"] then
|
||||
if static.alpha <= 0 then
|
||||
static.alpha = 0
|
||||
metadata["system"]["closing"] = false
|
||||
metadata["system"]["closed"] = true
|
||||
else
|
||||
static.alpha = static.alpha - time.delta()
|
||||
end
|
||||
elseif metadata["system"]["closed"] then
|
||||
timer:stop()
|
||||
local callback = metadata["system"]["hooks"]["onClose"]
|
||||
if callback then
|
||||
local payload = callback["payload"]
|
||||
local target = self
|
||||
if callback["scope"] == "parent" then
|
||||
target = ent:getParent()
|
||||
elseif callback["scope"] == "scene" then
|
||||
target = scene
|
||||
end
|
||||
|
||||
if type(callback["delay"]) == "number" and target:uid() ~= self:uid() then
|
||||
target:queueHook( callback["name"], payload, callback["delay"] );
|
||||
else
|
||||
target:callHook( callback["name"], payload );
|
||||
end
|
||||
end
|
||||
entities.destroy(self)
|
||||
-- scene:queueHook("system:Destroy", { uid = self:uid() }, 0)
|
||||
return
|
||||
else
|
||||
if not metadata["initialized"] then
|
||||
static.alpha = 0
|
||||
end
|
||||
metadata["initialized"] = true;
|
||||
if static.alpha >= 1.0 then
|
||||
static.alpha = 1.0
|
||||
else
|
||||
static.alpha = static.alpha + time.delta() * 1.5
|
||||
end
|
||||
end
|
||||
|
||||
metadata["alpha"] = static.alpha;
|
||||
self:setComponent("Metadata", metadata)
|
||||
-- set alphas
|
||||
for k, v in pairs(children) do
|
||||
if v:uid() <= 0 then goto continue end
|
||||
|
||||
-- set alpha
|
||||
local metadata = v:getComponent("Metadata")
|
||||
metadata["alpha"] = static.alpha
|
||||
v:setComponent("Metadata", metadata)
|
||||
|
||||
local transform = v:getComponent("Transform")
|
||||
local static = Static.get(v)
|
||||
-- translation
|
||||
if not static.from then goto continue end
|
||||
if not static.to then static.to = Vector3f(transform.position) end
|
||||
if not static.delta then static.delta = 0 end
|
||||
|
||||
if static.delta >= 1 then
|
||||
static.delta = 1
|
||||
else
|
||||
static.delta = static.delta + time.delta() * 1.5
|
||||
transform.position = Vector3f.lerp( static.from, static.to, static.delta )
|
||||
end
|
||||
|
||||
::continue::
|
||||
end
|
||||
|
||||
-- main text
|
||||
local child = children.mainText
|
||||
if child:uid() > 0 then
|
||||
local transform = child:getComponent("Transform")
|
||||
local metadata = child:getComponent("Metadata")
|
||||
local speed = metadata["hovered"] and 0.75 or 0.5
|
||||
transform.position.y = transform.position.y + time.delta() * speed
|
||||
if transform.position.y > 2 then
|
||||
transform.position.y = -2
|
||||
end
|
||||
end
|
||||
-- circle in
|
||||
child = children.circleIn
|
||||
if child:uid() > 0 then
|
||||
local static = Static.get( child )
|
||||
|
||||
local transform = child:getComponent("Transform")
|
||||
local metadata = child:getComponent("Metadata")
|
||||
|
||||
-- rotation
|
||||
local speed = metadata["hovered"] and 0.25 or 0.0125
|
||||
static.time = (static.time or 0) + time.delta() * -speed
|
||||
transform.orientation = Quaternion.axisAngle( Vector3f(0, 0, 1), static.time )
|
||||
end
|
||||
-- circle out
|
||||
child = children.circleOut
|
||||
if child:uid() > 0 then
|
||||
local static = Static.get( child )
|
||||
|
||||
local transform = child:getComponent("Transform")
|
||||
local metadata = child:getComponent("Metadata")
|
||||
|
||||
-- rotation
|
||||
local speed = metadata["hovered"] and 0.25 or 0.0125
|
||||
static.time = (static.time or 0) + time.delta() * speed
|
||||
transform.orientation = Quaternion.axisAngle( Vector3f(0, 0, 1), static.time )
|
||||
end
|
||||
|
||||
if window.keyPressed("Escape") and timer:elapsed() >= 1 then
|
||||
timer:reset()
|
||||
self:callHook("menu:Close.%UID%", {})
|
||||
end
|
||||
end )
|
||||
@ -1,38 +0,0 @@
|
||||
{
|
||||
"type": "Object",
|
||||
"name": "Sound Emitter",
|
||||
"ignore": false,
|
||||
"assets": [
|
||||
],
|
||||
"behaviors": [
|
||||
"SoundEmitterBehavior"
|
||||
],
|
||||
"transform": {
|
||||
"position": [ 0, 0, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 1, 0 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"system": {
|
||||
"hot reload": {
|
||||
"enabled": true
|
||||
},
|
||||
"defaults": {
|
||||
"render": true,
|
||||
"asset load": true
|
||||
},
|
||||
"load": {
|
||||
"ignore": true
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"audio": {
|
||||
"spatial": false,
|
||||
"loop": false,
|
||||
"volume": "sfx",
|
||||
"rolloffFactor": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,24 +0,0 @@
|
||||
{
|
||||
"name": "Menu: Tenkousei Option",
|
||||
"type": "Gui",
|
||||
"ignore": true,
|
||||
"transform": {
|
||||
"position": [ -0.65544, -0.52853, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 0, 1 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 0.156407, 0.0788377, 1 ]
|
||||
},
|
||||
"clickable": true,
|
||||
"hoverable": true,
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"location": "",
|
||||
"scaling": "relative",
|
||||
"text settings": {
|
||||
"string": "",
|
||||
"string1": "「転光生」"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 225 B |
@ -1,21 +0,0 @@
|
||||
{
|
||||
"name": "Menu: Transient Portrait",
|
||||
"type": "Gui",
|
||||
"ignore": true,
|
||||
"transform": {
|
||||
"position": [ 0.76, 0.2, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 1, 0, 0 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 0.43, 1, 1 ]
|
||||
},
|
||||
"clickable": true,
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"color": [ 1, 1, 1, 0 ],
|
||||
"location": "",
|
||||
"scaling": "relative",
|
||||
"depth": 0.1
|
||||
}
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
{
|
||||
"name": "Menu: Transient Shadow",
|
||||
"type": "Gui",
|
||||
"ignore": true,
|
||||
"transform": {
|
||||
"position": [ 0.46, 0, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 1, 0, 0 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 0.43, 1, 1 ]
|
||||
},
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"color": [ 1, 1, 1, 0 ],
|
||||
"location": "",
|
||||
"scaling": "relative",
|
||||
"shader": 1,
|
||||
"depth": 0.1
|
||||
}
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
{
|
||||
"name": "Menu: Left Rectangle",
|
||||
"type": "Gui",
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ -0.933374, 0, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 1, 0, 0 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 0.067, 1, 1 ]
|
||||
},
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
// "color": [ 1, 0.749, 0.368, 1 ],
|
||||
"color": [ 1, 0.749, 0.368, 1 ],
|
||||
"location": "",
|
||||
"scaling": "relative",
|
||||
"shader": 1,
|
||||
"mode": "flat"
|
||||
},
|
||||
"assets": [
|
||||
"./textures/square.png"
|
||||
]
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
{
|
||||
"name": "Gui: Text",
|
||||
"type": "Object",
|
||||
"behaviors": [
|
||||
"GuiBehavior"
|
||||
],
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ 0, 0, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 0, 1 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"color": [ 1, 1, 1, 1 ],
|
||||
"location": "",
|
||||
"scaling": "relative"
|
||||
}
|
||||
}
|
||||
@ -1,42 +0,0 @@
|
||||
{
|
||||
"name": "Gui: Text",
|
||||
"type": "Gui",
|
||||
"ignore": true,
|
||||
"transform": {
|
||||
"position": [ 0, 0, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 0, 1 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"metadata": {
|
||||
"text settings": {
|
||||
"legacy": false,
|
||||
"padding": [ 4, 4 ],
|
||||
"spread": 4,
|
||||
"weight": 0.48395,
|
||||
"size": 72,
|
||||
"scale": 1.25,
|
||||
// "size": 112,
|
||||
// "scale": 1,
|
||||
"sdf": true,
|
||||
"font": "TAZUGANEGOTHICSTDN-BOLD.otf",
|
||||
"kerning": 24,
|
||||
// "font": "Coolvetica.ttf",
|
||||
|
||||
"stroke": [ 0, 0, 0, 0 ],
|
||||
"color": [ 1, 1, 1, 1 ],
|
||||
|
||||
"direction": "down",
|
||||
"align": "left",
|
||||
"origin": [ 0, 0 ],
|
||||
|
||||
"string": "",
|
||||
|
||||
"world": false,
|
||||
// "depth": 0,
|
||||
"wrap": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,76 +0,0 @@
|
||||
{
|
||||
"name": "Hands",
|
||||
"type": "Object",
|
||||
"ignore": true,
|
||||
"transform": {
|
||||
"position": [ 0, 0, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 1, 0 ],
|
||||
"angle": 0.0
|
||||
},
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"assets": [
|
||||
],
|
||||
"behaviors": [
|
||||
"PlayerHandBehavior"
|
||||
],
|
||||
"metadata": {
|
||||
"hands": {
|
||||
"left": {
|
||||
"controller": {
|
||||
"model": "{indexcontroller}valve_controller_knu_1_0_left",
|
||||
"color": [ 1, 1, 1, 1 ]
|
||||
},
|
||||
"light": {
|
||||
"should": false,
|
||||
"type": 3,
|
||||
"color": [1, 1, 1],
|
||||
"power": 50,
|
||||
"fov": 80,
|
||||
"shadows": true,
|
||||
"bias": 0.000005,
|
||||
"resolution": 512,
|
||||
"static": false
|
||||
},
|
||||
"pointer": {
|
||||
"color": [ 1, 0, 1, 1 ],
|
||||
"length": 0, //128,
|
||||
"width": 8,
|
||||
"offset": [ 0, 0, 0 ],
|
||||
"orientation": {
|
||||
"axis": [ 1, 0, 0 ],
|
||||
"angle": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"controller": {
|
||||
"model": "{indexcontroller}valve_controller_knu_1_0_right",
|
||||
"color": [ 1, 1, 1, 1 ]
|
||||
},
|
||||
"light": {
|
||||
"should": false,
|
||||
"type": 3,
|
||||
"color": [1, 1, 1],
|
||||
"power": 50,
|
||||
"fov": 80,
|
||||
"shadows": true,
|
||||
"bias": 0.000005,
|
||||
"resolution": 512,
|
||||
"static": false
|
||||
},
|
||||
"pointer": {
|
||||
"color": [ 1, 0, 1, 1 ],
|
||||
"length": 0, //128,
|
||||
"width": 8,
|
||||
"offset": [ 0, 0, 0 ],
|
||||
"orientation": {
|
||||
"axis": [ 1, 0, 0 ],
|
||||
"angle": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
{
|
||||
"name": "HUD Text",
|
||||
"type": "Gui",
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ -0.830591, -0.899509, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 1, 0, 0 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 0.258737, 0.115371, 1 ]
|
||||
},
|
||||
"system": {
|
||||
"hot reload": {
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"location": "",
|
||||
"scaling": "relative",
|
||||
"text settings": {
|
||||
"stroke": [ 1, 0.749, 0.368, 1 ],
|
||||
"color": [ 1, 0.749, 0.368, 1 ],
|
||||
"depth": 0.5,
|
||||
"string": "."
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
{
|
||||
"type": "Object",
|
||||
"name": "Light",
|
||||
"behaviors": [ "LightBehavior" ],
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"reference": true
|
||||
},
|
||||
"system": {
|
||||
"renderer": {
|
||||
// "limiter": 128
|
||||
// "mode": "round robin"
|
||||
// "mode": "once"
|
||||
"mode": "in-range"
|
||||
},
|
||||
"behavior-0": {
|
||||
"tick": {
|
||||
"head loop children": true,
|
||||
"forward iteration": false,
|
||||
"multithreading": false
|
||||
},
|
||||
"render": {
|
||||
"multithreading": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"light": {
|
||||
"type": "point",
|
||||
"color": [1, 1, 1],
|
||||
"power": 100,
|
||||
"fov": 90,
|
||||
"bias": {
|
||||
"constant": 1.25,
|
||||
"slope": 1.75,
|
||||
"shader": 0.00005
|
||||
},
|
||||
"radius": [0.05, 0],
|
||||
"resolution": 512,
|
||||
"shadows": true,
|
||||
"static": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,108 +0,0 @@
|
||||
{
|
||||
"name": "Player",
|
||||
"type": "Object",
|
||||
"behaviors": [
|
||||
"PlayerBehavior",
|
||||
"CraetureBehavior"
|
||||
],
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ 0, 0, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 1, 0 ],
|
||||
"angle": 0.0
|
||||
},
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"assets": [
|
||||
{ "filename": "./playerModel.json", "delay": 1.0, "single threaded": true },
|
||||
"./hands.json"
|
||||
],
|
||||
"system": {
|
||||
"behavior-0": {
|
||||
"tick": {
|
||||
"head loop children": false,
|
||||
"multithreading": false
|
||||
}
|
||||
},
|
||||
"physics": {
|
||||
"collision": 1.0,
|
||||
"impulse": true,
|
||||
"gravity": [ 0, -9.81, 0 ],
|
||||
"walk": 1,
|
||||
"move": 4,
|
||||
"run": 8,
|
||||
"rotate": 1.25,
|
||||
"crouch": 1,
|
||||
"jump": [ 0, 4, 0 ],
|
||||
|
||||
"type": "Capsule",
|
||||
"radius": 1,
|
||||
"height": 2,
|
||||
"mass": 100,
|
||||
"shared": false
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"overlay": {
|
||||
// "position": [ 0, 0, -3 ],
|
||||
// "scale": [ -1.77778, -1, 1 ],
|
||||
"position": [ 0, 0, -3 ],
|
||||
"scale": [ 1.77778, -1, 1 ],
|
||||
"orientation": [ 0, 0, 0, 1 ],
|
||||
"floating": false,
|
||||
"enabled": true,
|
||||
"alpha": 1.0,
|
||||
"cursor": {
|
||||
"type": "mouse",
|
||||
"radius": 0.05,
|
||||
"color": [ 0.2, 0.2, 1.0, 1.0 ],
|
||||
"enabled": false
|
||||
}
|
||||
},
|
||||
"light": {
|
||||
"should": false,
|
||||
"color": [1, 1, 1],
|
||||
"position": [ 0, 2.5, 0 ],
|
||||
"power": 0.1,
|
||||
"radius": [0.001, 32]
|
||||
},
|
||||
"region": {
|
||||
"track": true,
|
||||
"persist": true
|
||||
},
|
||||
"audio": {
|
||||
"footstep": {
|
||||
"volume": 0.5,
|
||||
"list": [
|
||||
"./data/audio/footstep/1.ogg",
|
||||
"./data/audio/footstep/2.ogg"
|
||||
]
|
||||
}
|
||||
},
|
||||
"camera": {
|
||||
"offset": [ 0, 0, 0 ],
|
||||
"position" : [ 0, 2, 0 ],
|
||||
"scale": [ 1, 1, 1 ],
|
||||
"invert": [ false, false, false ],
|
||||
"limit": {
|
||||
// "minima": [ null, -1.57079633, null ],
|
||||
// "maxima": [ null, 1.57079633, null ],
|
||||
|
||||
"minima": [ null, -1.0, null ],
|
||||
"maxima": [ null, 1.0, null ],
|
||||
|
||||
"current": [ null, 0, null ]
|
||||
},
|
||||
"settings": {
|
||||
"fov" : 90,
|
||||
"clip" : { "near" : 0.01, "far" : 512.0 },
|
||||
"size" : {
|
||||
"auto" : true,
|
||||
"x" : 7680,
|
||||
"y" : 4320
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,49 +0,0 @@
|
||||
{
|
||||
"type": "Object",
|
||||
"name": "Player: Model",
|
||||
"ignore": false,
|
||||
"assets": [
|
||||
"/player/bear.glb"
|
||||
// "/player/s.glb"
|
||||
],
|
||||
"behaviors": [
|
||||
"PlayerModelBehavior"
|
||||
],
|
||||
"transform": {
|
||||
"position": [ 0, -2.0, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 1, 0 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 0.16, 0.16, 0.16 ]
|
||||
},
|
||||
"system": {
|
||||
"hot reload": {
|
||||
"enabled": true
|
||||
},
|
||||
"defaults": {
|
||||
// "render": true,
|
||||
"asset load": true
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"track via reference": true,
|
||||
"track player": true,
|
||||
"hide player model": true,
|
||||
"model": {
|
||||
"animation": "wank",
|
||||
"print animations": true,
|
||||
// "mesh optimization": 1,
|
||||
"flags": {
|
||||
"RENDER": true,
|
||||
"COLLISION": false,
|
||||
"SEPARATE": true,
|
||||
"NORMALS": false,
|
||||
"LOAD": false,
|
||||
"ATLAS": false,
|
||||
"SKINNED": true,
|
||||
"INVERT": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
{
|
||||
"type": "Portals",
|
||||
"ignore": false,
|
||||
"metadata": {
|
||||
"portals": [
|
||||
{
|
||||
"transform": {
|
||||
"position": [ 0, 0, -10 ],
|
||||
"orientation": [ 0, 0, 0, 1 ],
|
||||
"scale": [ 6, 4, 1 ]
|
||||
},
|
||||
"metadata": {
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
"transform": {
|
||||
"position": [ 0, 0, 10 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 1, 0 ],
|
||||
"angle": 3.14159
|
||||
},
|
||||
"scale": [ 6, 4, 1 ]
|
||||
},
|
||||
"metadata": {
|
||||
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
{
|
||||
"name": "Scene",
|
||||
"assets": [
|
||||
"/gui.json"
|
||||
],
|
||||
"behaviors": [
|
||||
"SceneBehavior",
|
||||
"SceneCollisionBehavior",
|
||||
"ExtSceneBehavior"
|
||||
]
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
{
|
||||
"name": "Gui: Loading",
|
||||
"type": "Object",
|
||||
"behaviors": [
|
||||
// "GuiBehavior"
|
||||
],
|
||||
"assets": [
|
||||
{ "filename": "./mcdonalds.json", "delay": 0 }
|
||||
],
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ -0.830591, -0.699509, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 1, 0, 0 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 0.258737, 0.115371, 1 ]
|
||||
},
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"color": [ 1, 1, 1, 0.1 ],
|
||||
"location": "",
|
||||
"scaling": "relative",
|
||||
"text settings": {
|
||||
"stroke": [ 1, 0.749, 0.368, 1 ],
|
||||
"color": [ 1, 0.749, 0.368, 1 ],
|
||||
|
||||
"string": "Loading...",
|
||||
"string1": "コマンド"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,24 +0,0 @@
|
||||
{
|
||||
"name": "Marker",
|
||||
"type": "Gui",
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ 0, 0, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 1, 0, 0 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"color": [ 1, 1, 1, 0.8 ],
|
||||
"location": "",
|
||||
"scaling": [ 1, 1 ],
|
||||
"world": true,
|
||||
"gui layer": false
|
||||
},
|
||||
"assets": [
|
||||
"https://cdn..xyz//unity/Android/sprite/sprite_magiccircle_in2.png"
|
||||
]
|
||||
}
|
||||
@ -1,78 +0,0 @@
|
||||
{
|
||||
"type": "Object",
|
||||
"name": "Map",
|
||||
"ignore": false,
|
||||
"assets": [
|
||||
{ "filename": "./models/mcdonalds.glb", "delay": 0, "single threaded": false },
|
||||
{ "filename": "./static.json", "delay": 1 }
|
||||
],
|
||||
"behaviors": [
|
||||
"LoadingBehavior"
|
||||
],
|
||||
"transform": {
|
||||
"position": [ 0, 0, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 0, 1, 0 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 1, 1, 1 ]
|
||||
},
|
||||
"system": {
|
||||
"defaults": {
|
||||
"asset load": true
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"textures": {
|
||||
"map": {
|
||||
// "22": [ 86, "sin(time)" ],
|
||||
// "4": [ 88, "sin(time)" ],
|
||||
// "36": [ 87, 1.0 ]
|
||||
}
|
||||
},
|
||||
"model": {
|
||||
// "mesh optimization": 0,
|
||||
"cull mode": "auto",
|
||||
"flags": {
|
||||
"RENDER": true,
|
||||
"COLLISION": false,
|
||||
"SEPARATE": false,
|
||||
"NORMALS": false,
|
||||
"LOAD": false,
|
||||
"ATLAS": true,
|
||||
"SKINNED": false,
|
||||
"INVERT": false,
|
||||
"TRANSFORM": false
|
||||
},
|
||||
"lights": {
|
||||
// "renderMode": { "target": "worldspawn_1" },
|
||||
"shadows": true
|
||||
},
|
||||
"tags": {
|
||||
"worldspawn_1": { "collision": "static mesh" },
|
||||
"worldspawn_2": { "collision": "static mesh" },
|
||||
"info_player_spawn": { "action": "attach", "filename": "./player.json", "preserve orientation": true },
|
||||
/*
|
||||
"light_5752": {
|
||||
"transform": { "offset": true, "position": [ 0, -2.1768, 0 ] },
|
||||
"light": {
|
||||
// "flicker": { "rate": 0.5, "power": 0, "timeout": 4 },
|
||||
"fade": { "rate": 4, "color": [0, 0, 0], "timeout": 16 },
|
||||
"shadows": false
|
||||
}
|
||||
},
|
||||
*/
|
||||
"func_door_rotating_5243": { "action": "load", "payload": { "assets": ["./scripts/door.lua"], "metadata": { "angle":-1.570795 } } },
|
||||
"func_door_rotating_5444": { "action": "load", "payload": { "assets": ["./scripts/door.lua"], "metadata": { "angle": 1.570795 } } },
|
||||
"func_door_rotating_5495": { "action": "load", "payload": { "assets": ["./scripts/door.lua"], "metadata": { "angle": 1.570795 } } },
|
||||
"func_door_rotating_5220": { "action": "load", "payload": { "assets": ["./scripts/door.lua"], "metadata": { "angle":-1.570795 } } },
|
||||
"func_door_rotating_5556": { "action": "load", "payload": { "assets": ["./scripts/door.lua"], "metadata": { "angle": 1.570795 } } },
|
||||
"func_door_rotating_5689": { "action": "load", "payload": { "assets": ["./scripts/door.lua"], "metadata": { "angle":-1.570795 } } },
|
||||
"func_door_rotating_5712": { "action": "load", "payload": { "assets": ["./scripts/door.lua"], "metadata": { "angle": 1.570795 } } },
|
||||
"func_door_rotating_5576": { "action": "load", "payload": { "assets": ["./scripts/door.lua"], "metadata": { "angle":-1.570795 } } },
|
||||
"func_door_rotating_5584": { "action": "load", "payload": { "assets": ["./scripts/door.lua"], "metadata": { "angle":-1.570795 } } },
|
||||
"func_door_rotating_5568": { "action": "load", "payload": { "assets": ["./scripts/door.lua"], "metadata": { "angle":-1.570795 } } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
{
|
||||
"import": "/player.json",
|
||||
"assets": [
|
||||
// { "filename": "/gui/hud/hud.json", "delay": 0 }
|
||||
],
|
||||
"metadata": {
|
||||
"overlay": {
|
||||
"floating": true
|
||||
},
|
||||
"collider": true,
|
||||
"light": {
|
||||
"should": false,
|
||||
"color": [1, 1, 1],
|
||||
"position": [ 0, 2.5, 0 ],
|
||||
"power": 1,
|
||||
"radius": [0.001, 32]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,50 +0,0 @@
|
||||
{
|
||||
"import": "/scene.json",
|
||||
"assets": [
|
||||
"./audio/soundscape/ambience.ogg",
|
||||
"./loading.json"
|
||||
],
|
||||
"system": {
|
||||
"hot reload": {
|
||||
"enabled": true
|
||||
},
|
||||
"renderer": {
|
||||
"shader": {
|
||||
"mode": 1,
|
||||
"scalar": 16,
|
||||
"parameters": [ 0, 0, 0, 0 ]
|
||||
},
|
||||
"clear values": [
|
||||
[ 1, 1, 1, 0 ]
|
||||
]
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"menus": {
|
||||
"pause": "/gui/pause/menu.json"
|
||||
},
|
||||
"volumes": {
|
||||
"sfx": 0.25,
|
||||
"bgm": 0.75,
|
||||
"voice": 1.0
|
||||
},
|
||||
"light": {
|
||||
"ambient": [ 0.025, 0.025, 0.025 ],
|
||||
"kexp": 0,
|
||||
"fog": {
|
||||
"color": [ 0.25, 0.25, 0.25 ],
|
||||
"range": [ 32, 64 ],
|
||||
"step scale": 4,
|
||||
"absorbtion": 0.07,
|
||||
"density": {
|
||||
"threshold": 0.35,
|
||||
"multiplier": 5.0,
|
||||
"scale": 25.0,
|
||||
"offset": [0, -1, 1],
|
||||
"timescale": 8
|
||||
}
|
||||
},
|
||||
"should": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
local scene = entities.currentScene()
|
||||
local controller = entities.controller()
|
||||
|
||||
local timer = Timer.new()
|
||||
if not timer:running() then
|
||||
timer:start();
|
||||
end
|
||||
|
||||
local target = Vector3f(0,0,0)
|
||||
local transform = ent:getComponent("Transform")
|
||||
local metadata = ent:getComponent("Metadata")
|
||||
local speed = metadata["speed"] or 1.0 / 3.0
|
||||
local starting = Quaternion(transform.orientation)
|
||||
local ending = transform.orientation:multiply(Quaternion.axisAngle( Vector3f(0,1,0), metadata["angle"] ))
|
||||
-- on tick
|
||||
ent:bind( "tick", function(self)
|
||||
transform.orientation = starting:slerp( ending, math.cos(time.current() * speed) * 0.5 + 0.5 )
|
||||
end )
|
||||