port from perforce
This commit is contained in:
1514
underwater4k/4klang.asm
Normal file
1514
underwater4k/4klang.asm
Normal file
File diff suppressed because it is too large
Load Diff
22
underwater4k/4klang.h
Normal file
22
underwater4k/4klang.h
Normal file
@@ -0,0 +1,22 @@
|
||||
// some useful song defines for 4klang
|
||||
#define SAMPLE_RATE 44100
|
||||
#define BPM 137.126862
|
||||
#define MAX_INSTRUMENTS 9
|
||||
#define MAX_PATTERNS 132
|
||||
#define PATTERN_SIZE_SHIFT 3
|
||||
#define PATTERN_SIZE (1 << PATTERN_SIZE_SHIFT)
|
||||
#define MAX_TICKS (MAX_PATTERNS*PATTERN_SIZE)
|
||||
#define SAMPLES_PER_TICK 4824
|
||||
#define MAX_SAMPLES (SAMPLES_PER_TICK*MAX_TICKS)
|
||||
#define POLYPHONY 1
|
||||
#define FLOAT_32BIT
|
||||
#define SAMPLE_TYPE float
|
||||
|
||||
#define WINDOWS_OBJECT
|
||||
|
||||
// declaration of the external synth render function, you'll always need that
|
||||
extern "C" void __stdcall _4klang_render(void*);
|
||||
// declaration of the external envelope buffer. access only if you're song was exported with that option
|
||||
extern "C" float _4klang_envelope_buffer;
|
||||
// declaration of the external note buffer. access only if you're song was exported with that option
|
||||
extern "C" int _4klang_note_buffer;
|
||||
850
underwater4k/4klang.inc
Normal file
850
underwater4k/4klang.inc
Normal file
@@ -0,0 +1,850 @@
|
||||
%macro export_func 1
|
||||
global _%1
|
||||
_%1:
|
||||
%endmacro
|
||||
%define USE_SECTIONS
|
||||
%define SAMPLE_RATE 44100
|
||||
%define MAX_INSTRUMENTS 9
|
||||
%define MAX_VOICES 1
|
||||
%define HLD 1
|
||||
%define BPM 137.126862
|
||||
%define MAX_PATTERNS 132
|
||||
%define PATTERN_SIZE_SHIFT 3
|
||||
%define PATTERN_SIZE (1 << PATTERN_SIZE_SHIFT)
|
||||
%define MAX_TICKS (MAX_PATTERNS*PATTERN_SIZE)
|
||||
%define SAMPLES_PER_TICK 4824
|
||||
%define DEF_LFO_NORMALIZE 0.0000518242
|
||||
%define MAX_SAMPLES (SAMPLES_PER_TICK*MAX_TICKS)
|
||||
;%define GO4K_USE_16BIT_OUTPUT
|
||||
;%define GO4K_USE_GROOVE_PATTERN
|
||||
%define GO4K_USE_ENVELOPE_RECORDINGS
|
||||
;%define GO4K_USE_NOTE_RECORDINGS
|
||||
%define GO4K_CLIP_OUTPUT
|
||||
%define GO4K_USE_DST
|
||||
%define GO4K_USE_DLL
|
||||
%define GO4K_USE_PAN
|
||||
%define GO4K_USE_GLOBAL_DLL
|
||||
%define GO4K_USE_FSTG
|
||||
%define GO4K_USE_ENV_CHECK
|
||||
%define GO4K_USE_ENV_MOD_GM
|
||||
%define GO4K_USE_VCO_CHECK
|
||||
%define GO4K_USE_VCO_PHASE_OFFSET
|
||||
%define GO4K_USE_VCO_SHAPE
|
||||
%define GO4K_USE_VCO_GATE
|
||||
%define GO4K_USE_VCO_MOD_TM
|
||||
%define GO4K_USE_VCO_MOD_DM
|
||||
%define GO4K_USE_VCO_MOD_CM
|
||||
%define GO4K_USE_VCF_CHECK
|
||||
%define GO4K_USE_VCF_MOD_FM
|
||||
%define GO4K_USE_VCF_MOD_RM
|
||||
%define GO4K_USE_VCF_HIGH
|
||||
%define GO4K_USE_VCF_BAND
|
||||
%define GO4K_USE_VCF_PEAK
|
||||
%define GO4K_USE_DST_CHECK
|
||||
%define GO4K_USE_DLL_CHORUS
|
||||
%define GO4K_USE_DLL_CHORUS_CLAMP
|
||||
%define GO4K_USE_DLL_DAMP
|
||||
%define GO4K_USE_DLL_DC_FILTER
|
||||
%define GO4K_USE_FSTG_CHECK
|
||||
%define GO4K_USE_WAVESHAPER_CLIP
|
||||
%define MAX_DELAY 65536
|
||||
%define MAX_WORKSPACE_SLOTS 8
|
||||
%define GO4K_BEGIN_CMDDEF(def_name)
|
||||
%define GO4K_END_CMDDEF db 0
|
||||
%define GO4K_BEGIN_PARAMDEF(def_name)
|
||||
%define GO4K_END_PARAMDEF
|
||||
GO4K_ENV_ID equ 1
|
||||
%macro GO4K_ENV 5
|
||||
db %1
|
||||
db %2
|
||||
db %3
|
||||
db %4
|
||||
db %5
|
||||
%endmacro
|
||||
%define ATTAC(val) val
|
||||
%define DECAY(val) val
|
||||
%define SUSTAIN(val) val
|
||||
%define RELEASE(val) val
|
||||
%define GAIN(val) val
|
||||
struc go4kENV_val
|
||||
.attac resd 1
|
||||
.decay resd 1
|
||||
.sustain resd 1
|
||||
.release resd 1
|
||||
.gain resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kENV_wrk
|
||||
.state resd 1
|
||||
.level resd 1
|
||||
.gm resd 1
|
||||
.am resd 1
|
||||
.dm resd 1
|
||||
.sm resd 1
|
||||
.rm resd 1
|
||||
.size
|
||||
endstruc
|
||||
%define ENV_STATE_ATTAC 0
|
||||
%define ENV_STATE_DECAY 1
|
||||
%define ENV_STATE_SUSTAIN 2
|
||||
%define ENV_STATE_RELEASE 3
|
||||
%define ENV_STATE_OFF 4
|
||||
GO4K_VCO_ID equ 2
|
||||
%macro GO4K_VCO 8
|
||||
db %1
|
||||
db %2
|
||||
%ifdef GO4K_USE_VCO_PHASE_OFFSET
|
||||
db %3
|
||||
%endif
|
||||
%ifdef GO4K_USE_VCO_GATE
|
||||
db %4
|
||||
%endif
|
||||
db %5
|
||||
%ifdef GO4K_USE_VCO_SHAPE
|
||||
db %6
|
||||
%endif
|
||||
db %7
|
||||
db %8
|
||||
%endmacro
|
||||
%define TRANSPOSE(val) val
|
||||
%define DETUNE(val) val
|
||||
%define PHASE(val) val
|
||||
%define GATES(val) val
|
||||
%define COLOR(val) val
|
||||
%define SHAPE(val) val
|
||||
%define FLAGS(val) val
|
||||
%define SINE 0x01
|
||||
%define TRISAW 0x02
|
||||
%define PULSE 0x04
|
||||
%define NOISE 0x08
|
||||
%define LFO 0x10
|
||||
%define GATE 0x20
|
||||
struc go4kVCO_val
|
||||
.transpose resd 1
|
||||
.detune resd 1
|
||||
%ifdef GO4K_USE_VCO_PHASE_OFFSET
|
||||
.phaseofs resd 1
|
||||
%endif
|
||||
%ifdef GO4K_USE_VCO_GATE
|
||||
.gate resd 1
|
||||
%endif
|
||||
.color resd 1
|
||||
%ifdef GO4K_USE_VCO_SHAPE
|
||||
.shape resd 1
|
||||
%endif
|
||||
.gain resd 1
|
||||
.flags resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kVCO_wrk
|
||||
.phase resd 1
|
||||
.tm resd 1
|
||||
.dm resd 1
|
||||
.fm resd 1
|
||||
.pm resd 1
|
||||
.cm resd 1
|
||||
.sm resd 1
|
||||
.gm resd 1
|
||||
.size
|
||||
endstruc
|
||||
GO4K_VCF_ID equ 3
|
||||
%macro GO4K_VCF 3
|
||||
db %1
|
||||
db %2
|
||||
db %3
|
||||
%endmacro
|
||||
%define LOWPASS 0x1
|
||||
%define HIGHPASS 0x2
|
||||
%define BANDPASS 0x4
|
||||
%define BANDSTOP 0x3
|
||||
%define ALLPASS 0x7
|
||||
%define PEAK 0x8
|
||||
%define FREQUENCY(val) val
|
||||
%define RESONANCE(val) val
|
||||
%define VCFTYPE(val) val
|
||||
struc go4kVCF_val
|
||||
.freq resd 1
|
||||
.res resd 1
|
||||
.type resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kVCF_wrk
|
||||
.low resd 1
|
||||
.high resd 1
|
||||
.band resd 1
|
||||
.freq resd 1
|
||||
.fm resd 1
|
||||
.rm resd 1
|
||||
.size
|
||||
endstruc
|
||||
GO4K_DST_ID equ 4
|
||||
%macro GO4K_DST 2
|
||||
db %1
|
||||
%ifdef GO4K_USE_DST_SH
|
||||
db %2
|
||||
%endif
|
||||
%endmacro
|
||||
%define DRIVE(val) val
|
||||
%define SNHFREQ(val) val
|
||||
struc go4kDST_val
|
||||
.drive resd 1
|
||||
%ifdef GO4K_USE_DST_SH
|
||||
.snhfreq resd 1
|
||||
%endif
|
||||
.size
|
||||
endstruc
|
||||
struc go4kDST_wrk
|
||||
%ifdef GO4K_USE_DST_SH
|
||||
.out resd 1
|
||||
.snhphase resd 1
|
||||
%endif
|
||||
.dm resd 1
|
||||
.sm resd 1
|
||||
.size
|
||||
endstruc
|
||||
GO4K_DLL_ID equ 5
|
||||
%macro GO4K_DLL 8
|
||||
db %1
|
||||
db %2
|
||||
db %3
|
||||
%ifdef GO4K_USE_DLL_DAMP
|
||||
db %4
|
||||
%endif
|
||||
%ifdef GO4K_USE_DLL_CHORUS
|
||||
db %5
|
||||
db %6
|
||||
%endif
|
||||
db %7
|
||||
db %8
|
||||
%endmacro
|
||||
%define PREGAIN(val) val
|
||||
%define DRY(val) val
|
||||
%define FEEDBACK(val) val
|
||||
%define DEPTH(val) val
|
||||
%define DAMP(val) val
|
||||
%define DELAY(val) val
|
||||
%define COUNT(val) val
|
||||
struc go4kDLL_val
|
||||
.pregain resd 1
|
||||
.dry resd 1
|
||||
.feedback resd 1
|
||||
%ifdef GO4K_USE_DLL_DAMP
|
||||
.damp resd 1
|
||||
%endif
|
||||
%ifdef GO4K_USE_DLL_CHORUS
|
||||
.freq resd 1
|
||||
.depth
|
||||
%endif
|
||||
.delay resd 1
|
||||
.count resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kDLL_wrk
|
||||
.index resd 1
|
||||
.store resd 1
|
||||
.dcin resd 1
|
||||
.dcout resd 1
|
||||
%ifdef GO4K_USE_DLL_CHORUS
|
||||
.phase resd 1
|
||||
%endif
|
||||
.buffer resd MAX_DELAY
|
||||
.size
|
||||
endstruc
|
||||
struc go4kDLL_wrk2
|
||||
.pm resd 1
|
||||
.fm resd 1
|
||||
.im resd 1
|
||||
.dm resd 1
|
||||
.sm resd 1
|
||||
.am resd 1
|
||||
.size
|
||||
endstruc
|
||||
GO4K_FOP_ID equ 6
|
||||
%macro GO4K_FOP 1
|
||||
db %1
|
||||
%endmacro
|
||||
%define OP(val) val
|
||||
%define FOP_POP 0x1
|
||||
%define FOP_ADDP 0x2
|
||||
%define FOP_MULP 0x3
|
||||
%define FOP_PUSH 0x4
|
||||
%define FOP_XCH 0x5
|
||||
%define FOP_ADD 0x6
|
||||
%define FOP_MUL 0x7
|
||||
%define FOP_ADDP2 0x8
|
||||
%define FOP_LOADNOTE 0x9
|
||||
struc go4kFOP_val
|
||||
.flags resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kFOP_wrk
|
||||
.size
|
||||
endstruc
|
||||
GO4K_FST_ID equ 7
|
||||
%macro GO4K_FST 2
|
||||
db %1
|
||||
db %2
|
||||
%endmacro
|
||||
%define AMOUNT(val) val
|
||||
%define DEST(val) val
|
||||
struc go4kFST_val
|
||||
.amount resd 1
|
||||
.op1 resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kFST_wrk
|
||||
.size
|
||||
endstruc
|
||||
GO4K_PAN_ID equ 8
|
||||
%macro GO4K_PAN 1
|
||||
%ifdef GO4K_USE_PAN
|
||||
db %1
|
||||
%endif
|
||||
%endmacro
|
||||
%define PANNING(val) val
|
||||
struc go4kPAN_val
|
||||
%ifdef GO4K_USE_PAN
|
||||
.panning resd 1
|
||||
%endif
|
||||
.size
|
||||
endstruc
|
||||
struc go4kPAN_wrk
|
||||
.pm resd 1
|
||||
.size
|
||||
endstruc
|
||||
GO4K_OUT_ID equ 9
|
||||
%macro GO4K_OUT 2
|
||||
db %1
|
||||
%ifdef GO4K_USE_GLOBAL_DLL
|
||||
db %2
|
||||
%endif
|
||||
%endmacro
|
||||
%define AUXSEND(val) val
|
||||
struc go4kOUT_val
|
||||
.gain resd 1
|
||||
%ifdef GO4K_USE_GLOBAL_DLL
|
||||
.auxsend resd 1
|
||||
%endif
|
||||
.size
|
||||
endstruc
|
||||
struc go4kOUT_wrk
|
||||
.am resd 1
|
||||
.gm resd 1
|
||||
.size
|
||||
endstruc
|
||||
GO4K_ACC_ID equ 10
|
||||
%macro GO4K_ACC 1
|
||||
db %1
|
||||
%endmacro
|
||||
%define OUTPUT 0
|
||||
%define AUX 8
|
||||
%define ACCTYPE(val) val
|
||||
struc go4kACC_val
|
||||
.acctype resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kACC_wrk
|
||||
.size
|
||||
endstruc
|
||||
%ifdef GO4K_USE_FLD
|
||||
GO4K_FLD_ID equ 11
|
||||
%macro GO4K_FLD 1
|
||||
db
|
||||
%endmacro
|
||||
%define VALUE(val) val
|
||||
struc go4kFLD_val
|
||||
.value resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kFLD_wrk
|
||||
.vm resd 1
|
||||
.size
|
||||
endstruc
|
||||
%endif
|
||||
%ifdef GO4K_USE_FSTG
|
||||
GO4K_FSTG_ID equ 12
|
||||
%macro GO4K_FSTG 2
|
||||
db %1
|
||||
dd %2
|
||||
%endmacro
|
||||
struc go4kFSTG_val
|
||||
.amount resd 1
|
||||
.op1 resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4kFSTG_wrk
|
||||
.size
|
||||
endstruc
|
||||
%endif
|
||||
struc go4k_instrument
|
||||
.release resd 1
|
||||
.note resd 1
|
||||
.workspace resd 256
|
||||
.dlloutl resd 1
|
||||
.dlloutr resd 1
|
||||
.outl resd 1
|
||||
.outr resd 1
|
||||
.size
|
||||
endstruc
|
||||
struc go4k_synth
|
||||
.instruments resb go4k_instrument.size * MAX_INSTRUMENTS * MAX_VOICES
|
||||
.global resb go4k_instrument.size * MAX_VOICES
|
||||
.size
|
||||
endstruc
|
||||
%ifdef USE_SECTIONS
|
||||
section .g4kmuc1 data align=1
|
||||
%else
|
||||
section .data align=1
|
||||
%endif
|
||||
go4k_patterns
|
||||
db 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
db 50, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db HLD, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 38, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 57, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 45, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 48, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 36, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 55, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 43, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 60, HLD, 0, 0, 60, HLD, 0, 0,
|
||||
db 60, HLD, 0, 0, 0, 0, 0, 0,
|
||||
db 0, 50, 62, 50, 0, 50, 62, 50,
|
||||
db 0, 45, 57, 45, 0, 45, 57, 45,
|
||||
db 0, 48, 60, 48, 0, 48, 60, 48,
|
||||
db 0, 55, 67, 55, 0, 55, 67, 55,
|
||||
db 0, 0, 0, 0, 62, HLD, HLD, HLD,
|
||||
db HLD, HLD, HLD, HLD, 62, HLD, HLD, HLD,
|
||||
db 62, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 60, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 0, 0, 0, 88, 89, HLD, 89, HLD,
|
||||
db 0, 0, 0, 88, 84, HLD, 84, HLD,
|
||||
db 0, 0, 0, 86, 88, HLD, 88, HLD,
|
||||
db 0, 0, 0, 84, 81, HLD, 81, HLD,
|
||||
db 0, 0, 0, 84, 79, HLD, 79, HLD,
|
||||
db 0, 0, 0, 84, 86, HLD, 86, HLD,
|
||||
db 0, 0, 0, 84, 83, HLD, 83, HLD,
|
||||
db 0, 0, 0, 89, 91, HLD, 91, HLD,
|
||||
db 0, 0, 0, 91, 89, HLD, 89, HLD,
|
||||
db 86, HLD, 0, 0, 0, 0, 74, HLD,
|
||||
db 81, HLD, 0, 0, 0, 0, 69, HLD,
|
||||
db 84, HLD, 0, 0, 0, 0, 72, HLD,
|
||||
db 79, HLD, 0, 0, 0, 0, 67, HLD,
|
||||
db 93, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 98, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 0, 0, 0, 0, 0, 0, 0, 91,
|
||||
db 93, HLD, 91, HLD, 93, HLD, 96, HLD,
|
||||
db 0, 0, 0, 0, 0, 0, 96, HLD,
|
||||
db 98, HLD, HLD, HLD, 96, HLD, 98, HLD,
|
||||
db 100, HLD, HLD, HLD, HLD, HLD, HLD, HLD,
|
||||
db 0, 0, 0, 0, 0, 0, 98, 0,
|
||||
db 100, HLD, 98, HLD, 100, HLD, 103, HLD,
|
||||
db HLD, 0, 0, 0, 0, 0, 0, 0,
|
||||
go4k_patterns_end
|
||||
%ifdef USE_SECTIONS
|
||||
section .g4kmuc2 data align=1
|
||||
%else
|
||||
section .data
|
||||
%endif
|
||||
go4k_pattern_lists
|
||||
Instrument0List db 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 3, 4, 5, 4, 5, 6, 7, 6, 7, 8, 9, 8, 9, 1, 3, 1, 3, 4, 5, 4, 5, 6, 7, 6, 7, 8, 9, 8, 9, 1, 3, 1, 3, 4, 5, 4, 5, 6, 7, 6, 7, 8, 9, 8, 9, 1, 3, 1, 3, 4, 5, 4, 5, 6, 7, 6, 7, 8, 9, 8, 9, 1, 3, 1, 3, 4, 5, 4, 5, 6, 7, 6, 7, 8, 9, 8, 9, 1, 3, 1, 3, 4, 5, 4, 5, 6, 7, 6, 7, 8, 9, 8, 9, 1, 3, 1, 3, 4, 5, 4, 5, 6, 7, 6, 7, 8, 9, 8, 9, 1, 2, 0, 0,
|
||||
Instrument1List db 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 0,
|
||||
Instrument2List db 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 12, 12, 0, 0,
|
||||
Instrument3List db 0, 0, 0, 0, 0, 0, 0, 16, 2, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
Instrument4List db 0, 0, 0, 0, 0, 0, 0, 0, 19, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
Instrument5List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 20, 21, 22, 23, 22, 23, 22, 24, 22, 24, 25, 26, 27, 28, 20, 21, 20, 21, 22, 23, 22, 23, 22, 24, 22, 24, 25, 26, 27, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 20, 21, 22, 23, 22, 23, 22, 24, 22, 24, 25, 26, 27, 28, 20, 21, 20, 21, 22, 23, 22, 23, 22, 24, 22, 24, 25, 26, 27, 28, 20, 21, 20, 21, 22, 23, 22, 23, 22, 24, 22, 24, 25, 26, 27, 28, 0, 0, 0, 0,
|
||||
Instrument6List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 29, 0, 30, 0, 30, 0, 31, 0, 31, 0, 32, 0, 32, 0, 29, 0, 29, 0, 30, 0, 30, 0, 31, 0, 31, 0, 32, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 29, 0, 30, 0, 30, 0, 31, 0, 31, 0, 32, 0, 32, 0, 29, 0, 29, 0, 30, 0, 30, 0, 31, 0, 31, 0, 32, 0, 32, 0, 29, 0, 0, 0,
|
||||
Instrument7List db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 34, 2, 35, 36, 2, 2, 37, 38, 39, 2, 40, 41, 34, 2, 0, 33, 34, 2, 35, 36, 2, 2, 37, 38, 39, 2, 40, 41, 34, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 34, 2, 35, 36, 2, 2, 37, 38, 39, 2, 40, 41, 34, 2, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
Instrument8List db 19, 2, 2, 2, 2, 2, 2, 2, 19, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 19, 2, 2, 42,
|
||||
go4k_pattern_lists_end
|
||||
%ifdef USE_SECTIONS
|
||||
section .g4kmuc3 data align=1
|
||||
%else
|
||||
section .data
|
||||
%endif
|
||||
go4k_synth_instructions
|
||||
GO4K_BEGIN_CMDDEF(Instrument0)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DST_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_DST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_DST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument1)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FSTG_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_DST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument2)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument3)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument4)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument5)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument6)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FST_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument7)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_VCO_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_PAN_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Instrument8)
|
||||
db GO4K_ENV_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_FSTG_ID
|
||||
db GO4K_FSTG_ID
|
||||
db GO4K_FSTG_ID
|
||||
db GO4K_FSTG_ID
|
||||
db GO4K_FOP_ID
|
||||
GO4K_END_CMDDEF
|
||||
GO4K_BEGIN_CMDDEF(Global)
|
||||
db GO4K_ACC_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_VCF_ID
|
||||
db GO4K_DLL_ID
|
||||
db GO4K_ACC_ID
|
||||
db GO4K_FOP_ID
|
||||
db GO4K_OUT_ID
|
||||
GO4K_END_CMDDEF
|
||||
go4k_synth_instructions_end
|
||||
%ifdef USE_SECTIONS
|
||||
section .g4kmuc4 data align=1
|
||||
%else
|
||||
section .data
|
||||
%endif
|
||||
go4k_synth_parameter_values
|
||||
GO4K_BEGIN_PARAMDEF(Instrument0)
|
||||
GO4K_ENV ATTAC(0),DECAY(64),SUSTAIN(64),RELEASE(0),GAIN(128)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(66),PHASE(96),GATES(0),COLOR(112),SHAPE(32),GAIN(128),FLAGS(TRISAW)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(72),PHASE(0),GATES(85),COLOR(48),SHAPE(80),GAIN(128),FLAGS(SINE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(56),PHASE(32),GATES(85),COLOR(40),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(72),PHASE(48),GATES(85),COLOR(48),SHAPE(32),GAIN(128),FLAGS(SINE)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_DST DRIVE(80), SNHFREQ(128)
|
||||
GO4K_VCF FREQUENCY(96),RESONANCE(64),VCFTYPE(LOWPASS)
|
||||
GO4K_DST DRIVE(96), SNHFREQ(128)
|
||||
GO4K_FOP OP(FOP_PUSH)
|
||||
GO4K_VCF FREQUENCY(64),RESONANCE(64),VCFTYPE(HIGHPASS)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_VCF FREQUENCY(64),RESONANCE(64),VCFTYPE(LOWPASS)
|
||||
GO4K_DST DRIVE(96), SNHFREQ(128)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_OUT GAIN(128), AUXSEND(8)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument1)
|
||||
GO4K_ENV ATTAC(0),DECAY(32),SUSTAIN(96),RELEASE(64),GAIN(128)
|
||||
GO4K_FST AMOUNT(128),DEST(0*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_ENV ATTAC(0),DECAY(72),SUSTAIN(0),RELEASE(0),GAIN(128)
|
||||
GO4K_FSTG AMOUNT(128),DEST(8*go4k_instrument.size*MAX_VOICES+0*MAX_WORKSPACE_SLOTS*4+2*4+go4k_instrument.workspace)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_ENV ATTAC(0),DECAY(72),SUSTAIN(0),RELEASE(0),GAIN(128)
|
||||
GO4K_DST DRIVE(32), SNHFREQ(128)
|
||||
GO4K_FST AMOUNT(80),DEST(9*MAX_WORKSPACE_SLOTS+1)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_VCO TRANSPOSE(44),DETUNE(64),PHASE(0),GATES(85),COLOR(64),SHAPE(64),GAIN(128),FLAGS(SINE)
|
||||
GO4K_ENV ATTAC(0),DECAY(32),SUSTAIN(0),RELEASE(0),GAIN(128)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(0),GATES(0),COLOR(64),SHAPE(64),GAIN(128),FLAGS(NOISE)
|
||||
GO4K_VCF FREQUENCY(64),RESONANCE(128),VCFTYPE(HIGHPASS)
|
||||
GO4K_VCF FREQUENCY(96),RESONANCE(64),VCFTYPE(LOWPASS)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_OUT GAIN(128), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument2)
|
||||
GO4K_ENV ATTAC(0),DECAY(64),SUSTAIN(0),RELEASE(72),GAIN(128)
|
||||
GO4K_ENV ATTAC(0),DECAY(72),SUSTAIN(0),RELEASE(80),GAIN(128)
|
||||
GO4K_FST AMOUNT(96),DEST(18*MAX_WORKSPACE_SLOTS+4)
|
||||
GO4K_FST AMOUNT(96),DEST(19*MAX_WORKSPACE_SLOTS+4)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_FOP OP(FOP_PUSH)
|
||||
GO4K_VCO TRANSPOSE(72),DETUNE(64),PHASE(0),GATES(85),COLOR(64),SHAPE(64),GAIN(128),FLAGS(SINE|LFO)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FST AMOUNT(32),DEST(13*MAX_WORKSPACE_SLOTS+5)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_VCO TRANSPOSE(96),DETUNE(64),PHASE(0),GATES(85),COLOR(64),SHAPE(64),GAIN(128),FLAGS(SINE|LFO)
|
||||
GO4K_FST AMOUNT(80),DEST(15*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_VCO TRANSPOSE(76),DETUNE(64),PHASE(0),GATES(85),COLOR(128),SHAPE(64),GAIN(128),FLAGS(PULSE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(0),GATES(85),COLOR(64),SHAPE(64),GAIN(128),FLAGS(PULSE)
|
||||
GO4K_VCO TRANSPOSE(76),DETUNE(64),PHASE(0),GATES(85),COLOR(0),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_VCF FREQUENCY(24),RESONANCE(96),VCFTYPE(LOWPASS)
|
||||
GO4K_VCF FREQUENCY(24),RESONANCE(96),VCFTYPE(PEAK)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_DLL PREGAIN(64),DRY(128),FEEDBACK(64),DAMP(32),FREQUENCY(0),DEPTH(0),DELAY(16),COUNT(1)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_DLL PREGAIN(128),DRY(0),FEEDBACK(0),DAMP(0),FREQUENCY(0),DEPTH(0),DELAY(17),COUNT(1)
|
||||
GO4K_OUT GAIN(40), AUXSEND(8)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument3)
|
||||
GO4K_ENV ATTAC(0),DECAY(80),SUSTAIN(0),RELEASE(0),GAIN(128)
|
||||
GO4K_FST AMOUNT(128),DEST(0*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_ENV ATTAC(0),DECAY(32),SUSTAIN(0),RELEASE(0),GAIN(128)
|
||||
GO4K_FST AMOUNT(104),DEST(6*MAX_WORKSPACE_SLOTS+1)
|
||||
GO4K_FST AMOUNT(72),DEST(7*MAX_WORKSPACE_SLOTS+1)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_VCO TRANSPOSE(52),DETUNE(64),PHASE(0),GATES(85),COLOR(64),SHAPE(32),GAIN(48),FLAGS(SINE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(0),GATES(85),COLOR(64),SHAPE(80),GAIN(48),FLAGS(SINE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(0),GATES(85),COLOR(64),SHAPE(16),GAIN(64),FLAGS(NOISE)
|
||||
GO4K_VCF FREQUENCY(112),RESONANCE(128),VCFTYPE(LOWPASS)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(0),GATES(85),COLOR(64),SHAPE(64),GAIN(16),FLAGS(NOISE)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(24),RESONANCE(32),VCFTYPE(HIGHPASS)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_OUT GAIN(8), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument4)
|
||||
GO4K_ENV ATTAC(0),DECAY(128),SUSTAIN(128),RELEASE(0),GAIN(128)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(64),GATES(85),COLOR(64),SHAPE(64),GAIN(128),FLAGS(NOISE)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_VCF FREQUENCY(112),RESONANCE(128),VCFTYPE(HIGHPASS)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(0),GATES(17),COLOR(17),SHAPE(64),GAIN(128),FLAGS(GATE|LFO)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_OUT GAIN(8), AUXSEND(16)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument5)
|
||||
GO4K_ENV ATTAC(0),DECAY(64),SUSTAIN(64),RELEASE(72),GAIN(128)
|
||||
GO4K_FST AMOUNT(112),DEST(0*MAX_WORKSPACE_SLOTS+2)
|
||||
GO4K_VCO TRANSPOSE(52),DETUNE(64),PHASE(0),GATES(85),COLOR(64),SHAPE(64),GAIN(128),FLAGS(PULSE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(0),GATES(85),COLOR(0),SHAPE(64),GAIN(128),FLAGS(TRISAW)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_ENV ATTAC(0),DECAY(64),SUSTAIN(16),RELEASE(64),GAIN(128)
|
||||
GO4K_FST AMOUNT(96),DEST(9*MAX_WORKSPACE_SLOTS+4)
|
||||
GO4K_FST AMOUNT(96),DEST(10*MAX_WORKSPACE_SLOTS+4)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_VCF FREQUENCY(16),RESONANCE(128),VCFTYPE(PEAK)
|
||||
GO4K_VCF FREQUENCY(8),RESONANCE(128),VCFTYPE(LOWPASS)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_DLL PREGAIN(64),DRY(128),FEEDBACK(64),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(16),COUNT(1)
|
||||
GO4K_PAN PANNING(64)
|
||||
GO4K_DLL PREGAIN(128),DRY(0),FEEDBACK(0),DAMP(0),FREQUENCY(0),DEPTH(0),DELAY(18),COUNT(1)
|
||||
GO4K_OUT GAIN(32), AUXSEND(8)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument6)
|
||||
GO4K_ENV ATTAC(48),DECAY(80),SUSTAIN(64),RELEASE(64),GAIN(128)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(0),GATES(85),COLOR(64),SHAPE(64),GAIN(64),FLAGS(NOISE)
|
||||
GO4K_VCO TRANSPOSE(16),DETUNE(64),PHASE(0),GATES(85),COLOR(64),SHAPE(64),GAIN(128),FLAGS(TRISAW|LFO)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FST AMOUNT(40),DEST(9*MAX_WORKSPACE_SLOTS+4)
|
||||
GO4K_FST AMOUNT(58),DEST(9*MAX_WORKSPACE_SLOTS+5)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_VCO TRANSPOSE(88),DETUNE(64),PHASE(0),GATES(85),COLOR(64),SHAPE(64),GAIN(128),FLAGS(SINE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(64),GATES(85),COLOR(64),SHAPE(64),GAIN(8),FLAGS(NOISE)
|
||||
GO4K_VCF FREQUENCY(72),RESONANCE(24),VCFTYPE(BANDPASS)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_PUSH)
|
||||
GO4K_VCF FREQUENCY(32),RESONANCE(128),VCFTYPE(BANDPASS)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_VCF FREQUENCY(96),RESONANCE(128),VCFTYPE(BANDPASS)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_DLL PREGAIN(64),DRY(128),FEEDBACK(64),DAMP(64),FREQUENCY(0),DEPTH(0),DELAY(19),COUNT(1)
|
||||
GO4K_PAN PANNING(48)
|
||||
GO4K_OUT GAIN(64), AUXSEND(16)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument7)
|
||||
GO4K_ENV ATTAC(0),DECAY(64),SUSTAIN(64),RELEASE(64),GAIN(128)
|
||||
GO4K_VCO TRANSPOSE(52),DETUNE(64),PHASE(0),GATES(85),COLOR(64),SHAPE(64),GAIN(128),FLAGS(PULSE)
|
||||
GO4K_VCO TRANSPOSE(64),DETUNE(64),PHASE(0),GATES(85),COLOR(64),SHAPE(64),GAIN(128),FLAGS(SINE)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_VCF FREQUENCY(48),RESONANCE(64),VCFTYPE(LOWPASS)
|
||||
GO4K_FOP OP(FOP_MULP)
|
||||
GO4K_PAN PANNING(48)
|
||||
GO4K_DLL PREGAIN(128),DRY(64),FEEDBACK(64),DAMP(64),FREQUENCY(48),DEPTH(64),DELAY(18),COUNT(1)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_DLL PREGAIN(112),DRY(64),FEEDBACK(64),DAMP(64),FREQUENCY(46),DEPTH(64),DELAY(18),COUNT(1)
|
||||
GO4K_OUT GAIN(32), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Instrument8)
|
||||
GO4K_ENV ATTAC(0),DECAY(128),SUSTAIN(0),RELEASE(0),GAIN(0)
|
||||
GO4K_FOP OP(FOP_PUSH)
|
||||
GO4K_FOP OP(FOP_ADDP)
|
||||
GO4K_FSTG AMOUNT(16),DEST(0*go4k_instrument.size*MAX_VOICES+0*MAX_WORKSPACE_SLOTS*4+2*4+go4k_instrument.workspace)
|
||||
GO4K_FSTG AMOUNT(0),DEST(2*go4k_instrument.size*MAX_VOICES+0*MAX_WORKSPACE_SLOTS*4+2*4+go4k_instrument.workspace)
|
||||
GO4K_FSTG AMOUNT(16),DEST(4*go4k_instrument.size*MAX_VOICES+0*MAX_WORKSPACE_SLOTS*4+2*4+go4k_instrument.workspace)
|
||||
GO4K_FSTG AMOUNT(48),DEST(7*go4k_instrument.size*MAX_VOICES+0*MAX_WORKSPACE_SLOTS*4+2*4+go4k_instrument.workspace)
|
||||
GO4K_FOP OP(FOP_POP)
|
||||
GO4K_END_PARAMDEF
|
||||
GO4K_BEGIN_PARAMDEF(Global)
|
||||
GO4K_ACC ACCTYPE(AUX)
|
||||
GO4K_VCF FREQUENCY(4),RESONANCE(64),VCFTYPE(HIGHPASS)
|
||||
GO4K_DLL PREGAIN(24),DRY(128),FEEDBACK(126),DAMP(96),FREQUENCY(0),DEPTH(0),DELAY(0),COUNT(8)
|
||||
GO4K_FOP OP(FOP_XCH)
|
||||
GO4K_VCF FREQUENCY(4),RESONANCE(64),VCFTYPE(HIGHPASS)
|
||||
GO4K_DLL PREGAIN(24),DRY(128),FEEDBACK(126),DAMP(96),FREQUENCY(0),DEPTH(0),DELAY(8),COUNT(8)
|
||||
GO4K_ACC ACCTYPE(OUTPUT)
|
||||
GO4K_FOP OP(FOP_ADDP2)
|
||||
GO4K_OUT GAIN(48), AUXSEND(0)
|
||||
GO4K_END_PARAMDEF
|
||||
go4k_synth_parameter_values_end
|
||||
%ifdef USE_SECTIONS
|
||||
section .g4kmuc5 data align=1
|
||||
%else
|
||||
section .data
|
||||
%endif
|
||||
%ifdef GO4K_USE_DLL
|
||||
global _go4k_delay_times
|
||||
_go4k_delay_times
|
||||
dw 1116
|
||||
dw 1188
|
||||
dw 1276
|
||||
dw 1356
|
||||
dw 1422
|
||||
dw 1492
|
||||
dw 1556
|
||||
dw 1618
|
||||
dw 1140
|
||||
dw 1212
|
||||
dw 1300
|
||||
dw 1380
|
||||
dw 1446
|
||||
dw 1516
|
||||
dw 1580
|
||||
dw 1642
|
||||
dw 14472
|
||||
dw 528
|
||||
dw 544
|
||||
dw 19296
|
||||
%endif
|
||||
BIN
underwater4k/4klang.obj
Normal file
BIN
underwater4k/4klang.obj
Normal file
Binary file not shown.
BIN
underwater4k/GlU32.Lib
Normal file
BIN
underwater4k/GlU32.Lib
Normal file
Binary file not shown.
BIN
underwater4k/OpenGL32.Lib
Normal file
BIN
underwater4k/OpenGL32.Lib
Normal file
Binary file not shown.
364
underwater4k/Shaders.cpp
Normal file
364
underwater4k/Shaders.cpp
Normal file
@@ -0,0 +1,364 @@
|
||||
|
||||
//#define DEBUG_COMPRESSED_SHADER
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include "Shaders.h"
|
||||
|
||||
PFNGLCREATESHADERPROC glCreateShader = NULL;
|
||||
PFNGLSHADERSOURCEPROC glShaderSource = NULL;
|
||||
PFNGLCOMPILESHADERPROC glCompileShader = NULL;
|
||||
PFNGLGETSHADERIVPROC glGetShaderiv = NULL;
|
||||
PFNGLGETPROGRAMIVPROC glGetProgramiv = NULL;
|
||||
PFNGLCREATEPROGRAMPROC glCreateProgram = NULL;
|
||||
PFNGLATTACHSHADERPROC glAttachShader = NULL;
|
||||
PFNGLLINKPROGRAMPROC glLinkProgram = NULL;
|
||||
PFNGLUSEPROGRAMPROC glUseProgram = NULL;
|
||||
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL;
|
||||
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = NULL;
|
||||
|
||||
|
||||
void useProgram(GLhandleARB ah_Program)
|
||||
{
|
||||
glUseProgram(ah_Program);
|
||||
}
|
||||
|
||||
|
||||
void initShaders()
|
||||
{
|
||||
glCreateShader = (PFNGLCREATESHADERPROC)myGetProcAddress("glCreateShader");
|
||||
glShaderSource = (PFNGLSHADERSOURCEPROC)myGetProcAddress("glShaderSource");
|
||||
glCompileShader = (PFNGLCOMPILESHADERPROC)myGetProcAddress("glCompileShader");
|
||||
glGetShaderiv = (PFNGLGETSHADERIVPROC)myGetProcAddress("glGetShaderiv");
|
||||
glGetProgramiv = (PFNGLGETPROGRAMIVPROC)myGetProcAddress("glGetProgramiv");
|
||||
glCreateProgram = (PFNGLCREATEPROGRAMPROC)myGetProcAddress("glCreateProgram");
|
||||
glAttachShader = (PFNGLATTACHSHADERPROC)myGetProcAddress("glAttachShader");
|
||||
glLinkProgram = (PFNGLLINKPROGRAMPROC)myGetProcAddress("glLinkProgram");
|
||||
glUseProgram = (PFNGLUSEPROGRAMPROC)myGetProcAddress("glUseProgram");
|
||||
glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)myGetProcAddress("glGetShaderInfoLog");
|
||||
glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)myGetProcAddress("glGetProgramInfoLog");
|
||||
|
||||
if (!(glCreateShader && glShaderSource && glCompileShader && glGetShaderiv && glGetProgramiv && glCreateProgram && glAttachShader && glLinkProgram && glUseProgram && glGetShaderInfoLog && glGetProgramInfoLog))
|
||||
{
|
||||
std::cerr << "Some shader functions are not available!" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
||||
std::string ReplaceString(const std::string &stringSearchString, const std::string &stringReplaceString, std::string stringStringToReplace)
|
||||
{
|
||||
std::string::size_type pos = stringStringToReplace.find(stringSearchString, 0);
|
||||
int intLengthSearch = stringSearchString.length();
|
||||
int intLengthReplacment = stringReplaceString.length();
|
||||
|
||||
while(std::string::npos != pos)
|
||||
{
|
||||
stringStringToReplace.replace(pos, intLengthSearch, stringReplaceString);
|
||||
pos = stringStringToReplace.find(stringSearchString, pos + intLengthReplacment);
|
||||
}
|
||||
|
||||
return stringStringToReplace;
|
||||
}
|
||||
|
||||
std::string MakeFileName( const char* as_FileName, int ShaderID, bool bDebug )
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << as_FileName << "_" << ShaderID;
|
||||
if( bDebug )
|
||||
{
|
||||
ss << "_dbg";
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void CreateSubShader( const char* as_FileName, int ShaderID, bool bDebug )
|
||||
{
|
||||
char* ls_ShaderSource = textFileRead(as_FileName);
|
||||
std::string strData= ls_ShaderSource;
|
||||
std::string strNewData;
|
||||
bool bRemove= false;
|
||||
for( size_t i= 0; i < strData.size(); ++i )
|
||||
{
|
||||
bool bEndRemove= false;
|
||||
if( strData[ i ] == '@' )
|
||||
{
|
||||
if( i + 2 >= strData.size() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
if( strData[ i ] == '@' )
|
||||
{
|
||||
bRemove= false;
|
||||
}
|
||||
else if( strData[ i ] == 'D' )
|
||||
{
|
||||
bRemove= !bDebug;
|
||||
}
|
||||
else
|
||||
{
|
||||
int ID= (int)(strData[ i ] - '0');
|
||||
bRemove= ID!=ShaderID;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if( !bRemove || strData[ i ] == 10 || strData[ i ] == 13)
|
||||
{
|
||||
strNewData+= strData[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
std::string strFileOut= MakeFileName( as_FileName, ShaderID, bDebug );
|
||||
std::ofstream ofs(strFileOut.c_str());
|
||||
|
||||
// some Renaming
|
||||
/*strNewData= ReplaceString( "rayDir","q", strNewData);
|
||||
strNewData= ReplaceString( "cRes","b", strNewData);
|
||||
strNewData= ReplaceString( "cFac","a", strNewData);
|
||||
strNewData= ReplaceString( "CurStep","d", strNewData);
|
||||
strNewData= ReplaceString( "CurStep","d", strNewData);
|
||||
strNewData= ReplaceString( "rotate","r", strNewData);
|
||||
strNewData= ReplaceString( "repeatHex","sh", strNewData);
|
||||
strNewData= ReplaceString( "repeat","s", strNewData);
|
||||
strNewData= ReplaceString( "pi2","P", strNewData);
|
||||
strNewData= ReplaceString( "sqrtOf075","Q", strNewData);
|
||||
strNewData= ReplaceString( "EndlessBar","O", strNewData);
|
||||
strNewData= ReplaceString( "CurTime","R", strNewData);
|
||||
strNewData= ReplaceString( "CurScene","S", strNewData);
|
||||
strNewData= ReplaceString( "torus","T", strNewData);
|
||||
strNewData= ReplaceString( "noise3D","N", strNewData);
|
||||
strNewData= ReplaceString( "smoothnoise","M", strNewData);*/
|
||||
|
||||
ofs << strNewData;
|
||||
}
|
||||
|
||||
void CreateAllSubShader( const char* as_FileName )
|
||||
{
|
||||
for( int i= 0; i < MAX_SHADER_ID; ++i )
|
||||
{
|
||||
CreateSubShader( as_FileName, i, true );
|
||||
CreateSubShader( as_FileName, i, false );
|
||||
}
|
||||
}
|
||||
|
||||
void PrintErrors()
|
||||
{
|
||||
GLenum lr_Error = GL_NO_ERROR;
|
||||
int li_ErrorCount = 5;
|
||||
do
|
||||
{
|
||||
lr_Error = glGetError();
|
||||
if (lr_Error != GL_NO_ERROR)
|
||||
{
|
||||
li_ErrorCount--;
|
||||
char* ls_ErrorString = (char*)gluErrorString(lr_Error);
|
||||
if (ls_ErrorString != 0)
|
||||
std::cout << "OPENGL :: ERROR " << ls_ErrorString << std::endl;
|
||||
}
|
||||
if (li_ErrorCount == 0)
|
||||
{
|
||||
std::cout << "OPENGL :: ERROR Too many errors!" << std::endl;
|
||||
break;
|
||||
}
|
||||
} while (lr_Error != GL_NO_ERROR);
|
||||
}
|
||||
|
||||
|
||||
GLhandleARB createVertexShader(const char* as_FileName)
|
||||
{
|
||||
GLhandleARB lh_Shader = 0;
|
||||
|
||||
char* ls_ShaderSource = textFileRead(as_FileName);
|
||||
|
||||
if (ls_ShaderSource == NULL)
|
||||
{
|
||||
std::cerr << "Error reading file: " << as_FileName << std::endl;
|
||||
return lh_Shader;
|
||||
}
|
||||
|
||||
lh_Shader = glCreateShader(GL_VERTEX_SHADER);
|
||||
|
||||
glShaderSource(lh_Shader, 1, (const char**)&ls_ShaderSource, NULL);
|
||||
glCompileShader(lh_Shader);
|
||||
|
||||
free(ls_ShaderSource);
|
||||
|
||||
int li_Status = 0;
|
||||
glGetShaderiv(lh_Shader, GL_COMPILE_STATUS, &li_Status);
|
||||
|
||||
if (li_Status == GL_FALSE)
|
||||
{
|
||||
std::cerr << "Error compiling vertex shader: " << as_FileName << std::endl;
|
||||
printShaderInfoLog(lh_Shader);
|
||||
}
|
||||
|
||||
return lh_Shader;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_COMPRESSED_SHADER
|
||||
#include "shader_code.h"
|
||||
#endif
|
||||
|
||||
GLhandleARB createFragmentShader(const char* as_FileName, int ShaderID, bool bDebug)
|
||||
{
|
||||
CreateAllSubShader( as_FileName );
|
||||
|
||||
GLhandleARB lh_Shader = 0;
|
||||
|
||||
char* ls_ShaderSource = textFileRead(MakeFileName(as_FileName, ShaderID, bDebug).c_str());
|
||||
if (ls_ShaderSource == NULL)
|
||||
{
|
||||
std::cerr << "Error reading file: " << as_FileName << std::endl;
|
||||
return lh_Shader;
|
||||
}
|
||||
|
||||
lh_Shader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
glShaderSource(lh_Shader, 1, (const char**)&ls_ShaderSource, NULL);
|
||||
#ifdef DEBUG_COMPRESSED_SHADER
|
||||
glShaderSource(lh_Shader, 1, (const char**)&mark_fs, NULL);
|
||||
#endif
|
||||
glCompileShader(lh_Shader);
|
||||
|
||||
int li_Status = 0;
|
||||
|
||||
glGetShaderiv(lh_Shader, GL_COMPILE_STATUS, &li_Status);
|
||||
|
||||
if (li_Status == GL_FALSE)
|
||||
{
|
||||
std::cerr << "Error compiling fragment shader: " << as_FileName << std::endl;
|
||||
printShaderInfoLog(lh_Shader);
|
||||
}
|
||||
|
||||
free(ls_ShaderSource);
|
||||
|
||||
return lh_Shader;
|
||||
}
|
||||
|
||||
|
||||
GLhandleARB createProgram(GLhandleARB ah_VertexShader, GLhandleARB ah_FragmentShader)
|
||||
{
|
||||
GLhandleARB lh_Program = 0;
|
||||
|
||||
if (ah_VertexShader + ah_FragmentShader <= 1)
|
||||
{
|
||||
std::cerr << "Cannot create program." << std::endl;
|
||||
return lh_Program;
|
||||
}
|
||||
|
||||
lh_Program = glCreateProgram();
|
||||
|
||||
glAttachShader(lh_Program, ah_VertexShader);
|
||||
glAttachShader(lh_Program, ah_FragmentShader);
|
||||
glLinkProgram(lh_Program);
|
||||
|
||||
int li_Status = 0;
|
||||
|
||||
glGetProgramiv(lh_Program, GL_LINK_STATUS, &li_Status);
|
||||
|
||||
if (li_Status == GL_FALSE)
|
||||
{
|
||||
std::cerr << "Error linking shaders." << std::endl;
|
||||
printProgramInfoLog(lh_Program);
|
||||
}
|
||||
|
||||
return lh_Program;
|
||||
}
|
||||
|
||||
|
||||
char* textFileRead(const char* as_FileName)
|
||||
{
|
||||
FILE* lh_File;
|
||||
char* ls_Content = NULL;
|
||||
size_t li_Count = 0;
|
||||
|
||||
if (as_FileName != NULL)
|
||||
{
|
||||
fopen_s(&lh_File, as_FileName, "rt");
|
||||
|
||||
if (lh_File != NULL)
|
||||
{
|
||||
fseek(lh_File, 0, SEEK_END);
|
||||
li_Count = ftell(lh_File);
|
||||
rewind(lh_File);
|
||||
|
||||
if (li_Count > 0)
|
||||
{
|
||||
ls_Content = (char*) malloc(sizeof(char) * (li_Count + 1));
|
||||
li_Count = fread(ls_Content, sizeof(char), li_Count, lh_File);
|
||||
ls_Content[li_Count] = '\0';
|
||||
}
|
||||
|
||||
fclose(lh_File);
|
||||
}
|
||||
}
|
||||
|
||||
return ls_Content;
|
||||
}
|
||||
|
||||
|
||||
void printShaderInfoLog(GLhandleARB ah_Shader)
|
||||
{
|
||||
int li_InfologLength = 0;
|
||||
int li_CharsWritten = 0;
|
||||
char* li_InfoLog;
|
||||
|
||||
glGetShaderiv(ah_Shader, GL_INFO_LOG_LENGTH, &li_InfologLength);
|
||||
|
||||
if (li_InfologLength > 0)
|
||||
{
|
||||
li_InfoLog = (char*) malloc(li_InfologLength);
|
||||
|
||||
glGetShaderInfoLog(ah_Shader, li_InfologLength, &li_CharsWritten, li_InfoLog);
|
||||
|
||||
std::cerr << li_InfoLog << std::endl;
|
||||
free(li_InfoLog);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void printProgramInfoLog(GLhandleARB ah_Program)
|
||||
{
|
||||
int li_InfologLength = 0;
|
||||
int li_CharsWritten = 0;
|
||||
char* ls_InfoLog;
|
||||
|
||||
glGetProgramiv(ah_Program, GL_INFO_LOG_LENGTH, &li_InfologLength);
|
||||
|
||||
if (li_InfologLength > 0)
|
||||
{
|
||||
ls_InfoLog = (char *)malloc(li_InfologLength);
|
||||
|
||||
glGetProgramInfoLog(ah_Program, li_InfologLength, &li_CharsWritten, ls_InfoLog);
|
||||
|
||||
std::cerr << ls_InfoLog << std::endl;
|
||||
free(ls_InfoLog);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool printShaderStatistics()
|
||||
{
|
||||
if (GL_VERSION_2_1) std::cout << "Supports OpenGL 2.1. " << std::endl;
|
||||
else if (GL_VERSION_2_0) std::cout << "Supports OpenGL 2.0. " << std::endl;
|
||||
else if (GL_VERSION_1_5) std::cout << "Supports OpenGL 1.5. " << std::endl;
|
||||
else if (GL_VERSION_1_4) std::cout << "Supports OpenGL 1.4. " << std::endl;
|
||||
else if (GL_VERSION_1_3) std::cout << "Supports OpenGL 1.3. " << std::endl;
|
||||
else if (GL_VERSION_1_2) std::cout << "Supports OpenGL 1.2. " << std::endl;
|
||||
else if (GL_VERSION_1_1) std::cout << "Supports OpenGL 1.1. " << std::endl;
|
||||
|
||||
if (GL_ARB_shader_objects && GL_ARB_vertex_shader && GL_ARB_fragment_shader)
|
||||
{
|
||||
std::cout << "Status: Using GLSL " << glGetString(GL_SHADING_LANGUAGE_VERSION_ARB) << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "No GLSL support!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
21
underwater4k/Shaders.h
Normal file
21
underwater4k/Shaders.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#define MAX_SHADER_ID 4
|
||||
|
||||
#include <windows.h>
|
||||
#include <iostream>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "glext.h"
|
||||
#define myGetProcAddress(name) wglGetProcAddress((LPCSTR)name)
|
||||
|
||||
void initShaders();
|
||||
GLhandleARB createVertexShader(const char* as_FileName);
|
||||
GLhandleARB createFragmentShader(const char* as_FileName, int ShaderID, bool bDebug);
|
||||
GLhandleARB createProgram(GLhandleARB ah_VertexShader, GLhandleARB ah_FragmentShader);
|
||||
void PrintErrors();
|
||||
void useProgram(GLhandleARB ah_Program);
|
||||
char* textFileRead(const char* as_FileName);
|
||||
void printShaderInfoLog(GLhandleARB ah_Shader);
|
||||
void printProgramInfoLog(GLhandleARB ah_Program);
|
||||
bool printShaderStatistics();
|
||||
15
underwater4k/build-all.cmd
Normal file
15
underwater4k/build-all.cmd
Normal file
@@ -0,0 +1,15 @@
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
|
||||
call "build.cmd" 1.33 800 600 W
|
||||
call "build.cmd" 1.88 960 510 W
|
||||
call "build.cmd" 1.33 1024 768
|
||||
call "build.cmd" 1.25 1280 1024
|
||||
call "build.cmd" 1.77 1280 720
|
||||
call "build.cmd" 1.6 1280 800
|
||||
call "build.cmd" 1.33 1280 960
|
||||
call "build.cmd" 1.55 1400 900
|
||||
call "build.cmd" 1.33 1400 1050
|
||||
call "build.cmd" 1.6 1680 1050
|
||||
call "build.cmd" 1.77 1920 1080
|
||||
call "build.cmd" 1.6 1920 1200
|
||||
call "build.cmd" 1.33 800 600
|
||||
|
||||
9
underwater4k/build.cmd
Normal file
9
underwater4k/build.cmd
Normal file
@@ -0,0 +1,9 @@
|
||||
IF [%4]==[W] GOTO :windowed
|
||||
:fullscreen
|
||||
cl /c @switches.txt /DASPECT=%1 /DSCREENWIDTH=%2 /DSCREENHEIGHT=%3 main_release.cpp
|
||||
crinkler @linkparams.txt /out:"final\custom\mirror_%2x%3.exe"
|
||||
goto :end
|
||||
:windowed
|
||||
cl /c @switches.txt /DASPECT=%1 /DSCREENWIDTH=%2 /DSCREENHEIGHT=%3 /DWINDOWED main_release.cpp
|
||||
crinkler @linkparams.txt /out:"final\custom\mirror_%2x%3_window.exe"
|
||||
:end
|
||||
BIN
underwater4k/crinkler.exe
Normal file
BIN
underwater4k/crinkler.exe
Normal file
Binary file not shown.
1
underwater4k/do_minify.bat
Normal file
1
underwater4k/do_minify.bat
Normal file
@@ -0,0 +1 @@
|
||||
minify\shader_minifier.exe "fragment.glsl_0" -o fragment_small.h -v
|
||||
1
underwater4k/files.txt
Normal file
1
underwater4k/files.txt
Normal file
@@ -0,0 +1 @@
|
||||
main_release.cpp
|
||||
557
underwater4k/fragment.glsl
Normal file
557
underwater4k/fragment.glsl
Normal file
@@ -0,0 +1,557 @@
|
||||
@0
|
||||
const int shader= 0;
|
||||
@@
|
||||
@1
|
||||
const int shader= 1;
|
||||
@@
|
||||
@2
|
||||
const int shader= 2;
|
||||
@@
|
||||
@3
|
||||
const int shader= 3;
|
||||
@@
|
||||
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
varying vec4 Y;
|
||||
|
||||
// Position of the fragment
|
||||
varying vec2 Z;
|
||||
|
||||
uniform sampler2D V;
|
||||
uniform sampler2D HEIGHT;
|
||||
|
||||
// Forward declarations
|
||||
vec4 traceRay(vec3 ro, vec3 rd, int ignore);
|
||||
vec3 shade(vec4 hitPoint, vec3 newRo, vec3 rd);
|
||||
|
||||
|
||||
// All data of our world
|
||||
vec3 spherePos, lightDir, lightColor, waterColor, ro, rd, interlacing;
|
||||
float sphereRadius, gf_DetailLevel, pi, eps, bigeps;
|
||||
|
||||
|
||||
// Pseudo random number base generator (credits go to iq/rgba)
|
||||
float rnd(vec2 x)
|
||||
{
|
||||
int n = int(x.x * 40 + x.y * 6400);
|
||||
n = (n << 13) ^ n;
|
||||
return 1 - float( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824;
|
||||
}
|
||||
|
||||
|
||||
// Generate cubic interpolated random values
|
||||
float smoothrnd(vec2 x)
|
||||
{
|
||||
x = mod(x,1000.0);
|
||||
vec2 a = fract(x);
|
||||
x -= a;
|
||||
vec2 u = a*a*(3.0-2.0*a);
|
||||
return mix(
|
||||
mix(rnd(x+vec2(0,0)),rnd(x+vec2(1,0)), u.x),
|
||||
mix(rnd(x+vec2(0,1)),rnd(x+vec2(1,1)), u.x), u.y);
|
||||
}
|
||||
|
||||
|
||||
// Convert the cipher range from [-1,1] to [0,1]
|
||||
float norm(float x)
|
||||
{
|
||||
return x * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
return (0.01 + ((.25*texture2D(V, p * 128.0).x) + texture2D(V, p * 32.0).x)) * smoothstep(0.25, 0.35, texture2D(V, p * 11).y * texture2D(V, p * 13).y);
|
||||
}
|
||||
|
||||
float texnoise(vec2 p)
|
||||
{
|
||||
return texture2D(V, p).y;
|
||||
}
|
||||
|
||||
float grass(vec2 p)
|
||||
{
|
||||
return texnoise(p * 57) * texnoise(p * 13) * 2.0;
|
||||
}
|
||||
|
||||
// Our heightmap calculation function, we could use some perlin noise here if it wouldn't be so performance killing
|
||||
float height(vec2 x)
|
||||
{
|
||||
return texture2D(HEIGHT, x).x;
|
||||
}
|
||||
|
||||
|
||||
// Gets the terrain normal
|
||||
vec3 getTerrainNormal(vec3 p)
|
||||
{
|
||||
return normalize(vec3(
|
||||
height(p.xz - vec2(bigeps, 0)) - height(p.xz + vec2(bigeps, 0)),
|
||||
2 * bigeps,
|
||||
height(p.xz - vec2(0, bigeps)) - height(p.xz + vec2(0, bigeps))));
|
||||
}
|
||||
|
||||
|
||||
// Global diffuse lighting formula
|
||||
vec3 diffuseLight(vec3 incolor, float shadow, vec3 normal)
|
||||
{
|
||||
return (0.3 + shadow * 0.7 * max(dot(normal, lightDir), 0.0)) * lightColor * incolor;
|
||||
}
|
||||
|
||||
|
||||
// Calculates the water "waves". To reduce the bumpiness, increment the y-axis
|
||||
vec3 getWaterNormal(vec3 p)
|
||||
{
|
||||
return normalize(vec3(
|
||||
texnoise(p.xz * 40 + Y.x*.5)*2-1,
|
||||
8,
|
||||
texnoise(p.xz * 80 - Y.x*.25)*2-1));
|
||||
}
|
||||
|
||||
|
||||
float caustic(vec3 p)
|
||||
{
|
||||
vec2 q = p.xz * (1 - p.y * .01);
|
||||
float noiseX = texnoise(q * .125 * (.05*Y.x+vec2(2,3)));
|
||||
float noiseY = texnoise(q * .125 * (.05*Y.x+vec2(4,5)));
|
||||
q = mod(q * 10.0 + vec2(noiseX, noiseY) * 16.0, 1.0);
|
||||
q -= step(0.5, q) * 2 * (q - 0.5);
|
||||
q *= 2;
|
||||
return max(pow(q.x, 4.0 + 4.0 * noiseX), pow(q.y, 4.0 + 4.0 * noiseX));
|
||||
}
|
||||
|
||||
float caustics(vec3 p)
|
||||
{
|
||||
return caustic(p * 31) * caustic(p * 17);
|
||||
}
|
||||
|
||||
// Our fake godray effect (bad if moving fast, but awesome any other time)
|
||||
vec3 godrays(vec3 ro, vec3 rd, float maxt, vec3 color)
|
||||
{
|
||||
const int iterations = 16;
|
||||
float dt = 0.001, t = 0;
|
||||
float cs = 0.0;
|
||||
for (int i = 0; i < iterations; ++i)
|
||||
{
|
||||
vec3 p = ro + rd * t;
|
||||
vec2 q = p.xz * (1 - p.y * .4);
|
||||
|
||||
float shadow = 1.0-step(1,traceRay(p, lightDir, 2).w);
|
||||
cs = max(cs, (1 + p.y * 8) * shadow * smoothstep(0.4, 0.7, texnoise(q * 64)) / (1+t*2));
|
||||
t += dt;
|
||||
}
|
||||
return color + pow(cs, 4.0) * lightColor * .1;
|
||||
}
|
||||
|
||||
// Calculate the terrain color for the given voxel
|
||||
vec3 shadeTerrain(vec3 p, vec3 rd)
|
||||
{
|
||||
vec3 n = getTerrainNormal(p);
|
||||
float vrn = voronoi(p.xz);
|
||||
vec3 grassColor = vec3(0.8, 0.85, 0.4) * 1.5 * grass(p.xz);
|
||||
vec3 dirtColor = vec3(0.65, 0.6, 0.4) * (.5+grass(p.xz));
|
||||
vec3 stoneColor = vec3(0.5, 0.5, 0.4) * (.5+grass(p.xz));
|
||||
float groundFactor = smoothstep(0.7, 0.8, n.y) * (1.0 - step(p.y, texnoise(p.xz*128)*0.01-0.003)); // shore
|
||||
float dirtFactor = smoothstep(0.4, 0.6, texture2D(V, p.xz * 40).y);
|
||||
vec3 ground = mix(mix(stoneColor, dirtColor, dirtFactor), grassColor, groundFactor);
|
||||
|
||||
vec3 rockColor = vec3(0.5, 0.5, 0.5) * (.75 + vrn) * (.75+.5*grass(p.xz * 8));
|
||||
vec3 color = mix(ground, rockColor, smoothstep(0.0, 0.05,vrn));
|
||||
|
||||
float shadow = 1.0-step(1,traceRay(p + n * 0.005, lightDir, 2).w);
|
||||
|
||||
if (p.y <= 0)
|
||||
color = max(0.0, 0.7 + 8 * p.y) * (color + lightColor * shadow * max(0, 1 + 32 * p.y) * caustics(p));
|
||||
else
|
||||
color *= 0.6+0.4*min(1.0, p.y * 999.0);
|
||||
|
||||
color = color * (.5+.5*vrn);
|
||||
return diffuseLight(color, shadow, n);
|
||||
}
|
||||
|
||||
|
||||
// Create a blueish sky transition from navy blue to badass dark blue
|
||||
vec3 shadeSky(vec3 ro, vec3 rd)
|
||||
{
|
||||
vec3 farColor = vec3(0.0, 0.0, 0.4);
|
||||
return mix(waterColor, farColor, max(0, rd.y))
|
||||
+ 0.25*lightColor * pow(max(0, dot(rd, lightDir)), 4)
|
||||
+ lightColor * pow(max(0, dot(rd, lightDir)), 1000);
|
||||
}
|
||||
|
||||
|
||||
// Calculates the refraction and reflection of the water surface.
|
||||
// Also mixes both values by the depth of the water and the fresnel term.
|
||||
// Possible improvements: fix fake underwater reflection and refraction
|
||||
vec3 shadeWaterRefl(vec3 p, vec3 newrd)
|
||||
{
|
||||
vec3 waterNormal = getWaterNormal(p);
|
||||
|
||||
// perform raytracing/raymarching for both reflection and refraction
|
||||
// calc the water refraction, the refraction index (0.9) will decrease with the distance to allow a better over/under water transition
|
||||
vec3 refrd = mix(newrd, refract(newrd, waterNormal, 0.9), step(0.0, ro.y));
|
||||
vec4 refracted = traceRay(p, refrd, 2);//mix(0.9, 1.0, smoothstep(0.01, 0.0, length(p-ro)))), 2);
|
||||
|
||||
// calculate the depth factor (water entry point to terrain voxel) (black magic involved here!)
|
||||
float depth = clamp(pow(1.03 * (1 - length(refracted.xyz - p)), 16.0), 0.0, 1.0);
|
||||
|
||||
float shadow = 0.9 + 0.1 * (1.0-step(1,traceRay(p + waterNormal * 0.005, lightDir, 2).w));
|
||||
float fresnel = pow(clamp(abs(-rd.y), 0.0, 1.0),1.8);
|
||||
// Finally stir the pot =)
|
||||
return shadow * mix(
|
||||
shadeSky(p, refrd), // Water color
|
||||
mix(
|
||||
shade(traceRay(p, reflect(newrd, waterNormal), 2), p, newrd), // Reflection color
|
||||
shade(refracted, p, newrd), // Refraction color
|
||||
fresnel), // fresnel term
|
||||
pow(depth, 0.5)); // water color contribution
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Texture our "AMIGAAAAAAA!!" ball
|
||||
vec3 shadeAttractor(vec3 p, vec3 rd)
|
||||
{
|
||||
vec3 n,color;
|
||||
|
||||
// get the sphere normal, first
|
||||
n = normalize(p - spherePos);
|
||||
|
||||
// now calculate the texture coordinates
|
||||
vec2 uv = 0.5 + 0.5 * vec2(atan(n.z, n.x), acos(n.y)) / pi;
|
||||
|
||||
// We'll animate our x-texture coordinate with the time, this gives the impression of a rotating ball
|
||||
uv.x -= Y.x;
|
||||
|
||||
// This spell will convert any dull ball into an amiga ball, caution is advised.
|
||||
color = mix(vec3(1), vec3(1, 0, 0), mod(step(fract(uv.x * 6), 0.5) + step(fract(uv.y * 6), 0.5), 2.0));
|
||||
|
||||
return diffuseLight(color, 1, n)
|
||||
+ pow(max(dot(n, normalize(lightDir - rd)), 0.0), 33.0) * lightColor; // specular light spot
|
||||
}
|
||||
|
||||
#define INTERVAL_ITERS 5
|
||||
#define LINEAR_ACCURACY 0.5
|
||||
|
||||
// Raymarch the terrain function, returns the distance from the ray origin to the terrain voxel
|
||||
// This function was originally adopted from an implementation by iq/rgba
|
||||
float traceTerrain(vec3 ro, vec3 rd, float maxt)
|
||||
{
|
||||
float samplePosY, h, prevt, t;
|
||||
vec3 samplePos;
|
||||
|
||||
// advance our sample position from our nearplane to our farplane
|
||||
for (t = 0; t < maxt;)
|
||||
{
|
||||
// advance our ray
|
||||
samplePos = ro + rd * t;
|
||||
samplePosY = samplePos.y;
|
||||
|
||||
// get the height at the given sample 2d (!) position (we could enhance this by sampling a voxel and returning only the distance to the voxel)
|
||||
h = height(samplePos.xz);
|
||||
float dist = samplePosY - h;
|
||||
if (dist < 0.0) break;
|
||||
|
||||
prevt = t;
|
||||
|
||||
if (dist > 0.0001)
|
||||
t += max(dist * 1.4, 0.0001) * LINEAR_ACCURACY;
|
||||
else
|
||||
t += max(dist, 0.00001) * LINEAR_ACCURACY;
|
||||
}
|
||||
|
||||
if (samplePosY <= h)
|
||||
{
|
||||
/// Interval mapping
|
||||
float before = prevt;
|
||||
vec3 beforePos = ro + rd * before;
|
||||
float beforeH = height(beforePos.xz);
|
||||
|
||||
float after = t;
|
||||
vec3 afterPos = ro + rd * after;
|
||||
float afterH = height(afterPos.xz);
|
||||
|
||||
for (int i = 0; i < INTERVAL_ITERS; i++)
|
||||
{
|
||||
float interval = after - before;
|
||||
float deltaL = beforeH - afterH;
|
||||
float deltaR = rd.y * interval;
|
||||
|
||||
float curt = (beforeH * interval - deltaL * before) / (deltaR - deltaL);
|
||||
if (curt <= before - 0.000001 || curt >= after + 0.000001) break;
|
||||
|
||||
samplePos = ro + rd * curt;
|
||||
float h = height(samplePos.xz);
|
||||
|
||||
if (h <= samplePos.y)
|
||||
{
|
||||
beforeH = h;
|
||||
before = curt;
|
||||
t = curt;
|
||||
}
|
||||
else
|
||||
{
|
||||
afterH = h;
|
||||
after = curt;
|
||||
t = curt;
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// we hit nothing
|
||||
return 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Ray vs. sphere intersection function
|
||||
float traceAttractor(vec3 ro, vec3 rd)
|
||||
{
|
||||
vec3 dst = ro - spherePos;
|
||||
float B,D;
|
||||
B = dot(dst, rd);
|
||||
if (B > 0)
|
||||
return 9.0;
|
||||
D = B*B - dot(dst, dst) + sphereRadius*sphereRadius;
|
||||
if (D > 0)
|
||||
{
|
||||
return -B - sqrt(D);
|
||||
}
|
||||
return 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Ray vs. plane intersection function
|
||||
float traceWater(vec3 ro, vec3 rd)
|
||||
{
|
||||
float tPlane = -ro.y / rd.y;
|
||||
return tPlane >= eps ? tPlane : 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Raytracing entry point, returns voxel and object ID
|
||||
// IDs:
|
||||
// 0 = sky (not the armageddon, xTr1m!!)
|
||||
// 1 = terrain
|
||||
// 2 = water
|
||||
// 3 = attractive amiga ball (you have never seen such a sexy amiga ball before, admit it!)
|
||||
vec4 traceRay(vec3 ro, vec3 rd, int ignore)
|
||||
{
|
||||
float water, attractor, terrain, minDist;
|
||||
|
||||
// trace only the objects we need (only one could maximally be ignored)
|
||||
water = ignore != 2 ? traceWater(ro, rd) : 9.0;
|
||||
attractor = ignore != 3 ? traceAttractor(ro, rd) : 9.0;
|
||||
terrain = ignore != 1 ? traceTerrain(ro, rd, min(0.5, 0.002+min(water, attractor))) : 9.0;
|
||||
|
||||
// auto detail level reducing (common dude, give the GPU some breathing room)
|
||||
gf_DetailLevel /= 20;
|
||||
|
||||
// find the nearest distance
|
||||
minDist = min(terrain, min(water, min(attractor, 9.0)));
|
||||
|
||||
// we hit nothing or the hitpoint is too far
|
||||
if (minDist == 9)
|
||||
return vec4(0);
|
||||
|
||||
// calculate the hit/voxel position
|
||||
vec3 hitPos = ro + rd * minDist;
|
||||
|
||||
// check what we might have hit
|
||||
if (minDist == terrain)
|
||||
return vec4(hitPos, 1);
|
||||
if (minDist == water)
|
||||
return vec4(hitPos, 2);
|
||||
if (minDist == attractor)
|
||||
return vec4(hitPos, 3);
|
||||
|
||||
// Panic, worry, die to death! Probably we'll land on the moon (this should never happen)
|
||||
//return vec4(0);
|
||||
}
|
||||
|
||||
|
||||
// Entrypoint for color calculation
|
||||
vec3 shadeRefl(vec4 hitPoint, vec3 newRo, vec3 rd)
|
||||
{
|
||||
// determine the fog color for this very precise point in the space time continuum
|
||||
vec3 myFog = newRo.y < eps ? waterColor : shadeSky(ro, rd);
|
||||
|
||||
// generate the distance value for the fog calculation
|
||||
float distance = clamp(length(hitPoint.xyz - newRo) * (ro.y <= 0 ? 4 : 2), 0.0, 1.0);
|
||||
|
||||
// get the color of the hit object and mix it with the fog
|
||||
// in most cases we allow further raytracing here (not for the terrain, its not shiny enough)
|
||||
if (hitPoint.w == 1)
|
||||
return mix(shadeTerrain(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 2)
|
||||
return mix(shadeWaterRefl(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 3)
|
||||
return mix(
|
||||
// Our amiga ball is shiny so reflect the scene!
|
||||
mix(shadeAttractor(hitPoint.xyz, rd), shade(traceRay(hitPoint.xyz, reflect(rd, normalize(hitPoint.xyz - spherePos)), 3), hitPoint.xyz, rd), 0.5)
|
||||
, myFog, distance);
|
||||
|
||||
return shadeSky(newRo, rd);
|
||||
}
|
||||
|
||||
|
||||
// Get the color from the object we just hit (without further raytraces)
|
||||
// this is necessary because no recursion is allowed in GLSL (damn you!)
|
||||
vec3 shade(vec4 hitPoint, vec3 newRo, vec3 rd)
|
||||
{
|
||||
// determine the fog color for the very same point we discussed earlier
|
||||
vec3 myFog = newRo.y < eps ? waterColor : shadeSky(ro, rd);
|
||||
|
||||
// generate the other distance value. Paid attention? If you don't know what value I'm talking about, rtfm or gtfo.
|
||||
float distance = clamp(length(hitPoint.xyz - newRo) * (ro.y <= 0 ? 4 : 2), 0.0, 1.0);
|
||||
|
||||
// get the color of the hit object and mix it with the fog
|
||||
if (hitPoint.w == 1)
|
||||
return mix(shadeTerrain(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 2)
|
||||
return mix(waterColor, myFog, distance);
|
||||
if (hitPoint.w == 3)
|
||||
return mix(shadeAttractor(hitPoint.xyz, rd), myFog, distance);
|
||||
|
||||
return myFog;
|
||||
}
|
||||
|
||||
// Now we're just being copycats. We're not creative enough to define own entry points
|
||||
// Sure, we could "#define MYENTRYPOINT main"! Or just void main(){MyEntryPoint();}
|
||||
// None of that would help us win the compo, would it?
|
||||
void main()
|
||||
{
|
||||
// Set the quality setting for the raymarcher, a higher value results in a longer processing time
|
||||
// try to find a good balance between these two, low values wivoronoill result in a wobbling endresult
|
||||
// low quality = 50.0 (visual results are ok at 640x480)
|
||||
// mid quality = 100.0
|
||||
// high quality = 200.0
|
||||
gf_DetailLevel = 100;
|
||||
|
||||
// Give our saviour global variables some life!
|
||||
pi = 3.1416;
|
||||
interlacing = vec3(1.2, 0.9, 0.9);
|
||||
eps = 0.0001;
|
||||
bigeps = 0.01;
|
||||
|
||||
// Nifty random number generator gets initialized
|
||||
float seed = 10;
|
||||
|
||||
// Determine the scene we're in
|
||||
int scene = int(Y.x);
|
||||
|
||||
// Get the look direction for the current pixel (always look forwards)
|
||||
rd = vec3((Z.xy - 0.5), 1);
|
||||
|
||||
float tex = texture2D(V, clamp(Z.xy, 0.0, 1.0), 1.0).x;
|
||||
gl_FragColor = vec4(tex, tex, tex, 1);
|
||||
return;
|
||||
|
||||
// Merry-go-round on a boat (yeah, this makes no sense. Go watch the intro and see for yourself)
|
||||
if (scene > 22 && scene < 27)
|
||||
{
|
||||
seed = min(1.0, sin((Y.x-23)*pi*0.25)*12);
|
||||
ro = vec3(0.12, 0.005, Y.x*0.08);
|
||||
rd = vec3(gl_ModelViewMatrix * vec4(rd, 1));
|
||||
rd.y += 0.1*cos(Y.x*4);
|
||||
}
|
||||
// Intermezzo: Dolphin like animation inside and outside the water, chasing that amiga ball!
|
||||
else if (scene > 14 && scene < 23)
|
||||
{
|
||||
seed = min(1.0, sin((Y.x-15)*pi*0.125)*24);
|
||||
rd += vec3(0,0.1*cos(Y.x*4), 0);
|
||||
ro = vec3(0.08, 0.01*sin(Y.x*4)+0.002, Y.x*0.11);
|
||||
}
|
||||
// Intro and Outro: Show still scenes
|
||||
else
|
||||
{
|
||||
// Get a random initial position for our camera
|
||||
ro = vec3(0.1,0.004,0.0) + vec3(0.1,0.005,20)
|
||||
*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)));
|
||||
|
||||
// Basing on the initial position, choose some "random" start and end points nearby
|
||||
ro = mix(
|
||||
ro+vec3(0.008)*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++))),
|
||||
ro+vec3(0.008)*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++))),
|
||||
// and move the camera!
|
||||
Y.x-scene);
|
||||
|
||||
// We adjust the height of the camera to the terrain height
|
||||
ro.y += height(ro.xz)+0.02;
|
||||
|
||||
// Deviate the camera position in the direction of the normal of the underlying terrain
|
||||
ro += 0.02*getTerrainNormal(ro);
|
||||
|
||||
// Reusing a float variable here, this controls the scene fade in / fade out animation
|
||||
seed = min(1.0, step(-28.0, -Y.x) * sin((Y.x-scene)*pi)*3);
|
||||
}
|
||||
|
||||
@D
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//Debugzeug fuer Kamerasteuerung
|
||||
{
|
||||
ro.x= gl_ModelViewMatrix[0][0];
|
||||
ro.y= gl_ModelViewMatrix[0][1];
|
||||
ro.z= gl_ModelViewMatrix[0][2];
|
||||
|
||||
float a1= gl_ModelViewMatrix[1][1];
|
||||
float c1,s1;vec3 q1= vec3((Z.xy - 0.5), 0.8);
|
||||
c1 = cos(a1); s1 = sin(a1);
|
||||
rd.y = c1 * q1.y - s1 * q1.z;
|
||||
rd.x= q1.x;
|
||||
rd.z = s1 * q1.y + c1 * q1.z;
|
||||
|
||||
a1= gl_ModelViewMatrix[1][0];
|
||||
q1=rd;
|
||||
c1 = cos(a1); s1 = sin(a1);
|
||||
rd.x = c1 * q1.x + s1 * q1.z;
|
||||
rd.z = -s1 * q1.x + c1 * q1.z;
|
||||
|
||||
}
|
||||
//Ende Debugzeug fuer Kamerasteuerung
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
@@
|
||||
|
||||
rd = normalize(rd);
|
||||
|
||||
// Now boot the amiga workbench (erm, no...)
|
||||
// mantain a relative distance to the camera
|
||||
if (scene > 22 && scene < 27)
|
||||
spherePos = ro + 0.1 * vec3(gl_ModelViewMatrix * vec4(0, 0, 1, 1));
|
||||
else
|
||||
spherePos = ro + 0.02 * vec3(sin(Y.x), 0, 5+cos(Y.x));
|
||||
|
||||
spherePos.y += 0.01 + height(spherePos.xz); // mantain a relative height to the underlying terrain
|
||||
sphereRadius = scene < 14 ? 0.0 : bigeps * 0.5 + bigeps * Y.z; // The amiga ball is bigger when the snare drum is hit!
|
||||
spherePos += 2*sphereRadius * getTerrainNormal(spherePos); // deviate according to the underlying terrain's normal
|
||||
|
||||
// Make our world pretty and worthy to live in (you can cultivate algae and eat them, they're surely enough for survival)
|
||||
lightDir = normalize(vec3(0.78, 0.12 + Y.x*.2, -0.18));
|
||||
lightColor = vec3(2.4, 2.0, 1.0) + Y.x*.5;
|
||||
waterColor = mix(vec3(0.4, 0.33, 0.4), vec3(0.4, 0.5, 0.6), Y.x);
|
||||
|
||||
// Our GPU feels good underwater, almost like a refreshing experience :) cool, eh?
|
||||
if (ro.y <= 0)
|
||||
{
|
||||
// Less work to do...
|
||||
gf_DetailLevel *= 0.75;
|
||||
|
||||
// ...and a cozy darker atmosphere
|
||||
lightColor *= 0.8;
|
||||
}
|
||||
|
||||
// Here we go, shoot'em rays and get the color of our fragment!
|
||||
vec4 hit = traceRay(ro, rd, 0);
|
||||
vec3 color = shadeRefl(hit, ro, rd);
|
||||
|
||||
// Underwater there are beams of light emanating from god (so called "god" rays...)
|
||||
// ...this prooves that god is nothing less than a water surface.
|
||||
if (ro.y <= 0)
|
||||
color = godrays(ro, rd, length(hit.xyz-ro), color);
|
||||
|
||||
// Apply post processing and fade effects to the color, and finally return it.
|
||||
gl_FragColor.xyz = color;
|
||||
}
|
||||
557
underwater4k/fragment.glsl_0
Normal file
557
underwater4k/fragment.glsl_0
Normal file
@@ -0,0 +1,557 @@
|
||||
|
||||
const int shader= 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
varying vec4 Y;
|
||||
|
||||
// Position of the fragment
|
||||
varying vec2 Z;
|
||||
|
||||
uniform sampler2D V;
|
||||
uniform sampler2D HEIGHT;
|
||||
|
||||
// Forward declarations
|
||||
vec4 traceRay(vec3 ro, vec3 rd, int ignore);
|
||||
vec3 shade(vec4 hitPoint, vec3 newRo, vec3 rd);
|
||||
|
||||
|
||||
// All data of our world
|
||||
vec3 spherePos, lightDir, lightColor, waterColor, ro, rd, interlacing;
|
||||
float sphereRadius, gf_DetailLevel, pi, eps, bigeps;
|
||||
|
||||
|
||||
// Pseudo random number base generator (credits go to iq/rgba)
|
||||
float rnd(vec2 x)
|
||||
{
|
||||
int n = int(x.x * 40 + x.y * 6400);
|
||||
n = (n << 13) ^ n;
|
||||
return 1 - float( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824;
|
||||
}
|
||||
|
||||
|
||||
// Generate cubic interpolated random values
|
||||
float smoothrnd(vec2 x)
|
||||
{
|
||||
x = mod(x,1000.0);
|
||||
vec2 a = fract(x);
|
||||
x -= a;
|
||||
vec2 u = a*a*(3.0-2.0*a);
|
||||
return mix(
|
||||
mix(rnd(x+vec2(0,0)),rnd(x+vec2(1,0)), u.x),
|
||||
mix(rnd(x+vec2(0,1)),rnd(x+vec2(1,1)), u.x), u.y);
|
||||
}
|
||||
|
||||
|
||||
// Convert the cipher range from [-1,1] to [0,1]
|
||||
float norm(float x)
|
||||
{
|
||||
return x * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
return (0.01 + ((.25*texture2D(V, p * 128.0).x) + texture2D(V, p * 32.0).x)) * smoothstep(0.25, 0.35, texture2D(V, p * 11).y * texture2D(V, p * 13).y);
|
||||
}
|
||||
|
||||
float texnoise(vec2 p)
|
||||
{
|
||||
return texture2D(V, p).y;
|
||||
}
|
||||
|
||||
float grass(vec2 p)
|
||||
{
|
||||
return texnoise(p * 57) * texnoise(p * 13) * 2.0;
|
||||
}
|
||||
|
||||
// Our heightmap calculation function, we could use some perlin noise here if it wouldn't be so performance killing
|
||||
float height(vec2 x)
|
||||
{
|
||||
return texture2D(HEIGHT, x).x;
|
||||
}
|
||||
|
||||
|
||||
// Gets the terrain normal
|
||||
vec3 getTerrainNormal(vec3 p)
|
||||
{
|
||||
return normalize(vec3(
|
||||
height(p.xz - vec2(bigeps, 0)) - height(p.xz + vec2(bigeps, 0)),
|
||||
2 * bigeps,
|
||||
height(p.xz - vec2(0, bigeps)) - height(p.xz + vec2(0, bigeps))));
|
||||
}
|
||||
|
||||
|
||||
// Global diffuse lighting formula
|
||||
vec3 diffuseLight(vec3 incolor, float shadow, vec3 normal)
|
||||
{
|
||||
return (0.3 + shadow * 0.7 * max(dot(normal, lightDir), 0.0)) * lightColor * incolor;
|
||||
}
|
||||
|
||||
|
||||
// Calculates the water "waves". To reduce the bumpiness, increment the y-axis
|
||||
vec3 getWaterNormal(vec3 p)
|
||||
{
|
||||
return normalize(vec3(
|
||||
texnoise(p.xz * 40 + Y.x*.5)*2-1,
|
||||
8,
|
||||
texnoise(p.xz * 80 - Y.x*.25)*2-1));
|
||||
}
|
||||
|
||||
|
||||
float caustic(vec3 p)
|
||||
{
|
||||
vec2 q = p.xz * (1 - p.y * .01);
|
||||
float noiseX = texnoise(q * .125 * (.05*Y.x+vec2(2,3)));
|
||||
float noiseY = texnoise(q * .125 * (.05*Y.x+vec2(4,5)));
|
||||
q = mod(q * 10.0 + vec2(noiseX, noiseY) * 16.0, 1.0);
|
||||
q -= step(0.5, q) * 2 * (q - 0.5);
|
||||
q *= 2;
|
||||
return max(pow(q.x, 4.0 + 4.0 * noiseX), pow(q.y, 4.0 + 4.0 * noiseX));
|
||||
}
|
||||
|
||||
float caustics(vec3 p)
|
||||
{
|
||||
return caustic(p * 31) * caustic(p * 17);
|
||||
}
|
||||
|
||||
// Our fake godray effect (bad if moving fast, but awesome any other time)
|
||||
vec3 godrays(vec3 ro, vec3 rd, float maxt, vec3 color)
|
||||
{
|
||||
const int iterations = 16;
|
||||
float dt = 0.001, t = 0;
|
||||
float cs = 0.0;
|
||||
for (int i = 0; i < iterations; ++i)
|
||||
{
|
||||
vec3 p = ro + rd * t;
|
||||
vec2 q = p.xz * (1 - p.y * .4);
|
||||
|
||||
float shadow = 1.0-step(1,traceRay(p, lightDir, 2).w);
|
||||
cs = max(cs, (1 + p.y * 8) * shadow * smoothstep(0.4, 0.7, texnoise(q * 64)) / (1+t*2));
|
||||
t += dt;
|
||||
}
|
||||
return color + pow(cs, 4.0) * lightColor * .1;
|
||||
}
|
||||
|
||||
// Calculate the terrain color for the given voxel
|
||||
vec3 shadeTerrain(vec3 p, vec3 rd)
|
||||
{
|
||||
vec3 n = getTerrainNormal(p);
|
||||
float vrn = voronoi(p.xz);
|
||||
vec3 grassColor = vec3(0.8, 0.85, 0.4) * 1.5 * grass(p.xz);
|
||||
vec3 dirtColor = vec3(0.65, 0.6, 0.4) * (.5+grass(p.xz));
|
||||
vec3 stoneColor = vec3(0.5, 0.5, 0.4) * (.5+grass(p.xz));
|
||||
float groundFactor = smoothstep(0.7, 0.8, n.y) * (1.0 - step(p.y, texnoise(p.xz*128)*0.01-0.003)); // shore
|
||||
float dirtFactor = smoothstep(0.4, 0.6, texture2D(V, p.xz * 40).y);
|
||||
vec3 ground = mix(mix(stoneColor, dirtColor, dirtFactor), grassColor, groundFactor);
|
||||
|
||||
vec3 rockColor = vec3(0.5, 0.5, 0.5) * (.75 + vrn) * (.75+.5*grass(p.xz * 8));
|
||||
vec3 color = mix(ground, rockColor, smoothstep(0.0, 0.05,vrn));
|
||||
|
||||
float shadow = 1.0-step(1,traceRay(p + n * 0.005, lightDir, 2).w);
|
||||
|
||||
if (p.y <= 0)
|
||||
color = max(0.0, 0.7 + 8 * p.y) * (color + lightColor * shadow * max(0, 1 + 32 * p.y) * caustics(p));
|
||||
else
|
||||
color *= 0.6+0.4*min(1.0, p.y * 999.0);
|
||||
|
||||
color = color * (.5+.5*vrn);
|
||||
return diffuseLight(color, shadow, n);
|
||||
}
|
||||
|
||||
|
||||
// Create a blueish sky transition from navy blue to badass dark blue
|
||||
vec3 shadeSky(vec3 ro, vec3 rd)
|
||||
{
|
||||
vec3 farColor = vec3(0.0, 0.0, 0.4);
|
||||
return mix(waterColor, farColor, max(0, rd.y))
|
||||
+ 0.25*lightColor * pow(max(0, dot(rd, lightDir)), 4)
|
||||
+ lightColor * pow(max(0, dot(rd, lightDir)), 1000);
|
||||
}
|
||||
|
||||
|
||||
// Calculates the refraction and reflection of the water surface.
|
||||
// Also mixes both values by the depth of the water and the fresnel term.
|
||||
// Possible improvements: fix fake underwater reflection and refraction
|
||||
vec3 shadeWaterRefl(vec3 p, vec3 newrd)
|
||||
{
|
||||
vec3 waterNormal = getWaterNormal(p);
|
||||
|
||||
// perform raytracing/raymarching for both reflection and refraction
|
||||
// calc the water refraction, the refraction index (0.9) will decrease with the distance to allow a better over/under water transition
|
||||
vec3 refrd = mix(newrd, refract(newrd, waterNormal, 0.9), step(0.0, ro.y));
|
||||
vec4 refracted = traceRay(p, refrd, 2);//mix(0.9, 1.0, smoothstep(0.01, 0.0, length(p-ro)))), 2);
|
||||
|
||||
// calculate the depth factor (water entry point to terrain voxel) (black magic involved here!)
|
||||
float depth = clamp(pow(1.03 * (1 - length(refracted.xyz - p)), 16.0), 0.0, 1.0);
|
||||
|
||||
float shadow = 0.9 + 0.1 * (1.0-step(1,traceRay(p + waterNormal * 0.005, lightDir, 2).w));
|
||||
float fresnel = pow(clamp(abs(-rd.y), 0.0, 1.0),1.8);
|
||||
// Finally stir the pot =)
|
||||
return shadow * mix(
|
||||
shadeSky(p, refrd), // Water color
|
||||
mix(
|
||||
shade(traceRay(p, reflect(newrd, waterNormal), 2), p, newrd), // Reflection color
|
||||
shade(refracted, p, newrd), // Refraction color
|
||||
fresnel), // fresnel term
|
||||
pow(depth, 0.5)); // water color contribution
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Texture our "AMIGAAAAAAA!!" ball
|
||||
vec3 shadeAttractor(vec3 p, vec3 rd)
|
||||
{
|
||||
vec3 n,color;
|
||||
|
||||
// get the sphere normal, first
|
||||
n = normalize(p - spherePos);
|
||||
|
||||
// now calculate the texture coordinates
|
||||
vec2 uv = 0.5 + 0.5 * vec2(atan(n.z, n.x), acos(n.y)) / pi;
|
||||
|
||||
// We'll animate our x-texture coordinate with the time, this gives the impression of a rotating ball
|
||||
uv.x -= Y.x;
|
||||
|
||||
// This spell will convert any dull ball into an amiga ball, caution is advised.
|
||||
color = mix(vec3(1), vec3(1, 0, 0), mod(step(fract(uv.x * 6), 0.5) + step(fract(uv.y * 6), 0.5), 2.0));
|
||||
|
||||
return diffuseLight(color, 1, n)
|
||||
+ pow(max(dot(n, normalize(lightDir - rd)), 0.0), 33.0) * lightColor; // specular light spot
|
||||
}
|
||||
|
||||
#define INTERVAL_ITERS 5
|
||||
#define LINEAR_ACCURACY 0.5
|
||||
|
||||
// Raymarch the terrain function, returns the distance from the ray origin to the terrain voxel
|
||||
// This function was originally adopted from an implementation by iq/rgba
|
||||
float traceTerrain(vec3 ro, vec3 rd, float maxt)
|
||||
{
|
||||
float samplePosY, h, prevt, t;
|
||||
vec3 samplePos;
|
||||
|
||||
// advance our sample position from our nearplane to our farplane
|
||||
for (t = 0; t < maxt;)
|
||||
{
|
||||
// advance our ray
|
||||
samplePos = ro + rd * t;
|
||||
samplePosY = samplePos.y;
|
||||
|
||||
// get the height at the given sample 2d (!) position (we could enhance this by sampling a voxel and returning only the distance to the voxel)
|
||||
h = height(samplePos.xz);
|
||||
float dist = samplePosY - h;
|
||||
if (dist < 0.0) break;
|
||||
|
||||
prevt = t;
|
||||
|
||||
if (dist > 0.0001)
|
||||
t += max(dist * 1.4, 0.0001) * LINEAR_ACCURACY;
|
||||
else
|
||||
t += max(dist, 0.00001) * LINEAR_ACCURACY;
|
||||
}
|
||||
|
||||
if (samplePosY <= h)
|
||||
{
|
||||
/// Interval mapping
|
||||
float before = prevt;
|
||||
vec3 beforePos = ro + rd * before;
|
||||
float beforeH = height(beforePos.xz);
|
||||
|
||||
float after = t;
|
||||
vec3 afterPos = ro + rd * after;
|
||||
float afterH = height(afterPos.xz);
|
||||
|
||||
for (int i = 0; i < INTERVAL_ITERS; i++)
|
||||
{
|
||||
float interval = after - before;
|
||||
float deltaL = beforeH - afterH;
|
||||
float deltaR = rd.y * interval;
|
||||
|
||||
float curt = (beforeH * interval - deltaL * before) / (deltaR - deltaL);
|
||||
if (curt <= before - 0.000001 || curt >= after + 0.000001) break;
|
||||
|
||||
samplePos = ro + rd * curt;
|
||||
float h = height(samplePos.xz);
|
||||
|
||||
if (h <= samplePos.y)
|
||||
{
|
||||
beforeH = h;
|
||||
before = curt;
|
||||
t = curt;
|
||||
}
|
||||
else
|
||||
{
|
||||
afterH = h;
|
||||
after = curt;
|
||||
t = curt;
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// we hit nothing
|
||||
return 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Ray vs. sphere intersection function
|
||||
float traceAttractor(vec3 ro, vec3 rd)
|
||||
{
|
||||
vec3 dst = ro - spherePos;
|
||||
float B,D;
|
||||
B = dot(dst, rd);
|
||||
if (B > 0)
|
||||
return 9.0;
|
||||
D = B*B - dot(dst, dst) + sphereRadius*sphereRadius;
|
||||
if (D > 0)
|
||||
{
|
||||
return -B - sqrt(D);
|
||||
}
|
||||
return 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Ray vs. plane intersection function
|
||||
float traceWater(vec3 ro, vec3 rd)
|
||||
{
|
||||
float tPlane = -ro.y / rd.y;
|
||||
return tPlane >= eps ? tPlane : 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Raytracing entry point, returns voxel and object ID
|
||||
// IDs:
|
||||
// 0 = sky (not the armageddon, xTr1m!!)
|
||||
// 1 = terrain
|
||||
// 2 = water
|
||||
// 3 = attractive amiga ball (you have never seen such a sexy amiga ball before, admit it!)
|
||||
vec4 traceRay(vec3 ro, vec3 rd, int ignore)
|
||||
{
|
||||
float water, attractor, terrain, minDist;
|
||||
|
||||
// trace only the objects we need (only one could maximally be ignored)
|
||||
water = ignore != 2 ? traceWater(ro, rd) : 9.0;
|
||||
attractor = ignore != 3 ? traceAttractor(ro, rd) : 9.0;
|
||||
terrain = ignore != 1 ? traceTerrain(ro, rd, min(0.5, 0.002+min(water, attractor))) : 9.0;
|
||||
|
||||
// auto detail level reducing (common dude, give the GPU some breathing room)
|
||||
gf_DetailLevel /= 20;
|
||||
|
||||
// find the nearest distance
|
||||
minDist = min(terrain, min(water, min(attractor, 9.0)));
|
||||
|
||||
// we hit nothing or the hitpoint is too far
|
||||
if (minDist == 9)
|
||||
return vec4(0);
|
||||
|
||||
// calculate the hit/voxel position
|
||||
vec3 hitPos = ro + rd * minDist;
|
||||
|
||||
// check what we might have hit
|
||||
if (minDist == terrain)
|
||||
return vec4(hitPos, 1);
|
||||
if (minDist == water)
|
||||
return vec4(hitPos, 2);
|
||||
if (minDist == attractor)
|
||||
return vec4(hitPos, 3);
|
||||
|
||||
// Panic, worry, die to death! Probably we'll land on the moon (this should never happen)
|
||||
//return vec4(0);
|
||||
}
|
||||
|
||||
|
||||
// Entrypoint for color calculation
|
||||
vec3 shadeRefl(vec4 hitPoint, vec3 newRo, vec3 rd)
|
||||
{
|
||||
// determine the fog color for this very precise point in the space time continuum
|
||||
vec3 myFog = newRo.y < eps ? waterColor : shadeSky(ro, rd);
|
||||
|
||||
// generate the distance value for the fog calculation
|
||||
float distance = clamp(length(hitPoint.xyz - newRo) * (ro.y <= 0 ? 4 : 2), 0.0, 1.0);
|
||||
|
||||
// get the color of the hit object and mix it with the fog
|
||||
// in most cases we allow further raytracing here (not for the terrain, its not shiny enough)
|
||||
if (hitPoint.w == 1)
|
||||
return mix(shadeTerrain(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 2)
|
||||
return mix(shadeWaterRefl(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 3)
|
||||
return mix(
|
||||
// Our amiga ball is shiny so reflect the scene!
|
||||
mix(shadeAttractor(hitPoint.xyz, rd), shade(traceRay(hitPoint.xyz, reflect(rd, normalize(hitPoint.xyz - spherePos)), 3), hitPoint.xyz, rd), 0.5)
|
||||
, myFog, distance);
|
||||
|
||||
return shadeSky(newRo, rd);
|
||||
}
|
||||
|
||||
|
||||
// Get the color from the object we just hit (without further raytraces)
|
||||
// this is necessary because no recursion is allowed in GLSL (damn you!)
|
||||
vec3 shade(vec4 hitPoint, vec3 newRo, vec3 rd)
|
||||
{
|
||||
// determine the fog color for the very same point we discussed earlier
|
||||
vec3 myFog = newRo.y < eps ? waterColor : shadeSky(ro, rd);
|
||||
|
||||
// generate the other distance value. Paid attention? If you don't know what value I'm talking about, rtfm or gtfo.
|
||||
float distance = clamp(length(hitPoint.xyz - newRo) * (ro.y <= 0 ? 4 : 2), 0.0, 1.0);
|
||||
|
||||
// get the color of the hit object and mix it with the fog
|
||||
if (hitPoint.w == 1)
|
||||
return mix(shadeTerrain(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 2)
|
||||
return mix(waterColor, myFog, distance);
|
||||
if (hitPoint.w == 3)
|
||||
return mix(shadeAttractor(hitPoint.xyz, rd), myFog, distance);
|
||||
|
||||
return myFog;
|
||||
}
|
||||
|
||||
// Now we're just being copycats. We're not creative enough to define own entry points
|
||||
// Sure, we could "#define MYENTRYPOINT main"! Or just void main(){MyEntryPoint();}
|
||||
// None of that would help us win the compo, would it?
|
||||
void main()
|
||||
{
|
||||
// Set the quality setting for the raymarcher, a higher value results in a longer processing time
|
||||
// try to find a good balance between these two, low values wivoronoill result in a wobbling endresult
|
||||
// low quality = 50.0 (visual results are ok at 640x480)
|
||||
// mid quality = 100.0
|
||||
// high quality = 200.0
|
||||
gf_DetailLevel = 100;
|
||||
|
||||
// Give our saviour global variables some life!
|
||||
pi = 3.1416;
|
||||
interlacing = vec3(1.2, 0.9, 0.9);
|
||||
eps = 0.0001;
|
||||
bigeps = 0.01;
|
||||
|
||||
// Nifty random number generator gets initialized
|
||||
float seed = 10;
|
||||
|
||||
// Determine the scene we're in
|
||||
int scene = int(Y.x);
|
||||
|
||||
// Get the look direction for the current pixel (always look forwards)
|
||||
rd = vec3((Z.xy - 0.5), 1);
|
||||
|
||||
float tex = texture2D(V, clamp(Z.xy, 0.0, 1.0), 1.0).x;
|
||||
gl_FragColor = vec4(tex, tex, tex, 1);
|
||||
return;
|
||||
|
||||
// Merry-go-round on a boat (yeah, this makes no sense. Go watch the intro and see for yourself)
|
||||
if (scene > 22 && scene < 27)
|
||||
{
|
||||
seed = min(1.0, sin((Y.x-23)*pi*0.25)*12);
|
||||
ro = vec3(0.12, 0.005, Y.x*0.08);
|
||||
rd = vec3(gl_ModelViewMatrix * vec4(rd, 1));
|
||||
rd.y += 0.1*cos(Y.x*4);
|
||||
}
|
||||
// Intermezzo: Dolphin like animation inside and outside the water, chasing that amiga ball!
|
||||
else if (scene > 14 && scene < 23)
|
||||
{
|
||||
seed = min(1.0, sin((Y.x-15)*pi*0.125)*24);
|
||||
rd += vec3(0,0.1*cos(Y.x*4), 0);
|
||||
ro = vec3(0.08, 0.01*sin(Y.x*4)+0.002, Y.x*0.11);
|
||||
}
|
||||
// Intro and Outro: Show still scenes
|
||||
else
|
||||
{
|
||||
// Get a random initial position for our camera
|
||||
ro = vec3(0.1,0.004,0.0) + vec3(0.1,0.005,20)
|
||||
*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)));
|
||||
|
||||
// Basing on the initial position, choose some "random" start and end points nearby
|
||||
ro = mix(
|
||||
ro+vec3(0.008)*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++))),
|
||||
ro+vec3(0.008)*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++))),
|
||||
// and move the camera!
|
||||
Y.x-scene);
|
||||
|
||||
// We adjust the height of the camera to the terrain height
|
||||
ro.y += height(ro.xz)+0.02;
|
||||
|
||||
// Deviate the camera position in the direction of the normal of the underlying terrain
|
||||
ro += 0.02*getTerrainNormal(ro);
|
||||
|
||||
// Reusing a float variable here, this controls the scene fade in / fade out animation
|
||||
seed = min(1.0, step(-28.0, -Y.x) * sin((Y.x-scene)*pi)*3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
rd = normalize(rd);
|
||||
|
||||
// Now boot the amiga workbench (erm, no...)
|
||||
// mantain a relative distance to the camera
|
||||
if (scene > 22 && scene < 27)
|
||||
spherePos = ro + 0.1 * vec3(gl_ModelViewMatrix * vec4(0, 0, 1, 1));
|
||||
else
|
||||
spherePos = ro + 0.02 * vec3(sin(Y.x), 0, 5+cos(Y.x));
|
||||
|
||||
spherePos.y += 0.01 + height(spherePos.xz); // mantain a relative height to the underlying terrain
|
||||
sphereRadius = scene < 14 ? 0.0 : bigeps * 0.5 + bigeps * Y.z; // The amiga ball is bigger when the snare drum is hit!
|
||||
spherePos += 2*sphereRadius * getTerrainNormal(spherePos); // deviate according to the underlying terrain's normal
|
||||
|
||||
// Make our world pretty and worthy to live in (you can cultivate algae and eat them, they're surely enough for survival)
|
||||
lightDir = normalize(vec3(0.78, 0.12 + Y.x*.2, -0.18));
|
||||
lightColor = vec3(2.4, 2.0, 1.0) + Y.x*.5;
|
||||
waterColor = mix(vec3(0.4, 0.33, 0.4), vec3(0.4, 0.5, 0.6), Y.x);
|
||||
|
||||
// Our GPU feels good underwater, almost like a refreshing experience :) cool, eh?
|
||||
if (ro.y <= 0)
|
||||
{
|
||||
// Less work to do...
|
||||
gf_DetailLevel *= 0.75;
|
||||
|
||||
// ...and a cozy darker atmosphere
|
||||
lightColor *= 0.8;
|
||||
}
|
||||
|
||||
// Here we go, shoot'em rays and get the color of our fragment!
|
||||
vec4 hit = traceRay(ro, rd, 0);
|
||||
vec3 color = shadeRefl(hit, ro, rd);
|
||||
|
||||
// Underwater there are beams of light emanating from god (so called "god" rays...)
|
||||
// ...this prooves that god is nothing less than a water surface.
|
||||
if (ro.y <= 0)
|
||||
color = godrays(ro, rd, length(hit.xyz-ro), color);
|
||||
|
||||
// Apply post processing and fade effects to the color, and finally return it.
|
||||
gl_FragColor.xyz = color;
|
||||
}
|
||||
557
underwater4k/fragment.glsl_0_dbg
Normal file
557
underwater4k/fragment.glsl_0_dbg
Normal file
@@ -0,0 +1,557 @@
|
||||
|
||||
const int shader= 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
varying vec4 Y;
|
||||
|
||||
// Position of the fragment
|
||||
varying vec2 Z;
|
||||
|
||||
uniform sampler2D V;
|
||||
uniform sampler2D HEIGHT;
|
||||
|
||||
// Forward declarations
|
||||
vec4 traceRay(vec3 ro, vec3 rd, int ignore);
|
||||
vec3 shade(vec4 hitPoint, vec3 newRo, vec3 rd);
|
||||
|
||||
|
||||
// All data of our world
|
||||
vec3 spherePos, lightDir, lightColor, waterColor, ro, rd, interlacing;
|
||||
float sphereRadius, gf_DetailLevel, pi, eps, bigeps;
|
||||
|
||||
|
||||
// Pseudo random number base generator (credits go to iq/rgba)
|
||||
float rnd(vec2 x)
|
||||
{
|
||||
int n = int(x.x * 40 + x.y * 6400);
|
||||
n = (n << 13) ^ n;
|
||||
return 1 - float( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824;
|
||||
}
|
||||
|
||||
|
||||
// Generate cubic interpolated random values
|
||||
float smoothrnd(vec2 x)
|
||||
{
|
||||
x = mod(x,1000.0);
|
||||
vec2 a = fract(x);
|
||||
x -= a;
|
||||
vec2 u = a*a*(3.0-2.0*a);
|
||||
return mix(
|
||||
mix(rnd(x+vec2(0,0)),rnd(x+vec2(1,0)), u.x),
|
||||
mix(rnd(x+vec2(0,1)),rnd(x+vec2(1,1)), u.x), u.y);
|
||||
}
|
||||
|
||||
|
||||
// Convert the cipher range from [-1,1] to [0,1]
|
||||
float norm(float x)
|
||||
{
|
||||
return x * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
return (0.01 + ((.25*texture2D(V, p * 128.0).x) + texture2D(V, p * 32.0).x)) * smoothstep(0.25, 0.35, texture2D(V, p * 11).y * texture2D(V, p * 13).y);
|
||||
}
|
||||
|
||||
float texnoise(vec2 p)
|
||||
{
|
||||
return texture2D(V, p).y;
|
||||
}
|
||||
|
||||
float grass(vec2 p)
|
||||
{
|
||||
return texnoise(p * 57) * texnoise(p * 13) * 2.0;
|
||||
}
|
||||
|
||||
// Our heightmap calculation function, we could use some perlin noise here if it wouldn't be so performance killing
|
||||
float height(vec2 x)
|
||||
{
|
||||
return texture2D(HEIGHT, x).x;
|
||||
}
|
||||
|
||||
|
||||
// Gets the terrain normal
|
||||
vec3 getTerrainNormal(vec3 p)
|
||||
{
|
||||
return normalize(vec3(
|
||||
height(p.xz - vec2(bigeps, 0)) - height(p.xz + vec2(bigeps, 0)),
|
||||
2 * bigeps,
|
||||
height(p.xz - vec2(0, bigeps)) - height(p.xz + vec2(0, bigeps))));
|
||||
}
|
||||
|
||||
|
||||
// Global diffuse lighting formula
|
||||
vec3 diffuseLight(vec3 incolor, float shadow, vec3 normal)
|
||||
{
|
||||
return (0.3 + shadow * 0.7 * max(dot(normal, lightDir), 0.0)) * lightColor * incolor;
|
||||
}
|
||||
|
||||
|
||||
// Calculates the water "waves". To reduce the bumpiness, increment the y-axis
|
||||
vec3 getWaterNormal(vec3 p)
|
||||
{
|
||||
return normalize(vec3(
|
||||
texnoise(p.xz * 40 + Y.x*.5)*2-1,
|
||||
8,
|
||||
texnoise(p.xz * 80 - Y.x*.25)*2-1));
|
||||
}
|
||||
|
||||
|
||||
float caustic(vec3 p)
|
||||
{
|
||||
vec2 q = p.xz * (1 - p.y * .01);
|
||||
float noiseX = texnoise(q * .125 * (.05*Y.x+vec2(2,3)));
|
||||
float noiseY = texnoise(q * .125 * (.05*Y.x+vec2(4,5)));
|
||||
q = mod(q * 10.0 + vec2(noiseX, noiseY) * 16.0, 1.0);
|
||||
q -= step(0.5, q) * 2 * (q - 0.5);
|
||||
q *= 2;
|
||||
return max(pow(q.x, 4.0 + 4.0 * noiseX), pow(q.y, 4.0 + 4.0 * noiseX));
|
||||
}
|
||||
|
||||
float caustics(vec3 p)
|
||||
{
|
||||
return caustic(p * 31) * caustic(p * 17);
|
||||
}
|
||||
|
||||
// Our fake godray effect (bad if moving fast, but awesome any other time)
|
||||
vec3 godrays(vec3 ro, vec3 rd, float maxt, vec3 color)
|
||||
{
|
||||
const int iterations = 16;
|
||||
float dt = 0.001, t = 0;
|
||||
float cs = 0.0;
|
||||
for (int i = 0; i < iterations; ++i)
|
||||
{
|
||||
vec3 p = ro + rd * t;
|
||||
vec2 q = p.xz * (1 - p.y * .4);
|
||||
|
||||
float shadow = 1.0-step(1,traceRay(p, lightDir, 2).w);
|
||||
cs = max(cs, (1 + p.y * 8) * shadow * smoothstep(0.4, 0.7, texnoise(q * 64)) / (1+t*2));
|
||||
t += dt;
|
||||
}
|
||||
return color + pow(cs, 4.0) * lightColor * .1;
|
||||
}
|
||||
|
||||
// Calculate the terrain color for the given voxel
|
||||
vec3 shadeTerrain(vec3 p, vec3 rd)
|
||||
{
|
||||
vec3 n = getTerrainNormal(p);
|
||||
float vrn = voronoi(p.xz);
|
||||
vec3 grassColor = vec3(0.8, 0.85, 0.4) * 1.5 * grass(p.xz);
|
||||
vec3 dirtColor = vec3(0.65, 0.6, 0.4) * (.5+grass(p.xz));
|
||||
vec3 stoneColor = vec3(0.5, 0.5, 0.4) * (.5+grass(p.xz));
|
||||
float groundFactor = smoothstep(0.7, 0.8, n.y) * (1.0 - step(p.y, texnoise(p.xz*128)*0.01-0.003)); // shore
|
||||
float dirtFactor = smoothstep(0.4, 0.6, texture2D(V, p.xz * 40).y);
|
||||
vec3 ground = mix(mix(stoneColor, dirtColor, dirtFactor), grassColor, groundFactor);
|
||||
|
||||
vec3 rockColor = vec3(0.5, 0.5, 0.5) * (.75 + vrn) * (.75+.5*grass(p.xz * 8));
|
||||
vec3 color = mix(ground, rockColor, smoothstep(0.0, 0.05,vrn));
|
||||
|
||||
float shadow = 1.0-step(1,traceRay(p + n * 0.005, lightDir, 2).w);
|
||||
|
||||
if (p.y <= 0)
|
||||
color = max(0.0, 0.7 + 8 * p.y) * (color + lightColor * shadow * max(0, 1 + 32 * p.y) * caustics(p));
|
||||
else
|
||||
color *= 0.6+0.4*min(1.0, p.y * 999.0);
|
||||
|
||||
color = color * (.5+.5*vrn);
|
||||
return diffuseLight(color, shadow, n);
|
||||
}
|
||||
|
||||
|
||||
// Create a blueish sky transition from navy blue to badass dark blue
|
||||
vec3 shadeSky(vec3 ro, vec3 rd)
|
||||
{
|
||||
vec3 farColor = vec3(0.0, 0.0, 0.4);
|
||||
return mix(waterColor, farColor, max(0, rd.y))
|
||||
+ 0.25*lightColor * pow(max(0, dot(rd, lightDir)), 4)
|
||||
+ lightColor * pow(max(0, dot(rd, lightDir)), 1000);
|
||||
}
|
||||
|
||||
|
||||
// Calculates the refraction and reflection of the water surface.
|
||||
// Also mixes both values by the depth of the water and the fresnel term.
|
||||
// Possible improvements: fix fake underwater reflection and refraction
|
||||
vec3 shadeWaterRefl(vec3 p, vec3 newrd)
|
||||
{
|
||||
vec3 waterNormal = getWaterNormal(p);
|
||||
|
||||
// perform raytracing/raymarching for both reflection and refraction
|
||||
// calc the water refraction, the refraction index (0.9) will decrease with the distance to allow a better over/under water transition
|
||||
vec3 refrd = mix(newrd, refract(newrd, waterNormal, 0.9), step(0.0, ro.y));
|
||||
vec4 refracted = traceRay(p, refrd, 2);//mix(0.9, 1.0, smoothstep(0.01, 0.0, length(p-ro)))), 2);
|
||||
|
||||
// calculate the depth factor (water entry point to terrain voxel) (black magic involved here!)
|
||||
float depth = clamp(pow(1.03 * (1 - length(refracted.xyz - p)), 16.0), 0.0, 1.0);
|
||||
|
||||
float shadow = 0.9 + 0.1 * (1.0-step(1,traceRay(p + waterNormal * 0.005, lightDir, 2).w));
|
||||
float fresnel = pow(clamp(abs(-rd.y), 0.0, 1.0),1.8);
|
||||
// Finally stir the pot =)
|
||||
return shadow * mix(
|
||||
shadeSky(p, refrd), // Water color
|
||||
mix(
|
||||
shade(traceRay(p, reflect(newrd, waterNormal), 2), p, newrd), // Reflection color
|
||||
shade(refracted, p, newrd), // Refraction color
|
||||
fresnel), // fresnel term
|
||||
pow(depth, 0.5)); // water color contribution
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Texture our "AMIGAAAAAAA!!" ball
|
||||
vec3 shadeAttractor(vec3 p, vec3 rd)
|
||||
{
|
||||
vec3 n,color;
|
||||
|
||||
// get the sphere normal, first
|
||||
n = normalize(p - spherePos);
|
||||
|
||||
// now calculate the texture coordinates
|
||||
vec2 uv = 0.5 + 0.5 * vec2(atan(n.z, n.x), acos(n.y)) / pi;
|
||||
|
||||
// We'll animate our x-texture coordinate with the time, this gives the impression of a rotating ball
|
||||
uv.x -= Y.x;
|
||||
|
||||
// This spell will convert any dull ball into an amiga ball, caution is advised.
|
||||
color = mix(vec3(1), vec3(1, 0, 0), mod(step(fract(uv.x * 6), 0.5) + step(fract(uv.y * 6), 0.5), 2.0));
|
||||
|
||||
return diffuseLight(color, 1, n)
|
||||
+ pow(max(dot(n, normalize(lightDir - rd)), 0.0), 33.0) * lightColor; // specular light spot
|
||||
}
|
||||
|
||||
#define INTERVAL_ITERS 5
|
||||
#define LINEAR_ACCURACY 0.5
|
||||
|
||||
// Raymarch the terrain function, returns the distance from the ray origin to the terrain voxel
|
||||
// This function was originally adopted from an implementation by iq/rgba
|
||||
float traceTerrain(vec3 ro, vec3 rd, float maxt)
|
||||
{
|
||||
float samplePosY, h, prevt, t;
|
||||
vec3 samplePos;
|
||||
|
||||
// advance our sample position from our nearplane to our farplane
|
||||
for (t = 0; t < maxt;)
|
||||
{
|
||||
// advance our ray
|
||||
samplePos = ro + rd * t;
|
||||
samplePosY = samplePos.y;
|
||||
|
||||
// get the height at the given sample 2d (!) position (we could enhance this by sampling a voxel and returning only the distance to the voxel)
|
||||
h = height(samplePos.xz);
|
||||
float dist = samplePosY - h;
|
||||
if (dist < 0.0) break;
|
||||
|
||||
prevt = t;
|
||||
|
||||
if (dist > 0.0001)
|
||||
t += max(dist * 1.4, 0.0001) * LINEAR_ACCURACY;
|
||||
else
|
||||
t += max(dist, 0.00001) * LINEAR_ACCURACY;
|
||||
}
|
||||
|
||||
if (samplePosY <= h)
|
||||
{
|
||||
/// Interval mapping
|
||||
float before = prevt;
|
||||
vec3 beforePos = ro + rd * before;
|
||||
float beforeH = height(beforePos.xz);
|
||||
|
||||
float after = t;
|
||||
vec3 afterPos = ro + rd * after;
|
||||
float afterH = height(afterPos.xz);
|
||||
|
||||
for (int i = 0; i < INTERVAL_ITERS; i++)
|
||||
{
|
||||
float interval = after - before;
|
||||
float deltaL = beforeH - afterH;
|
||||
float deltaR = rd.y * interval;
|
||||
|
||||
float curt = (beforeH * interval - deltaL * before) / (deltaR - deltaL);
|
||||
if (curt <= before - 0.000001 || curt >= after + 0.000001) break;
|
||||
|
||||
samplePos = ro + rd * curt;
|
||||
float h = height(samplePos.xz);
|
||||
|
||||
if (h <= samplePos.y)
|
||||
{
|
||||
beforeH = h;
|
||||
before = curt;
|
||||
t = curt;
|
||||
}
|
||||
else
|
||||
{
|
||||
afterH = h;
|
||||
after = curt;
|
||||
t = curt;
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// we hit nothing
|
||||
return 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Ray vs. sphere intersection function
|
||||
float traceAttractor(vec3 ro, vec3 rd)
|
||||
{
|
||||
vec3 dst = ro - spherePos;
|
||||
float B,D;
|
||||
B = dot(dst, rd);
|
||||
if (B > 0)
|
||||
return 9.0;
|
||||
D = B*B - dot(dst, dst) + sphereRadius*sphereRadius;
|
||||
if (D > 0)
|
||||
{
|
||||
return -B - sqrt(D);
|
||||
}
|
||||
return 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Ray vs. plane intersection function
|
||||
float traceWater(vec3 ro, vec3 rd)
|
||||
{
|
||||
float tPlane = -ro.y / rd.y;
|
||||
return tPlane >= eps ? tPlane : 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Raytracing entry point, returns voxel and object ID
|
||||
// IDs:
|
||||
// 0 = sky (not the armageddon, xTr1m!!)
|
||||
// 1 = terrain
|
||||
// 2 = water
|
||||
// 3 = attractive amiga ball (you have never seen such a sexy amiga ball before, admit it!)
|
||||
vec4 traceRay(vec3 ro, vec3 rd, int ignore)
|
||||
{
|
||||
float water, attractor, terrain, minDist;
|
||||
|
||||
// trace only the objects we need (only one could maximally be ignored)
|
||||
water = ignore != 2 ? traceWater(ro, rd) : 9.0;
|
||||
attractor = ignore != 3 ? traceAttractor(ro, rd) : 9.0;
|
||||
terrain = ignore != 1 ? traceTerrain(ro, rd, min(0.5, 0.002+min(water, attractor))) : 9.0;
|
||||
|
||||
// auto detail level reducing (common dude, give the GPU some breathing room)
|
||||
gf_DetailLevel /= 20;
|
||||
|
||||
// find the nearest distance
|
||||
minDist = min(terrain, min(water, min(attractor, 9.0)));
|
||||
|
||||
// we hit nothing or the hitpoint is too far
|
||||
if (minDist == 9)
|
||||
return vec4(0);
|
||||
|
||||
// calculate the hit/voxel position
|
||||
vec3 hitPos = ro + rd * minDist;
|
||||
|
||||
// check what we might have hit
|
||||
if (minDist == terrain)
|
||||
return vec4(hitPos, 1);
|
||||
if (minDist == water)
|
||||
return vec4(hitPos, 2);
|
||||
if (minDist == attractor)
|
||||
return vec4(hitPos, 3);
|
||||
|
||||
// Panic, worry, die to death! Probably we'll land on the moon (this should never happen)
|
||||
//return vec4(0);
|
||||
}
|
||||
|
||||
|
||||
// Entrypoint for color calculation
|
||||
vec3 shadeRefl(vec4 hitPoint, vec3 newRo, vec3 rd)
|
||||
{
|
||||
// determine the fog color for this very precise point in the space time continuum
|
||||
vec3 myFog = newRo.y < eps ? waterColor : shadeSky(ro, rd);
|
||||
|
||||
// generate the distance value for the fog calculation
|
||||
float distance = clamp(length(hitPoint.xyz - newRo) * (ro.y <= 0 ? 4 : 2), 0.0, 1.0);
|
||||
|
||||
// get the color of the hit object and mix it with the fog
|
||||
// in most cases we allow further raytracing here (not for the terrain, its not shiny enough)
|
||||
if (hitPoint.w == 1)
|
||||
return mix(shadeTerrain(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 2)
|
||||
return mix(shadeWaterRefl(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 3)
|
||||
return mix(
|
||||
// Our amiga ball is shiny so reflect the scene!
|
||||
mix(shadeAttractor(hitPoint.xyz, rd), shade(traceRay(hitPoint.xyz, reflect(rd, normalize(hitPoint.xyz - spherePos)), 3), hitPoint.xyz, rd), 0.5)
|
||||
, myFog, distance);
|
||||
|
||||
return shadeSky(newRo, rd);
|
||||
}
|
||||
|
||||
|
||||
// Get the color from the object we just hit (without further raytraces)
|
||||
// this is necessary because no recursion is allowed in GLSL (damn you!)
|
||||
vec3 shade(vec4 hitPoint, vec3 newRo, vec3 rd)
|
||||
{
|
||||
// determine the fog color for the very same point we discussed earlier
|
||||
vec3 myFog = newRo.y < eps ? waterColor : shadeSky(ro, rd);
|
||||
|
||||
// generate the other distance value. Paid attention? If you don't know what value I'm talking about, rtfm or gtfo.
|
||||
float distance = clamp(length(hitPoint.xyz - newRo) * (ro.y <= 0 ? 4 : 2), 0.0, 1.0);
|
||||
|
||||
// get the color of the hit object and mix it with the fog
|
||||
if (hitPoint.w == 1)
|
||||
return mix(shadeTerrain(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 2)
|
||||
return mix(waterColor, myFog, distance);
|
||||
if (hitPoint.w == 3)
|
||||
return mix(shadeAttractor(hitPoint.xyz, rd), myFog, distance);
|
||||
|
||||
return myFog;
|
||||
}
|
||||
|
||||
// Now we're just being copycats. We're not creative enough to define own entry points
|
||||
// Sure, we could "#define MYENTRYPOINT main"! Or just void main(){MyEntryPoint();}
|
||||
// None of that would help us win the compo, would it?
|
||||
void main()
|
||||
{
|
||||
// Set the quality setting for the raymarcher, a higher value results in a longer processing time
|
||||
// try to find a good balance between these two, low values wivoronoill result in a wobbling endresult
|
||||
// low quality = 50.0 (visual results are ok at 640x480)
|
||||
// mid quality = 100.0
|
||||
// high quality = 200.0
|
||||
gf_DetailLevel = 100;
|
||||
|
||||
// Give our saviour global variables some life!
|
||||
pi = 3.1416;
|
||||
interlacing = vec3(1.2, 0.9, 0.9);
|
||||
eps = 0.0001;
|
||||
bigeps = 0.01;
|
||||
|
||||
// Nifty random number generator gets initialized
|
||||
float seed = 10;
|
||||
|
||||
// Determine the scene we're in
|
||||
int scene = int(Y.x);
|
||||
|
||||
// Get the look direction for the current pixel (always look forwards)
|
||||
rd = vec3((Z.xy - 0.5), 1);
|
||||
|
||||
float tex = texture2D(V, clamp(Z.xy, 0.0, 1.0), 1.0).x;
|
||||
gl_FragColor = vec4(tex, tex, tex, 1);
|
||||
return;
|
||||
|
||||
// Merry-go-round on a boat (yeah, this makes no sense. Go watch the intro and see for yourself)
|
||||
if (scene > 22 && scene < 27)
|
||||
{
|
||||
seed = min(1.0, sin((Y.x-23)*pi*0.25)*12);
|
||||
ro = vec3(0.12, 0.005, Y.x*0.08);
|
||||
rd = vec3(gl_ModelViewMatrix * vec4(rd, 1));
|
||||
rd.y += 0.1*cos(Y.x*4);
|
||||
}
|
||||
// Intermezzo: Dolphin like animation inside and outside the water, chasing that amiga ball!
|
||||
else if (scene > 14 && scene < 23)
|
||||
{
|
||||
seed = min(1.0, sin((Y.x-15)*pi*0.125)*24);
|
||||
rd += vec3(0,0.1*cos(Y.x*4), 0);
|
||||
ro = vec3(0.08, 0.01*sin(Y.x*4)+0.002, Y.x*0.11);
|
||||
}
|
||||
// Intro and Outro: Show still scenes
|
||||
else
|
||||
{
|
||||
// Get a random initial position for our camera
|
||||
ro = vec3(0.1,0.004,0.0) + vec3(0.1,0.005,20)
|
||||
*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)));
|
||||
|
||||
// Basing on the initial position, choose some "random" start and end points nearby
|
||||
ro = mix(
|
||||
ro+vec3(0.008)*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++))),
|
||||
ro+vec3(0.008)*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++))),
|
||||
// and move the camera!
|
||||
Y.x-scene);
|
||||
|
||||
// We adjust the height of the camera to the terrain height
|
||||
ro.y += height(ro.xz)+0.02;
|
||||
|
||||
// Deviate the camera position in the direction of the normal of the underlying terrain
|
||||
ro += 0.02*getTerrainNormal(ro);
|
||||
|
||||
// Reusing a float variable here, this controls the scene fade in / fade out animation
|
||||
seed = min(1.0, step(-28.0, -Y.x) * sin((Y.x-scene)*pi)*3);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//Debugzeug fuer Kamerasteuerung
|
||||
{
|
||||
ro.x= gl_ModelViewMatrix[0][0];
|
||||
ro.y= gl_ModelViewMatrix[0][1];
|
||||
ro.z= gl_ModelViewMatrix[0][2];
|
||||
|
||||
float a1= gl_ModelViewMatrix[1][1];
|
||||
float c1,s1;vec3 q1= vec3((Z.xy - 0.5), 0.8);
|
||||
c1 = cos(a1); s1 = sin(a1);
|
||||
rd.y = c1 * q1.y - s1 * q1.z;
|
||||
rd.x= q1.x;
|
||||
rd.z = s1 * q1.y + c1 * q1.z;
|
||||
|
||||
a1= gl_ModelViewMatrix[1][0];
|
||||
q1=rd;
|
||||
c1 = cos(a1); s1 = sin(a1);
|
||||
rd.x = c1 * q1.x + s1 * q1.z;
|
||||
rd.z = -s1 * q1.x + c1 * q1.z;
|
||||
|
||||
}
|
||||
//Ende Debugzeug fuer Kamerasteuerung
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
rd = normalize(rd);
|
||||
|
||||
// Now boot the amiga workbench (erm, no...)
|
||||
// mantain a relative distance to the camera
|
||||
if (scene > 22 && scene < 27)
|
||||
spherePos = ro + 0.1 * vec3(gl_ModelViewMatrix * vec4(0, 0, 1, 1));
|
||||
else
|
||||
spherePos = ro + 0.02 * vec3(sin(Y.x), 0, 5+cos(Y.x));
|
||||
|
||||
spherePos.y += 0.01 + height(spherePos.xz); // mantain a relative height to the underlying terrain
|
||||
sphereRadius = scene < 14 ? 0.0 : bigeps * 0.5 + bigeps * Y.z; // The amiga ball is bigger when the snare drum is hit!
|
||||
spherePos += 2*sphereRadius * getTerrainNormal(spherePos); // deviate according to the underlying terrain's normal
|
||||
|
||||
// Make our world pretty and worthy to live in (you can cultivate algae and eat them, they're surely enough for survival)
|
||||
lightDir = normalize(vec3(0.78, 0.12 + Y.x*.2, -0.18));
|
||||
lightColor = vec3(2.4, 2.0, 1.0) + Y.x*.5;
|
||||
waterColor = mix(vec3(0.4, 0.33, 0.4), vec3(0.4, 0.5, 0.6), Y.x);
|
||||
|
||||
// Our GPU feels good underwater, almost like a refreshing experience :) cool, eh?
|
||||
if (ro.y <= 0)
|
||||
{
|
||||
// Less work to do...
|
||||
gf_DetailLevel *= 0.75;
|
||||
|
||||
// ...and a cozy darker atmosphere
|
||||
lightColor *= 0.8;
|
||||
}
|
||||
|
||||
// Here we go, shoot'em rays and get the color of our fragment!
|
||||
vec4 hit = traceRay(ro, rd, 0);
|
||||
vec3 color = shadeRefl(hit, ro, rd);
|
||||
|
||||
// Underwater there are beams of light emanating from god (so called "god" rays...)
|
||||
// ...this prooves that god is nothing less than a water surface.
|
||||
if (ro.y <= 0)
|
||||
color = godrays(ro, rd, length(hit.xyz-ro), color);
|
||||
|
||||
// Apply post processing and fade effects to the color, and finally return it.
|
||||
gl_FragColor.xyz = color;
|
||||
}
|
||||
557
underwater4k/fragment.glsl_1
Normal file
557
underwater4k/fragment.glsl_1
Normal file
@@ -0,0 +1,557 @@
|
||||
|
||||
|
||||
|
||||
|
||||
const int shader= 1;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
varying vec4 Y;
|
||||
|
||||
// Position of the fragment
|
||||
varying vec2 Z;
|
||||
|
||||
uniform sampler2D V;
|
||||
uniform sampler2D HEIGHT;
|
||||
|
||||
// Forward declarations
|
||||
vec4 traceRay(vec3 ro, vec3 rd, int ignore);
|
||||
vec3 shade(vec4 hitPoint, vec3 newRo, vec3 rd);
|
||||
|
||||
|
||||
// All data of our world
|
||||
vec3 spherePos, lightDir, lightColor, waterColor, ro, rd, interlacing;
|
||||
float sphereRadius, gf_DetailLevel, pi, eps, bigeps;
|
||||
|
||||
|
||||
// Pseudo random number base generator (credits go to iq/rgba)
|
||||
float rnd(vec2 x)
|
||||
{
|
||||
int n = int(x.x * 40 + x.y * 6400);
|
||||
n = (n << 13) ^ n;
|
||||
return 1 - float( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824;
|
||||
}
|
||||
|
||||
|
||||
// Generate cubic interpolated random values
|
||||
float smoothrnd(vec2 x)
|
||||
{
|
||||
x = mod(x,1000.0);
|
||||
vec2 a = fract(x);
|
||||
x -= a;
|
||||
vec2 u = a*a*(3.0-2.0*a);
|
||||
return mix(
|
||||
mix(rnd(x+vec2(0,0)),rnd(x+vec2(1,0)), u.x),
|
||||
mix(rnd(x+vec2(0,1)),rnd(x+vec2(1,1)), u.x), u.y);
|
||||
}
|
||||
|
||||
|
||||
// Convert the cipher range from [-1,1] to [0,1]
|
||||
float norm(float x)
|
||||
{
|
||||
return x * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
return (0.01 + ((.25*texture2D(V, p * 128.0).x) + texture2D(V, p * 32.0).x)) * smoothstep(0.25, 0.35, texture2D(V, p * 11).y * texture2D(V, p * 13).y);
|
||||
}
|
||||
|
||||
float texnoise(vec2 p)
|
||||
{
|
||||
return texture2D(V, p).y;
|
||||
}
|
||||
|
||||
float grass(vec2 p)
|
||||
{
|
||||
return texnoise(p * 57) * texnoise(p * 13) * 2.0;
|
||||
}
|
||||
|
||||
// Our heightmap calculation function, we could use some perlin noise here if it wouldn't be so performance killing
|
||||
float height(vec2 x)
|
||||
{
|
||||
return texture2D(HEIGHT, x).x;
|
||||
}
|
||||
|
||||
|
||||
// Gets the terrain normal
|
||||
vec3 getTerrainNormal(vec3 p)
|
||||
{
|
||||
return normalize(vec3(
|
||||
height(p.xz - vec2(bigeps, 0)) - height(p.xz + vec2(bigeps, 0)),
|
||||
2 * bigeps,
|
||||
height(p.xz - vec2(0, bigeps)) - height(p.xz + vec2(0, bigeps))));
|
||||
}
|
||||
|
||||
|
||||
// Global diffuse lighting formula
|
||||
vec3 diffuseLight(vec3 incolor, float shadow, vec3 normal)
|
||||
{
|
||||
return (0.3 + shadow * 0.7 * max(dot(normal, lightDir), 0.0)) * lightColor * incolor;
|
||||
}
|
||||
|
||||
|
||||
// Calculates the water "waves". To reduce the bumpiness, increment the y-axis
|
||||
vec3 getWaterNormal(vec3 p)
|
||||
{
|
||||
return normalize(vec3(
|
||||
texnoise(p.xz * 40 + Y.x*.5)*2-1,
|
||||
8,
|
||||
texnoise(p.xz * 80 - Y.x*.25)*2-1));
|
||||
}
|
||||
|
||||
|
||||
float caustic(vec3 p)
|
||||
{
|
||||
vec2 q = p.xz * (1 - p.y * .01);
|
||||
float noiseX = texnoise(q * .125 * (.05*Y.x+vec2(2,3)));
|
||||
float noiseY = texnoise(q * .125 * (.05*Y.x+vec2(4,5)));
|
||||
q = mod(q * 10.0 + vec2(noiseX, noiseY) * 16.0, 1.0);
|
||||
q -= step(0.5, q) * 2 * (q - 0.5);
|
||||
q *= 2;
|
||||
return max(pow(q.x, 4.0 + 4.0 * noiseX), pow(q.y, 4.0 + 4.0 * noiseX));
|
||||
}
|
||||
|
||||
float caustics(vec3 p)
|
||||
{
|
||||
return caustic(p * 31) * caustic(p * 17);
|
||||
}
|
||||
|
||||
// Our fake godray effect (bad if moving fast, but awesome any other time)
|
||||
vec3 godrays(vec3 ro, vec3 rd, float maxt, vec3 color)
|
||||
{
|
||||
const int iterations = 16;
|
||||
float dt = 0.001, t = 0;
|
||||
float cs = 0.0;
|
||||
for (int i = 0; i < iterations; ++i)
|
||||
{
|
||||
vec3 p = ro + rd * t;
|
||||
vec2 q = p.xz * (1 - p.y * .4);
|
||||
|
||||
float shadow = 1.0-step(1,traceRay(p, lightDir, 2).w);
|
||||
cs = max(cs, (1 + p.y * 8) * shadow * smoothstep(0.4, 0.7, texnoise(q * 64)) / (1+t*2));
|
||||
t += dt;
|
||||
}
|
||||
return color + pow(cs, 4.0) * lightColor * .1;
|
||||
}
|
||||
|
||||
// Calculate the terrain color for the given voxel
|
||||
vec3 shadeTerrain(vec3 p, vec3 rd)
|
||||
{
|
||||
vec3 n = getTerrainNormal(p);
|
||||
float vrn = voronoi(p.xz);
|
||||
vec3 grassColor = vec3(0.8, 0.85, 0.4) * 1.5 * grass(p.xz);
|
||||
vec3 dirtColor = vec3(0.65, 0.6, 0.4) * (.5+grass(p.xz));
|
||||
vec3 stoneColor = vec3(0.5, 0.5, 0.4) * (.5+grass(p.xz));
|
||||
float groundFactor = smoothstep(0.7, 0.8, n.y) * (1.0 - step(p.y, texnoise(p.xz*128)*0.01-0.003)); // shore
|
||||
float dirtFactor = smoothstep(0.4, 0.6, texture2D(V, p.xz * 40).y);
|
||||
vec3 ground = mix(mix(stoneColor, dirtColor, dirtFactor), grassColor, groundFactor);
|
||||
|
||||
vec3 rockColor = vec3(0.5, 0.5, 0.5) * (.75 + vrn) * (.75+.5*grass(p.xz * 8));
|
||||
vec3 color = mix(ground, rockColor, smoothstep(0.0, 0.05,vrn));
|
||||
|
||||
float shadow = 1.0-step(1,traceRay(p + n * 0.005, lightDir, 2).w);
|
||||
|
||||
if (p.y <= 0)
|
||||
color = max(0.0, 0.7 + 8 * p.y) * (color + lightColor * shadow * max(0, 1 + 32 * p.y) * caustics(p));
|
||||
else
|
||||
color *= 0.6+0.4*min(1.0, p.y * 999.0);
|
||||
|
||||
color = color * (.5+.5*vrn);
|
||||
return diffuseLight(color, shadow, n);
|
||||
}
|
||||
|
||||
|
||||
// Create a blueish sky transition from navy blue to badass dark blue
|
||||
vec3 shadeSky(vec3 ro, vec3 rd)
|
||||
{
|
||||
vec3 farColor = vec3(0.0, 0.0, 0.4);
|
||||
return mix(waterColor, farColor, max(0, rd.y))
|
||||
+ 0.25*lightColor * pow(max(0, dot(rd, lightDir)), 4)
|
||||
+ lightColor * pow(max(0, dot(rd, lightDir)), 1000);
|
||||
}
|
||||
|
||||
|
||||
// Calculates the refraction and reflection of the water surface.
|
||||
// Also mixes both values by the depth of the water and the fresnel term.
|
||||
// Possible improvements: fix fake underwater reflection and refraction
|
||||
vec3 shadeWaterRefl(vec3 p, vec3 newrd)
|
||||
{
|
||||
vec3 waterNormal = getWaterNormal(p);
|
||||
|
||||
// perform raytracing/raymarching for both reflection and refraction
|
||||
// calc the water refraction, the refraction index (0.9) will decrease with the distance to allow a better over/under water transition
|
||||
vec3 refrd = mix(newrd, refract(newrd, waterNormal, 0.9), step(0.0, ro.y));
|
||||
vec4 refracted = traceRay(p, refrd, 2);//mix(0.9, 1.0, smoothstep(0.01, 0.0, length(p-ro)))), 2);
|
||||
|
||||
// calculate the depth factor (water entry point to terrain voxel) (black magic involved here!)
|
||||
float depth = clamp(pow(1.03 * (1 - length(refracted.xyz - p)), 16.0), 0.0, 1.0);
|
||||
|
||||
float shadow = 0.9 + 0.1 * (1.0-step(1,traceRay(p + waterNormal * 0.005, lightDir, 2).w));
|
||||
float fresnel = pow(clamp(abs(-rd.y), 0.0, 1.0),1.8);
|
||||
// Finally stir the pot =)
|
||||
return shadow * mix(
|
||||
shadeSky(p, refrd), // Water color
|
||||
mix(
|
||||
shade(traceRay(p, reflect(newrd, waterNormal), 2), p, newrd), // Reflection color
|
||||
shade(refracted, p, newrd), // Refraction color
|
||||
fresnel), // fresnel term
|
||||
pow(depth, 0.5)); // water color contribution
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Texture our "AMIGAAAAAAA!!" ball
|
||||
vec3 shadeAttractor(vec3 p, vec3 rd)
|
||||
{
|
||||
vec3 n,color;
|
||||
|
||||
// get the sphere normal, first
|
||||
n = normalize(p - spherePos);
|
||||
|
||||
// now calculate the texture coordinates
|
||||
vec2 uv = 0.5 + 0.5 * vec2(atan(n.z, n.x), acos(n.y)) / pi;
|
||||
|
||||
// We'll animate our x-texture coordinate with the time, this gives the impression of a rotating ball
|
||||
uv.x -= Y.x;
|
||||
|
||||
// This spell will convert any dull ball into an amiga ball, caution is advised.
|
||||
color = mix(vec3(1), vec3(1, 0, 0), mod(step(fract(uv.x * 6), 0.5) + step(fract(uv.y * 6), 0.5), 2.0));
|
||||
|
||||
return diffuseLight(color, 1, n)
|
||||
+ pow(max(dot(n, normalize(lightDir - rd)), 0.0), 33.0) * lightColor; // specular light spot
|
||||
}
|
||||
|
||||
#define INTERVAL_ITERS 5
|
||||
#define LINEAR_ACCURACY 0.5
|
||||
|
||||
// Raymarch the terrain function, returns the distance from the ray origin to the terrain voxel
|
||||
// This function was originally adopted from an implementation by iq/rgba
|
||||
float traceTerrain(vec3 ro, vec3 rd, float maxt)
|
||||
{
|
||||
float samplePosY, h, prevt, t;
|
||||
vec3 samplePos;
|
||||
|
||||
// advance our sample position from our nearplane to our farplane
|
||||
for (t = 0; t < maxt;)
|
||||
{
|
||||
// advance our ray
|
||||
samplePos = ro + rd * t;
|
||||
samplePosY = samplePos.y;
|
||||
|
||||
// get the height at the given sample 2d (!) position (we could enhance this by sampling a voxel and returning only the distance to the voxel)
|
||||
h = height(samplePos.xz);
|
||||
float dist = samplePosY - h;
|
||||
if (dist < 0.0) break;
|
||||
|
||||
prevt = t;
|
||||
|
||||
if (dist > 0.0001)
|
||||
t += max(dist * 1.4, 0.0001) * LINEAR_ACCURACY;
|
||||
else
|
||||
t += max(dist, 0.00001) * LINEAR_ACCURACY;
|
||||
}
|
||||
|
||||
if (samplePosY <= h)
|
||||
{
|
||||
/// Interval mapping
|
||||
float before = prevt;
|
||||
vec3 beforePos = ro + rd * before;
|
||||
float beforeH = height(beforePos.xz);
|
||||
|
||||
float after = t;
|
||||
vec3 afterPos = ro + rd * after;
|
||||
float afterH = height(afterPos.xz);
|
||||
|
||||
for (int i = 0; i < INTERVAL_ITERS; i++)
|
||||
{
|
||||
float interval = after - before;
|
||||
float deltaL = beforeH - afterH;
|
||||
float deltaR = rd.y * interval;
|
||||
|
||||
float curt = (beforeH * interval - deltaL * before) / (deltaR - deltaL);
|
||||
if (curt <= before - 0.000001 || curt >= after + 0.000001) break;
|
||||
|
||||
samplePos = ro + rd * curt;
|
||||
float h = height(samplePos.xz);
|
||||
|
||||
if (h <= samplePos.y)
|
||||
{
|
||||
beforeH = h;
|
||||
before = curt;
|
||||
t = curt;
|
||||
}
|
||||
else
|
||||
{
|
||||
afterH = h;
|
||||
after = curt;
|
||||
t = curt;
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// we hit nothing
|
||||
return 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Ray vs. sphere intersection function
|
||||
float traceAttractor(vec3 ro, vec3 rd)
|
||||
{
|
||||
vec3 dst = ro - spherePos;
|
||||
float B,D;
|
||||
B = dot(dst, rd);
|
||||
if (B > 0)
|
||||
return 9.0;
|
||||
D = B*B - dot(dst, dst) + sphereRadius*sphereRadius;
|
||||
if (D > 0)
|
||||
{
|
||||
return -B - sqrt(D);
|
||||
}
|
||||
return 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Ray vs. plane intersection function
|
||||
float traceWater(vec3 ro, vec3 rd)
|
||||
{
|
||||
float tPlane = -ro.y / rd.y;
|
||||
return tPlane >= eps ? tPlane : 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Raytracing entry point, returns voxel and object ID
|
||||
// IDs:
|
||||
// 0 = sky (not the armageddon, xTr1m!!)
|
||||
// 1 = terrain
|
||||
// 2 = water
|
||||
// 3 = attractive amiga ball (you have never seen such a sexy amiga ball before, admit it!)
|
||||
vec4 traceRay(vec3 ro, vec3 rd, int ignore)
|
||||
{
|
||||
float water, attractor, terrain, minDist;
|
||||
|
||||
// trace only the objects we need (only one could maximally be ignored)
|
||||
water = ignore != 2 ? traceWater(ro, rd) : 9.0;
|
||||
attractor = ignore != 3 ? traceAttractor(ro, rd) : 9.0;
|
||||
terrain = ignore != 1 ? traceTerrain(ro, rd, min(0.5, 0.002+min(water, attractor))) : 9.0;
|
||||
|
||||
// auto detail level reducing (common dude, give the GPU some breathing room)
|
||||
gf_DetailLevel /= 20;
|
||||
|
||||
// find the nearest distance
|
||||
minDist = min(terrain, min(water, min(attractor, 9.0)));
|
||||
|
||||
// we hit nothing or the hitpoint is too far
|
||||
if (minDist == 9)
|
||||
return vec4(0);
|
||||
|
||||
// calculate the hit/voxel position
|
||||
vec3 hitPos = ro + rd * minDist;
|
||||
|
||||
// check what we might have hit
|
||||
if (minDist == terrain)
|
||||
return vec4(hitPos, 1);
|
||||
if (minDist == water)
|
||||
return vec4(hitPos, 2);
|
||||
if (minDist == attractor)
|
||||
return vec4(hitPos, 3);
|
||||
|
||||
// Panic, worry, die to death! Probably we'll land on the moon (this should never happen)
|
||||
//return vec4(0);
|
||||
}
|
||||
|
||||
|
||||
// Entrypoint for color calculation
|
||||
vec3 shadeRefl(vec4 hitPoint, vec3 newRo, vec3 rd)
|
||||
{
|
||||
// determine the fog color for this very precise point in the space time continuum
|
||||
vec3 myFog = newRo.y < eps ? waterColor : shadeSky(ro, rd);
|
||||
|
||||
// generate the distance value for the fog calculation
|
||||
float distance = clamp(length(hitPoint.xyz - newRo) * (ro.y <= 0 ? 4 : 2), 0.0, 1.0);
|
||||
|
||||
// get the color of the hit object and mix it with the fog
|
||||
// in most cases we allow further raytracing here (not for the terrain, its not shiny enough)
|
||||
if (hitPoint.w == 1)
|
||||
return mix(shadeTerrain(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 2)
|
||||
return mix(shadeWaterRefl(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 3)
|
||||
return mix(
|
||||
// Our amiga ball is shiny so reflect the scene!
|
||||
mix(shadeAttractor(hitPoint.xyz, rd), shade(traceRay(hitPoint.xyz, reflect(rd, normalize(hitPoint.xyz - spherePos)), 3), hitPoint.xyz, rd), 0.5)
|
||||
, myFog, distance);
|
||||
|
||||
return shadeSky(newRo, rd);
|
||||
}
|
||||
|
||||
|
||||
// Get the color from the object we just hit (without further raytraces)
|
||||
// this is necessary because no recursion is allowed in GLSL (damn you!)
|
||||
vec3 shade(vec4 hitPoint, vec3 newRo, vec3 rd)
|
||||
{
|
||||
// determine the fog color for the very same point we discussed earlier
|
||||
vec3 myFog = newRo.y < eps ? waterColor : shadeSky(ro, rd);
|
||||
|
||||
// generate the other distance value. Paid attention? If you don't know what value I'm talking about, rtfm or gtfo.
|
||||
float distance = clamp(length(hitPoint.xyz - newRo) * (ro.y <= 0 ? 4 : 2), 0.0, 1.0);
|
||||
|
||||
// get the color of the hit object and mix it with the fog
|
||||
if (hitPoint.w == 1)
|
||||
return mix(shadeTerrain(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 2)
|
||||
return mix(waterColor, myFog, distance);
|
||||
if (hitPoint.w == 3)
|
||||
return mix(shadeAttractor(hitPoint.xyz, rd), myFog, distance);
|
||||
|
||||
return myFog;
|
||||
}
|
||||
|
||||
// Now we're just being copycats. We're not creative enough to define own entry points
|
||||
// Sure, we could "#define MYENTRYPOINT main"! Or just void main(){MyEntryPoint();}
|
||||
// None of that would help us win the compo, would it?
|
||||
void main()
|
||||
{
|
||||
// Set the quality setting for the raymarcher, a higher value results in a longer processing time
|
||||
// try to find a good balance between these two, low values wivoronoill result in a wobbling endresult
|
||||
// low quality = 50.0 (visual results are ok at 640x480)
|
||||
// mid quality = 100.0
|
||||
// high quality = 200.0
|
||||
gf_DetailLevel = 100;
|
||||
|
||||
// Give our saviour global variables some life!
|
||||
pi = 3.1416;
|
||||
interlacing = vec3(1.2, 0.9, 0.9);
|
||||
eps = 0.0001;
|
||||
bigeps = 0.01;
|
||||
|
||||
// Nifty random number generator gets initialized
|
||||
float seed = 10;
|
||||
|
||||
// Determine the scene we're in
|
||||
int scene = int(Y.x);
|
||||
|
||||
// Get the look direction for the current pixel (always look forwards)
|
||||
rd = vec3((Z.xy - 0.5), 1);
|
||||
|
||||
float tex = texture2D(V, clamp(Z.xy, 0.0, 1.0), 1.0).x;
|
||||
gl_FragColor = vec4(tex, tex, tex, 1);
|
||||
return;
|
||||
|
||||
// Merry-go-round on a boat (yeah, this makes no sense. Go watch the intro and see for yourself)
|
||||
if (scene > 22 && scene < 27)
|
||||
{
|
||||
seed = min(1.0, sin((Y.x-23)*pi*0.25)*12);
|
||||
ro = vec3(0.12, 0.005, Y.x*0.08);
|
||||
rd = vec3(gl_ModelViewMatrix * vec4(rd, 1));
|
||||
rd.y += 0.1*cos(Y.x*4);
|
||||
}
|
||||
// Intermezzo: Dolphin like animation inside and outside the water, chasing that amiga ball!
|
||||
else if (scene > 14 && scene < 23)
|
||||
{
|
||||
seed = min(1.0, sin((Y.x-15)*pi*0.125)*24);
|
||||
rd += vec3(0,0.1*cos(Y.x*4), 0);
|
||||
ro = vec3(0.08, 0.01*sin(Y.x*4)+0.002, Y.x*0.11);
|
||||
}
|
||||
// Intro and Outro: Show still scenes
|
||||
else
|
||||
{
|
||||
// Get a random initial position for our camera
|
||||
ro = vec3(0.1,0.004,0.0) + vec3(0.1,0.005,20)
|
||||
*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)));
|
||||
|
||||
// Basing on the initial position, choose some "random" start and end points nearby
|
||||
ro = mix(
|
||||
ro+vec3(0.008)*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++))),
|
||||
ro+vec3(0.008)*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++))),
|
||||
// and move the camera!
|
||||
Y.x-scene);
|
||||
|
||||
// We adjust the height of the camera to the terrain height
|
||||
ro.y += height(ro.xz)+0.02;
|
||||
|
||||
// Deviate the camera position in the direction of the normal of the underlying terrain
|
||||
ro += 0.02*getTerrainNormal(ro);
|
||||
|
||||
// Reusing a float variable here, this controls the scene fade in / fade out animation
|
||||
seed = min(1.0, step(-28.0, -Y.x) * sin((Y.x-scene)*pi)*3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
rd = normalize(rd);
|
||||
|
||||
// Now boot the amiga workbench (erm, no...)
|
||||
// mantain a relative distance to the camera
|
||||
if (scene > 22 && scene < 27)
|
||||
spherePos = ro + 0.1 * vec3(gl_ModelViewMatrix * vec4(0, 0, 1, 1));
|
||||
else
|
||||
spherePos = ro + 0.02 * vec3(sin(Y.x), 0, 5+cos(Y.x));
|
||||
|
||||
spherePos.y += 0.01 + height(spherePos.xz); // mantain a relative height to the underlying terrain
|
||||
sphereRadius = scene < 14 ? 0.0 : bigeps * 0.5 + bigeps * Y.z; // The amiga ball is bigger when the snare drum is hit!
|
||||
spherePos += 2*sphereRadius * getTerrainNormal(spherePos); // deviate according to the underlying terrain's normal
|
||||
|
||||
// Make our world pretty and worthy to live in (you can cultivate algae and eat them, they're surely enough for survival)
|
||||
lightDir = normalize(vec3(0.78, 0.12 + Y.x*.2, -0.18));
|
||||
lightColor = vec3(2.4, 2.0, 1.0) + Y.x*.5;
|
||||
waterColor = mix(vec3(0.4, 0.33, 0.4), vec3(0.4, 0.5, 0.6), Y.x);
|
||||
|
||||
// Our GPU feels good underwater, almost like a refreshing experience :) cool, eh?
|
||||
if (ro.y <= 0)
|
||||
{
|
||||
// Less work to do...
|
||||
gf_DetailLevel *= 0.75;
|
||||
|
||||
// ...and a cozy darker atmosphere
|
||||
lightColor *= 0.8;
|
||||
}
|
||||
|
||||
// Here we go, shoot'em rays and get the color of our fragment!
|
||||
vec4 hit = traceRay(ro, rd, 0);
|
||||
vec3 color = shadeRefl(hit, ro, rd);
|
||||
|
||||
// Underwater there are beams of light emanating from god (so called "god" rays...)
|
||||
// ...this prooves that god is nothing less than a water surface.
|
||||
if (ro.y <= 0)
|
||||
color = godrays(ro, rd, length(hit.xyz-ro), color);
|
||||
|
||||
// Apply post processing and fade effects to the color, and finally return it.
|
||||
gl_FragColor.xyz = color;
|
||||
}
|
||||
557
underwater4k/fragment.glsl_1_dbg
Normal file
557
underwater4k/fragment.glsl_1_dbg
Normal file
@@ -0,0 +1,557 @@
|
||||
|
||||
|
||||
|
||||
|
||||
const int shader= 1;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
varying vec4 Y;
|
||||
|
||||
// Position of the fragment
|
||||
varying vec2 Z;
|
||||
|
||||
uniform sampler2D V;
|
||||
uniform sampler2D HEIGHT;
|
||||
|
||||
// Forward declarations
|
||||
vec4 traceRay(vec3 ro, vec3 rd, int ignore);
|
||||
vec3 shade(vec4 hitPoint, vec3 newRo, vec3 rd);
|
||||
|
||||
|
||||
// All data of our world
|
||||
vec3 spherePos, lightDir, lightColor, waterColor, ro, rd, interlacing;
|
||||
float sphereRadius, gf_DetailLevel, pi, eps, bigeps;
|
||||
|
||||
|
||||
// Pseudo random number base generator (credits go to iq/rgba)
|
||||
float rnd(vec2 x)
|
||||
{
|
||||
int n = int(x.x * 40 + x.y * 6400);
|
||||
n = (n << 13) ^ n;
|
||||
return 1 - float( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824;
|
||||
}
|
||||
|
||||
|
||||
// Generate cubic interpolated random values
|
||||
float smoothrnd(vec2 x)
|
||||
{
|
||||
x = mod(x,1000.0);
|
||||
vec2 a = fract(x);
|
||||
x -= a;
|
||||
vec2 u = a*a*(3.0-2.0*a);
|
||||
return mix(
|
||||
mix(rnd(x+vec2(0,0)),rnd(x+vec2(1,0)), u.x),
|
||||
mix(rnd(x+vec2(0,1)),rnd(x+vec2(1,1)), u.x), u.y);
|
||||
}
|
||||
|
||||
|
||||
// Convert the cipher range from [-1,1] to [0,1]
|
||||
float norm(float x)
|
||||
{
|
||||
return x * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
return (0.01 + ((.25*texture2D(V, p * 128.0).x) + texture2D(V, p * 32.0).x)) * smoothstep(0.25, 0.35, texture2D(V, p * 11).y * texture2D(V, p * 13).y);
|
||||
}
|
||||
|
||||
float texnoise(vec2 p)
|
||||
{
|
||||
return texture2D(V, p).y;
|
||||
}
|
||||
|
||||
float grass(vec2 p)
|
||||
{
|
||||
return texnoise(p * 57) * texnoise(p * 13) * 2.0;
|
||||
}
|
||||
|
||||
// Our heightmap calculation function, we could use some perlin noise here if it wouldn't be so performance killing
|
||||
float height(vec2 x)
|
||||
{
|
||||
return texture2D(HEIGHT, x).x;
|
||||
}
|
||||
|
||||
|
||||
// Gets the terrain normal
|
||||
vec3 getTerrainNormal(vec3 p)
|
||||
{
|
||||
return normalize(vec3(
|
||||
height(p.xz - vec2(bigeps, 0)) - height(p.xz + vec2(bigeps, 0)),
|
||||
2 * bigeps,
|
||||
height(p.xz - vec2(0, bigeps)) - height(p.xz + vec2(0, bigeps))));
|
||||
}
|
||||
|
||||
|
||||
// Global diffuse lighting formula
|
||||
vec3 diffuseLight(vec3 incolor, float shadow, vec3 normal)
|
||||
{
|
||||
return (0.3 + shadow * 0.7 * max(dot(normal, lightDir), 0.0)) * lightColor * incolor;
|
||||
}
|
||||
|
||||
|
||||
// Calculates the water "waves". To reduce the bumpiness, increment the y-axis
|
||||
vec3 getWaterNormal(vec3 p)
|
||||
{
|
||||
return normalize(vec3(
|
||||
texnoise(p.xz * 40 + Y.x*.5)*2-1,
|
||||
8,
|
||||
texnoise(p.xz * 80 - Y.x*.25)*2-1));
|
||||
}
|
||||
|
||||
|
||||
float caustic(vec3 p)
|
||||
{
|
||||
vec2 q = p.xz * (1 - p.y * .01);
|
||||
float noiseX = texnoise(q * .125 * (.05*Y.x+vec2(2,3)));
|
||||
float noiseY = texnoise(q * .125 * (.05*Y.x+vec2(4,5)));
|
||||
q = mod(q * 10.0 + vec2(noiseX, noiseY) * 16.0, 1.0);
|
||||
q -= step(0.5, q) * 2 * (q - 0.5);
|
||||
q *= 2;
|
||||
return max(pow(q.x, 4.0 + 4.0 * noiseX), pow(q.y, 4.0 + 4.0 * noiseX));
|
||||
}
|
||||
|
||||
float caustics(vec3 p)
|
||||
{
|
||||
return caustic(p * 31) * caustic(p * 17);
|
||||
}
|
||||
|
||||
// Our fake godray effect (bad if moving fast, but awesome any other time)
|
||||
vec3 godrays(vec3 ro, vec3 rd, float maxt, vec3 color)
|
||||
{
|
||||
const int iterations = 16;
|
||||
float dt = 0.001, t = 0;
|
||||
float cs = 0.0;
|
||||
for (int i = 0; i < iterations; ++i)
|
||||
{
|
||||
vec3 p = ro + rd * t;
|
||||
vec2 q = p.xz * (1 - p.y * .4);
|
||||
|
||||
float shadow = 1.0-step(1,traceRay(p, lightDir, 2).w);
|
||||
cs = max(cs, (1 + p.y * 8) * shadow * smoothstep(0.4, 0.7, texnoise(q * 64)) / (1+t*2));
|
||||
t += dt;
|
||||
}
|
||||
return color + pow(cs, 4.0) * lightColor * .1;
|
||||
}
|
||||
|
||||
// Calculate the terrain color for the given voxel
|
||||
vec3 shadeTerrain(vec3 p, vec3 rd)
|
||||
{
|
||||
vec3 n = getTerrainNormal(p);
|
||||
float vrn = voronoi(p.xz);
|
||||
vec3 grassColor = vec3(0.8, 0.85, 0.4) * 1.5 * grass(p.xz);
|
||||
vec3 dirtColor = vec3(0.65, 0.6, 0.4) * (.5+grass(p.xz));
|
||||
vec3 stoneColor = vec3(0.5, 0.5, 0.4) * (.5+grass(p.xz));
|
||||
float groundFactor = smoothstep(0.7, 0.8, n.y) * (1.0 - step(p.y, texnoise(p.xz*128)*0.01-0.003)); // shore
|
||||
float dirtFactor = smoothstep(0.4, 0.6, texture2D(V, p.xz * 40).y);
|
||||
vec3 ground = mix(mix(stoneColor, dirtColor, dirtFactor), grassColor, groundFactor);
|
||||
|
||||
vec3 rockColor = vec3(0.5, 0.5, 0.5) * (.75 + vrn) * (.75+.5*grass(p.xz * 8));
|
||||
vec3 color = mix(ground, rockColor, smoothstep(0.0, 0.05,vrn));
|
||||
|
||||
float shadow = 1.0-step(1,traceRay(p + n * 0.005, lightDir, 2).w);
|
||||
|
||||
if (p.y <= 0)
|
||||
color = max(0.0, 0.7 + 8 * p.y) * (color + lightColor * shadow * max(0, 1 + 32 * p.y) * caustics(p));
|
||||
else
|
||||
color *= 0.6+0.4*min(1.0, p.y * 999.0);
|
||||
|
||||
color = color * (.5+.5*vrn);
|
||||
return diffuseLight(color, shadow, n);
|
||||
}
|
||||
|
||||
|
||||
// Create a blueish sky transition from navy blue to badass dark blue
|
||||
vec3 shadeSky(vec3 ro, vec3 rd)
|
||||
{
|
||||
vec3 farColor = vec3(0.0, 0.0, 0.4);
|
||||
return mix(waterColor, farColor, max(0, rd.y))
|
||||
+ 0.25*lightColor * pow(max(0, dot(rd, lightDir)), 4)
|
||||
+ lightColor * pow(max(0, dot(rd, lightDir)), 1000);
|
||||
}
|
||||
|
||||
|
||||
// Calculates the refraction and reflection of the water surface.
|
||||
// Also mixes both values by the depth of the water and the fresnel term.
|
||||
// Possible improvements: fix fake underwater reflection and refraction
|
||||
vec3 shadeWaterRefl(vec3 p, vec3 newrd)
|
||||
{
|
||||
vec3 waterNormal = getWaterNormal(p);
|
||||
|
||||
// perform raytracing/raymarching for both reflection and refraction
|
||||
// calc the water refraction, the refraction index (0.9) will decrease with the distance to allow a better over/under water transition
|
||||
vec3 refrd = mix(newrd, refract(newrd, waterNormal, 0.9), step(0.0, ro.y));
|
||||
vec4 refracted = traceRay(p, refrd, 2);//mix(0.9, 1.0, smoothstep(0.01, 0.0, length(p-ro)))), 2);
|
||||
|
||||
// calculate the depth factor (water entry point to terrain voxel) (black magic involved here!)
|
||||
float depth = clamp(pow(1.03 * (1 - length(refracted.xyz - p)), 16.0), 0.0, 1.0);
|
||||
|
||||
float shadow = 0.9 + 0.1 * (1.0-step(1,traceRay(p + waterNormal * 0.005, lightDir, 2).w));
|
||||
float fresnel = pow(clamp(abs(-rd.y), 0.0, 1.0),1.8);
|
||||
// Finally stir the pot =)
|
||||
return shadow * mix(
|
||||
shadeSky(p, refrd), // Water color
|
||||
mix(
|
||||
shade(traceRay(p, reflect(newrd, waterNormal), 2), p, newrd), // Reflection color
|
||||
shade(refracted, p, newrd), // Refraction color
|
||||
fresnel), // fresnel term
|
||||
pow(depth, 0.5)); // water color contribution
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Texture our "AMIGAAAAAAA!!" ball
|
||||
vec3 shadeAttractor(vec3 p, vec3 rd)
|
||||
{
|
||||
vec3 n,color;
|
||||
|
||||
// get the sphere normal, first
|
||||
n = normalize(p - spherePos);
|
||||
|
||||
// now calculate the texture coordinates
|
||||
vec2 uv = 0.5 + 0.5 * vec2(atan(n.z, n.x), acos(n.y)) / pi;
|
||||
|
||||
// We'll animate our x-texture coordinate with the time, this gives the impression of a rotating ball
|
||||
uv.x -= Y.x;
|
||||
|
||||
// This spell will convert any dull ball into an amiga ball, caution is advised.
|
||||
color = mix(vec3(1), vec3(1, 0, 0), mod(step(fract(uv.x * 6), 0.5) + step(fract(uv.y * 6), 0.5), 2.0));
|
||||
|
||||
return diffuseLight(color, 1, n)
|
||||
+ pow(max(dot(n, normalize(lightDir - rd)), 0.0), 33.0) * lightColor; // specular light spot
|
||||
}
|
||||
|
||||
#define INTERVAL_ITERS 5
|
||||
#define LINEAR_ACCURACY 0.5
|
||||
|
||||
// Raymarch the terrain function, returns the distance from the ray origin to the terrain voxel
|
||||
// This function was originally adopted from an implementation by iq/rgba
|
||||
float traceTerrain(vec3 ro, vec3 rd, float maxt)
|
||||
{
|
||||
float samplePosY, h, prevt, t;
|
||||
vec3 samplePos;
|
||||
|
||||
// advance our sample position from our nearplane to our farplane
|
||||
for (t = 0; t < maxt;)
|
||||
{
|
||||
// advance our ray
|
||||
samplePos = ro + rd * t;
|
||||
samplePosY = samplePos.y;
|
||||
|
||||
// get the height at the given sample 2d (!) position (we could enhance this by sampling a voxel and returning only the distance to the voxel)
|
||||
h = height(samplePos.xz);
|
||||
float dist = samplePosY - h;
|
||||
if (dist < 0.0) break;
|
||||
|
||||
prevt = t;
|
||||
|
||||
if (dist > 0.0001)
|
||||
t += max(dist * 1.4, 0.0001) * LINEAR_ACCURACY;
|
||||
else
|
||||
t += max(dist, 0.00001) * LINEAR_ACCURACY;
|
||||
}
|
||||
|
||||
if (samplePosY <= h)
|
||||
{
|
||||
/// Interval mapping
|
||||
float before = prevt;
|
||||
vec3 beforePos = ro + rd * before;
|
||||
float beforeH = height(beforePos.xz);
|
||||
|
||||
float after = t;
|
||||
vec3 afterPos = ro + rd * after;
|
||||
float afterH = height(afterPos.xz);
|
||||
|
||||
for (int i = 0; i < INTERVAL_ITERS; i++)
|
||||
{
|
||||
float interval = after - before;
|
||||
float deltaL = beforeH - afterH;
|
||||
float deltaR = rd.y * interval;
|
||||
|
||||
float curt = (beforeH * interval - deltaL * before) / (deltaR - deltaL);
|
||||
if (curt <= before - 0.000001 || curt >= after + 0.000001) break;
|
||||
|
||||
samplePos = ro + rd * curt;
|
||||
float h = height(samplePos.xz);
|
||||
|
||||
if (h <= samplePos.y)
|
||||
{
|
||||
beforeH = h;
|
||||
before = curt;
|
||||
t = curt;
|
||||
}
|
||||
else
|
||||
{
|
||||
afterH = h;
|
||||
after = curt;
|
||||
t = curt;
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// we hit nothing
|
||||
return 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Ray vs. sphere intersection function
|
||||
float traceAttractor(vec3 ro, vec3 rd)
|
||||
{
|
||||
vec3 dst = ro - spherePos;
|
||||
float B,D;
|
||||
B = dot(dst, rd);
|
||||
if (B > 0)
|
||||
return 9.0;
|
||||
D = B*B - dot(dst, dst) + sphereRadius*sphereRadius;
|
||||
if (D > 0)
|
||||
{
|
||||
return -B - sqrt(D);
|
||||
}
|
||||
return 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Ray vs. plane intersection function
|
||||
float traceWater(vec3 ro, vec3 rd)
|
||||
{
|
||||
float tPlane = -ro.y / rd.y;
|
||||
return tPlane >= eps ? tPlane : 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Raytracing entry point, returns voxel and object ID
|
||||
// IDs:
|
||||
// 0 = sky (not the armageddon, xTr1m!!)
|
||||
// 1 = terrain
|
||||
// 2 = water
|
||||
// 3 = attractive amiga ball (you have never seen such a sexy amiga ball before, admit it!)
|
||||
vec4 traceRay(vec3 ro, vec3 rd, int ignore)
|
||||
{
|
||||
float water, attractor, terrain, minDist;
|
||||
|
||||
// trace only the objects we need (only one could maximally be ignored)
|
||||
water = ignore != 2 ? traceWater(ro, rd) : 9.0;
|
||||
attractor = ignore != 3 ? traceAttractor(ro, rd) : 9.0;
|
||||
terrain = ignore != 1 ? traceTerrain(ro, rd, min(0.5, 0.002+min(water, attractor))) : 9.0;
|
||||
|
||||
// auto detail level reducing (common dude, give the GPU some breathing room)
|
||||
gf_DetailLevel /= 20;
|
||||
|
||||
// find the nearest distance
|
||||
minDist = min(terrain, min(water, min(attractor, 9.0)));
|
||||
|
||||
// we hit nothing or the hitpoint is too far
|
||||
if (minDist == 9)
|
||||
return vec4(0);
|
||||
|
||||
// calculate the hit/voxel position
|
||||
vec3 hitPos = ro + rd * minDist;
|
||||
|
||||
// check what we might have hit
|
||||
if (minDist == terrain)
|
||||
return vec4(hitPos, 1);
|
||||
if (minDist == water)
|
||||
return vec4(hitPos, 2);
|
||||
if (minDist == attractor)
|
||||
return vec4(hitPos, 3);
|
||||
|
||||
// Panic, worry, die to death! Probably we'll land on the moon (this should never happen)
|
||||
//return vec4(0);
|
||||
}
|
||||
|
||||
|
||||
// Entrypoint for color calculation
|
||||
vec3 shadeRefl(vec4 hitPoint, vec3 newRo, vec3 rd)
|
||||
{
|
||||
// determine the fog color for this very precise point in the space time continuum
|
||||
vec3 myFog = newRo.y < eps ? waterColor : shadeSky(ro, rd);
|
||||
|
||||
// generate the distance value for the fog calculation
|
||||
float distance = clamp(length(hitPoint.xyz - newRo) * (ro.y <= 0 ? 4 : 2), 0.0, 1.0);
|
||||
|
||||
// get the color of the hit object and mix it with the fog
|
||||
// in most cases we allow further raytracing here (not for the terrain, its not shiny enough)
|
||||
if (hitPoint.w == 1)
|
||||
return mix(shadeTerrain(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 2)
|
||||
return mix(shadeWaterRefl(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 3)
|
||||
return mix(
|
||||
// Our amiga ball is shiny so reflect the scene!
|
||||
mix(shadeAttractor(hitPoint.xyz, rd), shade(traceRay(hitPoint.xyz, reflect(rd, normalize(hitPoint.xyz - spherePos)), 3), hitPoint.xyz, rd), 0.5)
|
||||
, myFog, distance);
|
||||
|
||||
return shadeSky(newRo, rd);
|
||||
}
|
||||
|
||||
|
||||
// Get the color from the object we just hit (without further raytraces)
|
||||
// this is necessary because no recursion is allowed in GLSL (damn you!)
|
||||
vec3 shade(vec4 hitPoint, vec3 newRo, vec3 rd)
|
||||
{
|
||||
// determine the fog color for the very same point we discussed earlier
|
||||
vec3 myFog = newRo.y < eps ? waterColor : shadeSky(ro, rd);
|
||||
|
||||
// generate the other distance value. Paid attention? If you don't know what value I'm talking about, rtfm or gtfo.
|
||||
float distance = clamp(length(hitPoint.xyz - newRo) * (ro.y <= 0 ? 4 : 2), 0.0, 1.0);
|
||||
|
||||
// get the color of the hit object and mix it with the fog
|
||||
if (hitPoint.w == 1)
|
||||
return mix(shadeTerrain(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 2)
|
||||
return mix(waterColor, myFog, distance);
|
||||
if (hitPoint.w == 3)
|
||||
return mix(shadeAttractor(hitPoint.xyz, rd), myFog, distance);
|
||||
|
||||
return myFog;
|
||||
}
|
||||
|
||||
// Now we're just being copycats. We're not creative enough to define own entry points
|
||||
// Sure, we could "#define MYENTRYPOINT main"! Or just void main(){MyEntryPoint();}
|
||||
// None of that would help us win the compo, would it?
|
||||
void main()
|
||||
{
|
||||
// Set the quality setting for the raymarcher, a higher value results in a longer processing time
|
||||
// try to find a good balance between these two, low values wivoronoill result in a wobbling endresult
|
||||
// low quality = 50.0 (visual results are ok at 640x480)
|
||||
// mid quality = 100.0
|
||||
// high quality = 200.0
|
||||
gf_DetailLevel = 100;
|
||||
|
||||
// Give our saviour global variables some life!
|
||||
pi = 3.1416;
|
||||
interlacing = vec3(1.2, 0.9, 0.9);
|
||||
eps = 0.0001;
|
||||
bigeps = 0.01;
|
||||
|
||||
// Nifty random number generator gets initialized
|
||||
float seed = 10;
|
||||
|
||||
// Determine the scene we're in
|
||||
int scene = int(Y.x);
|
||||
|
||||
// Get the look direction for the current pixel (always look forwards)
|
||||
rd = vec3((Z.xy - 0.5), 1);
|
||||
|
||||
float tex = texture2D(V, clamp(Z.xy, 0.0, 1.0), 1.0).x;
|
||||
gl_FragColor = vec4(tex, tex, tex, 1);
|
||||
return;
|
||||
|
||||
// Merry-go-round on a boat (yeah, this makes no sense. Go watch the intro and see for yourself)
|
||||
if (scene > 22 && scene < 27)
|
||||
{
|
||||
seed = min(1.0, sin((Y.x-23)*pi*0.25)*12);
|
||||
ro = vec3(0.12, 0.005, Y.x*0.08);
|
||||
rd = vec3(gl_ModelViewMatrix * vec4(rd, 1));
|
||||
rd.y += 0.1*cos(Y.x*4);
|
||||
}
|
||||
// Intermezzo: Dolphin like animation inside and outside the water, chasing that amiga ball!
|
||||
else if (scene > 14 && scene < 23)
|
||||
{
|
||||
seed = min(1.0, sin((Y.x-15)*pi*0.125)*24);
|
||||
rd += vec3(0,0.1*cos(Y.x*4), 0);
|
||||
ro = vec3(0.08, 0.01*sin(Y.x*4)+0.002, Y.x*0.11);
|
||||
}
|
||||
// Intro and Outro: Show still scenes
|
||||
else
|
||||
{
|
||||
// Get a random initial position for our camera
|
||||
ro = vec3(0.1,0.004,0.0) + vec3(0.1,0.005,20)
|
||||
*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)));
|
||||
|
||||
// Basing on the initial position, choose some "random" start and end points nearby
|
||||
ro = mix(
|
||||
ro+vec3(0.008)*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++))),
|
||||
ro+vec3(0.008)*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++))),
|
||||
// and move the camera!
|
||||
Y.x-scene);
|
||||
|
||||
// We adjust the height of the camera to the terrain height
|
||||
ro.y += height(ro.xz)+0.02;
|
||||
|
||||
// Deviate the camera position in the direction of the normal of the underlying terrain
|
||||
ro += 0.02*getTerrainNormal(ro);
|
||||
|
||||
// Reusing a float variable here, this controls the scene fade in / fade out animation
|
||||
seed = min(1.0, step(-28.0, -Y.x) * sin((Y.x-scene)*pi)*3);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//Debugzeug fuer Kamerasteuerung
|
||||
{
|
||||
ro.x= gl_ModelViewMatrix[0][0];
|
||||
ro.y= gl_ModelViewMatrix[0][1];
|
||||
ro.z= gl_ModelViewMatrix[0][2];
|
||||
|
||||
float a1= gl_ModelViewMatrix[1][1];
|
||||
float c1,s1;vec3 q1= vec3((Z.xy - 0.5), 0.8);
|
||||
c1 = cos(a1); s1 = sin(a1);
|
||||
rd.y = c1 * q1.y - s1 * q1.z;
|
||||
rd.x= q1.x;
|
||||
rd.z = s1 * q1.y + c1 * q1.z;
|
||||
|
||||
a1= gl_ModelViewMatrix[1][0];
|
||||
q1=rd;
|
||||
c1 = cos(a1); s1 = sin(a1);
|
||||
rd.x = c1 * q1.x + s1 * q1.z;
|
||||
rd.z = -s1 * q1.x + c1 * q1.z;
|
||||
|
||||
}
|
||||
//Ende Debugzeug fuer Kamerasteuerung
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
rd = normalize(rd);
|
||||
|
||||
// Now boot the amiga workbench (erm, no...)
|
||||
// mantain a relative distance to the camera
|
||||
if (scene > 22 && scene < 27)
|
||||
spherePos = ro + 0.1 * vec3(gl_ModelViewMatrix * vec4(0, 0, 1, 1));
|
||||
else
|
||||
spherePos = ro + 0.02 * vec3(sin(Y.x), 0, 5+cos(Y.x));
|
||||
|
||||
spherePos.y += 0.01 + height(spherePos.xz); // mantain a relative height to the underlying terrain
|
||||
sphereRadius = scene < 14 ? 0.0 : bigeps * 0.5 + bigeps * Y.z; // The amiga ball is bigger when the snare drum is hit!
|
||||
spherePos += 2*sphereRadius * getTerrainNormal(spherePos); // deviate according to the underlying terrain's normal
|
||||
|
||||
// Make our world pretty and worthy to live in (you can cultivate algae and eat them, they're surely enough for survival)
|
||||
lightDir = normalize(vec3(0.78, 0.12 + Y.x*.2, -0.18));
|
||||
lightColor = vec3(2.4, 2.0, 1.0) + Y.x*.5;
|
||||
waterColor = mix(vec3(0.4, 0.33, 0.4), vec3(0.4, 0.5, 0.6), Y.x);
|
||||
|
||||
// Our GPU feels good underwater, almost like a refreshing experience :) cool, eh?
|
||||
if (ro.y <= 0)
|
||||
{
|
||||
// Less work to do...
|
||||
gf_DetailLevel *= 0.75;
|
||||
|
||||
// ...and a cozy darker atmosphere
|
||||
lightColor *= 0.8;
|
||||
}
|
||||
|
||||
// Here we go, shoot'em rays and get the color of our fragment!
|
||||
vec4 hit = traceRay(ro, rd, 0);
|
||||
vec3 color = shadeRefl(hit, ro, rd);
|
||||
|
||||
// Underwater there are beams of light emanating from god (so called "god" rays...)
|
||||
// ...this prooves that god is nothing less than a water surface.
|
||||
if (ro.y <= 0)
|
||||
color = godrays(ro, rd, length(hit.xyz-ro), color);
|
||||
|
||||
// Apply post processing and fade effects to the color, and finally return it.
|
||||
gl_FragColor.xyz = color;
|
||||
}
|
||||
557
underwater4k/fragment.glsl_2
Normal file
557
underwater4k/fragment.glsl_2
Normal file
@@ -0,0 +1,557 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const int shader= 2;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
varying vec4 Y;
|
||||
|
||||
// Position of the fragment
|
||||
varying vec2 Z;
|
||||
|
||||
uniform sampler2D V;
|
||||
uniform sampler2D HEIGHT;
|
||||
|
||||
// Forward declarations
|
||||
vec4 traceRay(vec3 ro, vec3 rd, int ignore);
|
||||
vec3 shade(vec4 hitPoint, vec3 newRo, vec3 rd);
|
||||
|
||||
|
||||
// All data of our world
|
||||
vec3 spherePos, lightDir, lightColor, waterColor, ro, rd, interlacing;
|
||||
float sphereRadius, gf_DetailLevel, pi, eps, bigeps;
|
||||
|
||||
|
||||
// Pseudo random number base generator (credits go to iq/rgba)
|
||||
float rnd(vec2 x)
|
||||
{
|
||||
int n = int(x.x * 40 + x.y * 6400);
|
||||
n = (n << 13) ^ n;
|
||||
return 1 - float( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824;
|
||||
}
|
||||
|
||||
|
||||
// Generate cubic interpolated random values
|
||||
float smoothrnd(vec2 x)
|
||||
{
|
||||
x = mod(x,1000.0);
|
||||
vec2 a = fract(x);
|
||||
x -= a;
|
||||
vec2 u = a*a*(3.0-2.0*a);
|
||||
return mix(
|
||||
mix(rnd(x+vec2(0,0)),rnd(x+vec2(1,0)), u.x),
|
||||
mix(rnd(x+vec2(0,1)),rnd(x+vec2(1,1)), u.x), u.y);
|
||||
}
|
||||
|
||||
|
||||
// Convert the cipher range from [-1,1] to [0,1]
|
||||
float norm(float x)
|
||||
{
|
||||
return x * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
return (0.01 + ((.25*texture2D(V, p * 128.0).x) + texture2D(V, p * 32.0).x)) * smoothstep(0.25, 0.35, texture2D(V, p * 11).y * texture2D(V, p * 13).y);
|
||||
}
|
||||
|
||||
float texnoise(vec2 p)
|
||||
{
|
||||
return texture2D(V, p).y;
|
||||
}
|
||||
|
||||
float grass(vec2 p)
|
||||
{
|
||||
return texnoise(p * 57) * texnoise(p * 13) * 2.0;
|
||||
}
|
||||
|
||||
// Our heightmap calculation function, we could use some perlin noise here if it wouldn't be so performance killing
|
||||
float height(vec2 x)
|
||||
{
|
||||
return texture2D(HEIGHT, x).x;
|
||||
}
|
||||
|
||||
|
||||
// Gets the terrain normal
|
||||
vec3 getTerrainNormal(vec3 p)
|
||||
{
|
||||
return normalize(vec3(
|
||||
height(p.xz - vec2(bigeps, 0)) - height(p.xz + vec2(bigeps, 0)),
|
||||
2 * bigeps,
|
||||
height(p.xz - vec2(0, bigeps)) - height(p.xz + vec2(0, bigeps))));
|
||||
}
|
||||
|
||||
|
||||
// Global diffuse lighting formula
|
||||
vec3 diffuseLight(vec3 incolor, float shadow, vec3 normal)
|
||||
{
|
||||
return (0.3 + shadow * 0.7 * max(dot(normal, lightDir), 0.0)) * lightColor * incolor;
|
||||
}
|
||||
|
||||
|
||||
// Calculates the water "waves". To reduce the bumpiness, increment the y-axis
|
||||
vec3 getWaterNormal(vec3 p)
|
||||
{
|
||||
return normalize(vec3(
|
||||
texnoise(p.xz * 40 + Y.x*.5)*2-1,
|
||||
8,
|
||||
texnoise(p.xz * 80 - Y.x*.25)*2-1));
|
||||
}
|
||||
|
||||
|
||||
float caustic(vec3 p)
|
||||
{
|
||||
vec2 q = p.xz * (1 - p.y * .01);
|
||||
float noiseX = texnoise(q * .125 * (.05*Y.x+vec2(2,3)));
|
||||
float noiseY = texnoise(q * .125 * (.05*Y.x+vec2(4,5)));
|
||||
q = mod(q * 10.0 + vec2(noiseX, noiseY) * 16.0, 1.0);
|
||||
q -= step(0.5, q) * 2 * (q - 0.5);
|
||||
q *= 2;
|
||||
return max(pow(q.x, 4.0 + 4.0 * noiseX), pow(q.y, 4.0 + 4.0 * noiseX));
|
||||
}
|
||||
|
||||
float caustics(vec3 p)
|
||||
{
|
||||
return caustic(p * 31) * caustic(p * 17);
|
||||
}
|
||||
|
||||
// Our fake godray effect (bad if moving fast, but awesome any other time)
|
||||
vec3 godrays(vec3 ro, vec3 rd, float maxt, vec3 color)
|
||||
{
|
||||
const int iterations = 16;
|
||||
float dt = 0.001, t = 0;
|
||||
float cs = 0.0;
|
||||
for (int i = 0; i < iterations; ++i)
|
||||
{
|
||||
vec3 p = ro + rd * t;
|
||||
vec2 q = p.xz * (1 - p.y * .4);
|
||||
|
||||
float shadow = 1.0-step(1,traceRay(p, lightDir, 2).w);
|
||||
cs = max(cs, (1 + p.y * 8) * shadow * smoothstep(0.4, 0.7, texnoise(q * 64)) / (1+t*2));
|
||||
t += dt;
|
||||
}
|
||||
return color + pow(cs, 4.0) * lightColor * .1;
|
||||
}
|
||||
|
||||
// Calculate the terrain color for the given voxel
|
||||
vec3 shadeTerrain(vec3 p, vec3 rd)
|
||||
{
|
||||
vec3 n = getTerrainNormal(p);
|
||||
float vrn = voronoi(p.xz);
|
||||
vec3 grassColor = vec3(0.8, 0.85, 0.4) * 1.5 * grass(p.xz);
|
||||
vec3 dirtColor = vec3(0.65, 0.6, 0.4) * (.5+grass(p.xz));
|
||||
vec3 stoneColor = vec3(0.5, 0.5, 0.4) * (.5+grass(p.xz));
|
||||
float groundFactor = smoothstep(0.7, 0.8, n.y) * (1.0 - step(p.y, texnoise(p.xz*128)*0.01-0.003)); // shore
|
||||
float dirtFactor = smoothstep(0.4, 0.6, texture2D(V, p.xz * 40).y);
|
||||
vec3 ground = mix(mix(stoneColor, dirtColor, dirtFactor), grassColor, groundFactor);
|
||||
|
||||
vec3 rockColor = vec3(0.5, 0.5, 0.5) * (.75 + vrn) * (.75+.5*grass(p.xz * 8));
|
||||
vec3 color = mix(ground, rockColor, smoothstep(0.0, 0.05,vrn));
|
||||
|
||||
float shadow = 1.0-step(1,traceRay(p + n * 0.005, lightDir, 2).w);
|
||||
|
||||
if (p.y <= 0)
|
||||
color = max(0.0, 0.7 + 8 * p.y) * (color + lightColor * shadow * max(0, 1 + 32 * p.y) * caustics(p));
|
||||
else
|
||||
color *= 0.6+0.4*min(1.0, p.y * 999.0);
|
||||
|
||||
color = color * (.5+.5*vrn);
|
||||
return diffuseLight(color, shadow, n);
|
||||
}
|
||||
|
||||
|
||||
// Create a blueish sky transition from navy blue to badass dark blue
|
||||
vec3 shadeSky(vec3 ro, vec3 rd)
|
||||
{
|
||||
vec3 farColor = vec3(0.0, 0.0, 0.4);
|
||||
return mix(waterColor, farColor, max(0, rd.y))
|
||||
+ 0.25*lightColor * pow(max(0, dot(rd, lightDir)), 4)
|
||||
+ lightColor * pow(max(0, dot(rd, lightDir)), 1000);
|
||||
}
|
||||
|
||||
|
||||
// Calculates the refraction and reflection of the water surface.
|
||||
// Also mixes both values by the depth of the water and the fresnel term.
|
||||
// Possible improvements: fix fake underwater reflection and refraction
|
||||
vec3 shadeWaterRefl(vec3 p, vec3 newrd)
|
||||
{
|
||||
vec3 waterNormal = getWaterNormal(p);
|
||||
|
||||
// perform raytracing/raymarching for both reflection and refraction
|
||||
// calc the water refraction, the refraction index (0.9) will decrease with the distance to allow a better over/under water transition
|
||||
vec3 refrd = mix(newrd, refract(newrd, waterNormal, 0.9), step(0.0, ro.y));
|
||||
vec4 refracted = traceRay(p, refrd, 2);//mix(0.9, 1.0, smoothstep(0.01, 0.0, length(p-ro)))), 2);
|
||||
|
||||
// calculate the depth factor (water entry point to terrain voxel) (black magic involved here!)
|
||||
float depth = clamp(pow(1.03 * (1 - length(refracted.xyz - p)), 16.0), 0.0, 1.0);
|
||||
|
||||
float shadow = 0.9 + 0.1 * (1.0-step(1,traceRay(p + waterNormal * 0.005, lightDir, 2).w));
|
||||
float fresnel = pow(clamp(abs(-rd.y), 0.0, 1.0),1.8);
|
||||
// Finally stir the pot =)
|
||||
return shadow * mix(
|
||||
shadeSky(p, refrd), // Water color
|
||||
mix(
|
||||
shade(traceRay(p, reflect(newrd, waterNormal), 2), p, newrd), // Reflection color
|
||||
shade(refracted, p, newrd), // Refraction color
|
||||
fresnel), // fresnel term
|
||||
pow(depth, 0.5)); // water color contribution
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Texture our "AMIGAAAAAAA!!" ball
|
||||
vec3 shadeAttractor(vec3 p, vec3 rd)
|
||||
{
|
||||
vec3 n,color;
|
||||
|
||||
// get the sphere normal, first
|
||||
n = normalize(p - spherePos);
|
||||
|
||||
// now calculate the texture coordinates
|
||||
vec2 uv = 0.5 + 0.5 * vec2(atan(n.z, n.x), acos(n.y)) / pi;
|
||||
|
||||
// We'll animate our x-texture coordinate with the time, this gives the impression of a rotating ball
|
||||
uv.x -= Y.x;
|
||||
|
||||
// This spell will convert any dull ball into an amiga ball, caution is advised.
|
||||
color = mix(vec3(1), vec3(1, 0, 0), mod(step(fract(uv.x * 6), 0.5) + step(fract(uv.y * 6), 0.5), 2.0));
|
||||
|
||||
return diffuseLight(color, 1, n)
|
||||
+ pow(max(dot(n, normalize(lightDir - rd)), 0.0), 33.0) * lightColor; // specular light spot
|
||||
}
|
||||
|
||||
#define INTERVAL_ITERS 5
|
||||
#define LINEAR_ACCURACY 0.5
|
||||
|
||||
// Raymarch the terrain function, returns the distance from the ray origin to the terrain voxel
|
||||
// This function was originally adopted from an implementation by iq/rgba
|
||||
float traceTerrain(vec3 ro, vec3 rd, float maxt)
|
||||
{
|
||||
float samplePosY, h, prevt, t;
|
||||
vec3 samplePos;
|
||||
|
||||
// advance our sample position from our nearplane to our farplane
|
||||
for (t = 0; t < maxt;)
|
||||
{
|
||||
// advance our ray
|
||||
samplePos = ro + rd * t;
|
||||
samplePosY = samplePos.y;
|
||||
|
||||
// get the height at the given sample 2d (!) position (we could enhance this by sampling a voxel and returning only the distance to the voxel)
|
||||
h = height(samplePos.xz);
|
||||
float dist = samplePosY - h;
|
||||
if (dist < 0.0) break;
|
||||
|
||||
prevt = t;
|
||||
|
||||
if (dist > 0.0001)
|
||||
t += max(dist * 1.4, 0.0001) * LINEAR_ACCURACY;
|
||||
else
|
||||
t += max(dist, 0.00001) * LINEAR_ACCURACY;
|
||||
}
|
||||
|
||||
if (samplePosY <= h)
|
||||
{
|
||||
/// Interval mapping
|
||||
float before = prevt;
|
||||
vec3 beforePos = ro + rd * before;
|
||||
float beforeH = height(beforePos.xz);
|
||||
|
||||
float after = t;
|
||||
vec3 afterPos = ro + rd * after;
|
||||
float afterH = height(afterPos.xz);
|
||||
|
||||
for (int i = 0; i < INTERVAL_ITERS; i++)
|
||||
{
|
||||
float interval = after - before;
|
||||
float deltaL = beforeH - afterH;
|
||||
float deltaR = rd.y * interval;
|
||||
|
||||
float curt = (beforeH * interval - deltaL * before) / (deltaR - deltaL);
|
||||
if (curt <= before - 0.000001 || curt >= after + 0.000001) break;
|
||||
|
||||
samplePos = ro + rd * curt;
|
||||
float h = height(samplePos.xz);
|
||||
|
||||
if (h <= samplePos.y)
|
||||
{
|
||||
beforeH = h;
|
||||
before = curt;
|
||||
t = curt;
|
||||
}
|
||||
else
|
||||
{
|
||||
afterH = h;
|
||||
after = curt;
|
||||
t = curt;
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// we hit nothing
|
||||
return 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Ray vs. sphere intersection function
|
||||
float traceAttractor(vec3 ro, vec3 rd)
|
||||
{
|
||||
vec3 dst = ro - spherePos;
|
||||
float B,D;
|
||||
B = dot(dst, rd);
|
||||
if (B > 0)
|
||||
return 9.0;
|
||||
D = B*B - dot(dst, dst) + sphereRadius*sphereRadius;
|
||||
if (D > 0)
|
||||
{
|
||||
return -B - sqrt(D);
|
||||
}
|
||||
return 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Ray vs. plane intersection function
|
||||
float traceWater(vec3 ro, vec3 rd)
|
||||
{
|
||||
float tPlane = -ro.y / rd.y;
|
||||
return tPlane >= eps ? tPlane : 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Raytracing entry point, returns voxel and object ID
|
||||
// IDs:
|
||||
// 0 = sky (not the armageddon, xTr1m!!)
|
||||
// 1 = terrain
|
||||
// 2 = water
|
||||
// 3 = attractive amiga ball (you have never seen such a sexy amiga ball before, admit it!)
|
||||
vec4 traceRay(vec3 ro, vec3 rd, int ignore)
|
||||
{
|
||||
float water, attractor, terrain, minDist;
|
||||
|
||||
// trace only the objects we need (only one could maximally be ignored)
|
||||
water = ignore != 2 ? traceWater(ro, rd) : 9.0;
|
||||
attractor = ignore != 3 ? traceAttractor(ro, rd) : 9.0;
|
||||
terrain = ignore != 1 ? traceTerrain(ro, rd, min(0.5, 0.002+min(water, attractor))) : 9.0;
|
||||
|
||||
// auto detail level reducing (common dude, give the GPU some breathing room)
|
||||
gf_DetailLevel /= 20;
|
||||
|
||||
// find the nearest distance
|
||||
minDist = min(terrain, min(water, min(attractor, 9.0)));
|
||||
|
||||
// we hit nothing or the hitpoint is too far
|
||||
if (minDist == 9)
|
||||
return vec4(0);
|
||||
|
||||
// calculate the hit/voxel position
|
||||
vec3 hitPos = ro + rd * minDist;
|
||||
|
||||
// check what we might have hit
|
||||
if (minDist == terrain)
|
||||
return vec4(hitPos, 1);
|
||||
if (minDist == water)
|
||||
return vec4(hitPos, 2);
|
||||
if (minDist == attractor)
|
||||
return vec4(hitPos, 3);
|
||||
|
||||
// Panic, worry, die to death! Probably we'll land on the moon (this should never happen)
|
||||
//return vec4(0);
|
||||
}
|
||||
|
||||
|
||||
// Entrypoint for color calculation
|
||||
vec3 shadeRefl(vec4 hitPoint, vec3 newRo, vec3 rd)
|
||||
{
|
||||
// determine the fog color for this very precise point in the space time continuum
|
||||
vec3 myFog = newRo.y < eps ? waterColor : shadeSky(ro, rd);
|
||||
|
||||
// generate the distance value for the fog calculation
|
||||
float distance = clamp(length(hitPoint.xyz - newRo) * (ro.y <= 0 ? 4 : 2), 0.0, 1.0);
|
||||
|
||||
// get the color of the hit object and mix it with the fog
|
||||
// in most cases we allow further raytracing here (not for the terrain, its not shiny enough)
|
||||
if (hitPoint.w == 1)
|
||||
return mix(shadeTerrain(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 2)
|
||||
return mix(shadeWaterRefl(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 3)
|
||||
return mix(
|
||||
// Our amiga ball is shiny so reflect the scene!
|
||||
mix(shadeAttractor(hitPoint.xyz, rd), shade(traceRay(hitPoint.xyz, reflect(rd, normalize(hitPoint.xyz - spherePos)), 3), hitPoint.xyz, rd), 0.5)
|
||||
, myFog, distance);
|
||||
|
||||
return shadeSky(newRo, rd);
|
||||
}
|
||||
|
||||
|
||||
// Get the color from the object we just hit (without further raytraces)
|
||||
// this is necessary because no recursion is allowed in GLSL (damn you!)
|
||||
vec3 shade(vec4 hitPoint, vec3 newRo, vec3 rd)
|
||||
{
|
||||
// determine the fog color for the very same point we discussed earlier
|
||||
vec3 myFog = newRo.y < eps ? waterColor : shadeSky(ro, rd);
|
||||
|
||||
// generate the other distance value. Paid attention? If you don't know what value I'm talking about, rtfm or gtfo.
|
||||
float distance = clamp(length(hitPoint.xyz - newRo) * (ro.y <= 0 ? 4 : 2), 0.0, 1.0);
|
||||
|
||||
// get the color of the hit object and mix it with the fog
|
||||
if (hitPoint.w == 1)
|
||||
return mix(shadeTerrain(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 2)
|
||||
return mix(waterColor, myFog, distance);
|
||||
if (hitPoint.w == 3)
|
||||
return mix(shadeAttractor(hitPoint.xyz, rd), myFog, distance);
|
||||
|
||||
return myFog;
|
||||
}
|
||||
|
||||
// Now we're just being copycats. We're not creative enough to define own entry points
|
||||
// Sure, we could "#define MYENTRYPOINT main"! Or just void main(){MyEntryPoint();}
|
||||
// None of that would help us win the compo, would it?
|
||||
void main()
|
||||
{
|
||||
// Set the quality setting for the raymarcher, a higher value results in a longer processing time
|
||||
// try to find a good balance between these two, low values wivoronoill result in a wobbling endresult
|
||||
// low quality = 50.0 (visual results are ok at 640x480)
|
||||
// mid quality = 100.0
|
||||
// high quality = 200.0
|
||||
gf_DetailLevel = 100;
|
||||
|
||||
// Give our saviour global variables some life!
|
||||
pi = 3.1416;
|
||||
interlacing = vec3(1.2, 0.9, 0.9);
|
||||
eps = 0.0001;
|
||||
bigeps = 0.01;
|
||||
|
||||
// Nifty random number generator gets initialized
|
||||
float seed = 10;
|
||||
|
||||
// Determine the scene we're in
|
||||
int scene = int(Y.x);
|
||||
|
||||
// Get the look direction for the current pixel (always look forwards)
|
||||
rd = vec3((Z.xy - 0.5), 1);
|
||||
|
||||
float tex = texture2D(V, clamp(Z.xy, 0.0, 1.0), 1.0).x;
|
||||
gl_FragColor = vec4(tex, tex, tex, 1);
|
||||
return;
|
||||
|
||||
// Merry-go-round on a boat (yeah, this makes no sense. Go watch the intro and see for yourself)
|
||||
if (scene > 22 && scene < 27)
|
||||
{
|
||||
seed = min(1.0, sin((Y.x-23)*pi*0.25)*12);
|
||||
ro = vec3(0.12, 0.005, Y.x*0.08);
|
||||
rd = vec3(gl_ModelViewMatrix * vec4(rd, 1));
|
||||
rd.y += 0.1*cos(Y.x*4);
|
||||
}
|
||||
// Intermezzo: Dolphin like animation inside and outside the water, chasing that amiga ball!
|
||||
else if (scene > 14 && scene < 23)
|
||||
{
|
||||
seed = min(1.0, sin((Y.x-15)*pi*0.125)*24);
|
||||
rd += vec3(0,0.1*cos(Y.x*4), 0);
|
||||
ro = vec3(0.08, 0.01*sin(Y.x*4)+0.002, Y.x*0.11);
|
||||
}
|
||||
// Intro and Outro: Show still scenes
|
||||
else
|
||||
{
|
||||
// Get a random initial position for our camera
|
||||
ro = vec3(0.1,0.004,0.0) + vec3(0.1,0.005,20)
|
||||
*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)));
|
||||
|
||||
// Basing on the initial position, choose some "random" start and end points nearby
|
||||
ro = mix(
|
||||
ro+vec3(0.008)*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++))),
|
||||
ro+vec3(0.008)*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++))),
|
||||
// and move the camera!
|
||||
Y.x-scene);
|
||||
|
||||
// We adjust the height of the camera to the terrain height
|
||||
ro.y += height(ro.xz)+0.02;
|
||||
|
||||
// Deviate the camera position in the direction of the normal of the underlying terrain
|
||||
ro += 0.02*getTerrainNormal(ro);
|
||||
|
||||
// Reusing a float variable here, this controls the scene fade in / fade out animation
|
||||
seed = min(1.0, step(-28.0, -Y.x) * sin((Y.x-scene)*pi)*3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
rd = normalize(rd);
|
||||
|
||||
// Now boot the amiga workbench (erm, no...)
|
||||
// mantain a relative distance to the camera
|
||||
if (scene > 22 && scene < 27)
|
||||
spherePos = ro + 0.1 * vec3(gl_ModelViewMatrix * vec4(0, 0, 1, 1));
|
||||
else
|
||||
spherePos = ro + 0.02 * vec3(sin(Y.x), 0, 5+cos(Y.x));
|
||||
|
||||
spherePos.y += 0.01 + height(spherePos.xz); // mantain a relative height to the underlying terrain
|
||||
sphereRadius = scene < 14 ? 0.0 : bigeps * 0.5 + bigeps * Y.z; // The amiga ball is bigger when the snare drum is hit!
|
||||
spherePos += 2*sphereRadius * getTerrainNormal(spherePos); // deviate according to the underlying terrain's normal
|
||||
|
||||
// Make our world pretty and worthy to live in (you can cultivate algae and eat them, they're surely enough for survival)
|
||||
lightDir = normalize(vec3(0.78, 0.12 + Y.x*.2, -0.18));
|
||||
lightColor = vec3(2.4, 2.0, 1.0) + Y.x*.5;
|
||||
waterColor = mix(vec3(0.4, 0.33, 0.4), vec3(0.4, 0.5, 0.6), Y.x);
|
||||
|
||||
// Our GPU feels good underwater, almost like a refreshing experience :) cool, eh?
|
||||
if (ro.y <= 0)
|
||||
{
|
||||
// Less work to do...
|
||||
gf_DetailLevel *= 0.75;
|
||||
|
||||
// ...and a cozy darker atmosphere
|
||||
lightColor *= 0.8;
|
||||
}
|
||||
|
||||
// Here we go, shoot'em rays and get the color of our fragment!
|
||||
vec4 hit = traceRay(ro, rd, 0);
|
||||
vec3 color = shadeRefl(hit, ro, rd);
|
||||
|
||||
// Underwater there are beams of light emanating from god (so called "god" rays...)
|
||||
// ...this prooves that god is nothing less than a water surface.
|
||||
if (ro.y <= 0)
|
||||
color = godrays(ro, rd, length(hit.xyz-ro), color);
|
||||
|
||||
// Apply post processing and fade effects to the color, and finally return it.
|
||||
gl_FragColor.xyz = color;
|
||||
}
|
||||
557
underwater4k/fragment.glsl_2_dbg
Normal file
557
underwater4k/fragment.glsl_2_dbg
Normal file
@@ -0,0 +1,557 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const int shader= 2;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
varying vec4 Y;
|
||||
|
||||
// Position of the fragment
|
||||
varying vec2 Z;
|
||||
|
||||
uniform sampler2D V;
|
||||
uniform sampler2D HEIGHT;
|
||||
|
||||
// Forward declarations
|
||||
vec4 traceRay(vec3 ro, vec3 rd, int ignore);
|
||||
vec3 shade(vec4 hitPoint, vec3 newRo, vec3 rd);
|
||||
|
||||
|
||||
// All data of our world
|
||||
vec3 spherePos, lightDir, lightColor, waterColor, ro, rd, interlacing;
|
||||
float sphereRadius, gf_DetailLevel, pi, eps, bigeps;
|
||||
|
||||
|
||||
// Pseudo random number base generator (credits go to iq/rgba)
|
||||
float rnd(vec2 x)
|
||||
{
|
||||
int n = int(x.x * 40 + x.y * 6400);
|
||||
n = (n << 13) ^ n;
|
||||
return 1 - float( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824;
|
||||
}
|
||||
|
||||
|
||||
// Generate cubic interpolated random values
|
||||
float smoothrnd(vec2 x)
|
||||
{
|
||||
x = mod(x,1000.0);
|
||||
vec2 a = fract(x);
|
||||
x -= a;
|
||||
vec2 u = a*a*(3.0-2.0*a);
|
||||
return mix(
|
||||
mix(rnd(x+vec2(0,0)),rnd(x+vec2(1,0)), u.x),
|
||||
mix(rnd(x+vec2(0,1)),rnd(x+vec2(1,1)), u.x), u.y);
|
||||
}
|
||||
|
||||
|
||||
// Convert the cipher range from [-1,1] to [0,1]
|
||||
float norm(float x)
|
||||
{
|
||||
return x * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
return (0.01 + ((.25*texture2D(V, p * 128.0).x) + texture2D(V, p * 32.0).x)) * smoothstep(0.25, 0.35, texture2D(V, p * 11).y * texture2D(V, p * 13).y);
|
||||
}
|
||||
|
||||
float texnoise(vec2 p)
|
||||
{
|
||||
return texture2D(V, p).y;
|
||||
}
|
||||
|
||||
float grass(vec2 p)
|
||||
{
|
||||
return texnoise(p * 57) * texnoise(p * 13) * 2.0;
|
||||
}
|
||||
|
||||
// Our heightmap calculation function, we could use some perlin noise here if it wouldn't be so performance killing
|
||||
float height(vec2 x)
|
||||
{
|
||||
return texture2D(HEIGHT, x).x;
|
||||
}
|
||||
|
||||
|
||||
// Gets the terrain normal
|
||||
vec3 getTerrainNormal(vec3 p)
|
||||
{
|
||||
return normalize(vec3(
|
||||
height(p.xz - vec2(bigeps, 0)) - height(p.xz + vec2(bigeps, 0)),
|
||||
2 * bigeps,
|
||||
height(p.xz - vec2(0, bigeps)) - height(p.xz + vec2(0, bigeps))));
|
||||
}
|
||||
|
||||
|
||||
// Global diffuse lighting formula
|
||||
vec3 diffuseLight(vec3 incolor, float shadow, vec3 normal)
|
||||
{
|
||||
return (0.3 + shadow * 0.7 * max(dot(normal, lightDir), 0.0)) * lightColor * incolor;
|
||||
}
|
||||
|
||||
|
||||
// Calculates the water "waves". To reduce the bumpiness, increment the y-axis
|
||||
vec3 getWaterNormal(vec3 p)
|
||||
{
|
||||
return normalize(vec3(
|
||||
texnoise(p.xz * 40 + Y.x*.5)*2-1,
|
||||
8,
|
||||
texnoise(p.xz * 80 - Y.x*.25)*2-1));
|
||||
}
|
||||
|
||||
|
||||
float caustic(vec3 p)
|
||||
{
|
||||
vec2 q = p.xz * (1 - p.y * .01);
|
||||
float noiseX = texnoise(q * .125 * (.05*Y.x+vec2(2,3)));
|
||||
float noiseY = texnoise(q * .125 * (.05*Y.x+vec2(4,5)));
|
||||
q = mod(q * 10.0 + vec2(noiseX, noiseY) * 16.0, 1.0);
|
||||
q -= step(0.5, q) * 2 * (q - 0.5);
|
||||
q *= 2;
|
||||
return max(pow(q.x, 4.0 + 4.0 * noiseX), pow(q.y, 4.0 + 4.0 * noiseX));
|
||||
}
|
||||
|
||||
float caustics(vec3 p)
|
||||
{
|
||||
return caustic(p * 31) * caustic(p * 17);
|
||||
}
|
||||
|
||||
// Our fake godray effect (bad if moving fast, but awesome any other time)
|
||||
vec3 godrays(vec3 ro, vec3 rd, float maxt, vec3 color)
|
||||
{
|
||||
const int iterations = 16;
|
||||
float dt = 0.001, t = 0;
|
||||
float cs = 0.0;
|
||||
for (int i = 0; i < iterations; ++i)
|
||||
{
|
||||
vec3 p = ro + rd * t;
|
||||
vec2 q = p.xz * (1 - p.y * .4);
|
||||
|
||||
float shadow = 1.0-step(1,traceRay(p, lightDir, 2).w);
|
||||
cs = max(cs, (1 + p.y * 8) * shadow * smoothstep(0.4, 0.7, texnoise(q * 64)) / (1+t*2));
|
||||
t += dt;
|
||||
}
|
||||
return color + pow(cs, 4.0) * lightColor * .1;
|
||||
}
|
||||
|
||||
// Calculate the terrain color for the given voxel
|
||||
vec3 shadeTerrain(vec3 p, vec3 rd)
|
||||
{
|
||||
vec3 n = getTerrainNormal(p);
|
||||
float vrn = voronoi(p.xz);
|
||||
vec3 grassColor = vec3(0.8, 0.85, 0.4) * 1.5 * grass(p.xz);
|
||||
vec3 dirtColor = vec3(0.65, 0.6, 0.4) * (.5+grass(p.xz));
|
||||
vec3 stoneColor = vec3(0.5, 0.5, 0.4) * (.5+grass(p.xz));
|
||||
float groundFactor = smoothstep(0.7, 0.8, n.y) * (1.0 - step(p.y, texnoise(p.xz*128)*0.01-0.003)); // shore
|
||||
float dirtFactor = smoothstep(0.4, 0.6, texture2D(V, p.xz * 40).y);
|
||||
vec3 ground = mix(mix(stoneColor, dirtColor, dirtFactor), grassColor, groundFactor);
|
||||
|
||||
vec3 rockColor = vec3(0.5, 0.5, 0.5) * (.75 + vrn) * (.75+.5*grass(p.xz * 8));
|
||||
vec3 color = mix(ground, rockColor, smoothstep(0.0, 0.05,vrn));
|
||||
|
||||
float shadow = 1.0-step(1,traceRay(p + n * 0.005, lightDir, 2).w);
|
||||
|
||||
if (p.y <= 0)
|
||||
color = max(0.0, 0.7 + 8 * p.y) * (color + lightColor * shadow * max(0, 1 + 32 * p.y) * caustics(p));
|
||||
else
|
||||
color *= 0.6+0.4*min(1.0, p.y * 999.0);
|
||||
|
||||
color = color * (.5+.5*vrn);
|
||||
return diffuseLight(color, shadow, n);
|
||||
}
|
||||
|
||||
|
||||
// Create a blueish sky transition from navy blue to badass dark blue
|
||||
vec3 shadeSky(vec3 ro, vec3 rd)
|
||||
{
|
||||
vec3 farColor = vec3(0.0, 0.0, 0.4);
|
||||
return mix(waterColor, farColor, max(0, rd.y))
|
||||
+ 0.25*lightColor * pow(max(0, dot(rd, lightDir)), 4)
|
||||
+ lightColor * pow(max(0, dot(rd, lightDir)), 1000);
|
||||
}
|
||||
|
||||
|
||||
// Calculates the refraction and reflection of the water surface.
|
||||
// Also mixes both values by the depth of the water and the fresnel term.
|
||||
// Possible improvements: fix fake underwater reflection and refraction
|
||||
vec3 shadeWaterRefl(vec3 p, vec3 newrd)
|
||||
{
|
||||
vec3 waterNormal = getWaterNormal(p);
|
||||
|
||||
// perform raytracing/raymarching for both reflection and refraction
|
||||
// calc the water refraction, the refraction index (0.9) will decrease with the distance to allow a better over/under water transition
|
||||
vec3 refrd = mix(newrd, refract(newrd, waterNormal, 0.9), step(0.0, ro.y));
|
||||
vec4 refracted = traceRay(p, refrd, 2);//mix(0.9, 1.0, smoothstep(0.01, 0.0, length(p-ro)))), 2);
|
||||
|
||||
// calculate the depth factor (water entry point to terrain voxel) (black magic involved here!)
|
||||
float depth = clamp(pow(1.03 * (1 - length(refracted.xyz - p)), 16.0), 0.0, 1.0);
|
||||
|
||||
float shadow = 0.9 + 0.1 * (1.0-step(1,traceRay(p + waterNormal * 0.005, lightDir, 2).w));
|
||||
float fresnel = pow(clamp(abs(-rd.y), 0.0, 1.0),1.8);
|
||||
// Finally stir the pot =)
|
||||
return shadow * mix(
|
||||
shadeSky(p, refrd), // Water color
|
||||
mix(
|
||||
shade(traceRay(p, reflect(newrd, waterNormal), 2), p, newrd), // Reflection color
|
||||
shade(refracted, p, newrd), // Refraction color
|
||||
fresnel), // fresnel term
|
||||
pow(depth, 0.5)); // water color contribution
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Texture our "AMIGAAAAAAA!!" ball
|
||||
vec3 shadeAttractor(vec3 p, vec3 rd)
|
||||
{
|
||||
vec3 n,color;
|
||||
|
||||
// get the sphere normal, first
|
||||
n = normalize(p - spherePos);
|
||||
|
||||
// now calculate the texture coordinates
|
||||
vec2 uv = 0.5 + 0.5 * vec2(atan(n.z, n.x), acos(n.y)) / pi;
|
||||
|
||||
// We'll animate our x-texture coordinate with the time, this gives the impression of a rotating ball
|
||||
uv.x -= Y.x;
|
||||
|
||||
// This spell will convert any dull ball into an amiga ball, caution is advised.
|
||||
color = mix(vec3(1), vec3(1, 0, 0), mod(step(fract(uv.x * 6), 0.5) + step(fract(uv.y * 6), 0.5), 2.0));
|
||||
|
||||
return diffuseLight(color, 1, n)
|
||||
+ pow(max(dot(n, normalize(lightDir - rd)), 0.0), 33.0) * lightColor; // specular light spot
|
||||
}
|
||||
|
||||
#define INTERVAL_ITERS 5
|
||||
#define LINEAR_ACCURACY 0.5
|
||||
|
||||
// Raymarch the terrain function, returns the distance from the ray origin to the terrain voxel
|
||||
// This function was originally adopted from an implementation by iq/rgba
|
||||
float traceTerrain(vec3 ro, vec3 rd, float maxt)
|
||||
{
|
||||
float samplePosY, h, prevt, t;
|
||||
vec3 samplePos;
|
||||
|
||||
// advance our sample position from our nearplane to our farplane
|
||||
for (t = 0; t < maxt;)
|
||||
{
|
||||
// advance our ray
|
||||
samplePos = ro + rd * t;
|
||||
samplePosY = samplePos.y;
|
||||
|
||||
// get the height at the given sample 2d (!) position (we could enhance this by sampling a voxel and returning only the distance to the voxel)
|
||||
h = height(samplePos.xz);
|
||||
float dist = samplePosY - h;
|
||||
if (dist < 0.0) break;
|
||||
|
||||
prevt = t;
|
||||
|
||||
if (dist > 0.0001)
|
||||
t += max(dist * 1.4, 0.0001) * LINEAR_ACCURACY;
|
||||
else
|
||||
t += max(dist, 0.00001) * LINEAR_ACCURACY;
|
||||
}
|
||||
|
||||
if (samplePosY <= h)
|
||||
{
|
||||
/// Interval mapping
|
||||
float before = prevt;
|
||||
vec3 beforePos = ro + rd * before;
|
||||
float beforeH = height(beforePos.xz);
|
||||
|
||||
float after = t;
|
||||
vec3 afterPos = ro + rd * after;
|
||||
float afterH = height(afterPos.xz);
|
||||
|
||||
for (int i = 0; i < INTERVAL_ITERS; i++)
|
||||
{
|
||||
float interval = after - before;
|
||||
float deltaL = beforeH - afterH;
|
||||
float deltaR = rd.y * interval;
|
||||
|
||||
float curt = (beforeH * interval - deltaL * before) / (deltaR - deltaL);
|
||||
if (curt <= before - 0.000001 || curt >= after + 0.000001) break;
|
||||
|
||||
samplePos = ro + rd * curt;
|
||||
float h = height(samplePos.xz);
|
||||
|
||||
if (h <= samplePos.y)
|
||||
{
|
||||
beforeH = h;
|
||||
before = curt;
|
||||
t = curt;
|
||||
}
|
||||
else
|
||||
{
|
||||
afterH = h;
|
||||
after = curt;
|
||||
t = curt;
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// we hit nothing
|
||||
return 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Ray vs. sphere intersection function
|
||||
float traceAttractor(vec3 ro, vec3 rd)
|
||||
{
|
||||
vec3 dst = ro - spherePos;
|
||||
float B,D;
|
||||
B = dot(dst, rd);
|
||||
if (B > 0)
|
||||
return 9.0;
|
||||
D = B*B - dot(dst, dst) + sphereRadius*sphereRadius;
|
||||
if (D > 0)
|
||||
{
|
||||
return -B - sqrt(D);
|
||||
}
|
||||
return 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Ray vs. plane intersection function
|
||||
float traceWater(vec3 ro, vec3 rd)
|
||||
{
|
||||
float tPlane = -ro.y / rd.y;
|
||||
return tPlane >= eps ? tPlane : 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Raytracing entry point, returns voxel and object ID
|
||||
// IDs:
|
||||
// 0 = sky (not the armageddon, xTr1m!!)
|
||||
// 1 = terrain
|
||||
// 2 = water
|
||||
// 3 = attractive amiga ball (you have never seen such a sexy amiga ball before, admit it!)
|
||||
vec4 traceRay(vec3 ro, vec3 rd, int ignore)
|
||||
{
|
||||
float water, attractor, terrain, minDist;
|
||||
|
||||
// trace only the objects we need (only one could maximally be ignored)
|
||||
water = ignore != 2 ? traceWater(ro, rd) : 9.0;
|
||||
attractor = ignore != 3 ? traceAttractor(ro, rd) : 9.0;
|
||||
terrain = ignore != 1 ? traceTerrain(ro, rd, min(0.5, 0.002+min(water, attractor))) : 9.0;
|
||||
|
||||
// auto detail level reducing (common dude, give the GPU some breathing room)
|
||||
gf_DetailLevel /= 20;
|
||||
|
||||
// find the nearest distance
|
||||
minDist = min(terrain, min(water, min(attractor, 9.0)));
|
||||
|
||||
// we hit nothing or the hitpoint is too far
|
||||
if (minDist == 9)
|
||||
return vec4(0);
|
||||
|
||||
// calculate the hit/voxel position
|
||||
vec3 hitPos = ro + rd * minDist;
|
||||
|
||||
// check what we might have hit
|
||||
if (minDist == terrain)
|
||||
return vec4(hitPos, 1);
|
||||
if (minDist == water)
|
||||
return vec4(hitPos, 2);
|
||||
if (minDist == attractor)
|
||||
return vec4(hitPos, 3);
|
||||
|
||||
// Panic, worry, die to death! Probably we'll land on the moon (this should never happen)
|
||||
//return vec4(0);
|
||||
}
|
||||
|
||||
|
||||
// Entrypoint for color calculation
|
||||
vec3 shadeRefl(vec4 hitPoint, vec3 newRo, vec3 rd)
|
||||
{
|
||||
// determine the fog color for this very precise point in the space time continuum
|
||||
vec3 myFog = newRo.y < eps ? waterColor : shadeSky(ro, rd);
|
||||
|
||||
// generate the distance value for the fog calculation
|
||||
float distance = clamp(length(hitPoint.xyz - newRo) * (ro.y <= 0 ? 4 : 2), 0.0, 1.0);
|
||||
|
||||
// get the color of the hit object and mix it with the fog
|
||||
// in most cases we allow further raytracing here (not for the terrain, its not shiny enough)
|
||||
if (hitPoint.w == 1)
|
||||
return mix(shadeTerrain(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 2)
|
||||
return mix(shadeWaterRefl(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 3)
|
||||
return mix(
|
||||
// Our amiga ball is shiny so reflect the scene!
|
||||
mix(shadeAttractor(hitPoint.xyz, rd), shade(traceRay(hitPoint.xyz, reflect(rd, normalize(hitPoint.xyz - spherePos)), 3), hitPoint.xyz, rd), 0.5)
|
||||
, myFog, distance);
|
||||
|
||||
return shadeSky(newRo, rd);
|
||||
}
|
||||
|
||||
|
||||
// Get the color from the object we just hit (without further raytraces)
|
||||
// this is necessary because no recursion is allowed in GLSL (damn you!)
|
||||
vec3 shade(vec4 hitPoint, vec3 newRo, vec3 rd)
|
||||
{
|
||||
// determine the fog color for the very same point we discussed earlier
|
||||
vec3 myFog = newRo.y < eps ? waterColor : shadeSky(ro, rd);
|
||||
|
||||
// generate the other distance value. Paid attention? If you don't know what value I'm talking about, rtfm or gtfo.
|
||||
float distance = clamp(length(hitPoint.xyz - newRo) * (ro.y <= 0 ? 4 : 2), 0.0, 1.0);
|
||||
|
||||
// get the color of the hit object and mix it with the fog
|
||||
if (hitPoint.w == 1)
|
||||
return mix(shadeTerrain(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 2)
|
||||
return mix(waterColor, myFog, distance);
|
||||
if (hitPoint.w == 3)
|
||||
return mix(shadeAttractor(hitPoint.xyz, rd), myFog, distance);
|
||||
|
||||
return myFog;
|
||||
}
|
||||
|
||||
// Now we're just being copycats. We're not creative enough to define own entry points
|
||||
// Sure, we could "#define MYENTRYPOINT main"! Or just void main(){MyEntryPoint();}
|
||||
// None of that would help us win the compo, would it?
|
||||
void main()
|
||||
{
|
||||
// Set the quality setting for the raymarcher, a higher value results in a longer processing time
|
||||
// try to find a good balance between these two, low values wivoronoill result in a wobbling endresult
|
||||
// low quality = 50.0 (visual results are ok at 640x480)
|
||||
// mid quality = 100.0
|
||||
// high quality = 200.0
|
||||
gf_DetailLevel = 100;
|
||||
|
||||
// Give our saviour global variables some life!
|
||||
pi = 3.1416;
|
||||
interlacing = vec3(1.2, 0.9, 0.9);
|
||||
eps = 0.0001;
|
||||
bigeps = 0.01;
|
||||
|
||||
// Nifty random number generator gets initialized
|
||||
float seed = 10;
|
||||
|
||||
// Determine the scene we're in
|
||||
int scene = int(Y.x);
|
||||
|
||||
// Get the look direction for the current pixel (always look forwards)
|
||||
rd = vec3((Z.xy - 0.5), 1);
|
||||
|
||||
float tex = texture2D(V, clamp(Z.xy, 0.0, 1.0), 1.0).x;
|
||||
gl_FragColor = vec4(tex, tex, tex, 1);
|
||||
return;
|
||||
|
||||
// Merry-go-round on a boat (yeah, this makes no sense. Go watch the intro and see for yourself)
|
||||
if (scene > 22 && scene < 27)
|
||||
{
|
||||
seed = min(1.0, sin((Y.x-23)*pi*0.25)*12);
|
||||
ro = vec3(0.12, 0.005, Y.x*0.08);
|
||||
rd = vec3(gl_ModelViewMatrix * vec4(rd, 1));
|
||||
rd.y += 0.1*cos(Y.x*4);
|
||||
}
|
||||
// Intermezzo: Dolphin like animation inside and outside the water, chasing that amiga ball!
|
||||
else if (scene > 14 && scene < 23)
|
||||
{
|
||||
seed = min(1.0, sin((Y.x-15)*pi*0.125)*24);
|
||||
rd += vec3(0,0.1*cos(Y.x*4), 0);
|
||||
ro = vec3(0.08, 0.01*sin(Y.x*4)+0.002, Y.x*0.11);
|
||||
}
|
||||
// Intro and Outro: Show still scenes
|
||||
else
|
||||
{
|
||||
// Get a random initial position for our camera
|
||||
ro = vec3(0.1,0.004,0.0) + vec3(0.1,0.005,20)
|
||||
*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)));
|
||||
|
||||
// Basing on the initial position, choose some "random" start and end points nearby
|
||||
ro = mix(
|
||||
ro+vec3(0.008)*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++))),
|
||||
ro+vec3(0.008)*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++))),
|
||||
// and move the camera!
|
||||
Y.x-scene);
|
||||
|
||||
// We adjust the height of the camera to the terrain height
|
||||
ro.y += height(ro.xz)+0.02;
|
||||
|
||||
// Deviate the camera position in the direction of the normal of the underlying terrain
|
||||
ro += 0.02*getTerrainNormal(ro);
|
||||
|
||||
// Reusing a float variable here, this controls the scene fade in / fade out animation
|
||||
seed = min(1.0, step(-28.0, -Y.x) * sin((Y.x-scene)*pi)*3);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//Debugzeug fuer Kamerasteuerung
|
||||
{
|
||||
ro.x= gl_ModelViewMatrix[0][0];
|
||||
ro.y= gl_ModelViewMatrix[0][1];
|
||||
ro.z= gl_ModelViewMatrix[0][2];
|
||||
|
||||
float a1= gl_ModelViewMatrix[1][1];
|
||||
float c1,s1;vec3 q1= vec3((Z.xy - 0.5), 0.8);
|
||||
c1 = cos(a1); s1 = sin(a1);
|
||||
rd.y = c1 * q1.y - s1 * q1.z;
|
||||
rd.x= q1.x;
|
||||
rd.z = s1 * q1.y + c1 * q1.z;
|
||||
|
||||
a1= gl_ModelViewMatrix[1][0];
|
||||
q1=rd;
|
||||
c1 = cos(a1); s1 = sin(a1);
|
||||
rd.x = c1 * q1.x + s1 * q1.z;
|
||||
rd.z = -s1 * q1.x + c1 * q1.z;
|
||||
|
||||
}
|
||||
//Ende Debugzeug fuer Kamerasteuerung
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
rd = normalize(rd);
|
||||
|
||||
// Now boot the amiga workbench (erm, no...)
|
||||
// mantain a relative distance to the camera
|
||||
if (scene > 22 && scene < 27)
|
||||
spherePos = ro + 0.1 * vec3(gl_ModelViewMatrix * vec4(0, 0, 1, 1));
|
||||
else
|
||||
spherePos = ro + 0.02 * vec3(sin(Y.x), 0, 5+cos(Y.x));
|
||||
|
||||
spherePos.y += 0.01 + height(spherePos.xz); // mantain a relative height to the underlying terrain
|
||||
sphereRadius = scene < 14 ? 0.0 : bigeps * 0.5 + bigeps * Y.z; // The amiga ball is bigger when the snare drum is hit!
|
||||
spherePos += 2*sphereRadius * getTerrainNormal(spherePos); // deviate according to the underlying terrain's normal
|
||||
|
||||
// Make our world pretty and worthy to live in (you can cultivate algae and eat them, they're surely enough for survival)
|
||||
lightDir = normalize(vec3(0.78, 0.12 + Y.x*.2, -0.18));
|
||||
lightColor = vec3(2.4, 2.0, 1.0) + Y.x*.5;
|
||||
waterColor = mix(vec3(0.4, 0.33, 0.4), vec3(0.4, 0.5, 0.6), Y.x);
|
||||
|
||||
// Our GPU feels good underwater, almost like a refreshing experience :) cool, eh?
|
||||
if (ro.y <= 0)
|
||||
{
|
||||
// Less work to do...
|
||||
gf_DetailLevel *= 0.75;
|
||||
|
||||
// ...and a cozy darker atmosphere
|
||||
lightColor *= 0.8;
|
||||
}
|
||||
|
||||
// Here we go, shoot'em rays and get the color of our fragment!
|
||||
vec4 hit = traceRay(ro, rd, 0);
|
||||
vec3 color = shadeRefl(hit, ro, rd);
|
||||
|
||||
// Underwater there are beams of light emanating from god (so called "god" rays...)
|
||||
// ...this prooves that god is nothing less than a water surface.
|
||||
if (ro.y <= 0)
|
||||
color = godrays(ro, rd, length(hit.xyz-ro), color);
|
||||
|
||||
// Apply post processing and fade effects to the color, and finally return it.
|
||||
gl_FragColor.xyz = color;
|
||||
}
|
||||
557
underwater4k/fragment.glsl_3
Normal file
557
underwater4k/fragment.glsl_3
Normal file
@@ -0,0 +1,557 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const int shader= 3;
|
||||
|
||||
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
varying vec4 Y;
|
||||
|
||||
// Position of the fragment
|
||||
varying vec2 Z;
|
||||
|
||||
uniform sampler2D V;
|
||||
uniform sampler2D HEIGHT;
|
||||
|
||||
// Forward declarations
|
||||
vec4 traceRay(vec3 ro, vec3 rd, int ignore);
|
||||
vec3 shade(vec4 hitPoint, vec3 newRo, vec3 rd);
|
||||
|
||||
|
||||
// All data of our world
|
||||
vec3 spherePos, lightDir, lightColor, waterColor, ro, rd, interlacing;
|
||||
float sphereRadius, gf_DetailLevel, pi, eps, bigeps;
|
||||
|
||||
|
||||
// Pseudo random number base generator (credits go to iq/rgba)
|
||||
float rnd(vec2 x)
|
||||
{
|
||||
int n = int(x.x * 40 + x.y * 6400);
|
||||
n = (n << 13) ^ n;
|
||||
return 1 - float( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824;
|
||||
}
|
||||
|
||||
|
||||
// Generate cubic interpolated random values
|
||||
float smoothrnd(vec2 x)
|
||||
{
|
||||
x = mod(x,1000.0);
|
||||
vec2 a = fract(x);
|
||||
x -= a;
|
||||
vec2 u = a*a*(3.0-2.0*a);
|
||||
return mix(
|
||||
mix(rnd(x+vec2(0,0)),rnd(x+vec2(1,0)), u.x),
|
||||
mix(rnd(x+vec2(0,1)),rnd(x+vec2(1,1)), u.x), u.y);
|
||||
}
|
||||
|
||||
|
||||
// Convert the cipher range from [-1,1] to [0,1]
|
||||
float norm(float x)
|
||||
{
|
||||
return x * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
return (0.01 + ((.25*texture2D(V, p * 128.0).x) + texture2D(V, p * 32.0).x)) * smoothstep(0.25, 0.35, texture2D(V, p * 11).y * texture2D(V, p * 13).y);
|
||||
}
|
||||
|
||||
float texnoise(vec2 p)
|
||||
{
|
||||
return texture2D(V, p).y;
|
||||
}
|
||||
|
||||
float grass(vec2 p)
|
||||
{
|
||||
return texnoise(p * 57) * texnoise(p * 13) * 2.0;
|
||||
}
|
||||
|
||||
// Our heightmap calculation function, we could use some perlin noise here if it wouldn't be so performance killing
|
||||
float height(vec2 x)
|
||||
{
|
||||
return texture2D(HEIGHT, x).x;
|
||||
}
|
||||
|
||||
|
||||
// Gets the terrain normal
|
||||
vec3 getTerrainNormal(vec3 p)
|
||||
{
|
||||
return normalize(vec3(
|
||||
height(p.xz - vec2(bigeps, 0)) - height(p.xz + vec2(bigeps, 0)),
|
||||
2 * bigeps,
|
||||
height(p.xz - vec2(0, bigeps)) - height(p.xz + vec2(0, bigeps))));
|
||||
}
|
||||
|
||||
|
||||
// Global diffuse lighting formula
|
||||
vec3 diffuseLight(vec3 incolor, float shadow, vec3 normal)
|
||||
{
|
||||
return (0.3 + shadow * 0.7 * max(dot(normal, lightDir), 0.0)) * lightColor * incolor;
|
||||
}
|
||||
|
||||
|
||||
// Calculates the water "waves". To reduce the bumpiness, increment the y-axis
|
||||
vec3 getWaterNormal(vec3 p)
|
||||
{
|
||||
return normalize(vec3(
|
||||
texnoise(p.xz * 40 + Y.x*.5)*2-1,
|
||||
8,
|
||||
texnoise(p.xz * 80 - Y.x*.25)*2-1));
|
||||
}
|
||||
|
||||
|
||||
float caustic(vec3 p)
|
||||
{
|
||||
vec2 q = p.xz * (1 - p.y * .01);
|
||||
float noiseX = texnoise(q * .125 * (.05*Y.x+vec2(2,3)));
|
||||
float noiseY = texnoise(q * .125 * (.05*Y.x+vec2(4,5)));
|
||||
q = mod(q * 10.0 + vec2(noiseX, noiseY) * 16.0, 1.0);
|
||||
q -= step(0.5, q) * 2 * (q - 0.5);
|
||||
q *= 2;
|
||||
return max(pow(q.x, 4.0 + 4.0 * noiseX), pow(q.y, 4.0 + 4.0 * noiseX));
|
||||
}
|
||||
|
||||
float caustics(vec3 p)
|
||||
{
|
||||
return caustic(p * 31) * caustic(p * 17);
|
||||
}
|
||||
|
||||
// Our fake godray effect (bad if moving fast, but awesome any other time)
|
||||
vec3 godrays(vec3 ro, vec3 rd, float maxt, vec3 color)
|
||||
{
|
||||
const int iterations = 16;
|
||||
float dt = 0.001, t = 0;
|
||||
float cs = 0.0;
|
||||
for (int i = 0; i < iterations; ++i)
|
||||
{
|
||||
vec3 p = ro + rd * t;
|
||||
vec2 q = p.xz * (1 - p.y * .4);
|
||||
|
||||
float shadow = 1.0-step(1,traceRay(p, lightDir, 2).w);
|
||||
cs = max(cs, (1 + p.y * 8) * shadow * smoothstep(0.4, 0.7, texnoise(q * 64)) / (1+t*2));
|
||||
t += dt;
|
||||
}
|
||||
return color + pow(cs, 4.0) * lightColor * .1;
|
||||
}
|
||||
|
||||
// Calculate the terrain color for the given voxel
|
||||
vec3 shadeTerrain(vec3 p, vec3 rd)
|
||||
{
|
||||
vec3 n = getTerrainNormal(p);
|
||||
float vrn = voronoi(p.xz);
|
||||
vec3 grassColor = vec3(0.8, 0.85, 0.4) * 1.5 * grass(p.xz);
|
||||
vec3 dirtColor = vec3(0.65, 0.6, 0.4) * (.5+grass(p.xz));
|
||||
vec3 stoneColor = vec3(0.5, 0.5, 0.4) * (.5+grass(p.xz));
|
||||
float groundFactor = smoothstep(0.7, 0.8, n.y) * (1.0 - step(p.y, texnoise(p.xz*128)*0.01-0.003)); // shore
|
||||
float dirtFactor = smoothstep(0.4, 0.6, texture2D(V, p.xz * 40).y);
|
||||
vec3 ground = mix(mix(stoneColor, dirtColor, dirtFactor), grassColor, groundFactor);
|
||||
|
||||
vec3 rockColor = vec3(0.5, 0.5, 0.5) * (.75 + vrn) * (.75+.5*grass(p.xz * 8));
|
||||
vec3 color = mix(ground, rockColor, smoothstep(0.0, 0.05,vrn));
|
||||
|
||||
float shadow = 1.0-step(1,traceRay(p + n * 0.005, lightDir, 2).w);
|
||||
|
||||
if (p.y <= 0)
|
||||
color = max(0.0, 0.7 + 8 * p.y) * (color + lightColor * shadow * max(0, 1 + 32 * p.y) * caustics(p));
|
||||
else
|
||||
color *= 0.6+0.4*min(1.0, p.y * 999.0);
|
||||
|
||||
color = color * (.5+.5*vrn);
|
||||
return diffuseLight(color, shadow, n);
|
||||
}
|
||||
|
||||
|
||||
// Create a blueish sky transition from navy blue to badass dark blue
|
||||
vec3 shadeSky(vec3 ro, vec3 rd)
|
||||
{
|
||||
vec3 farColor = vec3(0.0, 0.0, 0.4);
|
||||
return mix(waterColor, farColor, max(0, rd.y))
|
||||
+ 0.25*lightColor * pow(max(0, dot(rd, lightDir)), 4)
|
||||
+ lightColor * pow(max(0, dot(rd, lightDir)), 1000);
|
||||
}
|
||||
|
||||
|
||||
// Calculates the refraction and reflection of the water surface.
|
||||
// Also mixes both values by the depth of the water and the fresnel term.
|
||||
// Possible improvements: fix fake underwater reflection and refraction
|
||||
vec3 shadeWaterRefl(vec3 p, vec3 newrd)
|
||||
{
|
||||
vec3 waterNormal = getWaterNormal(p);
|
||||
|
||||
// perform raytracing/raymarching for both reflection and refraction
|
||||
// calc the water refraction, the refraction index (0.9) will decrease with the distance to allow a better over/under water transition
|
||||
vec3 refrd = mix(newrd, refract(newrd, waterNormal, 0.9), step(0.0, ro.y));
|
||||
vec4 refracted = traceRay(p, refrd, 2);//mix(0.9, 1.0, smoothstep(0.01, 0.0, length(p-ro)))), 2);
|
||||
|
||||
// calculate the depth factor (water entry point to terrain voxel) (black magic involved here!)
|
||||
float depth = clamp(pow(1.03 * (1 - length(refracted.xyz - p)), 16.0), 0.0, 1.0);
|
||||
|
||||
float shadow = 0.9 + 0.1 * (1.0-step(1,traceRay(p + waterNormal * 0.005, lightDir, 2).w));
|
||||
float fresnel = pow(clamp(abs(-rd.y), 0.0, 1.0),1.8);
|
||||
// Finally stir the pot =)
|
||||
return shadow * mix(
|
||||
shadeSky(p, refrd), // Water color
|
||||
mix(
|
||||
shade(traceRay(p, reflect(newrd, waterNormal), 2), p, newrd), // Reflection color
|
||||
shade(refracted, p, newrd), // Refraction color
|
||||
fresnel), // fresnel term
|
||||
pow(depth, 0.5)); // water color contribution
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Texture our "AMIGAAAAAAA!!" ball
|
||||
vec3 shadeAttractor(vec3 p, vec3 rd)
|
||||
{
|
||||
vec3 n,color;
|
||||
|
||||
// get the sphere normal, first
|
||||
n = normalize(p - spherePos);
|
||||
|
||||
// now calculate the texture coordinates
|
||||
vec2 uv = 0.5 + 0.5 * vec2(atan(n.z, n.x), acos(n.y)) / pi;
|
||||
|
||||
// We'll animate our x-texture coordinate with the time, this gives the impression of a rotating ball
|
||||
uv.x -= Y.x;
|
||||
|
||||
// This spell will convert any dull ball into an amiga ball, caution is advised.
|
||||
color = mix(vec3(1), vec3(1, 0, 0), mod(step(fract(uv.x * 6), 0.5) + step(fract(uv.y * 6), 0.5), 2.0));
|
||||
|
||||
return diffuseLight(color, 1, n)
|
||||
+ pow(max(dot(n, normalize(lightDir - rd)), 0.0), 33.0) * lightColor; // specular light spot
|
||||
}
|
||||
|
||||
#define INTERVAL_ITERS 5
|
||||
#define LINEAR_ACCURACY 0.5
|
||||
|
||||
// Raymarch the terrain function, returns the distance from the ray origin to the terrain voxel
|
||||
// This function was originally adopted from an implementation by iq/rgba
|
||||
float traceTerrain(vec3 ro, vec3 rd, float maxt)
|
||||
{
|
||||
float samplePosY, h, prevt, t;
|
||||
vec3 samplePos;
|
||||
|
||||
// advance our sample position from our nearplane to our farplane
|
||||
for (t = 0; t < maxt;)
|
||||
{
|
||||
// advance our ray
|
||||
samplePos = ro + rd * t;
|
||||
samplePosY = samplePos.y;
|
||||
|
||||
// get the height at the given sample 2d (!) position (we could enhance this by sampling a voxel and returning only the distance to the voxel)
|
||||
h = height(samplePos.xz);
|
||||
float dist = samplePosY - h;
|
||||
if (dist < 0.0) break;
|
||||
|
||||
prevt = t;
|
||||
|
||||
if (dist > 0.0001)
|
||||
t += max(dist * 1.4, 0.0001) * LINEAR_ACCURACY;
|
||||
else
|
||||
t += max(dist, 0.00001) * LINEAR_ACCURACY;
|
||||
}
|
||||
|
||||
if (samplePosY <= h)
|
||||
{
|
||||
/// Interval mapping
|
||||
float before = prevt;
|
||||
vec3 beforePos = ro + rd * before;
|
||||
float beforeH = height(beforePos.xz);
|
||||
|
||||
float after = t;
|
||||
vec3 afterPos = ro + rd * after;
|
||||
float afterH = height(afterPos.xz);
|
||||
|
||||
for (int i = 0; i < INTERVAL_ITERS; i++)
|
||||
{
|
||||
float interval = after - before;
|
||||
float deltaL = beforeH - afterH;
|
||||
float deltaR = rd.y * interval;
|
||||
|
||||
float curt = (beforeH * interval - deltaL * before) / (deltaR - deltaL);
|
||||
if (curt <= before - 0.000001 || curt >= after + 0.000001) break;
|
||||
|
||||
samplePos = ro + rd * curt;
|
||||
float h = height(samplePos.xz);
|
||||
|
||||
if (h <= samplePos.y)
|
||||
{
|
||||
beforeH = h;
|
||||
before = curt;
|
||||
t = curt;
|
||||
}
|
||||
else
|
||||
{
|
||||
afterH = h;
|
||||
after = curt;
|
||||
t = curt;
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// we hit nothing
|
||||
return 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Ray vs. sphere intersection function
|
||||
float traceAttractor(vec3 ro, vec3 rd)
|
||||
{
|
||||
vec3 dst = ro - spherePos;
|
||||
float B,D;
|
||||
B = dot(dst, rd);
|
||||
if (B > 0)
|
||||
return 9.0;
|
||||
D = B*B - dot(dst, dst) + sphereRadius*sphereRadius;
|
||||
if (D > 0)
|
||||
{
|
||||
return -B - sqrt(D);
|
||||
}
|
||||
return 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Ray vs. plane intersection function
|
||||
float traceWater(vec3 ro, vec3 rd)
|
||||
{
|
||||
float tPlane = -ro.y / rd.y;
|
||||
return tPlane >= eps ? tPlane : 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Raytracing entry point, returns voxel and object ID
|
||||
// IDs:
|
||||
// 0 = sky (not the armageddon, xTr1m!!)
|
||||
// 1 = terrain
|
||||
// 2 = water
|
||||
// 3 = attractive amiga ball (you have never seen such a sexy amiga ball before, admit it!)
|
||||
vec4 traceRay(vec3 ro, vec3 rd, int ignore)
|
||||
{
|
||||
float water, attractor, terrain, minDist;
|
||||
|
||||
// trace only the objects we need (only one could maximally be ignored)
|
||||
water = ignore != 2 ? traceWater(ro, rd) : 9.0;
|
||||
attractor = ignore != 3 ? traceAttractor(ro, rd) : 9.0;
|
||||
terrain = ignore != 1 ? traceTerrain(ro, rd, min(0.5, 0.002+min(water, attractor))) : 9.0;
|
||||
|
||||
// auto detail level reducing (common dude, give the GPU some breathing room)
|
||||
gf_DetailLevel /= 20;
|
||||
|
||||
// find the nearest distance
|
||||
minDist = min(terrain, min(water, min(attractor, 9.0)));
|
||||
|
||||
// we hit nothing or the hitpoint is too far
|
||||
if (minDist == 9)
|
||||
return vec4(0);
|
||||
|
||||
// calculate the hit/voxel position
|
||||
vec3 hitPos = ro + rd * minDist;
|
||||
|
||||
// check what we might have hit
|
||||
if (minDist == terrain)
|
||||
return vec4(hitPos, 1);
|
||||
if (minDist == water)
|
||||
return vec4(hitPos, 2);
|
||||
if (minDist == attractor)
|
||||
return vec4(hitPos, 3);
|
||||
|
||||
// Panic, worry, die to death! Probably we'll land on the moon (this should never happen)
|
||||
//return vec4(0);
|
||||
}
|
||||
|
||||
|
||||
// Entrypoint for color calculation
|
||||
vec3 shadeRefl(vec4 hitPoint, vec3 newRo, vec3 rd)
|
||||
{
|
||||
// determine the fog color for this very precise point in the space time continuum
|
||||
vec3 myFog = newRo.y < eps ? waterColor : shadeSky(ro, rd);
|
||||
|
||||
// generate the distance value for the fog calculation
|
||||
float distance = clamp(length(hitPoint.xyz - newRo) * (ro.y <= 0 ? 4 : 2), 0.0, 1.0);
|
||||
|
||||
// get the color of the hit object and mix it with the fog
|
||||
// in most cases we allow further raytracing here (not for the terrain, its not shiny enough)
|
||||
if (hitPoint.w == 1)
|
||||
return mix(shadeTerrain(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 2)
|
||||
return mix(shadeWaterRefl(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 3)
|
||||
return mix(
|
||||
// Our amiga ball is shiny so reflect the scene!
|
||||
mix(shadeAttractor(hitPoint.xyz, rd), shade(traceRay(hitPoint.xyz, reflect(rd, normalize(hitPoint.xyz - spherePos)), 3), hitPoint.xyz, rd), 0.5)
|
||||
, myFog, distance);
|
||||
|
||||
return shadeSky(newRo, rd);
|
||||
}
|
||||
|
||||
|
||||
// Get the color from the object we just hit (without further raytraces)
|
||||
// this is necessary because no recursion is allowed in GLSL (damn you!)
|
||||
vec3 shade(vec4 hitPoint, vec3 newRo, vec3 rd)
|
||||
{
|
||||
// determine the fog color for the very same point we discussed earlier
|
||||
vec3 myFog = newRo.y < eps ? waterColor : shadeSky(ro, rd);
|
||||
|
||||
// generate the other distance value. Paid attention? If you don't know what value I'm talking about, rtfm or gtfo.
|
||||
float distance = clamp(length(hitPoint.xyz - newRo) * (ro.y <= 0 ? 4 : 2), 0.0, 1.0);
|
||||
|
||||
// get the color of the hit object and mix it with the fog
|
||||
if (hitPoint.w == 1)
|
||||
return mix(shadeTerrain(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 2)
|
||||
return mix(waterColor, myFog, distance);
|
||||
if (hitPoint.w == 3)
|
||||
return mix(shadeAttractor(hitPoint.xyz, rd), myFog, distance);
|
||||
|
||||
return myFog;
|
||||
}
|
||||
|
||||
// Now we're just being copycats. We're not creative enough to define own entry points
|
||||
// Sure, we could "#define MYENTRYPOINT main"! Or just void main(){MyEntryPoint();}
|
||||
// None of that would help us win the compo, would it?
|
||||
void main()
|
||||
{
|
||||
// Set the quality setting for the raymarcher, a higher value results in a longer processing time
|
||||
// try to find a good balance between these two, low values wivoronoill result in a wobbling endresult
|
||||
// low quality = 50.0 (visual results are ok at 640x480)
|
||||
// mid quality = 100.0
|
||||
// high quality = 200.0
|
||||
gf_DetailLevel = 100;
|
||||
|
||||
// Give our saviour global variables some life!
|
||||
pi = 3.1416;
|
||||
interlacing = vec3(1.2, 0.9, 0.9);
|
||||
eps = 0.0001;
|
||||
bigeps = 0.01;
|
||||
|
||||
// Nifty random number generator gets initialized
|
||||
float seed = 10;
|
||||
|
||||
// Determine the scene we're in
|
||||
int scene = int(Y.x);
|
||||
|
||||
// Get the look direction for the current pixel (always look forwards)
|
||||
rd = vec3((Z.xy - 0.5), 1);
|
||||
|
||||
float tex = texture2D(V, clamp(Z.xy, 0.0, 1.0), 1.0).x;
|
||||
gl_FragColor = vec4(tex, tex, tex, 1);
|
||||
return;
|
||||
|
||||
// Merry-go-round on a boat (yeah, this makes no sense. Go watch the intro and see for yourself)
|
||||
if (scene > 22 && scene < 27)
|
||||
{
|
||||
seed = min(1.0, sin((Y.x-23)*pi*0.25)*12);
|
||||
ro = vec3(0.12, 0.005, Y.x*0.08);
|
||||
rd = vec3(gl_ModelViewMatrix * vec4(rd, 1));
|
||||
rd.y += 0.1*cos(Y.x*4);
|
||||
}
|
||||
// Intermezzo: Dolphin like animation inside and outside the water, chasing that amiga ball!
|
||||
else if (scene > 14 && scene < 23)
|
||||
{
|
||||
seed = min(1.0, sin((Y.x-15)*pi*0.125)*24);
|
||||
rd += vec3(0,0.1*cos(Y.x*4), 0);
|
||||
ro = vec3(0.08, 0.01*sin(Y.x*4)+0.002, Y.x*0.11);
|
||||
}
|
||||
// Intro and Outro: Show still scenes
|
||||
else
|
||||
{
|
||||
// Get a random initial position for our camera
|
||||
ro = vec3(0.1,0.004,0.0) + vec3(0.1,0.005,20)
|
||||
*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)));
|
||||
|
||||
// Basing on the initial position, choose some "random" start and end points nearby
|
||||
ro = mix(
|
||||
ro+vec3(0.008)*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++))),
|
||||
ro+vec3(0.008)*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++))),
|
||||
// and move the camera!
|
||||
Y.x-scene);
|
||||
|
||||
// We adjust the height of the camera to the terrain height
|
||||
ro.y += height(ro.xz)+0.02;
|
||||
|
||||
// Deviate the camera position in the direction of the normal of the underlying terrain
|
||||
ro += 0.02*getTerrainNormal(ro);
|
||||
|
||||
// Reusing a float variable here, this controls the scene fade in / fade out animation
|
||||
seed = min(1.0, step(-28.0, -Y.x) * sin((Y.x-scene)*pi)*3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
rd = normalize(rd);
|
||||
|
||||
// Now boot the amiga workbench (erm, no...)
|
||||
// mantain a relative distance to the camera
|
||||
if (scene > 22 && scene < 27)
|
||||
spherePos = ro + 0.1 * vec3(gl_ModelViewMatrix * vec4(0, 0, 1, 1));
|
||||
else
|
||||
spherePos = ro + 0.02 * vec3(sin(Y.x), 0, 5+cos(Y.x));
|
||||
|
||||
spherePos.y += 0.01 + height(spherePos.xz); // mantain a relative height to the underlying terrain
|
||||
sphereRadius = scene < 14 ? 0.0 : bigeps * 0.5 + bigeps * Y.z; // The amiga ball is bigger when the snare drum is hit!
|
||||
spherePos += 2*sphereRadius * getTerrainNormal(spherePos); // deviate according to the underlying terrain's normal
|
||||
|
||||
// Make our world pretty and worthy to live in (you can cultivate algae and eat them, they're surely enough for survival)
|
||||
lightDir = normalize(vec3(0.78, 0.12 + Y.x*.2, -0.18));
|
||||
lightColor = vec3(2.4, 2.0, 1.0) + Y.x*.5;
|
||||
waterColor = mix(vec3(0.4, 0.33, 0.4), vec3(0.4, 0.5, 0.6), Y.x);
|
||||
|
||||
// Our GPU feels good underwater, almost like a refreshing experience :) cool, eh?
|
||||
if (ro.y <= 0)
|
||||
{
|
||||
// Less work to do...
|
||||
gf_DetailLevel *= 0.75;
|
||||
|
||||
// ...and a cozy darker atmosphere
|
||||
lightColor *= 0.8;
|
||||
}
|
||||
|
||||
// Here we go, shoot'em rays and get the color of our fragment!
|
||||
vec4 hit = traceRay(ro, rd, 0);
|
||||
vec3 color = shadeRefl(hit, ro, rd);
|
||||
|
||||
// Underwater there are beams of light emanating from god (so called "god" rays...)
|
||||
// ...this prooves that god is nothing less than a water surface.
|
||||
if (ro.y <= 0)
|
||||
color = godrays(ro, rd, length(hit.xyz-ro), color);
|
||||
|
||||
// Apply post processing and fade effects to the color, and finally return it.
|
||||
gl_FragColor.xyz = color;
|
||||
}
|
||||
557
underwater4k/fragment.glsl_3_dbg
Normal file
557
underwater4k/fragment.glsl_3_dbg
Normal file
@@ -0,0 +1,557 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const int shader= 3;
|
||||
|
||||
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
varying vec4 Y;
|
||||
|
||||
// Position of the fragment
|
||||
varying vec2 Z;
|
||||
|
||||
uniform sampler2D V;
|
||||
uniform sampler2D HEIGHT;
|
||||
|
||||
// Forward declarations
|
||||
vec4 traceRay(vec3 ro, vec3 rd, int ignore);
|
||||
vec3 shade(vec4 hitPoint, vec3 newRo, vec3 rd);
|
||||
|
||||
|
||||
// All data of our world
|
||||
vec3 spherePos, lightDir, lightColor, waterColor, ro, rd, interlacing;
|
||||
float sphereRadius, gf_DetailLevel, pi, eps, bigeps;
|
||||
|
||||
|
||||
// Pseudo random number base generator (credits go to iq/rgba)
|
||||
float rnd(vec2 x)
|
||||
{
|
||||
int n = int(x.x * 40 + x.y * 6400);
|
||||
n = (n << 13) ^ n;
|
||||
return 1 - float( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824;
|
||||
}
|
||||
|
||||
|
||||
// Generate cubic interpolated random values
|
||||
float smoothrnd(vec2 x)
|
||||
{
|
||||
x = mod(x,1000.0);
|
||||
vec2 a = fract(x);
|
||||
x -= a;
|
||||
vec2 u = a*a*(3.0-2.0*a);
|
||||
return mix(
|
||||
mix(rnd(x+vec2(0,0)),rnd(x+vec2(1,0)), u.x),
|
||||
mix(rnd(x+vec2(0,1)),rnd(x+vec2(1,1)), u.x), u.y);
|
||||
}
|
||||
|
||||
|
||||
// Convert the cipher range from [-1,1] to [0,1]
|
||||
float norm(float x)
|
||||
{
|
||||
return x * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
return (0.01 + ((.25*texture2D(V, p * 128.0).x) + texture2D(V, p * 32.0).x)) * smoothstep(0.25, 0.35, texture2D(V, p * 11).y * texture2D(V, p * 13).y);
|
||||
}
|
||||
|
||||
float texnoise(vec2 p)
|
||||
{
|
||||
return texture2D(V, p).y;
|
||||
}
|
||||
|
||||
float grass(vec2 p)
|
||||
{
|
||||
return texnoise(p * 57) * texnoise(p * 13) * 2.0;
|
||||
}
|
||||
|
||||
// Our heightmap calculation function, we could use some perlin noise here if it wouldn't be so performance killing
|
||||
float height(vec2 x)
|
||||
{
|
||||
return texture2D(HEIGHT, x).x;
|
||||
}
|
||||
|
||||
|
||||
// Gets the terrain normal
|
||||
vec3 getTerrainNormal(vec3 p)
|
||||
{
|
||||
return normalize(vec3(
|
||||
height(p.xz - vec2(bigeps, 0)) - height(p.xz + vec2(bigeps, 0)),
|
||||
2 * bigeps,
|
||||
height(p.xz - vec2(0, bigeps)) - height(p.xz + vec2(0, bigeps))));
|
||||
}
|
||||
|
||||
|
||||
// Global diffuse lighting formula
|
||||
vec3 diffuseLight(vec3 incolor, float shadow, vec3 normal)
|
||||
{
|
||||
return (0.3 + shadow * 0.7 * max(dot(normal, lightDir), 0.0)) * lightColor * incolor;
|
||||
}
|
||||
|
||||
|
||||
// Calculates the water "waves". To reduce the bumpiness, increment the y-axis
|
||||
vec3 getWaterNormal(vec3 p)
|
||||
{
|
||||
return normalize(vec3(
|
||||
texnoise(p.xz * 40 + Y.x*.5)*2-1,
|
||||
8,
|
||||
texnoise(p.xz * 80 - Y.x*.25)*2-1));
|
||||
}
|
||||
|
||||
|
||||
float caustic(vec3 p)
|
||||
{
|
||||
vec2 q = p.xz * (1 - p.y * .01);
|
||||
float noiseX = texnoise(q * .125 * (.05*Y.x+vec2(2,3)));
|
||||
float noiseY = texnoise(q * .125 * (.05*Y.x+vec2(4,5)));
|
||||
q = mod(q * 10.0 + vec2(noiseX, noiseY) * 16.0, 1.0);
|
||||
q -= step(0.5, q) * 2 * (q - 0.5);
|
||||
q *= 2;
|
||||
return max(pow(q.x, 4.0 + 4.0 * noiseX), pow(q.y, 4.0 + 4.0 * noiseX));
|
||||
}
|
||||
|
||||
float caustics(vec3 p)
|
||||
{
|
||||
return caustic(p * 31) * caustic(p * 17);
|
||||
}
|
||||
|
||||
// Our fake godray effect (bad if moving fast, but awesome any other time)
|
||||
vec3 godrays(vec3 ro, vec3 rd, float maxt, vec3 color)
|
||||
{
|
||||
const int iterations = 16;
|
||||
float dt = 0.001, t = 0;
|
||||
float cs = 0.0;
|
||||
for (int i = 0; i < iterations; ++i)
|
||||
{
|
||||
vec3 p = ro + rd * t;
|
||||
vec2 q = p.xz * (1 - p.y * .4);
|
||||
|
||||
float shadow = 1.0-step(1,traceRay(p, lightDir, 2).w);
|
||||
cs = max(cs, (1 + p.y * 8) * shadow * smoothstep(0.4, 0.7, texnoise(q * 64)) / (1+t*2));
|
||||
t += dt;
|
||||
}
|
||||
return color + pow(cs, 4.0) * lightColor * .1;
|
||||
}
|
||||
|
||||
// Calculate the terrain color for the given voxel
|
||||
vec3 shadeTerrain(vec3 p, vec3 rd)
|
||||
{
|
||||
vec3 n = getTerrainNormal(p);
|
||||
float vrn = voronoi(p.xz);
|
||||
vec3 grassColor = vec3(0.8, 0.85, 0.4) * 1.5 * grass(p.xz);
|
||||
vec3 dirtColor = vec3(0.65, 0.6, 0.4) * (.5+grass(p.xz));
|
||||
vec3 stoneColor = vec3(0.5, 0.5, 0.4) * (.5+grass(p.xz));
|
||||
float groundFactor = smoothstep(0.7, 0.8, n.y) * (1.0 - step(p.y, texnoise(p.xz*128)*0.01-0.003)); // shore
|
||||
float dirtFactor = smoothstep(0.4, 0.6, texture2D(V, p.xz * 40).y);
|
||||
vec3 ground = mix(mix(stoneColor, dirtColor, dirtFactor), grassColor, groundFactor);
|
||||
|
||||
vec3 rockColor = vec3(0.5, 0.5, 0.5) * (.75 + vrn) * (.75+.5*grass(p.xz * 8));
|
||||
vec3 color = mix(ground, rockColor, smoothstep(0.0, 0.05,vrn));
|
||||
|
||||
float shadow = 1.0-step(1,traceRay(p + n * 0.005, lightDir, 2).w);
|
||||
|
||||
if (p.y <= 0)
|
||||
color = max(0.0, 0.7 + 8 * p.y) * (color + lightColor * shadow * max(0, 1 + 32 * p.y) * caustics(p));
|
||||
else
|
||||
color *= 0.6+0.4*min(1.0, p.y * 999.0);
|
||||
|
||||
color = color * (.5+.5*vrn);
|
||||
return diffuseLight(color, shadow, n);
|
||||
}
|
||||
|
||||
|
||||
// Create a blueish sky transition from navy blue to badass dark blue
|
||||
vec3 shadeSky(vec3 ro, vec3 rd)
|
||||
{
|
||||
vec3 farColor = vec3(0.0, 0.0, 0.4);
|
||||
return mix(waterColor, farColor, max(0, rd.y))
|
||||
+ 0.25*lightColor * pow(max(0, dot(rd, lightDir)), 4)
|
||||
+ lightColor * pow(max(0, dot(rd, lightDir)), 1000);
|
||||
}
|
||||
|
||||
|
||||
// Calculates the refraction and reflection of the water surface.
|
||||
// Also mixes both values by the depth of the water and the fresnel term.
|
||||
// Possible improvements: fix fake underwater reflection and refraction
|
||||
vec3 shadeWaterRefl(vec3 p, vec3 newrd)
|
||||
{
|
||||
vec3 waterNormal = getWaterNormal(p);
|
||||
|
||||
// perform raytracing/raymarching for both reflection and refraction
|
||||
// calc the water refraction, the refraction index (0.9) will decrease with the distance to allow a better over/under water transition
|
||||
vec3 refrd = mix(newrd, refract(newrd, waterNormal, 0.9), step(0.0, ro.y));
|
||||
vec4 refracted = traceRay(p, refrd, 2);//mix(0.9, 1.0, smoothstep(0.01, 0.0, length(p-ro)))), 2);
|
||||
|
||||
// calculate the depth factor (water entry point to terrain voxel) (black magic involved here!)
|
||||
float depth = clamp(pow(1.03 * (1 - length(refracted.xyz - p)), 16.0), 0.0, 1.0);
|
||||
|
||||
float shadow = 0.9 + 0.1 * (1.0-step(1,traceRay(p + waterNormal * 0.005, lightDir, 2).w));
|
||||
float fresnel = pow(clamp(abs(-rd.y), 0.0, 1.0),1.8);
|
||||
// Finally stir the pot =)
|
||||
return shadow * mix(
|
||||
shadeSky(p, refrd), // Water color
|
||||
mix(
|
||||
shade(traceRay(p, reflect(newrd, waterNormal), 2), p, newrd), // Reflection color
|
||||
shade(refracted, p, newrd), // Refraction color
|
||||
fresnel), // fresnel term
|
||||
pow(depth, 0.5)); // water color contribution
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Texture our "AMIGAAAAAAA!!" ball
|
||||
vec3 shadeAttractor(vec3 p, vec3 rd)
|
||||
{
|
||||
vec3 n,color;
|
||||
|
||||
// get the sphere normal, first
|
||||
n = normalize(p - spherePos);
|
||||
|
||||
// now calculate the texture coordinates
|
||||
vec2 uv = 0.5 + 0.5 * vec2(atan(n.z, n.x), acos(n.y)) / pi;
|
||||
|
||||
// We'll animate our x-texture coordinate with the time, this gives the impression of a rotating ball
|
||||
uv.x -= Y.x;
|
||||
|
||||
// This spell will convert any dull ball into an amiga ball, caution is advised.
|
||||
color = mix(vec3(1), vec3(1, 0, 0), mod(step(fract(uv.x * 6), 0.5) + step(fract(uv.y * 6), 0.5), 2.0));
|
||||
|
||||
return diffuseLight(color, 1, n)
|
||||
+ pow(max(dot(n, normalize(lightDir - rd)), 0.0), 33.0) * lightColor; // specular light spot
|
||||
}
|
||||
|
||||
#define INTERVAL_ITERS 5
|
||||
#define LINEAR_ACCURACY 0.5
|
||||
|
||||
// Raymarch the terrain function, returns the distance from the ray origin to the terrain voxel
|
||||
// This function was originally adopted from an implementation by iq/rgba
|
||||
float traceTerrain(vec3 ro, vec3 rd, float maxt)
|
||||
{
|
||||
float samplePosY, h, prevt, t;
|
||||
vec3 samplePos;
|
||||
|
||||
// advance our sample position from our nearplane to our farplane
|
||||
for (t = 0; t < maxt;)
|
||||
{
|
||||
// advance our ray
|
||||
samplePos = ro + rd * t;
|
||||
samplePosY = samplePos.y;
|
||||
|
||||
// get the height at the given sample 2d (!) position (we could enhance this by sampling a voxel and returning only the distance to the voxel)
|
||||
h = height(samplePos.xz);
|
||||
float dist = samplePosY - h;
|
||||
if (dist < 0.0) break;
|
||||
|
||||
prevt = t;
|
||||
|
||||
if (dist > 0.0001)
|
||||
t += max(dist * 1.4, 0.0001) * LINEAR_ACCURACY;
|
||||
else
|
||||
t += max(dist, 0.00001) * LINEAR_ACCURACY;
|
||||
}
|
||||
|
||||
if (samplePosY <= h)
|
||||
{
|
||||
/// Interval mapping
|
||||
float before = prevt;
|
||||
vec3 beforePos = ro + rd * before;
|
||||
float beforeH = height(beforePos.xz);
|
||||
|
||||
float after = t;
|
||||
vec3 afterPos = ro + rd * after;
|
||||
float afterH = height(afterPos.xz);
|
||||
|
||||
for (int i = 0; i < INTERVAL_ITERS; i++)
|
||||
{
|
||||
float interval = after - before;
|
||||
float deltaL = beforeH - afterH;
|
||||
float deltaR = rd.y * interval;
|
||||
|
||||
float curt = (beforeH * interval - deltaL * before) / (deltaR - deltaL);
|
||||
if (curt <= before - 0.000001 || curt >= after + 0.000001) break;
|
||||
|
||||
samplePos = ro + rd * curt;
|
||||
float h = height(samplePos.xz);
|
||||
|
||||
if (h <= samplePos.y)
|
||||
{
|
||||
beforeH = h;
|
||||
before = curt;
|
||||
t = curt;
|
||||
}
|
||||
else
|
||||
{
|
||||
afterH = h;
|
||||
after = curt;
|
||||
t = curt;
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// we hit nothing
|
||||
return 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Ray vs. sphere intersection function
|
||||
float traceAttractor(vec3 ro, vec3 rd)
|
||||
{
|
||||
vec3 dst = ro - spherePos;
|
||||
float B,D;
|
||||
B = dot(dst, rd);
|
||||
if (B > 0)
|
||||
return 9.0;
|
||||
D = B*B - dot(dst, dst) + sphereRadius*sphereRadius;
|
||||
if (D > 0)
|
||||
{
|
||||
return -B - sqrt(D);
|
||||
}
|
||||
return 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Ray vs. plane intersection function
|
||||
float traceWater(vec3 ro, vec3 rd)
|
||||
{
|
||||
float tPlane = -ro.y / rd.y;
|
||||
return tPlane >= eps ? tPlane : 9.0;
|
||||
}
|
||||
|
||||
|
||||
// Raytracing entry point, returns voxel and object ID
|
||||
// IDs:
|
||||
// 0 = sky (not the armageddon, xTr1m!!)
|
||||
// 1 = terrain
|
||||
// 2 = water
|
||||
// 3 = attractive amiga ball (you have never seen such a sexy amiga ball before, admit it!)
|
||||
vec4 traceRay(vec3 ro, vec3 rd, int ignore)
|
||||
{
|
||||
float water, attractor, terrain, minDist;
|
||||
|
||||
// trace only the objects we need (only one could maximally be ignored)
|
||||
water = ignore != 2 ? traceWater(ro, rd) : 9.0;
|
||||
attractor = ignore != 3 ? traceAttractor(ro, rd) : 9.0;
|
||||
terrain = ignore != 1 ? traceTerrain(ro, rd, min(0.5, 0.002+min(water, attractor))) : 9.0;
|
||||
|
||||
// auto detail level reducing (common dude, give the GPU some breathing room)
|
||||
gf_DetailLevel /= 20;
|
||||
|
||||
// find the nearest distance
|
||||
minDist = min(terrain, min(water, min(attractor, 9.0)));
|
||||
|
||||
// we hit nothing or the hitpoint is too far
|
||||
if (minDist == 9)
|
||||
return vec4(0);
|
||||
|
||||
// calculate the hit/voxel position
|
||||
vec3 hitPos = ro + rd * minDist;
|
||||
|
||||
// check what we might have hit
|
||||
if (minDist == terrain)
|
||||
return vec4(hitPos, 1);
|
||||
if (minDist == water)
|
||||
return vec4(hitPos, 2);
|
||||
if (minDist == attractor)
|
||||
return vec4(hitPos, 3);
|
||||
|
||||
// Panic, worry, die to death! Probably we'll land on the moon (this should never happen)
|
||||
//return vec4(0);
|
||||
}
|
||||
|
||||
|
||||
// Entrypoint for color calculation
|
||||
vec3 shadeRefl(vec4 hitPoint, vec3 newRo, vec3 rd)
|
||||
{
|
||||
// determine the fog color for this very precise point in the space time continuum
|
||||
vec3 myFog = newRo.y < eps ? waterColor : shadeSky(ro, rd);
|
||||
|
||||
// generate the distance value for the fog calculation
|
||||
float distance = clamp(length(hitPoint.xyz - newRo) * (ro.y <= 0 ? 4 : 2), 0.0, 1.0);
|
||||
|
||||
// get the color of the hit object and mix it with the fog
|
||||
// in most cases we allow further raytracing here (not for the terrain, its not shiny enough)
|
||||
if (hitPoint.w == 1)
|
||||
return mix(shadeTerrain(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 2)
|
||||
return mix(shadeWaterRefl(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 3)
|
||||
return mix(
|
||||
// Our amiga ball is shiny so reflect the scene!
|
||||
mix(shadeAttractor(hitPoint.xyz, rd), shade(traceRay(hitPoint.xyz, reflect(rd, normalize(hitPoint.xyz - spherePos)), 3), hitPoint.xyz, rd), 0.5)
|
||||
, myFog, distance);
|
||||
|
||||
return shadeSky(newRo, rd);
|
||||
}
|
||||
|
||||
|
||||
// Get the color from the object we just hit (without further raytraces)
|
||||
// this is necessary because no recursion is allowed in GLSL (damn you!)
|
||||
vec3 shade(vec4 hitPoint, vec3 newRo, vec3 rd)
|
||||
{
|
||||
// determine the fog color for the very same point we discussed earlier
|
||||
vec3 myFog = newRo.y < eps ? waterColor : shadeSky(ro, rd);
|
||||
|
||||
// generate the other distance value. Paid attention? If you don't know what value I'm talking about, rtfm or gtfo.
|
||||
float distance = clamp(length(hitPoint.xyz - newRo) * (ro.y <= 0 ? 4 : 2), 0.0, 1.0);
|
||||
|
||||
// get the color of the hit object and mix it with the fog
|
||||
if (hitPoint.w == 1)
|
||||
return mix(shadeTerrain(hitPoint.xyz, rd), myFog, distance);
|
||||
if (hitPoint.w == 2)
|
||||
return mix(waterColor, myFog, distance);
|
||||
if (hitPoint.w == 3)
|
||||
return mix(shadeAttractor(hitPoint.xyz, rd), myFog, distance);
|
||||
|
||||
return myFog;
|
||||
}
|
||||
|
||||
// Now we're just being copycats. We're not creative enough to define own entry points
|
||||
// Sure, we could "#define MYENTRYPOINT main"! Or just void main(){MyEntryPoint();}
|
||||
// None of that would help us win the compo, would it?
|
||||
void main()
|
||||
{
|
||||
// Set the quality setting for the raymarcher, a higher value results in a longer processing time
|
||||
// try to find a good balance between these two, low values wivoronoill result in a wobbling endresult
|
||||
// low quality = 50.0 (visual results are ok at 640x480)
|
||||
// mid quality = 100.0
|
||||
// high quality = 200.0
|
||||
gf_DetailLevel = 100;
|
||||
|
||||
// Give our saviour global variables some life!
|
||||
pi = 3.1416;
|
||||
interlacing = vec3(1.2, 0.9, 0.9);
|
||||
eps = 0.0001;
|
||||
bigeps = 0.01;
|
||||
|
||||
// Nifty random number generator gets initialized
|
||||
float seed = 10;
|
||||
|
||||
// Determine the scene we're in
|
||||
int scene = int(Y.x);
|
||||
|
||||
// Get the look direction for the current pixel (always look forwards)
|
||||
rd = vec3((Z.xy - 0.5), 1);
|
||||
|
||||
float tex = texture2D(V, clamp(Z.xy, 0.0, 1.0), 1.0).x;
|
||||
gl_FragColor = vec4(tex, tex, tex, 1);
|
||||
return;
|
||||
|
||||
// Merry-go-round on a boat (yeah, this makes no sense. Go watch the intro and see for yourself)
|
||||
if (scene > 22 && scene < 27)
|
||||
{
|
||||
seed = min(1.0, sin((Y.x-23)*pi*0.25)*12);
|
||||
ro = vec3(0.12, 0.005, Y.x*0.08);
|
||||
rd = vec3(gl_ModelViewMatrix * vec4(rd, 1));
|
||||
rd.y += 0.1*cos(Y.x*4);
|
||||
}
|
||||
// Intermezzo: Dolphin like animation inside and outside the water, chasing that amiga ball!
|
||||
else if (scene > 14 && scene < 23)
|
||||
{
|
||||
seed = min(1.0, sin((Y.x-15)*pi*0.125)*24);
|
||||
rd += vec3(0,0.1*cos(Y.x*4), 0);
|
||||
ro = vec3(0.08, 0.01*sin(Y.x*4)+0.002, Y.x*0.11);
|
||||
}
|
||||
// Intro and Outro: Show still scenes
|
||||
else
|
||||
{
|
||||
// Get a random initial position for our camera
|
||||
ro = vec3(0.1,0.004,0.0) + vec3(0.1,0.005,20)
|
||||
*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)));
|
||||
|
||||
// Basing on the initial position, choose some "random" start and end points nearby
|
||||
ro = mix(
|
||||
ro+vec3(0.008)*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++))),
|
||||
ro+vec3(0.008)*vec3(rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++)), rnd(vec2(scene, seed++))),
|
||||
// and move the camera!
|
||||
Y.x-scene);
|
||||
|
||||
// We adjust the height of the camera to the terrain height
|
||||
ro.y += height(ro.xz)+0.02;
|
||||
|
||||
// Deviate the camera position in the direction of the normal of the underlying terrain
|
||||
ro += 0.02*getTerrainNormal(ro);
|
||||
|
||||
// Reusing a float variable here, this controls the scene fade in / fade out animation
|
||||
seed = min(1.0, step(-28.0, -Y.x) * sin((Y.x-scene)*pi)*3);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//Debugzeug fuer Kamerasteuerung
|
||||
{
|
||||
ro.x= gl_ModelViewMatrix[0][0];
|
||||
ro.y= gl_ModelViewMatrix[0][1];
|
||||
ro.z= gl_ModelViewMatrix[0][2];
|
||||
|
||||
float a1= gl_ModelViewMatrix[1][1];
|
||||
float c1,s1;vec3 q1= vec3((Z.xy - 0.5), 0.8);
|
||||
c1 = cos(a1); s1 = sin(a1);
|
||||
rd.y = c1 * q1.y - s1 * q1.z;
|
||||
rd.x= q1.x;
|
||||
rd.z = s1 * q1.y + c1 * q1.z;
|
||||
|
||||
a1= gl_ModelViewMatrix[1][0];
|
||||
q1=rd;
|
||||
c1 = cos(a1); s1 = sin(a1);
|
||||
rd.x = c1 * q1.x + s1 * q1.z;
|
||||
rd.z = -s1 * q1.x + c1 * q1.z;
|
||||
|
||||
}
|
||||
//Ende Debugzeug fuer Kamerasteuerung
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
rd = normalize(rd);
|
||||
|
||||
// Now boot the amiga workbench (erm, no...)
|
||||
// mantain a relative distance to the camera
|
||||
if (scene > 22 && scene < 27)
|
||||
spherePos = ro + 0.1 * vec3(gl_ModelViewMatrix * vec4(0, 0, 1, 1));
|
||||
else
|
||||
spherePos = ro + 0.02 * vec3(sin(Y.x), 0, 5+cos(Y.x));
|
||||
|
||||
spherePos.y += 0.01 + height(spherePos.xz); // mantain a relative height to the underlying terrain
|
||||
sphereRadius = scene < 14 ? 0.0 : bigeps * 0.5 + bigeps * Y.z; // The amiga ball is bigger when the snare drum is hit!
|
||||
spherePos += 2*sphereRadius * getTerrainNormal(spherePos); // deviate according to the underlying terrain's normal
|
||||
|
||||
// Make our world pretty and worthy to live in (you can cultivate algae and eat them, they're surely enough for survival)
|
||||
lightDir = normalize(vec3(0.78, 0.12 + Y.x*.2, -0.18));
|
||||
lightColor = vec3(2.4, 2.0, 1.0) + Y.x*.5;
|
||||
waterColor = mix(vec3(0.4, 0.33, 0.4), vec3(0.4, 0.5, 0.6), Y.x);
|
||||
|
||||
// Our GPU feels good underwater, almost like a refreshing experience :) cool, eh?
|
||||
if (ro.y <= 0)
|
||||
{
|
||||
// Less work to do...
|
||||
gf_DetailLevel *= 0.75;
|
||||
|
||||
// ...and a cozy darker atmosphere
|
||||
lightColor *= 0.8;
|
||||
}
|
||||
|
||||
// Here we go, shoot'em rays and get the color of our fragment!
|
||||
vec4 hit = traceRay(ro, rd, 0);
|
||||
vec3 color = shadeRefl(hit, ro, rd);
|
||||
|
||||
// Underwater there are beams of light emanating from god (so called "god" rays...)
|
||||
// ...this prooves that god is nothing less than a water surface.
|
||||
if (ro.y <= 0)
|
||||
color = godrays(ro, rd, length(hit.xyz-ro), color);
|
||||
|
||||
// Apply post processing and fade effects to the color, and finally return it.
|
||||
gl_FragColor.xyz = color;
|
||||
}
|
||||
211
underwater4k/fragment_small.h
Normal file
211
underwater4k/fragment_small.h
Normal file
@@ -0,0 +1,211 @@
|
||||
/* File generated with Shader Minifier 1.1.1
|
||||
* http://www.ctrl-alt-test.fr
|
||||
*/
|
||||
#ifndef FRAGMENT_SMALL_H_
|
||||
# define FRAGMENT_SMALL_H_
|
||||
# define V_Y "v"
|
||||
# define V_Z "x"
|
||||
|
||||
char fragment_glsl_0[] = ""
|
||||
"const int m=0;"
|
||||
"varying vec4 v;"
|
||||
"varying vec2 x;"
|
||||
"vec3 r,i,z,f,s,y,w;"
|
||||
"float e,c,a,n,p;"
|
||||
"float t(vec2 v)"
|
||||
"{"
|
||||
"int i=int(v.x*40+v.y*6400);"
|
||||
"i=i<<13^i;"
|
||||
"return 1-float(i*(i*i*15731+789221)+1376312589&2147483647)/1073741824;"
|
||||
"}"
|
||||
"float d(vec2 v)"
|
||||
"{"
|
||||
"v=mod(v,1000.);"
|
||||
"vec2 x=fract(v);"
|
||||
"v-=x;"
|
||||
"vec2 s=x*x*(3.-2.*x);"
|
||||
"return mix(mix(t(v+vec2(0,0)),t(v+vec2(1,0)),s.x),mix(t(v+vec2(0,1)),t(v+vec2(1,1)),s.x),s.y);"
|
||||
"}"
|
||||
"float g(float x)"
|
||||
"{"
|
||||
"return x*.5+.5;"
|
||||
"}"
|
||||
"float d(float s,float z,float x)"
|
||||
"{"
|
||||
"float m=(g(sin(a*2*(s+z+v.x*x)))+g(sin(a*(z-s-v.x*x)))+g(sin(a*(z+v.x*x)))+g(sin(a*3*(s-v.x*x))))*.3;"
|
||||
"return pow(m,2.);"
|
||||
"}"
|
||||
"vec3 h(vec3 x)"
|
||||
"{"
|
||||
"int v=int(mod(gl_FragCoord.x,3.));"
|
||||
"if(v==0)"
|
||||
"x*=w.xyz;"
|
||||
"if(v==1)"
|
||||
"x*=w.yzx;"
|
||||
"if(v==2)"
|
||||
"x*=w.zxy;"
|
||||
"return x;"
|
||||
"}"
|
||||
"vec3 o(vec3 v)"
|
||||
"{"
|
||||
"vec2 m=x*2-1;"
|
||||
"float y=m.x*(m.y+3);"
|
||||
"return v+z*d(y+50*s.x,y+50*s.z,1.5)*g(m.y)*min(-s.y*30,.3);"
|
||||
"}"
|
||||
"float l(vec2 v)"
|
||||
"{"
|
||||
"return-.035+pow(d(v.x*10,v.y*10,0.)*2-1,2.)*.05-(v.x-.1)*.2;"
|
||||
"}"
|
||||
"vec3 u(vec3 v)"
|
||||
"{"
|
||||
"return normalize(vec3(l(v.xz-vec2(p,0))-l(v.xz+vec2(p,0)),2*p,l(v.xz-vec2(0,p))-l(v.xz+vec2(0,p))));"
|
||||
"}"
|
||||
"vec3 d(vec3 v,vec3 s)"
|
||||
"{"
|
||||
"return(.3+.7*max(dot(s,i),0.))*z*v;"
|
||||
"}"
|
||||
"vec3 M(vec3 v)"
|
||||
"{"
|
||||
"return normalize(vec3(d(v.x*160-cos(v.z*10)*12,v.z*140,4.),8,d(v.z*160-sin(v.x*10)*12,v.x*140,4.))*2-1);"
|
||||
"}"
|
||||
"vec3 M(vec3 v,vec3 x)"
|
||||
"{"
|
||||
"vec3 s=u(v),y=mix(vec3(.66,.55,.4)-.2*d(abs(v.xz*150))-.2*d(abs(v.yy+.002*d(abs(v.xz*150)))*3000),vec3(.1,.3,0)*(d(v.xz*7000.)*.4+.5),clamp(s.y*(d(v.x*111,v.z*111,0.)*.5-v.y*40),0.,1.));"
|
||||
"if(v.y<=0)"
|
||||
"y+=5*M(.8*v).x*min(.3,-v.y*8);"
|
||||
"return d(y,s);"
|
||||
"}"
|
||||
"vec3 g(vec3 v,vec3 s)"
|
||||
"{"
|
||||
"return v.y<=-n*n?f:mix(vec3(-.5,-.25,0),vec3(2),1-(s.y*.5+.5));"
|
||||
"}"
|
||||
"vec3 h(vec3 s,vec3 x)"
|
||||
"{"
|
||||
"vec3 m,y;"
|
||||
"m=normalize(s-r);"
|
||||
"vec2 f=.5+.5*vec2(atan(m.z,m.x),acos(m.y))/a;"
|
||||
"f.x-=v.x;"
|
||||
"y=mix(vec3(1),vec3(1,0,0),mod(step(fract(f.x*6),.5)+step(fract(f.y*6),.5),2.));"
|
||||
"return d(y,m)+pow(max(dot(m,normalize(i-x)),0.),33.)*z;"
|
||||
"}"
|
||||
"float M(vec3 v,vec3 x,float m)"
|
||||
"{"
|
||||
"float y,s,i,f;"
|
||||
"y=0;"
|
||||
"vec3 r=v;"
|
||||
"for(float z=0;z<m;z+=y)"
|
||||
"{"
|
||||
"r+=x*y;"
|
||||
"f=r.y;"
|
||||
"float w=l(r.xz);"
|
||||
"if(f<=w)"
|
||||
"return z-y+y*(s-i)/(f-w+s-i);"
|
||||
"s=w;"
|
||||
"i=f;"
|
||||
"y=.002+z/c;"
|
||||
"}"
|
||||
"return 9.;"
|
||||
"}"
|
||||
"float l(vec3 v,vec3 x)"
|
||||
"{"
|
||||
"vec3 s=v-r;"
|
||||
"float i,y;"
|
||||
"i=dot(s,x);"
|
||||
"if(i>0)"
|
||||
"return 9.;"
|
||||
"y=i*i-dot(s,s)+e*e;"
|
||||
"if(y>0)"
|
||||
"return-i-sqrt(y);"
|
||||
"return 9.;"
|
||||
"}"
|
||||
"float o(vec3 v,vec3 x)"
|
||||
"{"
|
||||
"float m=-v.y/x.y;"
|
||||
"return m>=n?m:9.;"
|
||||
"}"
|
||||
"vec4 g(vec3 v,vec3 x,int m)"
|
||||
"{"
|
||||
"float s,i,y,f;"
|
||||
"s=m!=2?o(v,x):9.;"
|
||||
"i=m!=3?l(v,x):9.;"
|
||||
"y=m!=1?M(v,x,min(.5,.002+min(s,i))):9.;"
|
||||
"c/=20;"
|
||||
"f=min(y,min(s,min(i,9.)));"
|
||||
"if(f==9)"
|
||||
"return vec4(0);"
|
||||
"vec3 z=v+x*f;"
|
||||
"if(f==y)"
|
||||
"return vec4(z,1);"
|
||||
"if(f==s)"
|
||||
"return vec4(z,2);"
|
||||
"if(f==i)"
|
||||
"return vec4(z,3);"
|
||||
"}"
|
||||
"vec3 h(vec4 v,vec3 x,vec3 m)"
|
||||
"{"
|
||||
"vec3 y=x.y<n?f:g(s,m);"
|
||||
"float i=clamp(length(v.xyz-x)*(s.y<=0?4:2),0.,1.);"
|
||||
"if(v.w==1)"
|
||||
"return mix(M(v.xyz,m),y,i);"
|
||||
"if(v.w==2)"
|
||||
"return mix(f,y,i);"
|
||||
"if(v.w==3)"
|
||||
"return mix(h(v.xyz,m),y,i);"
|
||||
"return y;"
|
||||
"}"
|
||||
"vec3 t(vec3 v,vec3 m)"
|
||||
"{"
|
||||
"vec3 x=M(v);"
|
||||
"vec4 i=g(v,refract(m,x,.9),2);"
|
||||
"float z=clamp(pow(1.03*(1-length(i.xyz-v)),16.),0.,1.);"
|
||||
"return mix(s.y<0?g(v,m):f,mix(h(g(v,reflect(m,x),2),v,m),h(i,v,m),clamp(-y.y+z,0.,1.)),i.w==3.?.5:pow(z,.5));"
|
||||
"}"
|
||||
"vec3 l(vec4 v,vec3 m,vec3 x)"
|
||||
"{"
|
||||
"vec3 y=m.y<n?f:g(s,x);"
|
||||
"float i=clamp(length(v.xyz-m)*(s.y<=0?4:2),0.,1.);"
|
||||
"if(v.w==1)"
|
||||
"return mix(M(v.xyz,x),y,i);"
|
||||
"if(v.w==2)"
|
||||
"return mix(t(v.xyz,x),y,i);"
|
||||
"if(v.w==3)"
|
||||
"return mix(mix(h(v.xyz,x),h(g(v.xyz,reflect(x,normalize(v.xyz-r)),3),v.xyz,x),.5),y,i);"
|
||||
"return g(m,x);"
|
||||
"}"
|
||||
"void main()"
|
||||
"{"
|
||||
"c=100;"
|
||||
"a=3.1416;"
|
||||
"w=vec3(1.2,.9,.9);"
|
||||
"n=.0001;"
|
||||
"p=.01;"
|
||||
"float m=10;"
|
||||
"int d=int(v.x);"
|
||||
"y=vec3(x.xy-.5,1);"
|
||||
"if(d>22&&d<27)"
|
||||
"m=min(1.,sin((v.x-23)*a*.25)*12),s=vec3(.12,.005,v.x*.08),y=vec3(gl_ModelViewMatrix*vec4(y,1)),y.y+=.1*cos(v.x*4);"
|
||||
"else"
|
||||
" if(d>14&&d<23)"
|
||||
"m=min(1.,sin((v.x-15)*a*.125)*24),y+=vec3(0,.1*cos(v.x*4),0),s=vec3(.08,.01*sin(v.x*4)+.002,v.x*.11);"
|
||||
"else"
|
||||
" s=vec3(.1,.004,0.)+vec3(.1,.005,20)*vec3(t(vec2(d,m++)),t(vec2(d,m++)),t(vec2(d,m++))),s=mix(s+vec3(.008)*vec3(t(vec2(d,m++)),t(vec2(d,m++)),t(vec2(d,m++))),s+vec3(.008)*vec3(t(vec2(d,m++)),t(vec2(d,m++)),t(vec2(d,m++))),v.x-d),s.y+=l(s.xz)+.02,s+=.02*u(s),m=min(1.,step(-28.,-v.x)*sin((v.x-d)*a)*3);"
|
||||
"y=normalize(y);"
|
||||
"if(d>22&&d<27)"
|
||||
"r=s+.1*vec3(gl_ModelViewMatrix*vec4(0,0,1,1));"
|
||||
"else"
|
||||
" r=s+.02*vec3(sin(v.x),0,5+cos(v.x));"
|
||||
"r.y+=.01+l(r.xz);"
|
||||
"e=d<14?0.:p*.5+p*v.z;"
|
||||
"r+=2*e*u(r);"
|
||||
"i=vec3(.58,.58,-.58);"
|
||||
"z=vec3(1.2);"
|
||||
"f=vec3(.3,.33,.4);"
|
||||
"if(s.y<=0)"
|
||||
"c*=.75,z*=.8;"
|
||||
"vec3 M=l(g(s,y,0),s,y);"
|
||||
"if(s.y<=0)"
|
||||
"M=o(M);"
|
||||
"gl_FragColor.xyz=h(m*M);"
|
||||
"}";
|
||||
|
||||
#endif // FRAGMENT_SMALL_H_
|
||||
13146
underwater4k/glext.h
Normal file
13146
underwater4k/glext.h
Normal file
File diff suppressed because it is too large
Load Diff
BIN
underwater4k/link.exe
Normal file
BIN
underwater4k/link.exe
Normal file
Binary file not shown.
28
underwater4k/linkparams.txt
Normal file
28
underwater4k/linkparams.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
/CRINKLER
|
||||
/COMPMODE:SLOW
|
||||
/ORDERTRIES:3000
|
||||
/HASHTRIES:200
|
||||
/UNSAFEIMPORT
|
||||
/TRUNCATEFLOATS:24
|
||||
/HASHSIZE:200
|
||||
/REPORT:report.html
|
||||
/RANGE:opengl32
|
||||
/TRANSFORM:CALLS
|
||||
/ENTRY:main
|
||||
/SUBSYSTEM:WINDOWS
|
||||
obj\bp4k_Compress_Slow\main_release.obj
|
||||
4klang.obj
|
||||
opengl32.lib
|
||||
winmm.lib
|
||||
kernel32.lib
|
||||
user32.lib
|
||||
gdi32.lib
|
||||
winspool.lib
|
||||
comdlg32.lib
|
||||
advapi32.lib
|
||||
shell32.lib
|
||||
ole32.lib
|
||||
oleaut32.lib
|
||||
uuid.lib
|
||||
odbc32.lib
|
||||
odbccp32.lib
|
||||
421
underwater4k/main.cpp
Normal file
421
underwater4k/main.cpp
Normal file
@@ -0,0 +1,421 @@
|
||||
#include <time.h>
|
||||
#include <io.h>
|
||||
#include <process.h>
|
||||
#include "Shaders.h"
|
||||
|
||||
HWND hWnd;
|
||||
|
||||
static const int gi_ScreenWidth = 1280;
|
||||
static const int gi_ScreenHeight = 720;
|
||||
static const int textureSize = 2048;
|
||||
|
||||
static const char* gs_VertexShader = "vertex.glsl";
|
||||
static const char* gs_ShaderFile = "fragment.glsl";
|
||||
|
||||
static const PIXELFORMATDESCRIPTOR pfd={
|
||||
0, 1, PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 8
|
||||
};
|
||||
|
||||
static DEVMODE dmScreenSettings={
|
||||
"",0,0,sizeof(dmScreenSettings),0,DM_PELSWIDTH|DM_PELSHEIGHT,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,"",0,0,gi_ScreenWidth,gi_ScreenHeight
|
||||
};
|
||||
|
||||
#define CHECK_DEBUG_OUTPUT(shader) \
|
||||
{\
|
||||
GLint success = 0;\
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);\
|
||||
if (!success)\
|
||||
{\
|
||||
GLchar infoLog[16384];\
|
||||
glGetShaderInfoLog(shader, 16384, NULL, infoLog);\
|
||||
OutputDebugString(infoLog);\
|
||||
}\
|
||||
}
|
||||
|
||||
struct filemon_struct
|
||||
{
|
||||
unsigned int shaderProgram;
|
||||
char* shaderFile;
|
||||
HANDLE shaderCompileEvent;
|
||||
__time64_t shaderChangedDate;
|
||||
};
|
||||
|
||||
DWORD WINAPI filemon(void* args)
|
||||
{
|
||||
filemon_struct* data = (filemon_struct*)args;
|
||||
while (true)
|
||||
{
|
||||
_finddata_t fdata;
|
||||
long hfile = _findfirst(data->shaderFile, &fdata);
|
||||
if (hfile != -1)
|
||||
{
|
||||
if (fdata.time_write != data->shaderChangedDate)
|
||||
{
|
||||
data->shaderChangedDate = fdata.time_write;
|
||||
::SetEvent(data->shaderCompileEvent);
|
||||
std::cout << "Shader loaded." << std::endl;
|
||||
}
|
||||
_findclose(hfile);
|
||||
}
|
||||
::Sleep(100);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <cmath>
|
||||
|
||||
float g_DebugCamPos[ 3 ]= {0,0.0f,0.0f};
|
||||
float g_DebugCamRot[ 2 ]= {0,0};
|
||||
|
||||
bool g_ShaderDebug= true;
|
||||
int g_ShaderID= 0;
|
||||
int g_SceneID= 0;
|
||||
int g_MaxSceneID= 17;
|
||||
|
||||
float g_fSpeedFac= 1.0f;
|
||||
|
||||
bool g_bForceCompile= true;
|
||||
|
||||
void MoveCam( float& fCurTime, float& fDeltaTime )
|
||||
{
|
||||
if (GetActiveWindow() != hWnd)
|
||||
return;
|
||||
|
||||
float fSpeed= 0.125f * fDeltaTime;
|
||||
|
||||
bool bShift= GetAsyncKeyState( VK_SHIFT ) || GetAsyncKeyState( VK_MBUTTON ) || GetAsyncKeyState( VK_RBUTTON );
|
||||
bool bStrg= GetAsyncKeyState( VK_CONTROL ) != 0;
|
||||
float a= g_DebugCamRot[ 0 ];
|
||||
float b= g_DebugCamRot[ 1 ];
|
||||
float g_Forward[ 3 ]= {sinf( a )*cosf(b),-sinf(b), cosf( a )*cosf(b)};
|
||||
float g_Right[ 3 ]= {cosf( a ),0, -sinf( a )};
|
||||
//if( bShift )
|
||||
{
|
||||
if( GetAsyncKeyState( VK_HOME ) )
|
||||
{
|
||||
g_DebugCamPos[ 0 ]= 0.0f;
|
||||
g_DebugCamPos[ 1 ]= 2.0f;
|
||||
g_DebugCamPos[ 2 ]= -5.0f;
|
||||
|
||||
g_DebugCamRot[ 0 ]= 0.0f;
|
||||
g_DebugCamRot[ 1 ]= 0.0f;
|
||||
}
|
||||
|
||||
if( GetAsyncKeyState( 'W' ) )
|
||||
{
|
||||
g_DebugCamPos[ 0 ]+= fSpeed * g_Forward[ 0 ];
|
||||
g_DebugCamPos[ 1 ]+= fSpeed * g_Forward[ 1 ];
|
||||
g_DebugCamPos[ 2 ]+= fSpeed * g_Forward[ 2 ];
|
||||
}
|
||||
if( GetAsyncKeyState( 'S' ) )
|
||||
{
|
||||
g_DebugCamPos[ 0 ]-= fSpeed * g_Forward[ 0 ];
|
||||
g_DebugCamPos[ 1 ]-= fSpeed * g_Forward[ 1 ];
|
||||
g_DebugCamPos[ 2 ]-= fSpeed * g_Forward[ 2 ];
|
||||
}
|
||||
if( GetAsyncKeyState( 'A' ) )
|
||||
{
|
||||
g_DebugCamPos[ 0 ]-= fSpeed * g_Right[ 0 ];
|
||||
g_DebugCamPos[ 1 ]-= fSpeed * g_Right[ 1 ];
|
||||
g_DebugCamPos[ 2 ]-= fSpeed * g_Right[ 2 ];
|
||||
}
|
||||
if( GetAsyncKeyState( 'D' ) )
|
||||
{
|
||||
g_DebugCamPos[ 0 ]+= fSpeed * g_Right[ 0 ];
|
||||
g_DebugCamPos[ 1 ]+= fSpeed * g_Right[ 1 ];
|
||||
g_DebugCamPos[ 2 ]+= fSpeed * g_Right[ 2 ];
|
||||
}
|
||||
if( GetAsyncKeyState( 'F' ) )
|
||||
{
|
||||
g_DebugCamPos[ 1 ]+= fSpeed;
|
||||
}
|
||||
if( GetAsyncKeyState( 'V' ) )
|
||||
{
|
||||
g_DebugCamPos[ 1 ]-= fSpeed;
|
||||
}
|
||||
|
||||
//if( bStrg )
|
||||
{
|
||||
if( ( GetAsyncKeyState( VK_F1 ) & 1 ) != 0)
|
||||
{
|
||||
g_ShaderDebug= !g_ShaderDebug;
|
||||
g_bForceCompile= true;
|
||||
}
|
||||
if( ( GetAsyncKeyState( VK_F2 ) & 1 ) != 0)
|
||||
{
|
||||
g_ShaderID= (g_ShaderID + MAX_SHADER_ID - 1 ) % MAX_SHADER_ID;
|
||||
g_bForceCompile= true;
|
||||
}
|
||||
if( ( GetAsyncKeyState( VK_F3 ) & 1 )!= 0)
|
||||
{
|
||||
g_ShaderID= (g_ShaderID + MAX_SHADER_ID + 1 ) % MAX_SHADER_ID;
|
||||
g_bForceCompile= true;
|
||||
}
|
||||
if( ( GetAsyncKeyState( VK_F4 ) & 1 )!= 0)
|
||||
{
|
||||
fCurTime= 0.0f;
|
||||
}
|
||||
if( ( GetAsyncKeyState( VK_F5 ) & 1 )!= 0)
|
||||
{
|
||||
g_fSpeedFac*= 2.0f;
|
||||
if( g_fSpeedFac > 32.0f )
|
||||
{
|
||||
g_fSpeedFac= 32.0f;
|
||||
}
|
||||
}
|
||||
if( ( GetAsyncKeyState( VK_F6 ) & 1 ) != 0)
|
||||
{
|
||||
g_fSpeedFac/= 2.0f;
|
||||
if( g_fSpeedFac < 0.03125f )
|
||||
{
|
||||
g_fSpeedFac= 0.03125f;
|
||||
}
|
||||
}
|
||||
if( ( GetAsyncKeyState( VK_F7 ) & 1 ) != 0)
|
||||
{
|
||||
g_SceneID= (g_SceneID + g_MaxSceneID - 1 ) % g_MaxSceneID;
|
||||
}
|
||||
if( ( GetAsyncKeyState( VK_F8 ) & 1 )!= 0)
|
||||
{
|
||||
g_SceneID= (g_SceneID + g_MaxSceneID + 1 ) % g_MaxSceneID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static POINT OldCurPos;
|
||||
POINT CurPos;
|
||||
GetCursorPos( &CurPos );
|
||||
|
||||
if( bShift )
|
||||
{
|
||||
g_DebugCamRot[ 0 ]-= 0.003f * ( OldCurPos.x - CurPos.x );
|
||||
g_DebugCamRot[ 1 ]-= 0.003f * ( OldCurPos.y - CurPos.y );
|
||||
g_DebugCamRot[ 1 ]= max( g_DebugCamRot[ 1 ], -1.56f );
|
||||
g_DebugCamRot[ 1 ]= min( g_DebugCamRot[ 1 ], 1.56f );
|
||||
}
|
||||
OldCurPos= CurPos;
|
||||
|
||||
}
|
||||
|
||||
LRESULT MessageCallback(HWND ar_Handle, UINT aw_Message, WPARAM aw_Param, LPARAM al_Param)
|
||||
{
|
||||
return DefWindowProc(ar_Handle, aw_Message, aw_Param, al_Param);
|
||||
}
|
||||
|
||||
int gCurScene= 0;
|
||||
int gCurSceneStart= 0;
|
||||
|
||||
int g_SceneLength[]=
|
||||
{
|
||||
16, 16, 16,
|
||||
16, 16, 16,
|
||||
16, 32, 16,
|
||||
16, 16, 16,
|
||||
0x80000000
|
||||
};
|
||||
|
||||
int g_SceneShader[]=
|
||||
{
|
||||
0,0,0,
|
||||
1,1,1,
|
||||
2,2,2,
|
||||
3,3,3,
|
||||
};
|
||||
|
||||
float g_SceneFactor[]=
|
||||
{
|
||||
0, 0, 0,
|
||||
0, 0, 1.0f,
|
||||
0, 0, 1.0f,
|
||||
0, 1.0f, 1.0f,
|
||||
0,
|
||||
};
|
||||
|
||||
void _cdecl main()
|
||||
{
|
||||
//ChangeDisplaySettings (&dmScreenSettings,CDS_FULLSCREEN);
|
||||
//HDC hDC = GetDC(CreateWindow("edit", 0, WS_POPUP | WS_VISIBLE | WS_MAXIMIZE, 0, 0, 0, 0, 0, 0, 0, 0));
|
||||
//HWND hWnd = CreateWindow("MDICLIENT", "Test", WS_OVERLAPPED | WS_VISIBLE | WS_SYSMENU, 0, 0, gi_ScreenWidth, gi_ScreenHeight, 0, 0, 0, 0);
|
||||
|
||||
WNDCLASSEX wndclass;
|
||||
wndclass.cbSize = sizeof (wndclass) ;
|
||||
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
|
||||
wndclass.lpfnWndProc = (WNDPROC)MessageCallback ;
|
||||
wndclass.cbClsExtra = 0 ;
|
||||
wndclass.cbWndExtra = 0 ;
|
||||
wndclass.hInstance = NULL ;
|
||||
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
|
||||
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
|
||||
wndclass.hbrBackground = (HBRUSH) GetStockObject (DKGRAY_BRUSH) ;
|
||||
wndclass.lpszMenuName = NULL;
|
||||
wndclass.lpszClassName = "Window" ;
|
||||
wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ;
|
||||
|
||||
RegisterClassEx(&wndclass);
|
||||
|
||||
hWnd = CreateWindow(
|
||||
"Window", /* Classname */
|
||||
"Title", /* Title Text */
|
||||
WS_EX_APPWINDOW, /* default window */
|
||||
10, /* Windows decides the position */
|
||||
30, /* where the window ends up on the screen */
|
||||
gi_ScreenWidth, /* The programs width */
|
||||
gi_ScreenHeight, /* and height in pixels */
|
||||
NULL, /* The window is a child-window to desktop */
|
||||
NULL, /* No menu */
|
||||
GetModuleHandle(NULL), //GetModuleHandle(NULL), /* Program Instance handler */
|
||||
NULL /* No Window Creation data */
|
||||
);
|
||||
|
||||
|
||||
HDC hDC = GetDC(hWnd);
|
||||
SetPixelFormat(hDC, ChoosePixelFormat(hDC, &pfd), &pfd);
|
||||
wglMakeCurrent(hDC, wglCreateContext(hDC));
|
||||
initShaders();
|
||||
|
||||
filemon_struct fragmentShader = {0};
|
||||
filemon_struct textureShader1 = {0};
|
||||
filemon_struct textureShader2 = {0};
|
||||
fragmentShader.shaderFile = "fragment.glsl";
|
||||
fragmentShader.shaderCompileEvent = ::CreateEvent(NULL, FALSE, FALSE, TEXT("WriteEvent"));
|
||||
textureShader1.shaderFile = "tex1.glsl";
|
||||
textureShader1.shaderCompileEvent = ::CreateEvent(NULL, FALSE, FALSE, TEXT("WriteEvent"));
|
||||
textureShader2.shaderFile = "tex2.glsl";
|
||||
textureShader2.shaderCompileEvent = ::CreateEvent(NULL, FALSE, FALSE, TEXT("WriteEvent"));
|
||||
SetThreadPriority((HANDLE)CreateThread(0, 0, &filemon, &fragmentShader, 0, 0), THREAD_PRIORITY_BELOW_NORMAL);
|
||||
SetThreadPriority((HANDLE)CreateThread(0, 0, &filemon, &textureShader1, 0, 0), THREAD_PRIORITY_BELOW_NORMAL);
|
||||
SetThreadPriority((HANDLE)CreateThread(0, 0, &filemon, &textureShader2, 0, 0), THREAD_PRIORITY_BELOW_NORMAL);
|
||||
auto events = new HANDLE[2];
|
||||
events[0] = fragmentShader.shaderCompileEvent;
|
||||
events[1] = textureShader1.shaderCompileEvent;
|
||||
events[2] = textureShader2.shaderCompileEvent;
|
||||
|
||||
ShowWindow (hWnd , SW_NORMAL );
|
||||
::Sleep(100);
|
||||
|
||||
LARGE_INTEGER li_OldTime = { 0 };
|
||||
unsigned int fbo1 = 0, fbo2 = 0;
|
||||
int iStartTick= timeGetTime();
|
||||
|
||||
GLuint tex1, tex2;
|
||||
glGenTextures(1, &tex1);
|
||||
glGenTextures(1, &tex2);
|
||||
glBindTexture(GL_TEXTURE_2D, tex1);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, textureSize, textureSize, 0, GL_RGBA, GL_FLOAT, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, tex2);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, textureSize, textureSize, 0, GL_RGBA, GL_FLOAT, 0);
|
||||
|
||||
((PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffers"))(1, &fbo1);
|
||||
((PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer"))(GL_FRAMEBUFFER, fbo1);
|
||||
((PFNGLFRAMEBUFFERTEXTURE2DPROC)wglGetProcAddress("glFramebufferTexture2D"))(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex1, 0);
|
||||
((PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffers"))(1, &fbo2);
|
||||
((PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer"))(GL_FRAMEBUFFER, fbo2);
|
||||
((PFNGLFRAMEBUFFERTEXTURE2DPROC)wglGetProcAddress("glFramebufferTexture2D"))(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2, 0);
|
||||
|
||||
float lf_Time= 0.0f;
|
||||
do
|
||||
{
|
||||
MSG msg;
|
||||
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
if (msg.message == WM_QUIT)
|
||||
return;
|
||||
else
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (::WaitForMultipleObjects(3, events, false, 0) == WAIT_OBJECT_0 || g_bForceCompile)
|
||||
{
|
||||
::Sleep(250);
|
||||
fragmentShader.shaderProgram = createProgram(createVertexShader(gs_VertexShader), createFragmentShader(fragmentShader.shaderFile, g_ShaderID, g_ShaderDebug));
|
||||
textureShader1.shaderProgram = createProgram(createVertexShader(gs_VertexShader), createFragmentShader(textureShader1.shaderFile, g_ShaderID, g_ShaderDebug));
|
||||
textureShader2.shaderProgram = createProgram(createVertexShader(gs_VertexShader), createFragmentShader(textureShader2.shaderFile, g_ShaderID, g_ShaderDebug));
|
||||
|
||||
glViewport(0, 0, textureSize, textureSize);
|
||||
|
||||
((PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer"))(GL_FRAMEBUFFER, fbo1);
|
||||
((PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram"))(textureShader1.shaderProgram);
|
||||
((PFNGLUNIFORM4FPROC)wglGetProcAddress("glUniform4f"))(0, textureSize, textureSize, lf_Time, 0);
|
||||
glRects(-1, -1, 1, 1);
|
||||
|
||||
((PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer"))(GL_FRAMEBUFFER, fbo2);
|
||||
((PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram"))(textureShader2.shaderProgram);
|
||||
((PFNGLUNIFORM4FPROC)wglGetProcAddress("glUniform4f"))(0, textureSize, textureSize, lf_Time, 0);
|
||||
((PFNGLUNIFORM1IPROC)wglGetProcAddress("glUniform1i"))(((PFNGLGETUNIFORMLOCATIONPROC)wglGetProcAddress("glGetUniformLocation"))(textureShader2.shaderProgram, "V"), 0);
|
||||
((PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture"))(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, tex1);
|
||||
glRects(-1, -1, 1, 1);
|
||||
|
||||
((PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer"))(GL_FRAMEBUFFER, 0);
|
||||
glViewport(0, 0, gi_ScreenWidth, gi_ScreenHeight);
|
||||
PrintErrors();
|
||||
g_bForceCompile= false;
|
||||
}
|
||||
|
||||
int SceneEnd= g_SceneLength[ gCurScene ] * (44100 * 60 / 145);//samples per tick
|
||||
|
||||
LARGE_INTEGER li_CurrentTime, li_CurrentFrequency;
|
||||
QueryPerformanceCounter(&li_CurrentTime);
|
||||
QueryPerformanceFrequency(&li_CurrentFrequency);
|
||||
float lf_DiffTime = (float)(li_CurrentTime.QuadPart - li_OldTime.QuadPart) / (float)li_CurrentFrequency.QuadPart;
|
||||
char windowText[255];
|
||||
sprintf_s(
|
||||
windowText,
|
||||
"Shader: %d Scene: %d FPS: %.2f, Render time: %.4fms",
|
||||
g_ShaderID,
|
||||
g_SceneID,
|
||||
1.0f / lf_DiffTime,
|
||||
lf_DiffTime );
|
||||
::SetWindowTextA(hWnd, windowText);
|
||||
|
||||
li_OldTime = li_CurrentTime;
|
||||
|
||||
lf_Time+= lf_DiffTime / 8.0f / g_fSpeedFac;
|
||||
if( lf_Time > 1.0f )
|
||||
{
|
||||
lf_Time= 0.0f;
|
||||
}
|
||||
float fBeat = lf_Time * 16.0f;
|
||||
while( fBeat > 1.0f )
|
||||
{
|
||||
fBeat-= 1.0f;
|
||||
}
|
||||
if( fBeat < 0.0f)
|
||||
{
|
||||
fBeat = 0.0f;
|
||||
}
|
||||
fBeat = pow( 10.0f, 4.0f * -fBeat );
|
||||
glColor3f((float)g_SceneID + lf_Time, fBeat, fBeat);
|
||||
MoveCam(lf_Time, lf_DiffTime);
|
||||
|
||||
float fDebugData[ 16 ];
|
||||
fDebugData[ 0 ]= g_DebugCamPos[ 0 ];
|
||||
fDebugData[ 1 ]= g_DebugCamPos[ 1 ];
|
||||
fDebugData[ 2 ]= g_DebugCamPos[ 2 ];
|
||||
fDebugData[ 4 ]= g_DebugCamRot[ 0 ];
|
||||
fDebugData[ 5 ]= g_DebugCamRot[ 1 ];
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadMatrixf((GLfloat*)&fDebugData);
|
||||
|
||||
((PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram"))(fragmentShader.shaderProgram);
|
||||
((PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture"))(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, tex1);
|
||||
((PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture"))(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, tex2);
|
||||
((PFNGLUNIFORM1IPROC)wglGetProcAddress("glUniform1i"))(((PFNGLGETUNIFORMLOCATIONPROC)wglGetProcAddress("glGetUniformLocation"))(fragmentShader.shaderProgram, "V"), 0);
|
||||
((PFNGLUNIFORM1IPROC)wglGetProcAddress("glUniform1i"))(((PFNGLGETUNIFORMLOCATIONPROC)wglGetProcAddress("glGetUniformLocation"))(fragmentShader.shaderProgram, "HEIGHT"), 1);
|
||||
glRects(-1, -1, 1, 1);
|
||||
|
||||
SwapBuffers(hDC);
|
||||
|
||||
}
|
||||
while ( !GetAsyncKeyState(VK_ESCAPE) );
|
||||
ExitProcess(0);
|
||||
}
|
||||
451
underwater4k/main_release.cpp
Normal file
451
underwater4k/main_release.cpp
Normal file
@@ -0,0 +1,451 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_EXTRA_LEAN
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <mmsystem.h>
|
||||
#include <mmreg.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "glext.h"
|
||||
#include "small.h"
|
||||
#include "4klang.h"
|
||||
|
||||
#pragma data_seg(".Shader0")
|
||||
#include "fragment_small.h"
|
||||
|
||||
/*******************************************************/
|
||||
/* config flags */
|
||||
|
||||
//#define DESKTOP_RESOLUTION
|
||||
#define WINDOWED
|
||||
#define CHANGERES_DELAY
|
||||
#define CLEAR_SCREEN_WHILE_LOADING
|
||||
#define SHADER_WARMUP
|
||||
|
||||
/* end config flags */
|
||||
/*******************************************************/
|
||||
|
||||
#ifndef DESKTOP_RESOLUTION
|
||||
#ifndef ASPECT
|
||||
#define ASPECT 1.33
|
||||
#endif
|
||||
|
||||
#ifndef SCREENWIDTH
|
||||
#define SCREENWIDTH 800
|
||||
#endif
|
||||
|
||||
#ifndef SCREENHEIGHT
|
||||
#define SCREENHEIGHT 600
|
||||
#endif
|
||||
#else
|
||||
// default aspect ratio for when using the desktop resolution
|
||||
#ifndef ASPECT
|
||||
#define ASPECT 1.77
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define USE_SOUND_THREAD
|
||||
#define STR2(x) #x
|
||||
#define STR(x) STR2(x)
|
||||
|
||||
#pragma data_seg(".vertexshader")
|
||||
static char* vertexShader = "varying vec4 "V_Y";varying vec2 "V_Z";void main(){"V_Y"=gl_Color;"V_Z"=(gl_Vertex.xy*vec2("STR(ASPECT)",1))*.5+.5;gl_Position=gl_Vertex;}";
|
||||
static char** vsh = &vertexShader;
|
||||
static char* pixelShader = (char*)fragment_glsl_0;
|
||||
static char** fsh = &pixelShader;
|
||||
|
||||
#pragma data_seg(".pfd")
|
||||
static const PIXELFORMATDESCRIPTOR pfd={
|
||||
0, 1, PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8
|
||||
};
|
||||
|
||||
#ifndef DESKTOP_RESOLUTION
|
||||
#pragma data_seg(".dms")
|
||||
static DEVMODE dmScreenSettings={
|
||||
"",0,0,sizeof(dmScreenSettings),0,DM_PELSWIDTH|DM_PELSHEIGHT,0,0,0,0,0,0,0,0,0,0,0,0,0,"",0,0,SCREENWIDTH,SCREENHEIGHT
|
||||
};
|
||||
#endif
|
||||
|
||||
#pragma bss_seg(".mainbss")
|
||||
static SAMPLE_TYPE lpSoundBuffer[MAX_SAMPLES*2];
|
||||
static HWAVEOUT hWaveOut;
|
||||
static unsigned int shaders[5];
|
||||
|
||||
#pragma data_seg(".wavefmt")
|
||||
WAVEFORMATEX WaveFMT =
|
||||
{
|
||||
#ifdef FLOAT_32BIT
|
||||
WAVE_FORMAT_IEEE_FLOAT,
|
||||
#else
|
||||
WAVE_FORMAT_PCM,
|
||||
#endif
|
||||
2, // channels
|
||||
SAMPLE_RATE, // samples per sec
|
||||
SAMPLE_RATE*sizeof(SAMPLE_TYPE)*2, // bytes per sec
|
||||
sizeof(SAMPLE_TYPE)*2, // block alignment;
|
||||
sizeof(SAMPLE_TYPE)*8, // bits per sample
|
||||
0 // extension not needed
|
||||
};
|
||||
|
||||
#pragma data_seg(".wavehdr")
|
||||
WAVEHDR WaveHDR =
|
||||
{
|
||||
(LPSTR)lpSoundBuffer,
|
||||
MAX_SAMPLES*sizeof(SAMPLE_TYPE)*2,
|
||||
0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
#pragma data_seg(".mmtime")
|
||||
MMTIME MMTime =
|
||||
{
|
||||
TIME_SAMPLES,
|
||||
0
|
||||
};
|
||||
|
||||
#pragma data_seg(".maindata")
|
||||
const float sceneLength = 64 * SAMPLES_PER_TICK;
|
||||
const int shaderLength = 4 * 64 * SAMPLES_PER_TICK;
|
||||
|
||||
#pragma data_seg(".windowClass")
|
||||
const char* edit = "edit";
|
||||
|
||||
#pragma data_seg(".glFunctions")
|
||||
const char* glUseProgram = "glUseProgram";
|
||||
const char* glCreateProgram = "glCreateProgram";
|
||||
const char* glCreateShader = "glCreateShader";
|
||||
const char* glShaderSource = "glShaderSource";
|
||||
const char* glCompileShader = "glCompileShader";
|
||||
const char* glAttachShader = "glAttachShader";
|
||||
const char* glLinkProgram = "glLinkProgram";
|
||||
|
||||
#pragma code_seg(".initsnd")
|
||||
__forceinline void InitSound()
|
||||
{
|
||||
_asm
|
||||
{
|
||||
#ifdef USE_SOUND_THREAD
|
||||
push ESI
|
||||
push ESI
|
||||
push offset [lpSoundBuffer]
|
||||
push dword ptr [_4klang_render]
|
||||
push ESI
|
||||
push ESI
|
||||
call dword ptr [CreateThread]
|
||||
#else
|
||||
push offset [lpSoundBuffer]
|
||||
push dword ptr [_4klang_render]
|
||||
#endif
|
||||
|
||||
push ESI
|
||||
push ESI
|
||||
push ESI
|
||||
push offset [WaveFMT]
|
||||
push -0x1
|
||||
push offset [hWaveOut]
|
||||
call dword ptr [waveOutOpen]
|
||||
|
||||
push 0x20
|
||||
push offset [WaveHDR]
|
||||
push dword ptr [hWaveOut]
|
||||
push 0x20
|
||||
push offset [WaveHDR]
|
||||
push dword ptr [hWaveOut]
|
||||
|
||||
call dword ptr [waveOutPrepareHeader]
|
||||
call dword ptr [waveOutWrite]
|
||||
}
|
||||
}
|
||||
|
||||
#pragma code_seg(".envelope")
|
||||
float get_Envelope(int instrument)
|
||||
{
|
||||
return (&_4klang_envelope_buffer)[(((MMTime.u.sample) >> 8) << 5) + POLYPHONY*instrument]; // the last number is the instrument
|
||||
}
|
||||
|
||||
#pragma code_seg(".sample")
|
||||
int get_Sample()
|
||||
{
|
||||
waveOutGetPosition(hWaveOut, &MMTime, sizeof(MMTIME));
|
||||
return MMTime.u.sample;
|
||||
}
|
||||
|
||||
#pragma code_seg(".compile")
|
||||
unsigned int compileShader()
|
||||
{
|
||||
_asm
|
||||
{
|
||||
push glCreateProgram
|
||||
call dword ptr [wglGetProcAddress]
|
||||
call eax
|
||||
mov ebx, eax
|
||||
|
||||
push ebx
|
||||
push glLinkProgram
|
||||
push GL_FRAGMENT_SHADER
|
||||
push glCreateShader
|
||||
push GL_VERTEX_SHADER
|
||||
push glCreateShader
|
||||
|
||||
call dword ptr [wglGetProcAddress]
|
||||
call eax
|
||||
push eax
|
||||
push ebx
|
||||
push glAttachShader
|
||||
push eax
|
||||
push glCompileShader
|
||||
push esi
|
||||
push vsh
|
||||
push 1
|
||||
push eax
|
||||
push glShaderSource
|
||||
call dword ptr [wglGetProcAddress]
|
||||
call eax
|
||||
call dword ptr [wglGetProcAddress]
|
||||
call eax
|
||||
call dword ptr [wglGetProcAddress]
|
||||
call eax
|
||||
call dword ptr [wglGetProcAddress]
|
||||
call eax
|
||||
push eax
|
||||
push ebx
|
||||
push glAttachShader
|
||||
push eax
|
||||
push glCompileShader
|
||||
push esi
|
||||
push fsh
|
||||
push 1
|
||||
push eax
|
||||
push glShaderSource
|
||||
call dword ptr [wglGetProcAddress]
|
||||
call eax
|
||||
call dword ptr [wglGetProcAddress]
|
||||
call eax
|
||||
call dword ptr [wglGetProcAddress]
|
||||
call eax
|
||||
call dword ptr [wglGetProcAddress]
|
||||
call eax
|
||||
|
||||
mov eax, ebx
|
||||
}
|
||||
}
|
||||
|
||||
// Aufbau der musik:
|
||||
// Teil / Dauer in Szenen
|
||||
// ----------------------
|
||||
// Intro / 2
|
||||
// A-Teil / 4
|
||||
// B-Teil / 4
|
||||
// A-Teil / 4
|
||||
// Outro / 3 (wobei die letzte Szene für fade-out dienen soll)
|
||||
|
||||
#pragma code_seg(".main")
|
||||
void _cdecl main()
|
||||
{
|
||||
register HDC hDC;
|
||||
_asm
|
||||
{
|
||||
xor esi,esi
|
||||
|
||||
push esi //ShowCursor
|
||||
|
||||
push esi //CreateWindowExA
|
||||
push esi
|
||||
push esi
|
||||
push esi
|
||||
#ifdef DESKTOP_RESOLUTION
|
||||
push esi
|
||||
push esi
|
||||
#else
|
||||
#ifdef WINDOWED
|
||||
push SCREENHEIGHT
|
||||
push SCREENWIDTH
|
||||
#else
|
||||
push esi
|
||||
push esi
|
||||
#endif
|
||||
#endif
|
||||
push esi
|
||||
push esi
|
||||
#ifdef DESKTOP_RESOLUTION
|
||||
push WS_POPUP | WS_VISIBLE | WS_MAXIMIZE
|
||||
#else
|
||||
#ifdef WINDOWED
|
||||
push WS_POPUP | WS_VISIBLE
|
||||
#else
|
||||
push WS_POPUP | WS_VISIBLE | WS_MAXIMIZE
|
||||
#endif
|
||||
#endif
|
||||
push esi
|
||||
push edit
|
||||
push esi
|
||||
#ifndef WINDOWED
|
||||
#ifndef DESKTOP_RESOLUTION
|
||||
push 4 //ChangeDisplaySettings
|
||||
push offset [dmScreenSettings]
|
||||
call dword ptr [ChangeDisplaySettings]
|
||||
#endif
|
||||
#endif
|
||||
call dword ptr [CreateWindowExA]
|
||||
push eax
|
||||
call dword ptr [GetDC]
|
||||
mov hDC, eax
|
||||
|
||||
mov eax, offset [pfd]
|
||||
push eax
|
||||
push eax
|
||||
push hDC
|
||||
call dword ptr [ChoosePixelFormat]
|
||||
push eax
|
||||
push hDC
|
||||
call dword ptr [SetPixelFormat]
|
||||
push hDC
|
||||
call dword ptr [wglCreateContext]
|
||||
push eax
|
||||
push hDC
|
||||
call dword ptr [wglMakeCurrent]
|
||||
|
||||
mov ebx, offset [shaders]
|
||||
mov edi, offset [fragment_glsl_0] + 12
|
||||
|
||||
call dword ptr[compileShader]
|
||||
mov dword ptr[ebx], eax
|
||||
inc dword ptr[edi]
|
||||
add ebx, 4
|
||||
|
||||
call dword ptr[compileShader]
|
||||
mov dword ptr[ebx], eax
|
||||
inc dword ptr[edi]
|
||||
add ebx, 4
|
||||
|
||||
call dword ptr[compileShader]
|
||||
mov dword ptr[ebx], eax
|
||||
inc dword ptr[edi]
|
||||
add ebx, 4
|
||||
|
||||
call dword ptr[compileShader]
|
||||
mov dword ptr[ebx], eax
|
||||
inc dword ptr[edi]
|
||||
add ebx, 4
|
||||
mov dword ptr[ebx], eax
|
||||
|
||||
call dword ptr[ShowCursor]
|
||||
|
||||
#ifdef CHANGERES_DELAY
|
||||
push 2048 // delay time in milliseconds
|
||||
#endif
|
||||
#ifdef CLEAR_SCREEN_WHILE_LOADING
|
||||
push hDC
|
||||
push 1 // glRects
|
||||
push 1
|
||||
push -1
|
||||
push -1
|
||||
push esi
|
||||
push esi
|
||||
push esi
|
||||
call dword ptr[glColor3f]
|
||||
call dword ptr[glRects]
|
||||
call dword ptr[SwapBuffers]
|
||||
#endif
|
||||
#ifdef CHANGERES_DELAY
|
||||
call dword ptr [Sleep]
|
||||
#endif
|
||||
}
|
||||
#ifdef SHADER_WARMUP
|
||||
_asm
|
||||
{
|
||||
push 1 // glRects
|
||||
push 1
|
||||
push -1
|
||||
push -1
|
||||
push dword ptr [shaders+12] // glUseProgram
|
||||
push dword ptr [glUseProgram] // wglGetProcAddress
|
||||
push 1 // glRects
|
||||
push 1
|
||||
push -1
|
||||
push -1
|
||||
push dword ptr [shaders+8] // glUseProgram
|
||||
push dword ptr [glUseProgram] // wglGetProcAddress
|
||||
push 1 // glRects
|
||||
push 1
|
||||
push -1
|
||||
push -1
|
||||
push dword ptr [shaders+4] // glUseProgram
|
||||
push dword ptr [glUseProgram] // wglGetProcAddress
|
||||
push 1 // glRects
|
||||
push 1
|
||||
push -1
|
||||
push -1
|
||||
push dword ptr [shaders+0] // glUseProgram
|
||||
push dword ptr [glUseProgram] // wglGetProcAddress
|
||||
call dword ptr [wglGetProcAddress]
|
||||
call eax
|
||||
call dword ptr[glRects]
|
||||
call dword ptr [wglGetProcAddress]
|
||||
call eax
|
||||
call dword ptr[glRects]
|
||||
call dword ptr [wglGetProcAddress]
|
||||
call eax
|
||||
call dword ptr[glRects]
|
||||
call dword ptr [wglGetProcAddress]
|
||||
call eax
|
||||
call dword ptr[glRects]
|
||||
}
|
||||
#endif
|
||||
_asm call dword ptr[InitSound]
|
||||
while (true)
|
||||
{
|
||||
_asm
|
||||
{
|
||||
push PM_REMOVE // PeekMessageA
|
||||
push esi
|
||||
push esi
|
||||
push esi
|
||||
push esi
|
||||
|
||||
push hDC // SwapBuffers
|
||||
|
||||
push 1 // glRects
|
||||
push 1
|
||||
push -1
|
||||
push -1
|
||||
|
||||
push esi //glColor3f
|
||||
push esi
|
||||
push esi
|
||||
|
||||
}
|
||||
if (get_Sample() >= MAX_TICKS * SAMPLES_PER_TICK)
|
||||
break;
|
||||
_asm
|
||||
{
|
||||
mov dword ptr [esp],eax
|
||||
cdq
|
||||
div dword ptr [shaderLength]
|
||||
mov ebx, eax
|
||||
fild dword ptr [esp]
|
||||
fdiv dword ptr [sceneLength]
|
||||
fstp dword ptr [esp]
|
||||
push 2
|
||||
call dword ptr [get_Envelope]
|
||||
fstp dword ptr [esp+4]
|
||||
push 6
|
||||
call dword ptr [get_Envelope]
|
||||
fstp dword ptr [esp+8]
|
||||
call dword ptr [glColor3f]
|
||||
|
||||
push dword ptr [ebx*4+shaders]
|
||||
push dword ptr [glUseProgram]
|
||||
call dword ptr [wglGetProcAddress]
|
||||
call eax
|
||||
|
||||
call dword ptr[glRects]
|
||||
call dword ptr[SwapBuffers]
|
||||
call dword ptr[PeekMessageA]
|
||||
}
|
||||
|
||||
if (GetAsyncKeyState(VK_ESCAPE))
|
||||
break;
|
||||
}
|
||||
|
||||
ExitProcess(0);
|
||||
}
|
||||
BIN
underwater4k/minify/shader_minifier.exe
Normal file
BIN
underwater4k/minify/shader_minifier.exe
Normal file
Binary file not shown.
191
underwater4k/release.h
Normal file
191
underwater4k/release.h
Normal file
@@ -0,0 +1,191 @@
|
||||
#pragma once
|
||||
|
||||
#pragma data_seg(".shaders")
|
||||
static char* fsh =
|
||||
"#define ve return\n" // Line 1
|
||||
"#define ec float\n" // Line 1
|
||||
"varying vec4 Y;" // Line 6
|
||||
"varying vec2 Z;" // Line 9
|
||||
"vec4 R(vec3 n,vec3 m,int k);" // Line 12
|
||||
"vec3 T(vec4 j,vec3 l,vec3 m);" // Line 13
|
||||
"vec3 f,b,a,h,e,d,X;" // Line 17
|
||||
"ec g,W,c,V,U;ec A(vec2 j){" // Line 18
|
||||
"int i=int(j.x*40+j.y*6400);" // Line 24
|
||||
"i=(i<<13)^i;" // Line 25
|
||||
"ve 1-ec((i*(i*i*15731+789221)+1376312589)&0x7fffffff)/1073741824;}ec B(vec2 k){" // Line 26
|
||||
"k=mod(k,1000.);" // Line 33
|
||||
"vec2 i=fract(k);" // Line 34
|
||||
"k-=i;" // Line 35
|
||||
"vec2 j=i*i*(3.-2.*i);" // Line 36
|
||||
"ve mix(" // Line 37
|
||||
"mix(A(k+vec2(0,0)),A(k+vec2(1,0)),j.x)," // Line 38
|
||||
"mix(A(k+vec2(0,1)),A(k+vec2(1,1)),j.x),j.y);}ec C(ec i){" // Line 39
|
||||
"ve i*.5+.5;}ec D(ec k,ec l,ec j){" // Line 46
|
||||
"ec i=(" // Line 53
|
||||
"C(sin(c*2*(k+l+Y.y*j)))+" // Line 54
|
||||
"C(sin(c*(l-k-Y.y*j)))+" // Line 55
|
||||
"C(sin(c*(l+Y.y*j)))+" // Line 56
|
||||
"C(sin(c*3*(k-Y.y*j))))*.3;" // Line 57
|
||||
"ve pow(i,2.);}vec3 E(vec3 j){" // Line 58
|
||||
"int i=int(mod(gl_FragCoord.x,3.));" // Line 65
|
||||
"if(i==0)j*=X.xyz;" // Line 66
|
||||
"if(i==1)j*=X.yzx;" // Line 67
|
||||
"if(i==2)j*=X.zxy;" // Line 68
|
||||
"ve mix(j,vec3(C(B(Z*333+A(vec2(Y.y))*33333))),Y.x*.3+.03);}vec3 F(vec3 i){" // Line 69
|
||||
"vec2 j=Z*2-1;" // Line 76
|
||||
"ec k=j.x*(j.y+3);" // Line 77
|
||||
"ve i+a*" // Line 78
|
||||
"D(k+50*e.x,k+50*e.z,1.5)*" // Line 79
|
||||
"(C(j.y))*min(-e.y*30,.3);}ec G(vec2 i){" // Line 80
|
||||
"ve (-.035+pow((D(i.x*10,i.y*10,.0)*2-1),2.)*.05)" // Line 87
|
||||
"-(i.x-.1)*.2;}vec3 H(vec3 i){" // Line 88
|
||||
"ve normalize(vec3(" // Line 95
|
||||
"G(i.xz-vec2(U,0))-G(i.xz+vec2(U,0))," // Line 96
|
||||
"2*U," // Line 97
|
||||
"G(i.xz-vec2(0,U))-G(i.xz+vec2(0,U))));}vec3 I(vec3 i,vec3 j){" // Line 98
|
||||
"ve (.3+.7*max(dot(j,b),.0))*a*i;}vec3 J(vec3 i){" // Line 105
|
||||
"ve normalize(vec3(" // Line 112
|
||||
"D(i.x*160-cos(i.z*10)*12,i.z*140,4.)," // Line 113
|
||||
"8," // Line 114
|
||||
"D(i.z*160-sin(i.x*10)*12,i.x*140,4.))*2-1);}vec3 K(vec3 k,vec3 l){" // Line 115
|
||||
"vec3 j=H(k);" // Line 122
|
||||
"vec3 i=mix(" // Line 123
|
||||
"vec3(.66,.55,.4)" // Line 125
|
||||
"-.2*B(abs(k.xz*150))" // Line 128
|
||||
"-.2*B(abs(k.yy+.002*B(abs(k.xz*150)))*3000)," // Line 131
|
||||
"vec3(.1,.3,0)*(B(k.xz*7000.)*.4+.5)," // Line 134
|
||||
"clamp(j.y*(D(k.x*111,k.z*111,.0)*.5-k.y*40),.0,1.));" // Line 137
|
||||
"if(k.y<=0)" // Line 140
|
||||
"i+=5*J(.8*k).x*min(.3,-k.y*8);" // Line 141
|
||||
"ve I(i,j);}vec3 L(vec3 j,vec3 i){" // Line 144
|
||||
"ve j.y<=-V*V?" // Line 151
|
||||
"h:" // Line 152
|
||||
"mix(vec3(-.5,-.25,0),vec3(2),1-(i.y*.5+.5));}vec3 M(vec3 k,vec3 j){" // Line 153
|
||||
"vec3 m=J(k);" // Line 162
|
||||
"vec4 l=R(k,refract(j,m,.9),2);" // Line 166
|
||||
"ec i=clamp(pow(1.03*(1-length(l.xyz-k)),16.),.0,1.);" // Line 169
|
||||
"ve mix(" // Line 172
|
||||
"e.y<0?L(k,j):h," // Line 173
|
||||
"mix(" // Line 174
|
||||
"T(R(k,reflect(j,m),2),k,j)," // Line 175
|
||||
"T(l,k,j)," // Line 176
|
||||
"clamp(-d.y+i,.0,1.))," // Line 177
|
||||
"l.w==3.?.5:pow(i,.5));}vec3 N(vec3 k,vec3 l){" // Line 178
|
||||
"vec3 j,i;" // Line 186
|
||||
"j=normalize(k-f);" // Line 189
|
||||
"vec2 m=.5+.5*vec2(atan(j.z,j.x),acos(j.y))/c;" // Line 192
|
||||
"m.x-=Y.y;" // Line 195
|
||||
"i=mix(vec3(1),vec3(1,0,0),mod(step(fract(m.x*6),.5)+step(fract(m.y*6),.5),2.));" // Line 198
|
||||
"ve I(i,j)" // Line 200
|
||||
"+pow(max(dot(j,normalize(b-l)),.0),33.)*a;}ec O(vec3 n,vec3 m,ec l){" // Line 201
|
||||
"ec i,j,k,p;" // Line 209
|
||||
"i=0;" // Line 210
|
||||
"vec3 o=n;" // Line 211
|
||||
"for(ec q=0;q<l;q+=i)" // Line 214
|
||||
"{" // Line 215
|
||||
"o+=m*i;" // Line 217
|
||||
"p=o.y;" // Line 218
|
||||
"ec r=G(o.xz);" // Line 221
|
||||
"if(p<=r)" // Line 223
|
||||
"{" // Line 224
|
||||
"ve q-i+i*(j-k)/(p-r+j-k);}" // Line 227
|
||||
"j=r;" // Line 232
|
||||
"k=p;" // Line 233
|
||||
"i=.002+(q/W);}" // Line 237
|
||||
"ve 9.;}ec P(vec3 m,vec3 l){" // Line 241
|
||||
"vec3 k=m-f;" // Line 248
|
||||
"ec i,j;" // Line 249
|
||||
"i=dot(k,l);" // Line 250
|
||||
"if(i>0)" // Line 251
|
||||
"ve 9.;" // Line 252
|
||||
"j=i*i-dot(k,k)+g*g;" // Line 253
|
||||
"if(j>0)" // Line 254
|
||||
"{" // Line 255
|
||||
"ve -i-sqrt(j);}" // Line 256
|
||||
"ve 9.;}ec Q(vec3 j,vec3 i){" // Line 258
|
||||
"ec k=-j.y/i.y;" // Line 265
|
||||
"ve k>=V?k:9.;}vec4 R(vec3 n,vec3 m,int k){" // Line 266
|
||||
"ec p,i,o,l;" // Line 278
|
||||
"p=k!=2?Q(n,m):9.;" // Line 281
|
||||
"i=k!=3?P(n,m):9.;" // Line 282
|
||||
"o=k!=1?O(n,m,min(.5,.002+min(p,i))):9.;" // Line 283
|
||||
"W/=20;" // Line 286
|
||||
"l=min(o,min(p,min(i,9.)));" // Line 289
|
||||
"if(l==9)" // Line 292
|
||||
"ve vec4(0);" // Line 293
|
||||
"vec3 j=n+m*l;" // Line 296
|
||||
"if(l==o)" // Line 299
|
||||
"ve vec4(j,1);" // Line 300
|
||||
"if(l==p)" // Line 301
|
||||
"ve vec4(j,2);" // Line 302
|
||||
"if(l==i)" // Line 303
|
||||
"ve vec4(j,3);}vec3 S(vec4 j,vec3 l,vec3 m){" // Line 304
|
||||
"vec3 k=l.y<V?h:L(e,m);" // Line 315
|
||||
"ec i=clamp(length(j.xyz-l)*(e.y<=0?4:2),.0,1.);" // Line 318
|
||||
"if(j.w==1)" // Line 322
|
||||
"ve mix(K(j.xyz,m),k,i);" // Line 323
|
||||
"if(j.w==2)" // Line 324
|
||||
"ve mix(M(j.xyz,m),k,i);" // Line 325
|
||||
"if(j.w==3)" // Line 326
|
||||
"ve mix(" // Line 327
|
||||
"mix(N(j.xyz,m),T(R(j.xyz,reflect(m,normalize(j.xyz-f)),3),j.xyz,m),.5)" // Line 329
|
||||
",k,i);" // Line 330
|
||||
"ve L(l,m);}vec3 T(vec4 j,vec3 l,vec3 m){" // Line 332
|
||||
"vec3 k=l.y<V?h:L(e,m);" // Line 341
|
||||
"ec i=clamp(length(j.xyz-l)*(e.y<=0?4:2),.0,1.);" // Line 344
|
||||
"if(j.w==1)" // Line 347
|
||||
"ve mix(K(j.xyz,m),k,i);" // Line 348
|
||||
"if(j.w==2)" // Line 349
|
||||
"ve mix(h,k,i);" // Line 350
|
||||
"if(j.w==3)" // Line 351
|
||||
"ve mix(N(j.xyz,m),k,i);" // Line 352
|
||||
"ve k;}void main(){" // Line 354
|
||||
"W=100;" // Line 368
|
||||
"c=3.1416;" // Line 371
|
||||
"X=vec3(1.2,.9,.9);" // Line 372
|
||||
"V=.0001;" // Line 373
|
||||
"U=.01;" // Line 374
|
||||
"ec k=10;" // Line 377
|
||||
"int j=int(Y.y);" // Line 380
|
||||
"d=vec3((Z.xy-.5),1);" // Line 383
|
||||
"if(j>22&&j<27)" // Line 386
|
||||
"{" // Line 387
|
||||
"k=min(1.,sin((Y.y-23)*c*.25)*12);" // Line 388
|
||||
"e=vec3(.12,.005,Y.y*.08);" // Line 389
|
||||
"d=vec3(gl_ModelViewMatrix*vec4(d,1));" // Line 390
|
||||
"d.y+=.1*cos(Y.y*4);}" // Line 391
|
||||
"else if(j>14&&j<23)" // Line 394
|
||||
"{" // Line 395
|
||||
"k=min(1.,sin((Y.y-15)*c*.125)*24);" // Line 396
|
||||
"d+=vec3(0,.1*cos(Y.y*4),0);" // Line 397
|
||||
"e=vec3(.08,.01*sin(Y.y*4)+.002,Y.y*.11);}" // Line 398
|
||||
"else " // Line 402
|
||||
"{" // Line 403
|
||||
"e=vec3(.1,.004,.0)+vec3(.1,.005,20)" // Line 405
|
||||
"*vec3(A(vec2(j,k++)),A(vec2(j,k++)),A(vec2(j,k++)));" // Line 406
|
||||
"e=mix(" // Line 409
|
||||
"e+vec3(.008)*vec3(A(vec2(j,k++)),A(vec2(j,k++)),A(vec2(j,k++)))," // Line 410
|
||||
"e+vec3(.008)*vec3(A(vec2(j,k++)),A(vec2(j,k++)),A(vec2(j,k++)))," // Line 411
|
||||
"Y.y-j);" // Line 413
|
||||
"e.y+=G(e.xz)+.02;" // Line 416
|
||||
"e+=.02*H(e);" // Line 419
|
||||
"k=min(1.,step(-28.,-Y.y)*sin((Y.y-j)*c)*3);}" // Line 422
|
||||
"d=normalize(d);" // Line 425
|
||||
"if(j>22&&j<27)" // Line 429
|
||||
"f=e+.1*vec3(gl_ModelViewMatrix*vec4(0,0,1,1));" // Line 430
|
||||
"else " // Line 432
|
||||
"f=e+.02*vec3(sin(Y.y),0,5+cos(Y.y));" // Line 433
|
||||
"f.y+=.01+G(f.xz);" // Line 435
|
||||
"g=j<14?.0:U*.5+U*Y.z;" // Line 436
|
||||
"f+=2*g*H(f);" // Line 437
|
||||
"b=vec3(.58,.58,-.58);" // Line 440
|
||||
"a=vec3(1.2);" // Line 441
|
||||
"h=vec3(.3,.33,.4);" // Line 442
|
||||
"if(e.y<=0)" // Line 445
|
||||
"{" // Line 446
|
||||
"W*=.75;" // Line 448
|
||||
"a*=.8;}" // Line 451
|
||||
"vec3 i=S(R(e,d,0),e,d);" // Line 455
|
||||
"if(e.y<=0)" // Line 459
|
||||
"i=F(i);" // Line 460
|
||||
"gl_FragColor.xyz=E(step(2.,Y.y)*k*i);}";
|
||||
163
underwater4k/shader_code.h
Normal file
163
underwater4k/shader_code.h
Normal file
@@ -0,0 +1,163 @@
|
||||
/* File generated with Shader Minifier 1.0.3
|
||||
* http://www.ctrl-alt-test.fr
|
||||
*/
|
||||
#ifndef SHADER_CODE_H_
|
||||
# define SHADER_CODE_H_
|
||||
# define V_Y "v"
|
||||
# define V_Z "m"
|
||||
|
||||
const char *mark_fs = ""
|
||||
"varying vec4 v;"
|
||||
"varying vec2 m;"
|
||||
"vec3 f,z;"
|
||||
"float x=6.28319;"
|
||||
"vec2 n(vec2 f,float v)"
|
||||
"{"
|
||||
"return cos(v)*f+sin(v)*vec2(-f.y,f.x);"
|
||||
"}"
|
||||
"void i(inout vec3 v,float f)"
|
||||
"{"
|
||||
"float z=mod(atan(v.z,v.x),f)-f*.5;"
|
||||
"v.xz=length(v.xz)*vec2(cos(z),sin(z));"
|
||||
"}"
|
||||
"float i(vec3 v,float f,float z)"
|
||||
"{"
|
||||
"return length(vec2(length(v.xz)-f,v.y))-z;"
|
||||
"}"
|
||||
"float s(vec3 v,float z)"
|
||||
"{"
|
||||
"return length(v)-z;"
|
||||
"}"
|
||||
"float i(vec3 v)"
|
||||
"{"
|
||||
"return v.y+.6;"
|
||||
"}"
|
||||
"float n(vec3 v)"
|
||||
"{"
|
||||
"return min(s(v+vec3(0,8.,0),8.5),i(v,2.3,.5));"
|
||||
"}"
|
||||
"float s(vec3 v)"
|
||||
"{"
|
||||
"float z=max(s(v,6.),v.y);"
|
||||
"i(v,x/64.);"
|
||||
"v.x=abs(v.x-5.)-2.;"
|
||||
"float f=mix(length(v.yz),length(v.xyz),step(0.,v.x));"
|
||||
"return min(z,f-.4);"
|
||||
"}"
|
||||
"float l(vec3 f)"
|
||||
"{"
|
||||
"return f.y-=4.,f.xz=n(f.xz,v.y*6.),i(f,x/12.),f.yz=n(f.yz,x/4.),min(i(f,2.,.15),s(f,1.5));"
|
||||
"}"
|
||||
"float h(vec3 v)"
|
||||
"{"
|
||||
"return min(min(min(i(v),n(v)),s(v)),l(v));"
|
||||
"}"
|
||||
"int g(vec3 v)"
|
||||
"{"
|
||||
"float z=1000.;"
|
||||
"int f;"
|
||||
"if(i(v)<z)"
|
||||
"z=i(v),f=0;"
|
||||
"if(n(v)<z)"
|
||||
"z=n(v),f=1;"
|
||||
"if(s(v)<z)"
|
||||
"z=s(v),f=2;"
|
||||
"if(l(v)<z)"
|
||||
"z=l(v),f=3;"
|
||||
"return f;"
|
||||
"}"
|
||||
"vec3 p(vec3 v)"
|
||||
"{"
|
||||
"vec3 z=vec3(.04,0.,0.),f;"
|
||||
"f.x=h(v+z.xyy)-h(v-z.xyy);"
|
||||
"f.y=h(v+z.yxy)-h(v-z.yxy);"
|
||||
"f.z=h(v+z.yyx)-h(v-z.yyx);"
|
||||
"return normalize(f);"
|
||||
"}"
|
||||
"float e(vec3 v)"
|
||||
"{"
|
||||
"float z=1.;"
|
||||
"for(float f=.2;f<12.;f=f*1.1+.125)"
|
||||
"z+=min(h(v+vec3(0.,1.,0.)*f),0.);"
|
||||
"return clamp(z,.2,1.);"
|
||||
"}"
|
||||
"float e(vec3 v,vec3 f,float z,float i)"
|
||||
"{"
|
||||
"float x,y=sign(z);"
|
||||
"for(x=y*.5+.5;i>0.;i--)"
|
||||
"x-=(i*z-h(v+f*i*z*y))/exp2(i);"
|
||||
"return x;"
|
||||
"}"
|
||||
"vec3 t(vec3 v)"
|
||||
"{"
|
||||
"float z=.3+.3*dot(v,vec3(0.,1.,0.));"
|
||||
"i(v,x/16.);"
|
||||
"v.x=abs(v.x-.2)-.08;"
|
||||
"float f=mix(abs(v.z),length(v.xz),step(0.,v.x));"
|
||||
"z+=pow(smoothstep(.1,0.,f),15.);"
|
||||
"return vec3(z);"
|
||||
"}"
|
||||
"float c(vec3 v)"
|
||||
"{"
|
||||
"float z=abs(v.y-.9);"
|
||||
"return.4+.3*(1-z);"
|
||||
"}"
|
||||
"void main()"
|
||||
"{"
|
||||
"int x=int(v.y);"
|
||||
"float y=mod(v.y,1.);"
|
||||
"z=vec3(m.xy-.5,1);"
|
||||
"f=vec3(-30.-y*5.,3.,-16.+y*24.);"
|
||||
"z.xz=n(z.xz,y*-2.5);"
|
||||
"if(false)"
|
||||
"{"
|
||||
"f.x=gl_ModelViewMatrix[0][0];"
|
||||
"f.y=gl_ModelViewMatrix[0][1];"
|
||||
"f.z=gl_ModelViewMatrix[0][2];"
|
||||
"float i=gl_ModelViewMatrix[1][1],s,r;"
|
||||
"vec3 l=vec3(m.xy-.5,1);"
|
||||
"s=cos(i);"
|
||||
"r=sin(i);"
|
||||
"z.y=s*l.y-r*l.z;"
|
||||
"z.x=l.x;"
|
||||
"z.z=r*l.y+s*l.z;"
|
||||
"i=gl_ModelViewMatrix[1][0];"
|
||||
"l=z;"
|
||||
"s=cos(i);"
|
||||
"r=sin(i);"
|
||||
"z.x=s*l.x+r*l.z;"
|
||||
"z.z=-r*l.x+s*l.z;"
|
||||
"}"
|
||||
"z=normalize(z);"
|
||||
"vec3 i=vec3(0.,0.,0.);"
|
||||
"float s=1.,l=0.,r=256.,a;"
|
||||
"while(s>.1)"
|
||||
"{"
|
||||
"for(a=1.;l<r&&a>.05;l+=a)"
|
||||
"a=h(f+z*l);"
|
||||
"if(l<r)"
|
||||
"{"
|
||||
"f+=z*l;"
|
||||
"vec3 o=p(f);"
|
||||
"z=reflect(z,o);"
|
||||
"l=.1;"
|
||||
"vec3 d=vec3(.3,.2,.1);"
|
||||
"float u=.125;"
|
||||
"int M=g(f);"
|
||||
"if(M==1)"
|
||||
"d=vec3(.1,.1,.1),u=.8;"
|
||||
"if(M==2)"
|
||||
"d=vec3(.4,.3,.03),u=.2;"
|
||||
"if(M==3)"
|
||||
"d=vec3(.7,0.,0.),u=.2;"
|
||||
"d*=c(o)*e(f)*e(f,o,.4,10.);"
|
||||
"i+=s*d;"
|
||||
"s*=u;"
|
||||
"}"
|
||||
"else"
|
||||
" i+=s*t(z),s=0.;"
|
||||
"}"
|
||||
"gl_FragColor.xyz=i;"
|
||||
"}";
|
||||
|
||||
#endif // SHADER_CODE_H_
|
||||
127
underwater4k/small.h
Normal file
127
underwater4k/small.h
Normal file
@@ -0,0 +1,127 @@
|
||||
#pragma once
|
||||
|
||||
#pragma code_seg("sm0")
|
||||
|
||||
DWORD x_Ftol(float af_Value)
|
||||
{
|
||||
DWORD ldw_RetVal;
|
||||
__asm fld af_Value
|
||||
__asm fistp ldw_RetVal
|
||||
return ldw_RetVal;
|
||||
}
|
||||
|
||||
#pragma code_seg("sm1")
|
||||
|
||||
__forceinline float x_Frac(float af_Value)
|
||||
{
|
||||
return af_Value - x_Ftol(af_Value);
|
||||
}
|
||||
|
||||
#pragma code_seg("sm2")
|
||||
|
||||
__forceinline float x_Abs(float af_Value)
|
||||
{
|
||||
__asm fld af_Value
|
||||
__asm fabs
|
||||
}
|
||||
|
||||
#pragma code_seg("sm3")
|
||||
|
||||
float x_Sin(float af_Value)
|
||||
{
|
||||
__asm fld af_Value
|
||||
__asm fsin
|
||||
}
|
||||
|
||||
#pragma code_seg("sm4")
|
||||
|
||||
float x_Sign(float af_Value)
|
||||
{
|
||||
if (af_Value != 0)
|
||||
return af_Value / x_Abs(af_Value);
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
#pragma code_seg("sm5")
|
||||
|
||||
float x_Sqrt(float af_Value)
|
||||
{
|
||||
__asm fld af_Value
|
||||
__asm fsqrt
|
||||
}
|
||||
|
||||
#pragma code_seg("sm7")
|
||||
|
||||
__forceinline void x_MemCopy(void* av_Dest_, const void* av_Src_, size_t ai_Size)
|
||||
{
|
||||
__asm mov esi, av_Src_
|
||||
__asm mov edi, av_Dest_
|
||||
__asm mov ecx, ai_Size
|
||||
__asm rep movsb
|
||||
}
|
||||
|
||||
#pragma code_seg("sm8")
|
||||
|
||||
float x_Fmod(float x, float y)
|
||||
{
|
||||
__asm fld y
|
||||
__asm fld x
|
||||
__asm fprem
|
||||
__asm fxch
|
||||
__asm fstp x
|
||||
}
|
||||
|
||||
#pragma data_seg("smA")
|
||||
|
||||
static unsigned long seed=0x12345678;
|
||||
|
||||
#pragma code_seg("sm9")
|
||||
|
||||
__forceinline void x_Randomize(unsigned long x)
|
||||
{
|
||||
seed = x;
|
||||
}
|
||||
|
||||
#pragma code_seg("smB")
|
||||
|
||||
float x_Rand()
|
||||
{
|
||||
seed = seed * 0x76364873 + 1234567;
|
||||
return (float)(seed & 0x7FFFFFFF) * (const float)(2.0f / (float)0x7FFFFFFF) - 1.0f;
|
||||
}
|
||||
|
||||
#pragma code_seg("smS")
|
||||
|
||||
__forceinline size_t x_Strlen(const char* as_String)
|
||||
{
|
||||
size_t li_Length = 0;
|
||||
while (*as_String++) ++li_Length;
|
||||
return li_Length;
|
||||
}
|
||||
|
||||
#pragma code_seg("smP")
|
||||
|
||||
float x_Pow(float x, float y){
|
||||
float r;
|
||||
__asm{
|
||||
fld y
|
||||
fld x
|
||||
fyl2x
|
||||
fld1
|
||||
fld st(1)
|
||||
fprem
|
||||
f2xm1
|
||||
faddp st(1),st
|
||||
fscale
|
||||
fxch st(1)
|
||||
fstp st(0)
|
||||
fstp r
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
int _fltused = 1;
|
||||
}
|
||||
23
underwater4k/switches.txt
Normal file
23
underwater4k/switches.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
/O1
|
||||
/Oi
|
||||
/Os
|
||||
/D "WIN32"
|
||||
/D "NDEBUG"
|
||||
/D "_WINDOWS"
|
||||
/FD
|
||||
/MT
|
||||
/GS-
|
||||
/GR-
|
||||
/Fp".\obj\bp4k_Compress_Slow/cmath.pch"
|
||||
/FAs
|
||||
/Fa".\obj\bp4k_Compress_Slow/"
|
||||
/Fo".\obj\bp4k_Compress_Slow/"
|
||||
/Fd".\obj\bp4k_Compress_Slow/"
|
||||
/FR".\obj\bp4k_Compress_Slow\\"
|
||||
/W0
|
||||
/nologo
|
||||
/c
|
||||
/Zi
|
||||
/Gz
|
||||
/TP
|
||||
/errorReport:prompt
|
||||
81
underwater4k/tex1.glsl
Normal file
81
underwater4k/tex1.glsl
Normal file
@@ -0,0 +1,81 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
float rnd(vec2 p)
|
||||
{
|
||||
p.x += p.y * 57.;
|
||||
return sin(cos(p.x) * p.x);
|
||||
}
|
||||
|
||||
float scale;
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = mod(p, scale);
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p, float s )
|
||||
{
|
||||
scale = s;
|
||||
p *= s;
|
||||
vec2 i = floor( p );
|
||||
vec2 f = fract( p );
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
p = mod(p, 1.0);
|
||||
float min1 = 1, min2 = 1; float seed = 10; const int numPoints = 256;
|
||||
for (int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
vec2 pointPos = vec2(rnd(vec2(0, seed++)), rnd(vec2(1, seed++)))*.5+.5;
|
||||
//pointPos += vec2(sin(Z.z+rnd(vec2(0, seed++))), cos(Z.z+rnd(vec2(1, seed++))))*0.1;
|
||||
vec2 d = abs(p - pointPos);
|
||||
vec2 s = step(0.5, d);
|
||||
d = s+d*(-s*2+1);
|
||||
float dist = length(d);
|
||||
if (dist < min2)
|
||||
{
|
||||
if (dist < min1)
|
||||
{
|
||||
min2 = min1;
|
||||
min1 = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
min2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return pow(1.0 - (min2 - min1), 32.0);
|
||||
return (min2 - min1) * 8.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = gl_FragCoord.xy / Z.xy;
|
||||
float l = voronoi(p);
|
||||
|
||||
float f = 0.5;
|
||||
float seed = 10.0;
|
||||
for (float t = 2.0; t <= Z.x; t *= 2.0)
|
||||
{
|
||||
f += (0.5 / pow(t, 0.8)) * noise(p,t);
|
||||
}
|
||||
gl_FragColor = vec4(l,f,l,1);
|
||||
}
|
||||
81
underwater4k/tex1.glsl_0
Normal file
81
underwater4k/tex1.glsl_0
Normal file
@@ -0,0 +1,81 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
float rnd(vec2 p)
|
||||
{
|
||||
p.x += p.y * 57.;
|
||||
return sin(cos(p.x) * p.x);
|
||||
}
|
||||
|
||||
float scale;
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = mod(p, scale);
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p, float s )
|
||||
{
|
||||
scale = s;
|
||||
p *= s;
|
||||
vec2 i = floor( p );
|
||||
vec2 f = fract( p );
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
p = mod(p, 1.0);
|
||||
float min1 = 1, min2 = 1; float seed = 10; const int numPoints = 256;
|
||||
for (int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
vec2 pointPos = vec2(rnd(vec2(0, seed++)), rnd(vec2(1, seed++)))*.5+.5;
|
||||
//pointPos += vec2(sin(Z.z+rnd(vec2(0, seed++))), cos(Z.z+rnd(vec2(1, seed++))))*0.1;
|
||||
vec2 d = abs(p - pointPos);
|
||||
vec2 s = step(0.5, d);
|
||||
d = s+d*(-s*2+1);
|
||||
float dist = length(d);
|
||||
if (dist < min2)
|
||||
{
|
||||
if (dist < min1)
|
||||
{
|
||||
min2 = min1;
|
||||
min1 = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
min2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return pow(1.0 - (min2 - min1), 32.0);
|
||||
return 1.0 - min1 * 10.0;//(min2 - min1) * 8.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = gl_FragCoord.xy / Z.xy;
|
||||
float l = voronoi(p);
|
||||
|
||||
float f = 0.5;
|
||||
float seed = 10.0;
|
||||
for (float t = 2.0; t <= Z.x; t *= 2.0)
|
||||
{
|
||||
f += (0.5 / pow(t, 0.8)) * noise(p,t);
|
||||
}
|
||||
gl_FragColor = vec4(l,f,l,1);
|
||||
}
|
||||
81
underwater4k/tex1.glsl_0_dbg
Normal file
81
underwater4k/tex1.glsl_0_dbg
Normal file
@@ -0,0 +1,81 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
float rnd(vec2 p)
|
||||
{
|
||||
p.x += p.y * 57.;
|
||||
return sin(cos(p.x) * p.x);
|
||||
}
|
||||
|
||||
float scale;
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = mod(p, scale);
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p, float s )
|
||||
{
|
||||
scale = s;
|
||||
p *= s;
|
||||
vec2 i = floor( p );
|
||||
vec2 f = fract( p );
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
p = mod(p, 1.0);
|
||||
float min1 = 1, min2 = 1; float seed = 10; const int numPoints = 256;
|
||||
for (int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
vec2 pointPos = vec2(rnd(vec2(0, seed++)), rnd(vec2(1, seed++)))*.5+.5;
|
||||
//pointPos += vec2(sin(Z.z+rnd(vec2(0, seed++))), cos(Z.z+rnd(vec2(1, seed++))))*0.1;
|
||||
vec2 d = abs(p - pointPos);
|
||||
vec2 s = step(0.5, d);
|
||||
d = s+d*(-s*2+1);
|
||||
float dist = length(d);
|
||||
if (dist < min2)
|
||||
{
|
||||
if (dist < min1)
|
||||
{
|
||||
min2 = min1;
|
||||
min1 = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
min2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return pow(1.0 - (min2 - min1), 32.0);
|
||||
return 1.0 - min1 * 10.0;//(min2 - min1) * 8.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = gl_FragCoord.xy / Z.xy;
|
||||
float l = voronoi(p);
|
||||
|
||||
float f = 0.5;
|
||||
float seed = 10.0;
|
||||
for (float t = 2.0; t <= Z.x; t *= 2.0)
|
||||
{
|
||||
f += (0.5 / pow(t, 0.8)) * noise(p,t);
|
||||
}
|
||||
gl_FragColor = vec4(l,f,l,1);
|
||||
}
|
||||
81
underwater4k/tex1.glsl_1
Normal file
81
underwater4k/tex1.glsl_1
Normal file
@@ -0,0 +1,81 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
float rnd(vec2 p)
|
||||
{
|
||||
p.x += p.y * 57.;
|
||||
return sin(cos(p.x) * p.x);
|
||||
}
|
||||
|
||||
float scale;
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = mod(p, scale);
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p, float s )
|
||||
{
|
||||
scale = s;
|
||||
p *= s;
|
||||
vec2 i = floor( p );
|
||||
vec2 f = fract( p );
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
p = mod(p, 1.0);
|
||||
float min1 = 1, min2 = 1; float seed = 10; const int numPoints = 256;
|
||||
for (int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
vec2 pointPos = vec2(rnd(vec2(0, seed++)), rnd(vec2(1, seed++)))*.5+.5;
|
||||
//pointPos += vec2(sin(Z.z+rnd(vec2(0, seed++))), cos(Z.z+rnd(vec2(1, seed++))))*0.1;
|
||||
vec2 d = abs(p - pointPos);
|
||||
vec2 s = step(0.5, d);
|
||||
d = s+d*(-s*2+1);
|
||||
float dist = length(d);
|
||||
if (dist < min2)
|
||||
{
|
||||
if (dist < min1)
|
||||
{
|
||||
min2 = min1;
|
||||
min1 = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
min2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return pow(1.0 - (min2 - min1), 32.0);
|
||||
return 1.0 - min1 * 10.0;//(min2 - min1) * 8.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = gl_FragCoord.xy / Z.xy;
|
||||
float l = voronoi(p);
|
||||
|
||||
float f = 0.5;
|
||||
float seed = 10.0;
|
||||
for (float t = 2.0; t <= Z.x; t *= 2.0)
|
||||
{
|
||||
f += (0.5 / pow(t, 0.8)) * noise(p,t);
|
||||
}
|
||||
gl_FragColor = vec4(l,f,l,1);
|
||||
}
|
||||
81
underwater4k/tex1.glsl_1_dbg
Normal file
81
underwater4k/tex1.glsl_1_dbg
Normal file
@@ -0,0 +1,81 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
float rnd(vec2 p)
|
||||
{
|
||||
p.x += p.y * 57.;
|
||||
return sin(cos(p.x) * p.x);
|
||||
}
|
||||
|
||||
float scale;
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = mod(p, scale);
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p, float s )
|
||||
{
|
||||
scale = s;
|
||||
p *= s;
|
||||
vec2 i = floor( p );
|
||||
vec2 f = fract( p );
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
p = mod(p, 1.0);
|
||||
float min1 = 1, min2 = 1; float seed = 10; const int numPoints = 256;
|
||||
for (int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
vec2 pointPos = vec2(rnd(vec2(0, seed++)), rnd(vec2(1, seed++)))*.5+.5;
|
||||
//pointPos += vec2(sin(Z.z+rnd(vec2(0, seed++))), cos(Z.z+rnd(vec2(1, seed++))))*0.1;
|
||||
vec2 d = abs(p - pointPos);
|
||||
vec2 s = step(0.5, d);
|
||||
d = s+d*(-s*2+1);
|
||||
float dist = length(d);
|
||||
if (dist < min2)
|
||||
{
|
||||
if (dist < min1)
|
||||
{
|
||||
min2 = min1;
|
||||
min1 = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
min2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return pow(1.0 - (min2 - min1), 32.0);
|
||||
return 1.0 - min1 * 10.0;//(min2 - min1) * 8.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = gl_FragCoord.xy / Z.xy;
|
||||
float l = voronoi(p);
|
||||
|
||||
float f = 0.5;
|
||||
float seed = 10.0;
|
||||
for (float t = 2.0; t <= Z.x; t *= 2.0)
|
||||
{
|
||||
f += (0.5 / pow(t, 0.8)) * noise(p,t);
|
||||
}
|
||||
gl_FragColor = vec4(l,f,l,1);
|
||||
}
|
||||
81
underwater4k/tex1.glsl_2
Normal file
81
underwater4k/tex1.glsl_2
Normal file
@@ -0,0 +1,81 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
float rnd(vec2 p)
|
||||
{
|
||||
p.x += p.y * 57.;
|
||||
return sin(cos(p.x) * p.x);
|
||||
}
|
||||
|
||||
float scale;
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = mod(p, scale);
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p, float s )
|
||||
{
|
||||
scale = s;
|
||||
p *= s;
|
||||
vec2 i = floor( p );
|
||||
vec2 f = fract( p );
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
p = mod(p, 1.0);
|
||||
float min1 = 1, min2 = 1; float seed = 10; const int numPoints = 256;
|
||||
for (int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
vec2 pointPos = vec2(rnd(vec2(0, seed++)), rnd(vec2(1, seed++)))*.5+.5;
|
||||
//pointPos += vec2(sin(Z.z+rnd(vec2(0, seed++))), cos(Z.z+rnd(vec2(1, seed++))))*0.1;
|
||||
vec2 d = abs(p - pointPos);
|
||||
vec2 s = step(0.5, d);
|
||||
d = s+d*(-s*2+1);
|
||||
float dist = length(d);
|
||||
if (dist < min2)
|
||||
{
|
||||
if (dist < min1)
|
||||
{
|
||||
min2 = min1;
|
||||
min1 = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
min2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return pow(1.0 - (min2 - min1), 32.0);
|
||||
return 1.0 - min1 * 10.0;//(min2 - min1) * 8.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = gl_FragCoord.xy / Z.xy;
|
||||
float l = voronoi(p);
|
||||
|
||||
float f = 0.5;
|
||||
float seed = 10.0;
|
||||
for (float t = 2.0; t <= Z.x; t *= 2.0)
|
||||
{
|
||||
f += (0.5 / pow(t, 0.8)) * noise(p,t);
|
||||
}
|
||||
gl_FragColor = vec4(l,f,l,1);
|
||||
}
|
||||
81
underwater4k/tex1.glsl_2_dbg
Normal file
81
underwater4k/tex1.glsl_2_dbg
Normal file
@@ -0,0 +1,81 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
float rnd(vec2 p)
|
||||
{
|
||||
p.x += p.y * 57.;
|
||||
return sin(cos(p.x) * p.x);
|
||||
}
|
||||
|
||||
float scale;
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = mod(p, scale);
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p, float s )
|
||||
{
|
||||
scale = s;
|
||||
p *= s;
|
||||
vec2 i = floor( p );
|
||||
vec2 f = fract( p );
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
p = mod(p, 1.0);
|
||||
float min1 = 1, min2 = 1; float seed = 10; const int numPoints = 256;
|
||||
for (int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
vec2 pointPos = vec2(rnd(vec2(0, seed++)), rnd(vec2(1, seed++)))*.5+.5;
|
||||
//pointPos += vec2(sin(Z.z+rnd(vec2(0, seed++))), cos(Z.z+rnd(vec2(1, seed++))))*0.1;
|
||||
vec2 d = abs(p - pointPos);
|
||||
vec2 s = step(0.5, d);
|
||||
d = s+d*(-s*2+1);
|
||||
float dist = length(d);
|
||||
if (dist < min2)
|
||||
{
|
||||
if (dist < min1)
|
||||
{
|
||||
min2 = min1;
|
||||
min1 = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
min2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return pow(1.0 - (min2 - min1), 32.0);
|
||||
return 1.0 - min1 * 10.0;//(min2 - min1) * 8.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = gl_FragCoord.xy / Z.xy;
|
||||
float l = voronoi(p);
|
||||
|
||||
float f = 0.5;
|
||||
float seed = 10.0;
|
||||
for (float t = 2.0; t <= Z.x; t *= 2.0)
|
||||
{
|
||||
f += (0.5 / pow(t, 0.8)) * noise(p,t);
|
||||
}
|
||||
gl_FragColor = vec4(l,f,l,1);
|
||||
}
|
||||
81
underwater4k/tex1.glsl_3
Normal file
81
underwater4k/tex1.glsl_3
Normal file
@@ -0,0 +1,81 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
float rnd(vec2 p)
|
||||
{
|
||||
p.x += p.y * 57.;
|
||||
return sin(cos(p.x) * p.x);
|
||||
}
|
||||
|
||||
float scale;
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = mod(p, scale);
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p, float s )
|
||||
{
|
||||
scale = s;
|
||||
p *= s;
|
||||
vec2 i = floor( p );
|
||||
vec2 f = fract( p );
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
p = mod(p, 1.0);
|
||||
float min1 = 1, min2 = 1; float seed = 10; const int numPoints = 256;
|
||||
for (int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
vec2 pointPos = vec2(rnd(vec2(0, seed++)), rnd(vec2(1, seed++)))*.5+.5;
|
||||
//pointPos += vec2(sin(Z.z+rnd(vec2(0, seed++))), cos(Z.z+rnd(vec2(1, seed++))))*0.1;
|
||||
vec2 d = abs(p - pointPos);
|
||||
vec2 s = step(0.5, d);
|
||||
d = s+d*(-s*2+1);
|
||||
float dist = length(d);
|
||||
if (dist < min2)
|
||||
{
|
||||
if (dist < min1)
|
||||
{
|
||||
min2 = min1;
|
||||
min1 = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
min2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return pow(1.0 - (min2 - min1), 32.0);
|
||||
return 1.0 - min1 * 10.0;//(min2 - min1) * 8.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = gl_FragCoord.xy / Z.xy;
|
||||
float l = voronoi(p);
|
||||
|
||||
float f = 0.5;
|
||||
float seed = 10.0;
|
||||
for (float t = 2.0; t <= Z.x; t *= 2.0)
|
||||
{
|
||||
f += (0.5 / pow(t, 0.8)) * noise(p,t);
|
||||
}
|
||||
gl_FragColor = vec4(l,f,l,1);
|
||||
}
|
||||
81
underwater4k/tex1.glsl_3_dbg
Normal file
81
underwater4k/tex1.glsl_3_dbg
Normal file
@@ -0,0 +1,81 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
float rnd(vec2 p)
|
||||
{
|
||||
p.x += p.y * 57.;
|
||||
return sin(cos(p.x) * p.x);
|
||||
}
|
||||
|
||||
float scale;
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = mod(p, scale);
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p, float s )
|
||||
{
|
||||
scale = s;
|
||||
p *= s;
|
||||
vec2 i = floor( p );
|
||||
vec2 f = fract( p );
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
p = mod(p, 1.0);
|
||||
float min1 = 1, min2 = 1; float seed = 10; const int numPoints = 256;
|
||||
for (int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
vec2 pointPos = vec2(rnd(vec2(0, seed++)), rnd(vec2(1, seed++)))*.5+.5;
|
||||
//pointPos += vec2(sin(Z.z+rnd(vec2(0, seed++))), cos(Z.z+rnd(vec2(1, seed++))))*0.1;
|
||||
vec2 d = abs(p - pointPos);
|
||||
vec2 s = step(0.5, d);
|
||||
d = s+d*(-s*2+1);
|
||||
float dist = length(d);
|
||||
if (dist < min2)
|
||||
{
|
||||
if (dist < min1)
|
||||
{
|
||||
min2 = min1;
|
||||
min1 = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
min2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return pow(1.0 - (min2 - min1), 32.0);
|
||||
return 1.0 - min1 * 10.0;//(min2 - min1) * 8.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = gl_FragCoord.xy / Z.xy;
|
||||
float l = voronoi(p);
|
||||
|
||||
float f = 0.5;
|
||||
float seed = 10.0;
|
||||
for (float t = 2.0; t <= Z.x; t *= 2.0)
|
||||
{
|
||||
f += (0.5 / pow(t, 0.8)) * noise(p,t);
|
||||
}
|
||||
gl_FragColor = vec4(l,f,l,1);
|
||||
}
|
||||
31
underwater4k/tex2.glsl
Normal file
31
underwater4k/tex2.glsl
Normal file
@@ -0,0 +1,31 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
uniform sampler2D V;
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
return (0.01 + ((.25*texture2D(V, p * 128.0).x) + texture2D(V, p * 32.0).x)) * smoothstep(0.25, 0.35, texture2D(V, p * 11).y * texture2D(V, p * 13).y);
|
||||
}
|
||||
|
||||
float texnoise(vec2 p)
|
||||
{
|
||||
return texture2D(V, p).y;
|
||||
}
|
||||
|
||||
float grass(vec2 p)
|
||||
{
|
||||
return texnoise(p * 57) * texnoise(p * 13) * 2.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 x = gl_FragCoord.xy / Z.xy;
|
||||
float vrn = voronoi(x);
|
||||
float r = -0.16 + texnoise(x) * 0.3 + mix(grass(x)*.5, vrn, smoothstep(0.0, 0.05,vrn)) * 0.002; // This line creates one entire continent and a big ocean!
|
||||
gl_FragColor = vec4(r,r,r,1);
|
||||
}
|
||||
31
underwater4k/tex2.glsl_0
Normal file
31
underwater4k/tex2.glsl_0
Normal file
@@ -0,0 +1,31 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
uniform sampler2D V;
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
return (0.01 + ((.25*texture2D(V, p * 128.0).x) + texture2D(V, p * 32.0).x)) * smoothstep(0.25, 0.35, texture2D(V, p * 11).y * texture2D(V, p * 13).y);
|
||||
}
|
||||
|
||||
float texnoise(vec2 p)
|
||||
{
|
||||
return texture2D(V, p).y;
|
||||
}
|
||||
|
||||
float grass(vec2 p)
|
||||
{
|
||||
return texnoise(p * 57) * texnoise(p * 13) * 2.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 x = gl_FragCoord.xy / Z.xy;
|
||||
float vrn = voronoi(x);
|
||||
float r = -0.16 + texnoise(x) * 0.3 + mix(grass(x)*.5, vrn, smoothstep(0.0, 0.05,vrn)) * 0.002; // This line creates one entire continent and a big ocean!
|
||||
gl_FragColor = vec4(r,r,r,1);
|
||||
}
|
||||
31
underwater4k/tex2.glsl_0_dbg
Normal file
31
underwater4k/tex2.glsl_0_dbg
Normal file
@@ -0,0 +1,31 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
uniform sampler2D V;
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
return (0.01 + ((.25*texture2D(V, p * 128.0).x) + texture2D(V, p * 32.0).x)) * smoothstep(0.25, 0.35, texture2D(V, p * 11).y * texture2D(V, p * 13).y);
|
||||
}
|
||||
|
||||
float texnoise(vec2 p)
|
||||
{
|
||||
return texture2D(V, p).y;
|
||||
}
|
||||
|
||||
float grass(vec2 p)
|
||||
{
|
||||
return texnoise(p * 57) * texnoise(p * 13) * 2.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 x = gl_FragCoord.xy / Z.xy;
|
||||
float vrn = voronoi(x);
|
||||
float r = -0.16 + texnoise(x) * 0.3 + mix(grass(x)*.5, vrn, smoothstep(0.0, 0.05,vrn)) * 0.002; // This line creates one entire continent and a big ocean!
|
||||
gl_FragColor = vec4(r,r,r,1);
|
||||
}
|
||||
31
underwater4k/tex2.glsl_1
Normal file
31
underwater4k/tex2.glsl_1
Normal file
@@ -0,0 +1,31 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
uniform sampler2D V;
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
return (0.01 + ((.25*texture2D(V, p * 128.0).x) + texture2D(V, p * 32.0).x)) * smoothstep(0.25, 0.35, texture2D(V, p * 11).y * texture2D(V, p * 13).y);
|
||||
}
|
||||
|
||||
float texnoise(vec2 p)
|
||||
{
|
||||
return texture2D(V, p).y;
|
||||
}
|
||||
|
||||
float grass(vec2 p)
|
||||
{
|
||||
return texnoise(p * 57) * texnoise(p * 13) * 2.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 x = gl_FragCoord.xy / Z.xy;
|
||||
float vrn = voronoi(x);
|
||||
float r = -0.16 + texnoise(x) * 0.3 + mix(grass(x)*.5, vrn, smoothstep(0.0, 0.05,vrn)) * 0.002; // This line creates one entire continent and a big ocean!
|
||||
gl_FragColor = vec4(r,r,r,1);
|
||||
}
|
||||
31
underwater4k/tex2.glsl_1_dbg
Normal file
31
underwater4k/tex2.glsl_1_dbg
Normal file
@@ -0,0 +1,31 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
uniform sampler2D V;
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
return (0.01 + ((.25*texture2D(V, p * 128.0).x) + texture2D(V, p * 32.0).x)) * smoothstep(0.25, 0.35, texture2D(V, p * 11).y * texture2D(V, p * 13).y);
|
||||
}
|
||||
|
||||
float texnoise(vec2 p)
|
||||
{
|
||||
return texture2D(V, p).y;
|
||||
}
|
||||
|
||||
float grass(vec2 p)
|
||||
{
|
||||
return texnoise(p * 57) * texnoise(p * 13) * 2.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 x = gl_FragCoord.xy / Z.xy;
|
||||
float vrn = voronoi(x);
|
||||
float r = -0.16 + texnoise(x) * 0.3 + mix(grass(x)*.5, vrn, smoothstep(0.0, 0.05,vrn)) * 0.002; // This line creates one entire continent and a big ocean!
|
||||
gl_FragColor = vec4(r,r,r,1);
|
||||
}
|
||||
31
underwater4k/tex2.glsl_2
Normal file
31
underwater4k/tex2.glsl_2
Normal file
@@ -0,0 +1,31 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
uniform sampler2D V;
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
return (0.01 + ((.25*texture2D(V, p * 128.0).x) + texture2D(V, p * 32.0).x)) * smoothstep(0.25, 0.35, texture2D(V, p * 11).y * texture2D(V, p * 13).y);
|
||||
}
|
||||
|
||||
float texnoise(vec2 p)
|
||||
{
|
||||
return texture2D(V, p).y;
|
||||
}
|
||||
|
||||
float grass(vec2 p)
|
||||
{
|
||||
return texnoise(p * 57) * texnoise(p * 13) * 2.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 x = gl_FragCoord.xy / Z.xy;
|
||||
float vrn = voronoi(x);
|
||||
float r = -0.16 + texnoise(x) * 0.3 + mix(grass(x)*.5, vrn, smoothstep(0.0, 0.05,vrn)) * 0.002; // This line creates one entire continent and a big ocean!
|
||||
gl_FragColor = vec4(r,r,r,1);
|
||||
}
|
||||
31
underwater4k/tex2.glsl_2_dbg
Normal file
31
underwater4k/tex2.glsl_2_dbg
Normal file
@@ -0,0 +1,31 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
uniform sampler2D V;
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
return (0.01 + ((.25*texture2D(V, p * 128.0).x) + texture2D(V, p * 32.0).x)) * smoothstep(0.25, 0.35, texture2D(V, p * 11).y * texture2D(V, p * 13).y);
|
||||
}
|
||||
|
||||
float texnoise(vec2 p)
|
||||
{
|
||||
return texture2D(V, p).y;
|
||||
}
|
||||
|
||||
float grass(vec2 p)
|
||||
{
|
||||
return texnoise(p * 57) * texnoise(p * 13) * 2.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 x = gl_FragCoord.xy / Z.xy;
|
||||
float vrn = voronoi(x);
|
||||
float r = -0.16 + texnoise(x) * 0.3 + mix(grass(x)*.5, vrn, smoothstep(0.0, 0.05,vrn)) * 0.002; // This line creates one entire continent and a big ocean!
|
||||
gl_FragColor = vec4(r,r,r,1);
|
||||
}
|
||||
31
underwater4k/tex2.glsl_3
Normal file
31
underwater4k/tex2.glsl_3
Normal file
@@ -0,0 +1,31 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
uniform sampler2D V;
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
return (0.01 + ((.25*texture2D(V, p * 128.0).x) + texture2D(V, p * 32.0).x)) * smoothstep(0.25, 0.35, texture2D(V, p * 11).y * texture2D(V, p * 13).y);
|
||||
}
|
||||
|
||||
float texnoise(vec2 p)
|
||||
{
|
||||
return texture2D(V, p).y;
|
||||
}
|
||||
|
||||
float grass(vec2 p)
|
||||
{
|
||||
return texnoise(p * 57) * texnoise(p * 13) * 2.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 x = gl_FragCoord.xy / Z.xy;
|
||||
float vrn = voronoi(x);
|
||||
float r = -0.16 + texnoise(x) * 0.3 + mix(grass(x)*.5, vrn, smoothstep(0.0, 0.05,vrn)) * 0.002; // This line creates one entire continent and a big ocean!
|
||||
gl_FragColor = vec4(r,r,r,1);
|
||||
}
|
||||
31
underwater4k/tex2.glsl_3_dbg
Normal file
31
underwater4k/tex2.glsl_3_dbg
Normal file
@@ -0,0 +1,31 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
uniform sampler2D V;
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
return (0.01 + ((.25*texture2D(V, p * 128.0).x) + texture2D(V, p * 32.0).x)) * smoothstep(0.25, 0.35, texture2D(V, p * 11).y * texture2D(V, p * 13).y);
|
||||
}
|
||||
|
||||
float texnoise(vec2 p)
|
||||
{
|
||||
return texture2D(V, p).y;
|
||||
}
|
||||
|
||||
float grass(vec2 p)
|
||||
{
|
||||
return texnoise(p * 57) * texnoise(p * 13) * 2.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 x = gl_FragCoord.xy / Z.xy;
|
||||
float vrn = voronoi(x);
|
||||
float r = -0.16 + texnoise(x) * 0.3 + mix(grass(x)*.5, vrn, smoothstep(0.0, 0.05,vrn)) * 0.002; // This line creates one entire continent and a big ocean!
|
||||
gl_FragColor = vec4(r,r,r,1);
|
||||
}
|
||||
81
underwater4k/texture.glsl
Normal file
81
underwater4k/texture.glsl
Normal file
@@ -0,0 +1,81 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
float rnd(vec2 p)
|
||||
{
|
||||
p.x += p.y * 57.;
|
||||
return sin(cos(p.x) * p.x);
|
||||
}
|
||||
|
||||
float scale;
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = mod(p, scale);
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p, float s )
|
||||
{
|
||||
scale = s;
|
||||
p *= s;
|
||||
vec2 i = floor( p );
|
||||
vec2 f = fract( p );
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
p = mod(p, 1.0);
|
||||
float min1 = 1, min2 = 1; float seed = 10; const int numPoints = 256;
|
||||
for (int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
vec2 pointPos = vec2(rnd(vec2(0, seed++)), rnd(vec2(1, seed++)))*.5+.5;
|
||||
//pointPos += vec2(sin(Z.z+rnd(vec2(0, seed++))), cos(Z.z+rnd(vec2(1, seed++))))*0.1;
|
||||
vec2 d = abs(p - pointPos);
|
||||
vec2 s = step(0.5, d);
|
||||
d = s+d*(-s*2+1);
|
||||
float dist = length(d);
|
||||
if (dist < min2)
|
||||
{
|
||||
if (dist < min1)
|
||||
{
|
||||
min2 = min1;
|
||||
min1 = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
min2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return pow(1.0 - (min2 - min1), 32.0);
|
||||
return (min2 - min1) * 8.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = gl_FragCoord.xy / Z.xy;
|
||||
float l = voronoi(p);
|
||||
|
||||
float f = 0.5;
|
||||
float seed = 10.0;
|
||||
for (float t = 2.0; t <= Z.x; t *= 2.0)
|
||||
{
|
||||
f += (0.5 / pow(t, 0.6)) * noise(p,t);
|
||||
}
|
||||
gl_FragColor = vec4(l,f,l,1);
|
||||
}
|
||||
81
underwater4k/texture.glsl_0
Normal file
81
underwater4k/texture.glsl_0
Normal file
@@ -0,0 +1,81 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
float rnd(vec2 p)
|
||||
{
|
||||
p.x += p.y * 57.;
|
||||
return sin(cos(p.x) * p.x);
|
||||
}
|
||||
|
||||
float scale;
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = mod(p, scale);
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p, float s )
|
||||
{
|
||||
scale = s;
|
||||
p *= s;
|
||||
vec2 i = floor( p );
|
||||
vec2 f = fract( p );
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
p = mod(p, 1.0);
|
||||
float min1 = 1, min2 = 1; float seed = 10; const int numPoints = 256;
|
||||
for (int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
vec2 pointPos = vec2(rnd(vec2(0, seed++)), rnd(vec2(1, seed++)))*.5+.5;
|
||||
//pointPos += vec2(sin(Z.z+rnd(vec2(0, seed++))), cos(Z.z+rnd(vec2(1, seed++))))*0.1;
|
||||
vec2 d = abs(p - pointPos);
|
||||
vec2 s = step(0.5, d);
|
||||
d = s+d*(-s*2+1);
|
||||
float dist = length(d);
|
||||
if (dist < min2)
|
||||
{
|
||||
if (dist < min1)
|
||||
{
|
||||
min2 = min1;
|
||||
min1 = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
min2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return pow(1.0 - (min2 - min1), 32.0);
|
||||
return (min2 - min1) * 8.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = gl_FragCoord.xy / Z.xy;
|
||||
float l = voronoi(p);
|
||||
|
||||
float f = 0.5;
|
||||
float seed = 10.0;
|
||||
for (float t = 2.0; t <= Z.x; t *= 2.0)
|
||||
{
|
||||
f += (0.5 / pow(t, 0.6)) * noise(p,t);
|
||||
}
|
||||
gl_FragColor = vec4(l,f,l,1);
|
||||
}
|
||||
81
underwater4k/texture.glsl_0_dbg
Normal file
81
underwater4k/texture.glsl_0_dbg
Normal file
@@ -0,0 +1,81 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
float rnd(vec2 p)
|
||||
{
|
||||
p.x += p.y * 57.;
|
||||
return sin(cos(p.x) * p.x);
|
||||
}
|
||||
|
||||
float scale;
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = mod(p, scale);
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p, float s )
|
||||
{
|
||||
scale = s;
|
||||
p *= s;
|
||||
vec2 i = floor( p );
|
||||
vec2 f = fract( p );
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
p = mod(p, 1.0);
|
||||
float min1 = 1, min2 = 1; float seed = 10; const int numPoints = 256;
|
||||
for (int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
vec2 pointPos = vec2(rnd(vec2(0, seed++)), rnd(vec2(1, seed++)))*.5+.5;
|
||||
//pointPos += vec2(sin(Z.z+rnd(vec2(0, seed++))), cos(Z.z+rnd(vec2(1, seed++))))*0.1;
|
||||
vec2 d = abs(p - pointPos);
|
||||
vec2 s = step(0.5, d);
|
||||
d = s+d*(-s*2+1);
|
||||
float dist = length(d);
|
||||
if (dist < min2)
|
||||
{
|
||||
if (dist < min1)
|
||||
{
|
||||
min2 = min1;
|
||||
min1 = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
min2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return pow(1.0 - (min2 - min1), 32.0);
|
||||
return (min2 - min1) * 8.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = gl_FragCoord.xy / Z.xy;
|
||||
float l = voronoi(p);
|
||||
|
||||
float f = 0.5;
|
||||
float seed = 10.0;
|
||||
for (float t = 2.0; t <= Z.x; t *= 2.0)
|
||||
{
|
||||
f += (0.5 / pow(t, 0.6)) * noise(p,t);
|
||||
}
|
||||
gl_FragColor = vec4(l,f,l,1);
|
||||
}
|
||||
81
underwater4k/texture.glsl_1
Normal file
81
underwater4k/texture.glsl_1
Normal file
@@ -0,0 +1,81 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
float rnd(vec2 p)
|
||||
{
|
||||
p.x += p.y * 57.;
|
||||
return sin(cos(p.x) * p.x);
|
||||
}
|
||||
|
||||
float scale;
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = mod(p, scale);
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p, float s )
|
||||
{
|
||||
scale = s;
|
||||
p *= s;
|
||||
vec2 i = floor( p );
|
||||
vec2 f = fract( p );
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
p = mod(p, 1.0);
|
||||
float min1 = 1, min2 = 1; float seed = 10; const int numPoints = 256;
|
||||
for (int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
vec2 pointPos = vec2(rnd(vec2(0, seed++)), rnd(vec2(1, seed++)))*.5+.5;
|
||||
//pointPos += vec2(sin(Z.z+rnd(vec2(0, seed++))), cos(Z.z+rnd(vec2(1, seed++))))*0.1;
|
||||
vec2 d = abs(p - pointPos);
|
||||
vec2 s = step(0.5, d);
|
||||
d = s+d*(-s*2+1);
|
||||
float dist = length(d);
|
||||
if (dist < min2)
|
||||
{
|
||||
if (dist < min1)
|
||||
{
|
||||
min2 = min1;
|
||||
min1 = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
min2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return pow(1.0 - (min2 - min1), 32.0);
|
||||
return (min2 - min1) * 8.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = gl_FragCoord.xy / Z.xy;
|
||||
float l = voronoi(p);
|
||||
|
||||
float f = 0.5;
|
||||
float seed = 10.0;
|
||||
for (float t = 2.0; t <= Z.x; t *= 2.0)
|
||||
{
|
||||
f += (0.5 / pow(t, 0.6)) * noise(p,t);
|
||||
}
|
||||
gl_FragColor = vec4(l,f,l,1);
|
||||
}
|
||||
81
underwater4k/texture.glsl_1_dbg
Normal file
81
underwater4k/texture.glsl_1_dbg
Normal file
@@ -0,0 +1,81 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
float rnd(vec2 p)
|
||||
{
|
||||
p.x += p.y * 57.;
|
||||
return sin(cos(p.x) * p.x);
|
||||
}
|
||||
|
||||
float scale;
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = mod(p, scale);
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p, float s )
|
||||
{
|
||||
scale = s;
|
||||
p *= s;
|
||||
vec2 i = floor( p );
|
||||
vec2 f = fract( p );
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
p = mod(p, 1.0);
|
||||
float min1 = 1, min2 = 1; float seed = 10; const int numPoints = 256;
|
||||
for (int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
vec2 pointPos = vec2(rnd(vec2(0, seed++)), rnd(vec2(1, seed++)))*.5+.5;
|
||||
//pointPos += vec2(sin(Z.z+rnd(vec2(0, seed++))), cos(Z.z+rnd(vec2(1, seed++))))*0.1;
|
||||
vec2 d = abs(p - pointPos);
|
||||
vec2 s = step(0.5, d);
|
||||
d = s+d*(-s*2+1);
|
||||
float dist = length(d);
|
||||
if (dist < min2)
|
||||
{
|
||||
if (dist < min1)
|
||||
{
|
||||
min2 = min1;
|
||||
min1 = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
min2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return pow(1.0 - (min2 - min1), 32.0);
|
||||
return (min2 - min1) * 8.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = gl_FragCoord.xy / Z.xy;
|
||||
float l = voronoi(p);
|
||||
|
||||
float f = 0.5;
|
||||
float seed = 10.0;
|
||||
for (float t = 2.0; t <= Z.x; t *= 2.0)
|
||||
{
|
||||
f += (0.5 / pow(t, 0.6)) * noise(p,t);
|
||||
}
|
||||
gl_FragColor = vec4(l,f,l,1);
|
||||
}
|
||||
81
underwater4k/texture.glsl_2
Normal file
81
underwater4k/texture.glsl_2
Normal file
@@ -0,0 +1,81 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
float rnd(vec2 p)
|
||||
{
|
||||
p.x += p.y * 57.;
|
||||
return sin(cos(p.x) * p.x);
|
||||
}
|
||||
|
||||
float scale;
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = mod(p, scale);
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p, float s )
|
||||
{
|
||||
scale = s;
|
||||
p *= s;
|
||||
vec2 i = floor( p );
|
||||
vec2 f = fract( p );
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
p = mod(p, 1.0);
|
||||
float min1 = 1, min2 = 1; float seed = 10; const int numPoints = 256;
|
||||
for (int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
vec2 pointPos = vec2(rnd(vec2(0, seed++)), rnd(vec2(1, seed++)))*.5+.5;
|
||||
//pointPos += vec2(sin(Z.z+rnd(vec2(0, seed++))), cos(Z.z+rnd(vec2(1, seed++))))*0.1;
|
||||
vec2 d = abs(p - pointPos);
|
||||
vec2 s = step(0.5, d);
|
||||
d = s+d*(-s*2+1);
|
||||
float dist = length(d);
|
||||
if (dist < min2)
|
||||
{
|
||||
if (dist < min1)
|
||||
{
|
||||
min2 = min1;
|
||||
min1 = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
min2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return pow(1.0 - (min2 - min1), 32.0);
|
||||
return (min2 - min1) * 8.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = gl_FragCoord.xy / Z.xy;
|
||||
float l = voronoi(p);
|
||||
|
||||
float f = 0.5;
|
||||
float seed = 10.0;
|
||||
for (float t = 2.0; t <= Z.x; t *= 2.0)
|
||||
{
|
||||
f += (0.5 / pow(t, 0.6)) * noise(p,t);
|
||||
}
|
||||
gl_FragColor = vec4(l,f,l,1);
|
||||
}
|
||||
81
underwater4k/texture.glsl_2_dbg
Normal file
81
underwater4k/texture.glsl_2_dbg
Normal file
@@ -0,0 +1,81 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
float rnd(vec2 p)
|
||||
{
|
||||
p.x += p.y * 57.;
|
||||
return sin(cos(p.x) * p.x);
|
||||
}
|
||||
|
||||
float scale;
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = mod(p, scale);
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p, float s )
|
||||
{
|
||||
scale = s;
|
||||
p *= s;
|
||||
vec2 i = floor( p );
|
||||
vec2 f = fract( p );
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
p = mod(p, 1.0);
|
||||
float min1 = 1, min2 = 1; float seed = 10; const int numPoints = 256;
|
||||
for (int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
vec2 pointPos = vec2(rnd(vec2(0, seed++)), rnd(vec2(1, seed++)))*.5+.5;
|
||||
//pointPos += vec2(sin(Z.z+rnd(vec2(0, seed++))), cos(Z.z+rnd(vec2(1, seed++))))*0.1;
|
||||
vec2 d = abs(p - pointPos);
|
||||
vec2 s = step(0.5, d);
|
||||
d = s+d*(-s*2+1);
|
||||
float dist = length(d);
|
||||
if (dist < min2)
|
||||
{
|
||||
if (dist < min1)
|
||||
{
|
||||
min2 = min1;
|
||||
min1 = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
min2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return pow(1.0 - (min2 - min1), 32.0);
|
||||
return (min2 - min1) * 8.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = gl_FragCoord.xy / Z.xy;
|
||||
float l = voronoi(p);
|
||||
|
||||
float f = 0.5;
|
||||
float seed = 10.0;
|
||||
for (float t = 2.0; t <= Z.x; t *= 2.0)
|
||||
{
|
||||
f += (0.5 / pow(t, 0.6)) * noise(p,t);
|
||||
}
|
||||
gl_FragColor = vec4(l,f,l,1);
|
||||
}
|
||||
81
underwater4k/texture.glsl_3
Normal file
81
underwater4k/texture.glsl_3
Normal file
@@ -0,0 +1,81 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
float rnd(vec2 p)
|
||||
{
|
||||
p.x += p.y * 57.;
|
||||
return sin(cos(p.x) * p.x);
|
||||
}
|
||||
|
||||
float scale;
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = mod(p, scale);
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p, float s )
|
||||
{
|
||||
scale = s;
|
||||
p *= s;
|
||||
vec2 i = floor( p );
|
||||
vec2 f = fract( p );
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
p = mod(p, 1.0);
|
||||
float min1 = 1, min2 = 1; float seed = 10; const int numPoints = 256;
|
||||
for (int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
vec2 pointPos = vec2(rnd(vec2(0, seed++)), rnd(vec2(1, seed++)))*.5+.5;
|
||||
//pointPos += vec2(sin(Z.z+rnd(vec2(0, seed++))), cos(Z.z+rnd(vec2(1, seed++))))*0.1;
|
||||
vec2 d = abs(p - pointPos);
|
||||
vec2 s = step(0.5, d);
|
||||
d = s+d*(-s*2+1);
|
||||
float dist = length(d);
|
||||
if (dist < min2)
|
||||
{
|
||||
if (dist < min1)
|
||||
{
|
||||
min2 = min1;
|
||||
min1 = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
min2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return pow(1.0 - (min2 - min1), 32.0);
|
||||
return (min2 - min1) * 8.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = gl_FragCoord.xy / Z.xy;
|
||||
float l = voronoi(p);
|
||||
|
||||
float f = 0.5;
|
||||
float seed = 10.0;
|
||||
for (float t = 2.0; t <= Z.x; t *= 2.0)
|
||||
{
|
||||
f += (0.5 / pow(t, 0.6)) * noise(p,t);
|
||||
}
|
||||
gl_FragColor = vec4(l,f,l,1);
|
||||
}
|
||||
81
underwater4k/texture.glsl_3_dbg
Normal file
81
underwater4k/texture.glsl_3_dbg
Normal file
@@ -0,0 +1,81 @@
|
||||
// Parameters from our host
|
||||
// x: #sceneid.#scenetime (float)
|
||||
// y: undefined
|
||||
// z: Snare drum intensity (amiga ball radius gain)
|
||||
// w: undefined
|
||||
uniform vec4 Z;
|
||||
|
||||
float rnd(vec2 p)
|
||||
{
|
||||
p.x += p.y * 57.;
|
||||
return sin(cos(p.x) * p.x);
|
||||
}
|
||||
|
||||
float scale;
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = mod(p, scale);
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p, float s )
|
||||
{
|
||||
scale = s;
|
||||
p *= s;
|
||||
vec2 i = floor( p );
|
||||
vec2 f = fract( p );
|
||||
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
|
||||
dot( hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
|
||||
mix( dot( hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
|
||||
dot( hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
|
||||
}
|
||||
|
||||
float voronoi(vec2 p)
|
||||
{
|
||||
p = mod(p, 1.0);
|
||||
float min1 = 1, min2 = 1; float seed = 10; const int numPoints = 256;
|
||||
for (int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
vec2 pointPos = vec2(rnd(vec2(0, seed++)), rnd(vec2(1, seed++)))*.5+.5;
|
||||
//pointPos += vec2(sin(Z.z+rnd(vec2(0, seed++))), cos(Z.z+rnd(vec2(1, seed++))))*0.1;
|
||||
vec2 d = abs(p - pointPos);
|
||||
vec2 s = step(0.5, d);
|
||||
d = s+d*(-s*2+1);
|
||||
float dist = length(d);
|
||||
if (dist < min2)
|
||||
{
|
||||
if (dist < min1)
|
||||
{
|
||||
min2 = min1;
|
||||
min1 = dist;
|
||||
}
|
||||
else
|
||||
{
|
||||
min2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return pow(1.0 - (min2 - min1), 32.0);
|
||||
return (min2 - min1) * 8.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = gl_FragCoord.xy / Z.xy;
|
||||
float l = voronoi(p);
|
||||
|
||||
float f = 0.5;
|
||||
float seed = 10.0;
|
||||
for (float t = 2.0; t <= Z.x; t *= 2.0)
|
||||
{
|
||||
f += (0.5 / pow(t, 0.6)) * noise(p,t);
|
||||
}
|
||||
gl_FragColor = vec4(l,f,l,1);
|
||||
}
|
||||
26
underwater4k/underwater4k.sln
Normal file
26
underwater4k/underwater4k.sln
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2012
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "underwater4k", "underwater4k.vcxproj", "{213903DE-E40A-4D23-9310-E520AC2B412E}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Compress_Slow|Win32 = Compress_Slow|Win32
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{213903DE-E40A-4D23-9310-E520AC2B412E}.Compress_Slow|Win32.ActiveCfg = Compress_Slow|Win32
|
||||
{213903DE-E40A-4D23-9310-E520AC2B412E}.Compress_Slow|Win32.Build.0 = Compress_Slow|Win32
|
||||
{213903DE-E40A-4D23-9310-E520AC2B412E}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{213903DE-E40A-4D23-9310-E520AC2B412E}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{213903DE-E40A-4D23-9310-E520AC2B412E}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{213903DE-E40A-4D23-9310-E520AC2B412E}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(Performance) = preSolution
|
||||
HasPerformanceSessions = true
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
BIN
underwater4k/underwater4k.v11.suo
Normal file
BIN
underwater4k/underwater4k.v11.suo
Normal file
Binary file not shown.
250
underwater4k/underwater4k.vcxproj
Normal file
250
underwater4k/underwater4k.vcxproj
Normal file
@@ -0,0 +1,250 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Compress_Slow|Win32">
|
||||
<Configuration>Compress_Slow</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{213903DE-E40A-4D23-9310-E520AC2B412E}</ProjectGuid>
|
||||
<RootNamespace>bp4k</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Compress_Slow|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v100</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v100</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v100</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Compress_Slow|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)bin\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)obj\$(ProjectName)_$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)bin\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)obj\$(ProjectName)_$(Configuration)\</IntDir>
|
||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Compress_Slow|Win32'">$(SolutionDir)bin\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Compress_Slow|Win32'">$(SolutionDir)obj\$(ProjectName)_$(Configuration)\</IntDir>
|
||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Compress_Slow|Win32'">false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ExecutablePath>$(ProjectDir);$(ExecutablePath)</ExecutablePath>
|
||||
<TargetName>$(ProjectName)_$(Configuration)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ExecutablePath>$(ProjectDir);$(ExecutablePath)</ExecutablePath>
|
||||
<TargetName>$(ProjectName)_$(Configuration)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Compress_Slow|Win32'">
|
||||
<TargetName>$(ProjectName)_$(Configuration)</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<CallingConvention>StdCall</CallingConvention>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>4klang.obj;Gdi32.lib;user32.lib;opengl32.lib;winmm.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EntryPointSymbol>main</EntryPointSymbol>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<PreBuildEvent>
|
||||
<Command>rem minify\shader_minifier.exe "mark.fs_0" -o mark_0.h -v --no-renaming
|
||||
rem minify\shader_minifier.exe "mark.fs_1" -o mark_1.h -v --no-renaming
|
||||
rem minify\shader_minifier.exe "mark.fs_2" -o mark_2.h -v --no-renaming
|
||||
rem minify\shader_minifier.exe "mark.fs_0" -o mark_small.h -v
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
<ClCompile>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ExceptionHandling>
|
||||
</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CallingConvention>StdCall</CallingConvention>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>4klang.obj;Gdi32.lib;user32.lib;opengl32.lib;winmm.lib;libcmt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<ManifestFile>
|
||||
</ManifestFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<LinkTimeCodeGeneration>
|
||||
</LinkTimeCodeGeneration>
|
||||
<EntryPointSymbol>main</EntryPointSymbol>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<LinkErrorReporting>
|
||||
</LinkErrorReporting>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Compress_Slow|Win32'">
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
<ClCompile>
|
||||
<AdditionalOptions>/QIfist %(AdditionalOptions)</AdditionalOptions>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>false</FunctionLevelLinking>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
<DebugInformationFormat>
|
||||
</DebugInformationFormat>
|
||||
<CallingConvention>StdCall</CallingConvention>
|
||||
<StringPooling Condition="'$(Configuration)|$(Platform)'=='Compress (Slow)|Win32'">false</StringPooling>
|
||||
<StringPooling Condition="'$(Configuration)|$(Platform)'=='Compress (Slow)|Win32'">true</StringPooling>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalOptions>/CRINKLER /COMPMODE:SLOW /ORDERTRIES:4000 /HASHTRIES:300 /UNSAFEIMPORT /TRUNCATEFLOATS:24 /HASHSIZE:200 /REPORT:report.html /RANGE:opengl32 /PROGRESSGUI /TRANSFORM:CALLS %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>4klang.obj;opengl32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<ManifestFile>
|
||||
</ManifestFile>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<LinkTimeCodeGeneration>
|
||||
</LinkTimeCodeGeneration>
|
||||
<EntryPointSymbol>main</EntryPointSymbol>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<LinkErrorReporting>
|
||||
</LinkErrorReporting>
|
||||
<SuppressStartupBanner Condition="'$(Configuration)|$(Platform)'=='Compress (Slow)|Win32'">false</SuppressStartupBanner>
|
||||
<ImageHasSafeExceptionHandlers Condition="'$(Configuration)|$(Platform)'=='Compress (Slow)|Win32'">false</ImageHasSafeExceptionHandlers>
|
||||
<DataExecutionPrevention Condition="'$(Configuration)|$(Platform)'=='Compress (Slow)|Win32'">false</DataExecutionPrevention>
|
||||
<RandomizedBaseAddress Condition="'$(Configuration)|$(Platform)'=='Compress (Slow)|Win32'">false</RandomizedBaseAddress>
|
||||
<IgnoreAllDefaultLibraries Condition="'$(Configuration)|$(Platform)'=='Compress (Slow)|Win32'">true</IgnoreAllDefaultLibraries>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies Condition="'$(Configuration)|$(Platform)'=='Compress (Slow)|Win32'">false</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Compress_Slow|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main_release.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Shaders.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="4klang.h" />
|
||||
<ClInclude Include="fragment_small.h" />
|
||||
<ClInclude Include="glext.h" />
|
||||
<ClInclude Include="va_stdafx.h" />
|
||||
<CustomBuild Include="release.h">
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Compress_Slow|Win32'">
|
||||
</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Compress_Slow|Win32'">
|
||||
</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Compress_Slow|Win32'">%(AdditionalInputs)</AdditionalInputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Compress_Slow|Win32'">%(Outputs)</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalInputs)</AdditionalInputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
<ClInclude Include="Shaders.h" />
|
||||
<ClInclude Include="small.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="4klang.asm">
|
||||
<FileType>Document</FileType>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Compress_Slow|Win32'">yasm-1.2.0-win32.exe -f win32 -o 4klang.obj 4klang.asm</Command>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Compress_Slow|Win32'">Compiling 4klang...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Compress_Slow|Win32'">4klang.obj</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">yasm-1.2.0-win32.exe -f win32 -o 4klang.obj 4klang.asm</Command>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compiling 4klang...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4klang.obj</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">yasm-1.2.0-win32.exe -f win32 -o 4klang.obj 4klang.asm</Command>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compiling 4klang...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">4klang.obj</Outputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">4klang.inc</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Compress_Slow|Win32'">4klang.inc</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4klang.inc</AdditionalInputs>
|
||||
</CustomBuild>
|
||||
<None Include="4klang.inc" />
|
||||
<None Include="tex1.glsl" />
|
||||
<None Include="tex2.glsl">
|
||||
<FileType>Document</FileType>
|
||||
</None>
|
||||
<None Include="fragment.glsl" />
|
||||
<None Include="vertex.glsl" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
6
underwater4k/underwater4k.vcxproj.user
Normal file
6
underwater4k/underwater4k.vcxproj.user
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ShowAllFiles>false</ShowAllFiles>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
80
underwater4k/underwater4k_Debug.psess
Normal file
80
underwater4k/underwater4k_Debug.psess
Normal file
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<VSPerformanceSession Version="1.00">
|
||||
<Options>
|
||||
<Solution>underwater4k.sln</Solution>
|
||||
<CollectionMethod>Sampling</CollectionMethod>
|
||||
<AllocationMethod>None</AllocationMethod>
|
||||
<AddReport>true</AddReport>
|
||||
<ResourceBasedAnalysisSelected>true</ResourceBasedAnalysisSelected>
|
||||
<UniqueReport>Timestamp</UniqueReport>
|
||||
<SamplingMethod>Cycles</SamplingMethod>
|
||||
<CycleCount>10000000</CycleCount>
|
||||
<PageFaultCount>10</PageFaultCount>
|
||||
<SysCallCount>10</SysCallCount>
|
||||
<SamplingCounter Name="" ReloadValue="00000000000f4240" DisplayName="" />
|
||||
<RelocateBinaries>false</RelocateBinaries>
|
||||
<HardwareCounters EnableHWCounters="false" />
|
||||
<EtwSettings />
|
||||
<PdhSettings>
|
||||
<PdhCountersEnabled>false</PdhCountersEnabled>
|
||||
<PdhCountersRate>500</PdhCountersRate>
|
||||
<PdhCounters>
|
||||
<PdhCounter>\Memory\Pages/sec</PdhCounter>
|
||||
<PdhCounter>\PhysicalDisk(_Total)\Avg. Disk Queue Length</PdhCounter>
|
||||
<PdhCounter>\Processor(_Total)\% Processor Time</PdhCounter>
|
||||
</PdhCounters>
|
||||
</PdhSettings>
|
||||
</Options>
|
||||
<ExcludeSmallFuncs>true</ExcludeSmallFuncs>
|
||||
<InteractionProfilingEnabled>false</InteractionProfilingEnabled>
|
||||
<JScriptProfilingEnabled>false</JScriptProfilingEnabled>
|
||||
<PreinstrumentEvent>
|
||||
<InstrEventExclude>false</InstrEventExclude>
|
||||
</PreinstrumentEvent>
|
||||
<PostinstrumentEvent>
|
||||
<InstrEventExclude>false</InstrEventExclude>
|
||||
</PostinstrumentEvent>
|
||||
<Binaries>
|
||||
<ProjBinary>
|
||||
<Path>bin\underwater4k_Debug.exe</Path>
|
||||
<ArgumentTimestamp>01/01/0001 00:00:00</ArgumentTimestamp>
|
||||
<Instrument>true</Instrument>
|
||||
<Sample>true</Sample>
|
||||
<ExternalWebsite>false</ExternalWebsite>
|
||||
<InteractionProfilingEnabled>false</InteractionProfilingEnabled>
|
||||
<IsLocalJavascript>false</IsLocalJavascript>
|
||||
<IsWindowsStoreApp>false</IsWindowsStoreApp>
|
||||
<IsWWA>false</IsWWA>
|
||||
<LaunchProject>true</LaunchProject>
|
||||
<OverrideProjectSettings>false</OverrideProjectSettings>
|
||||
<LaunchMethod>Executable</LaunchMethod>
|
||||
<ExecutablePath>bin\underwater4k_Debug.exe</ExecutablePath>
|
||||
<StartupDirectory>.\</StartupDirectory>
|
||||
<Arguments>
|
||||
</Arguments>
|
||||
<NetAppHost>IIS</NetAppHost>
|
||||
<NetBrowser>InternetExplorer</NetBrowser>
|
||||
<ExcludeSmallFuncs>true</ExcludeSmallFuncs>
|
||||
<JScriptProfilingEnabled>false</JScriptProfilingEnabled>
|
||||
<PreinstrumentEvent>
|
||||
<InstrEventExclude>false</InstrEventExclude>
|
||||
</PreinstrumentEvent>
|
||||
<PostinstrumentEvent>
|
||||
<InstrEventExclude>false</InstrEventExclude>
|
||||
</PostinstrumentEvent>
|
||||
<ProjRef>{213903DE-E40A-4D23-9310-E520AC2B412E}|underwater4k.vcxproj</ProjRef>
|
||||
<ProjPath>underwater4k.vcxproj</ProjPath>
|
||||
<ProjName>underwater4k</ProjName>
|
||||
</ProjBinary>
|
||||
</Binaries>
|
||||
<Reports>
|
||||
<Report>
|
||||
<Path>underwater4k_Debug130816.vsp</Path>
|
||||
</Report>
|
||||
</Reports>
|
||||
<Launches>
|
||||
<ProjBinary>
|
||||
<Path>:PB:{213903DE-E40A-4D23-9310-E520AC2B412E}|underwater4k.vcxproj</Path>
|
||||
</ProjBinary>
|
||||
</Launches>
|
||||
</VSPerformanceSession>
|
||||
BIN
underwater4k/underwater4k_Debug130816.vsp
Normal file
BIN
underwater4k/underwater4k_Debug130816.vsp
Normal file
Binary file not shown.
101
underwater4k/va_stdafx.h
Normal file
101
underwater4k/va_stdafx.h
Normal file
@@ -0,0 +1,101 @@
|
||||
#define @0
|
||||
#define @1
|
||||
#define @2
|
||||
#define @3
|
||||
#define @@
|
||||
#define uniform
|
||||
#define varying
|
||||
struct vec2
|
||||
{
|
||||
vec2(double t) {};
|
||||
vec2(double x, double y) {};
|
||||
double x;
|
||||
double y;
|
||||
vec2 operator + (vec2);
|
||||
vec2 operator - (vec2);
|
||||
vec2 operator * (vec2);
|
||||
vec2 operator / (vec2);
|
||||
vec2 operator + (double);
|
||||
vec2 operator - (double);
|
||||
vec2 operator * (double);
|
||||
vec2 operator / (double);
|
||||
friend vec2 operator +(double, vec2);
|
||||
friend vec2 operator -(double, vec2);
|
||||
friend vec2 operator *(double, vec2);
|
||||
friend vec2 operator /(double, vec2);
|
||||
void operator += (double);
|
||||
void operator -= (double);
|
||||
void operator *= (double);
|
||||
void operator /= (double);
|
||||
void operator += (vec2);
|
||||
void operator -= (vec2);
|
||||
void operator *= (vec2);
|
||||
void operator /= (vec2);
|
||||
};
|
||||
|
||||
struct vec3
|
||||
{
|
||||
vec3(double t) {};
|
||||
vec3(double x, double y, double z) {};
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
vec3 operator + (vec3);
|
||||
vec3 operator - (vec3);
|
||||
vec3 operator * (vec3);
|
||||
vec3 operator / (vec3);
|
||||
vec3 operator + (double);
|
||||
vec3 operator - (double);
|
||||
vec3 operator * (double);
|
||||
vec3 operator / (double);
|
||||
friend vec3 operator +(double, vec3);
|
||||
friend vec3 operator -(double, vec3);
|
||||
friend vec3 operator *(double, vec3);
|
||||
friend vec3 operator /(double, vec3);
|
||||
void operator += (double);
|
||||
void operator -= (double);
|
||||
void operator *= (double);
|
||||
void operator /= (double);
|
||||
void operator += (vec3);
|
||||
void operator -= (vec3);
|
||||
void operator *= (vec3);
|
||||
void operator /= (vec3);
|
||||
};
|
||||
|
||||
struct vec4
|
||||
{
|
||||
vec4(double t) {};
|
||||
vec4(double x, double y, double z, double w) {};
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
double w;
|
||||
vec4 operator + (vec4);
|
||||
vec4 operator - (vec4);
|
||||
vec4 operator * (vec4);
|
||||
vec4 operator / (vec4);
|
||||
vec4 operator + (double);
|
||||
vec4 operator - (double);
|
||||
vec4 operator * (double);
|
||||
vec4 operator / (double);
|
||||
friend vec4 operator +(double, vec4);
|
||||
friend vec4 operator -(double, vec4);
|
||||
friend vec4 operator *(double, vec4);
|
||||
friend vec4 operator /(double, vec4);
|
||||
void operator += (double);
|
||||
void operator -= (double);
|
||||
void operator *= (double);
|
||||
void operator /= (double);
|
||||
void operator += (vec4);
|
||||
void operator -= (vec4);
|
||||
void operator *= (vec4);
|
||||
void operator /= (vec4);
|
||||
};
|
||||
|
||||
typedef double sampler2D;
|
||||
vec4 texture2D(sampler2D t, vec2 uv);
|
||||
template <typename T> T mix(T a, T b, double c);
|
||||
template <typename T> T mod(T a, double b);
|
||||
template <typename T> T fract(T a);
|
||||
template <typename T> T step(double b, T a);
|
||||
template <typename T> T smoothstep(double a, double b, T a);
|
||||
9
underwater4k/vertex.glsl
Normal file
9
underwater4k/vertex.glsl
Normal file
@@ -0,0 +1,9 @@
|
||||
varying vec4 Y;
|
||||
varying vec2 Z;
|
||||
|
||||
void main()
|
||||
{
|
||||
Y = gl_Color;
|
||||
Z = (gl_Vertex.xy*vec2(1.7777,1.0))*0.5+0.5;
|
||||
gl_Position = gl_Vertex;
|
||||
}
|
||||
BIN
underwater4k/yasm-1.2.0-win32.exe
Normal file
BIN
underwater4k/yasm-1.2.0-win32.exe
Normal file
Binary file not shown.
Reference in New Issue
Block a user