mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-14 18:26:47 +02:00
Procedural shaders V2
This commit is contained in:
parent
670c5ee484
commit
743d79335d
20 changed files with 1275 additions and 47 deletions
55
examples/shaders/example.fs
Normal file
55
examples/shaders/example.fs
Normal file
|
@ -0,0 +1,55 @@
|
|||
#line 2
|
||||
|
||||
//////////////////////////////////
|
||||
//
|
||||
// Available inputs
|
||||
//
|
||||
// Uniforms: constant across the whole surface
|
||||
//
|
||||
// float iGlobalTime;
|
||||
// vec3 iWorldScale;
|
||||
//
|
||||
// Varyings: Per-pixel attributes that change for every pixel
|
||||
//
|
||||
// vec3 _normal
|
||||
// vec4 _position
|
||||
// vec2 _texCoord0 // reserved for future use, currently always vec2(0)
|
||||
// vec3 _color // reserved for future user, currently always vec3(1)
|
||||
//
|
||||
/////////////////////////////////
|
||||
|
||||
//////////////////////////////////
|
||||
//
|
||||
// Available functions
|
||||
//
|
||||
// All GLSL functions from GLSL version 4.10 and usable in fragment shaders
|
||||
// See Page 8 of this document: https://www.khronos.org/files/opengl41-quick-reference-card.pdf
|
||||
//
|
||||
// Additionally the snoise functions defined in WebGL-noise are available
|
||||
// See https://github.com/ashima/webgl-noise/tree/master/src
|
||||
//
|
||||
// float snoise(vec2)
|
||||
// float snoise(vec3)
|
||||
// float snoise(vec4)
|
||||
//
|
||||
|
||||
// Fade from black to white and back again
|
||||
vec4 getProceduralColor() {
|
||||
// set intensity to a sine wave with a frequency of 1 Hz
|
||||
float intensity = sin(iGlobalTime * 3.14159 * 2.0);
|
||||
|
||||
// Raise the wave to move between 0 and 2
|
||||
intensity += 1.0;
|
||||
|
||||
// Reducce the amplitude to between 0 and 1
|
||||
intensity /= 2.0;
|
||||
|
||||
// Set the base color to blue
|
||||
vec3 color = vec3(0.0, 0.0, 1.0);
|
||||
|
||||
// Multiply by the intensity
|
||||
color *= intensity;
|
||||
|
||||
// return the color as a vec 4
|
||||
return vec4(color, 1.0);
|
||||
}
|
49
examples/shaders/exampleFloor.fs
Normal file
49
examples/shaders/exampleFloor.fs
Normal file
|
@ -0,0 +1,49 @@
|
|||
#line 2
|
||||
|
||||
// Created by inigo quilez - iq/2014
|
||||
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
|
||||
|
||||
// { 2d cell id, distance to border, distnace to center )
|
||||
vec4 hexagon(vec2 p) {
|
||||
vec2 q = vec2(p.x * 2.0 * 0.5773503, p.y + p.x * 0.5773503);
|
||||
|
||||
vec2 pi = floor(q);
|
||||
vec2 pf = fract(q);
|
||||
|
||||
float v = mod(pi.x + pi.y, 3.0);
|
||||
|
||||
float ca = step(1.0, v);
|
||||
float cb = step(2.0, v);
|
||||
vec2 ma = step(pf.xy, pf.yx);
|
||||
|
||||
// distance to borders
|
||||
float e = dot(ma,
|
||||
1.0 - pf.yx + ca * (pf.x + pf.y - 1.0) + cb * (pf.yx - 2.0 * pf.xy));
|
||||
|
||||
// distance to center
|
||||
p = vec2(q.x + floor(0.5 + p.y / 1.5), 4.0 * p.y / 3.0) * 0.5 + 0.5;
|
||||
float f = length((fract(p) - 0.5) * vec2(1.0, 0.85));
|
||||
|
||||
return vec4(pi + ca - cb * ma, e, f);
|
||||
}
|
||||
|
||||
|
||||
float hash1(vec2 p) {
|
||||
float n = dot(p, vec2(127.1, 311.7));
|
||||
return fract(sin(n) * 43758.5453);
|
||||
}
|
||||
|
||||
vec4 getProceduralColor() {
|
||||
vec2 uv = _position.xz + 0.5;
|
||||
vec2 pos = _position.xz * iWorldScale.xz;
|
||||
// gray
|
||||
vec4 h = hexagon(8.0 * pos + 0.5);
|
||||
float n = snoise(vec3(0.3 * h.xy + iGlobalTime * 0.1, iGlobalTime));
|
||||
vec3 col = 0.15 + 0.15 * hash1(h.xy + 1.2) * vec3(1.0);
|
||||
col *= smoothstep(0.10, 0.11, h.z);
|
||||
col *= smoothstep(0.10, 0.11, h.w);
|
||||
col *= 1.0 + 0.15 * sin(40.0 * h.z);
|
||||
col *= 0.75 + 0.5 * h.z * n;
|
||||
col *= pow(16.0 * uv.x * (1.0 - uv.x) * uv.y * (1.0 - uv.y), 0.1);
|
||||
return vec4(col, 1.0);
|
||||
}
|
22
examples/shaders/exampleSphere.fs
Normal file
22
examples/shaders/exampleSphere.fs
Normal file
|
@ -0,0 +1,22 @@
|
|||
#line 2
|
||||
|
||||
const vec3 RED = vec3(1.0, 0.0, 0.0);
|
||||
const vec3 GREEN = vec3(0.0, 1.0, 0.0);
|
||||
const vec3 BLUE = vec3(0.0, 0.0, 1.0);
|
||||
const vec3 YELLOW = vec3(1.0, 1.0, 0.0);
|
||||
const vec3 WHITE = vec3(1.0, 1.0, 1.0);
|
||||
|
||||
vec4 getProceduralColor() {
|
||||
float intensity = 0.0;
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
float modifier = pow(2, i);
|
||||
float noise = snoise(vec4(_position.xyz * 10.0 * modifier, iGlobalTime));
|
||||
noise /= modifier;
|
||||
intensity += noise;
|
||||
}
|
||||
intensity /= 2.0;
|
||||
intensity += 0.5;
|
||||
vec3 color = (intensity * BLUE) + (1.0 - intensity) * YELLOW;
|
||||
return vec4(color, 1.0);
|
||||
}
|
||||
|
17
examples/shaders/exampleSphereDisco.fs
Normal file
17
examples/shaders/exampleSphereDisco.fs
Normal file
|
@ -0,0 +1,17 @@
|
|||
#line 2
|
||||
|
||||
float noise(vec3 v) {
|
||||
return snoise(vec4(v, iGlobalTime));
|
||||
}
|
||||
|
||||
vec3 noise3_3(vec3 p) {
|
||||
float fx = noise(p);
|
||||
float fy = noise(p + vec3(1345.67, 0, 45.67));
|
||||
float fz = noise(p + vec3(0, 134.67, 3245.67));
|
||||
return vec3(fx, fy, fz);
|
||||
}
|
||||
|
||||
vec4 getProceduralColor() {
|
||||
vec3 color = noise3_3(_position.xyz * 10.0);
|
||||
return vec4(color, 1.0);
|
||||
}
|
25
examples/shaders/exampleUserDataV2.json
Normal file
25
examples/shaders/exampleUserDataV2.json
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"ProceduralEntity": {
|
||||
"shaderUrl": "file:///C:/Users/bdavis/Git/hifi/examples/shaders/exampleV2.fs",
|
||||
// V2 and onwards, shaders must include a version identifier, or they will default
|
||||
// to V1 behavior
|
||||
"version": 2,
|
||||
// Any values specified here will be passed on to uniforms with matching names in
|
||||
// the shader. Only numbers and arrays of length 1-4 of numbers are supported.
|
||||
//
|
||||
// The size of the data must match the size of the uniform:
|
||||
// a number or 1 value array = 'uniform float'
|
||||
// 2 value array = 'uniform vec2'
|
||||
// 3 value array = 'uniform vec3'
|
||||
// 4 value array = 'uniform vec4'
|
||||
//
|
||||
// Uniforms should always be declared in the shader with a default value
|
||||
// or failure to specify the value here will result in undefined behavior.
|
||||
"uniforms": {
|
||||
// uniform float iSpeed = 1.0;
|
||||
"iSpeed": 2.0,
|
||||
// uniform vec3 iSize = vec3(1.0);
|
||||
"iSize": [1.0, 2.0, 4.0]
|
||||
}
|
||||
}
|
||||
}
|
40
examples/shaders/exampleV2.fs
Normal file
40
examples/shaders/exampleV2.fs
Normal file
|
@ -0,0 +1,40 @@
|
|||
const vec3 BLUE = vec3(0.0, 0.0, 1.0);
|
||||
const vec3 YELLOW = vec3(1.0, 1.0, 0.0);
|
||||
|
||||
uniform float iSpeed = 1.0;
|
||||
uniform vec3 iSize = vec3(1.0, 1.0, 1.0);
|
||||
|
||||
vec3 getNoiseColor() {
|
||||
float intensity = 0.0;
|
||||
vec3 position = _position.xyz;
|
||||
//position = normalize(position);
|
||||
float time = iGlobalTime * iSpeed;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
float modifier = pow(2, i);
|
||||
vec3 noisePosition = position * iSize * 10.0 * modifier;
|
||||
float noise = snoise(vec4(noisePosition, time));
|
||||
noise /= modifier;
|
||||
intensity += noise;
|
||||
}
|
||||
intensity /= 2.0; intensity += 0.5;
|
||||
return (intensity * BLUE) + (1.0 - intensity) * YELLOW;
|
||||
}
|
||||
|
||||
// Produce a lit procedural surface
|
||||
float getProceduralColorsLit(inout vec3 diffuse, inout vec3 specular, inout float shininess) {
|
||||
vec3 noiseColor = getNoiseColor();
|
||||
diffuse = noiseColor;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// Produce an unlit procedural surface: emulates old behavior
|
||||
float getProceduralColorsUnlit(inout vec3 diffuse, inout vec3 specular, inout float shininess) {
|
||||
vec3 noiseColor = getNoiseColor();
|
||||
diffuse = vec3(1.0);
|
||||
specular = noiseColor;
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
float getProceduralColors(inout vec3 diffuse, inout vec3 specular, inout float shininess) {
|
||||
return getProceduralColorsLit(diffuse, specular, shininess);
|
||||
}
|
39
examples/shaders/noise.fs
Normal file
39
examples/shaders/noise.fs
Normal file
|
@ -0,0 +1,39 @@
|
|||
#line 2
|
||||
|
||||
//////////////////////////////////
|
||||
//
|
||||
// Available inputs
|
||||
//
|
||||
// Uniforms: constant across the whole surface
|
||||
//
|
||||
// float iGlobalTime;
|
||||
// vec3 iWorldScale;
|
||||
//
|
||||
// Varyings: Per-pixel attributes that change for every pixel
|
||||
//
|
||||
// vec3 _normal
|
||||
// vec4 _position
|
||||
// vec2 _texCoord0 // reserved for future use, currently always vec2(0)
|
||||
// vec3 _color // reserved for future user, currently always vec3(1)
|
||||
//
|
||||
/////////////////////////////////
|
||||
|
||||
//////////////////////////////////
|
||||
//
|
||||
// Available functions
|
||||
//
|
||||
// All GLSL functions from GLSL version 4.10 and usable in fragment shaders
|
||||
// See Page 8 of this document: https://www.khronos.org/files/opengl41-quick-reference-card.pdf
|
||||
//
|
||||
// Additionally the snoise functions defined in WebGL-noise are available
|
||||
// See https://github.com/ashima/webgl-noise/tree/master/src
|
||||
//
|
||||
// float snoise(vec2)
|
||||
// float snoise(vec3)
|
||||
// float snoise(vec4)
|
||||
//
|
||||
|
||||
// Fade from black to white and back again
|
||||
vec4 getProceduralColor() {
|
||||
return vec4(vec3(abs((sin(iGlobalTime * 3.14159) + 1.0) / 2.0)), 1); // vec4(color, 1.0);
|
||||
}
|
136
examples/shaders/scratch.fs
Normal file
136
examples/shaders/scratch.fs
Normal file
|
@ -0,0 +1,136 @@
|
|||
#line 2
|
||||
vec2 iResolution = iWorldScale.xz;
|
||||
vec2 iMouse = vec2(0);
|
||||
|
||||
// From https://www.shadertoy.com/view/4djXzz
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
License CC0 - http://creativecommons.org/publicdomain/zero/1.0/
|
||||
To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty.
|
||||
----------------------------------------------------------------------------------------
|
||||
^ This means do ANYTHING YOU WANT with this code. Because we are programmers, not lawyers.
|
||||
-Otavio Good
|
||||
*/
|
||||
|
||||
// various noise functions
|
||||
float Hash2d(vec2 uv)
|
||||
{
|
||||
float f = uv.x + uv.y * 47.0;
|
||||
return fract(cos(f*3.333)*100003.9);
|
||||
}
|
||||
float Hash3d(vec3 uv) {
|
||||
float f = uv.x + uv.y * 37.0 + uv.z * 521.0;
|
||||
return fract(cos(f * 3.333) * 100003.9);
|
||||
}
|
||||
float mixP(float f0, float f1, float a) {
|
||||
return mix(f0, f1, a * a * (3.0 - 2.0 * a));
|
||||
}
|
||||
const vec2 zeroOne = vec2(0.0, 1.0);
|
||||
float noise2d(vec2 uv) {
|
||||
vec2 fr = fract(uv.xy);
|
||||
vec2 fl = floor(uv.xy);
|
||||
float h00 = Hash2d(fl);
|
||||
float h10 = Hash2d(fl + zeroOne.yx);
|
||||
float h01 = Hash2d(fl + zeroOne);
|
||||
float h11 = Hash2d(fl + zeroOne.yy);
|
||||
return mixP(mixP(h00, h10, fr.x), mixP(h01, h11, fr.x), fr.y);
|
||||
}
|
||||
|
||||
float noise(vec3 uv) {
|
||||
vec3 fr = fract(uv.xyz);
|
||||
vec3 fl = floor(uv.xyz);
|
||||
float h000 = Hash3d(fl);
|
||||
float h100 = Hash3d(fl + zeroOne.yxx);
|
||||
float h010 = Hash3d(fl + zeroOne.xyx);
|
||||
float h110 = Hash3d(fl + zeroOne.yyx);
|
||||
float h001 = Hash3d(fl + zeroOne.xxy);
|
||||
float h101 = Hash3d(fl + zeroOne.yxy);
|
||||
float h011 = Hash3d(fl + zeroOne.xyy);
|
||||
float h111 = Hash3d(fl + zeroOne.yyy);
|
||||
return mixP(mixP(mixP(h000, h100, fr.x), mixP(h010, h110, fr.x), fr.y),
|
||||
mixP(mixP(h001, h101, fr.x), mixP(h011, h111, fr.x), fr.y), fr.z);
|
||||
}
|
||||
|
||||
float PI = 3.14159265;
|
||||
|
||||
vec3 saturate(vec3 a) {
|
||||
return clamp(a, 0.0, 1.0);
|
||||
}
|
||||
vec2 saturate(vec2 a) {
|
||||
return clamp(a, 0.0, 1.0);
|
||||
}
|
||||
float saturate(float a) {
|
||||
return clamp(a, 0.0, 1.0);
|
||||
}
|
||||
|
||||
float Density(vec3 p) {
|
||||
//float ws = 0.06125*0.125;
|
||||
//vec3 warp = vec3(noise(p*ws), noise(p*ws + 111.11), noise(p*ws + 7111.11));
|
||||
float final = noise(p * 0.06125); // + sin(iGlobalTime)*0.5-1.95 + warp.x*4.0;
|
||||
float other = noise(p * 0.06125 + 1234.567);
|
||||
other -= 0.5;
|
||||
final -= 0.5;
|
||||
final = 0.1 / (abs(final * final * other));
|
||||
final += 0.5;
|
||||
return final * 0.0001;
|
||||
}
|
||||
|
||||
void mainImage( out vec4 fragColor, in vec2 fragCoord )
|
||||
{
|
||||
// ---------------- First, set up the camera rays for ray marching ----------------
|
||||
vec2 uv = fragCoord.xy/iResolution.xy * 2.0 - 1.0;// - 0.5;
|
||||
|
||||
// Camera up vector.
|
||||
vec3 camUp=vec3(0,1,0);// vuv
|
||||
|
||||
// Camera lookat.
|
||||
vec3 camLookat=vec3(0,0.0,0);// vrp
|
||||
|
||||
float mx=iMouse.x/iResolution.x*PI*2.0 + iGlobalTime * 0.01;
|
||||
float my=-iMouse.y/iResolution.y*10.0 + sin(iGlobalTime * 0.03)*0.2+0.2;//*PI/2.01;
|
||||
vec3 camPos=vec3(cos(my)*cos(mx),sin(my),cos(my)*sin(mx))*(200.2);// prp
|
||||
|
||||
// Camera setup.
|
||||
vec3 camVec=normalize(camLookat - camPos);//vpn
|
||||
vec3 sideNorm=normalize(cross(camUp, camVec));// u
|
||||
vec3 upNorm=cross(camVec, sideNorm);//v
|
||||
vec3 worldFacing=(camPos + camVec);//vcv
|
||||
vec3 worldPix = worldFacing + uv.x * sideNorm * (iResolution.x/iResolution.y) + uv.y * upNorm;//scrCoord
|
||||
vec3 relVec = normalize(worldPix - camPos);//scp
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
float t = 0.0;
|
||||
float inc = 0.02;
|
||||
float maxDepth = 70.0;
|
||||
vec3 pos = vec3(0,0,0);
|
||||
float density = 0.0;
|
||||
// ray marching time
|
||||
for (int i = 0; i < 37; i++)// This is the count of how many times the ray actually marches.
|
||||
{
|
||||
if ((t > maxDepth)) break;
|
||||
pos = camPos + relVec * t;
|
||||
float temp = Density(pos);
|
||||
//temp *= saturate(t-1.0);
|
||||
|
||||
inc = 1.9 + temp*0.05;// add temp because this makes it look extra crazy!
|
||||
density += temp * inc;
|
||||
t += inc;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// Now that we have done our ray marching, let's put some color on this.
|
||||
vec3 finalColor = vec3(0.01,0.1,1.0)* density*0.2;
|
||||
|
||||
// output the final color with sqrt for "gamma correction"
|
||||
fragColor = vec4(sqrt(clamp(finalColor, 0.0, 1.0)),1.0);
|
||||
}
|
||||
|
||||
vec4 getProceduralColor() {
|
||||
vec4 result;
|
||||
vec2 position = _position.xz;
|
||||
position += 0.5;
|
||||
|
||||
mainImage(result, position * iWorldScale.xz);
|
||||
|
||||
return result;
|
||||
}
|
32
examples/shaders/shadertoyWrapper.fs
Normal file
32
examples/shaders/shadertoyWrapper.fs
Normal file
|
@ -0,0 +1,32 @@
|
|||
vec2 iResolution = iWorldScale.xz;
|
||||
vec2 iMouse = vec2(0);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// REPLACE BELOW
|
||||
//
|
||||
// Replace the contents of this section with a shadertoy that includes a mainImage
|
||||
// function
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
|
||||
fragColor = vec4(0, 0, 1, 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// REPLACE ABOVE
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
vec4 getProceduralColor() {
|
||||
vec4 result;
|
||||
vec2 position = _position.xz;
|
||||
position += 0.5;
|
||||
|
||||
mainImage(result, position * iWorldScale.xz);
|
||||
|
||||
return result;
|
||||
}
|
231
examples/shaders/shadertoys/clock.fs
Normal file
231
examples/shaders/shadertoys/clock.fs
Normal file
|
@ -0,0 +1,231 @@
|
|||
vec2 iResolution = iWorldScale.xz;
|
||||
|
||||
// from https://www.shadertoy.com/view/Xd2XWR
|
||||
|
||||
// Created by Daniel Burke - burito/2014
|
||||
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
|
||||
|
||||
// Inspiration from Dr Who (2005) S7E13 - The Name of the Doctor
|
||||
|
||||
vec2 rot(vec2 p, float a)
|
||||
{
|
||||
float c = cos(a);
|
||||
float s = sin(a);
|
||||
return vec2(p.x*c + p.y*s,
|
||||
-p.x*s + p.y*c);
|
||||
}
|
||||
|
||||
float circle(vec2 pos, float radius)
|
||||
{
|
||||
return clamp(((1.0-abs(length(pos)-radius))-0.99)*100.0, 0.0, 1.0);
|
||||
|
||||
}
|
||||
|
||||
float circleFill(vec2 pos, float radius)
|
||||
{
|
||||
return clamp(((1.0-(length(pos)-radius))-0.99)*100.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
// Thanks Iñigo Quilez!
|
||||
float line( in vec2 p, in vec2 a, in vec2 b )
|
||||
{
|
||||
vec2 pa = -p - a;
|
||||
vec2 ba = b - a;
|
||||
float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
|
||||
float d = length( pa - ba*h );
|
||||
|
||||
return clamp(((1.0 - d)-0.99)*100.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
void mainImage( out vec4 fragColor, in vec2 fragCoord )
|
||||
{
|
||||
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||
vec2 p = -1.0 + 2.0 * uv;
|
||||
p.x *= iResolution.x / iResolution.y;
|
||||
|
||||
vec3 colour = vec3(0);
|
||||
vec3 white = vec3(1);
|
||||
|
||||
|
||||
|
||||
float c = circle(p, 0.2);
|
||||
c += circle(p, 0.1);
|
||||
c += circle(p, 0.18);
|
||||
c += circleFill(p, 0.005);
|
||||
|
||||
// c += circle(p, 1.3);
|
||||
c += circle(p, 1.0);
|
||||
if(p.x > 0.0)c += circle(p, 0.4);
|
||||
if(p.x > 0.0)c += circle(p, 0.42);
|
||||
if(p.x < 0.0)c += circle(p, 0.47);
|
||||
c += circleFill(p+vec2(0.47, 0.0), 0.02);
|
||||
c += circleFill(p+vec2(0.84147*0.47, 0.54030*0.47), 0.02);
|
||||
c += circleFill(p+vec2(0.84147*0.47, -0.54030*0.47), 0.02);
|
||||
c += circleFill(p+vec2(0.41614*0.47, 0.90929*0.47), 0.02);
|
||||
c += circleFill(p+vec2(0.41614*0.47, -0.90929*0.47), 0.02);
|
||||
|
||||
float t = iGlobalTime;
|
||||
float t2 = t * -0.01;
|
||||
float t3 = t * 0.03;
|
||||
|
||||
vec2 angle1 = vec2(sin(t), cos(t));
|
||||
vec2 a = angle1 * 0.7;
|
||||
|
||||
t *= 0.5;
|
||||
vec2 angle2 = vec2(sin(t), cos(t));
|
||||
vec2 b = angle2 * 0.8;
|
||||
|
||||
vec2 angle3 = vec2(sin(t2), cos(t2));
|
||||
vec2 d = b + angle3* 0.4;
|
||||
|
||||
vec2 angle4 = vec2(sin(t3), cos(t3));
|
||||
vec2 e = angle4 * 0.9;
|
||||
|
||||
vec2 angle5 = vec2(sin(t3+4.0), cos(t3+4.0));
|
||||
vec2 f = angle5 * 0.8;
|
||||
|
||||
vec2 angle6 = vec2(sin(t*-0.1+5.0), cos(t*-0.1+5.0));
|
||||
vec2 h = angle6 * 0.8;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
float tt = t * 1.4;
|
||||
|
||||
float tm = mod(tt, 0.5);
|
||||
float tmt = tt - tm;
|
||||
if( tm > 0.4) tmt += (tm-0.4)*5.0;
|
||||
vec2 tangle1 = vec2(sin(tmt), cos(tmt));
|
||||
|
||||
tt *= 0.8;
|
||||
tm = mod(tt, 0.6);
|
||||
float tmt2 = tt - tm;
|
||||
if( tm > 0.2) tmt2 += (tm-0.2)*1.5;
|
||||
|
||||
vec2 tangle2 = vec2(sin(tmt2*-4.0), cos(tmt2*-4.0));
|
||||
|
||||
vec2 tangle3 = vec2(sin(tmt2), cos(tmt2));
|
||||
|
||||
tt = t+3.0;
|
||||
tm = mod(tt, 0.2);
|
||||
tmt = tt - tm;
|
||||
if( tm > 0.1) tmt += (tm-0.1)*2.0;
|
||||
vec2 tangle4 = vec2(sin(-tmt), cos(-tmt)); tmt += 0.9;
|
||||
vec2 tangle41 = vec2(sin(-tmt), cos(-tmt)); tmt += 0.5;
|
||||
vec2 tangle42 = vec2(sin(-tmt), cos(-tmt)); tmt += 0.5;
|
||||
vec2 tangle43 = vec2(sin(-tmt), cos(-tmt)); tmt += 0.5;
|
||||
vec2 tangle44 = vec2(sin(-tmt), cos(-tmt)); tmt += 0.5;
|
||||
vec2 tangle45 = vec2(sin(-tmt), cos(-tmt));
|
||||
|
||||
tt = iGlobalTime+0.001;
|
||||
tm = mod(tt, 1.0);
|
||||
tmt = tt - tm;
|
||||
if( tm > 0.9) tmt += (tm-0.9)*10.0;
|
||||
|
||||
vec2 tangle51 = 0.17*vec2(sin(-tmt), cos(-tmt)); tmt += 1.0471975511965976;
|
||||
vec2 tangle52 = 0.17*vec2(sin(-tmt), cos(-tmt)); tmt += 1.0471975511965976;
|
||||
vec2 tangle53 = 0.17*vec2(sin(-tmt), cos(-tmt));
|
||||
|
||||
c += line(p, tangle51, -tangle53);
|
||||
c += line(p, tangle52, tangle51);
|
||||
c += line(p, tangle53, tangle52);
|
||||
c += line(p, -tangle51, tangle53);
|
||||
c += line(p, -tangle52, -tangle51);
|
||||
c += line(p, -tangle53, -tangle52);
|
||||
|
||||
c += circleFill(p+tangle51, 0.01);
|
||||
c += circleFill(p+tangle52, 0.01);
|
||||
c += circleFill(p+tangle53, 0.01);
|
||||
c += circleFill(p-tangle51, 0.01);
|
||||
c += circleFill(p-tangle52, 0.01);
|
||||
c += circleFill(p-tangle53, 0.01);
|
||||
|
||||
|
||||
|
||||
c += circle(p+a, 0.2);
|
||||
c += circle(p+a, 0.14);
|
||||
c += circle(p+a, 0.1);
|
||||
c += circleFill(p+a, 0.04);
|
||||
c += circleFill(p+a+tangle3*0.2, 0.025);
|
||||
|
||||
|
||||
c += circle(p+a, 0.14);
|
||||
|
||||
|
||||
c += circle(p+b, 0.2);
|
||||
c += circle(p+b, 0.03);
|
||||
c += circle(p+b, 0.15);
|
||||
c += circle(p+b, 0.45);
|
||||
c += circleFill(p+b+tangle1*0.05, 0.01);
|
||||
c += circleFill(p+b+tangle1*0.09, 0.02);
|
||||
c += circleFill(p+b+tangle1*0.15, 0.03);
|
||||
c += circle(p+b+tangle1*-0.15, 0.03);
|
||||
c += circle(p+b+tangle1*-0.07, 0.015);
|
||||
|
||||
c += circle(p+d, 0.08);
|
||||
|
||||
|
||||
c += circle(p+e, 0.08);
|
||||
|
||||
|
||||
c += circle(p+f, 0.12);
|
||||
c += circle(p+f, 0.10);
|
||||
c += circleFill(p+f+tangle2*0.05, 0.01);
|
||||
c += circleFill(p+f+tangle2*0.10, 0.01);
|
||||
c += circle(p+f-tangle2*0.03, 0.01);
|
||||
c += circleFill(p+f+vec2(0.085), 0.005);
|
||||
c += circleFill(p+f, 0.005);
|
||||
|
||||
|
||||
vec2 g = tangle4 * 0.16;
|
||||
c += circle(p+h, 0.05);
|
||||
c += circle(p+h, 0.1);
|
||||
c += circle(p+h, 0.17);
|
||||
c += circle(p+h, 0.2);
|
||||
c += circleFill(p+h+tangle41 *0.16, 0.01);
|
||||
c += circleFill(p+h+tangle42 *0.16, 0.01);
|
||||
c += circleFill(p+h+tangle43 *0.16, 0.01);
|
||||
c += circleFill(p+h+tangle44 *0.16, 0.01);
|
||||
c += circleFill(p+h+tangle45 *0.16, 0.01);
|
||||
c += circleFill(p+h+angle1 *0.06, 0.02);
|
||||
c += circleFill(p+h+tangle43*-0.16, 0.01);
|
||||
|
||||
|
||||
c += line(p, vec2(0.0), a);
|
||||
c += circleFill(p+b, 0.005);
|
||||
c += circleFill(p+d, 0.005);
|
||||
c += circleFill(p+e, 0.005);
|
||||
|
||||
c += line(p, b, a);
|
||||
c += line(p, d, e);
|
||||
c += line(p, b+tangle1*0.15, e);
|
||||
c += line(p, e, f+vec2(0.085));
|
||||
|
||||
c += line(p, h+angle1*0.06, f);
|
||||
c += line(p, h+tangle43*-0.16, d);
|
||||
c += line(p, h+tangle42*0.16, e);
|
||||
|
||||
|
||||
// of course I'd write a line function that
|
||||
// doesn't handle perfectly vertical lines
|
||||
c += line(p, vec2(0.001, -0.5), vec2(0.0001, 0.5));
|
||||
c += circleFill(p+vec2(0.001, -0.5), 0.005);
|
||||
c += circleFill(p+vec2(0.001, 0.5), 0.005);
|
||||
|
||||
c = clamp(c, 0.0, 1.0);
|
||||
colour = white * c;
|
||||
|
||||
|
||||
fragColor = vec4(colour, 1.0);
|
||||
}
|
||||
|
||||
|
||||
vec4 getProceduralColor() {
|
||||
vec4 result;
|
||||
vec2 position = _position.xz;
|
||||
position += 0.5;
|
||||
|
||||
mainImage(result, position * iWorldScale.xz);
|
||||
return result;
|
||||
}
|
269
examples/shaders/shadertoys/relentless.fs
Normal file
269
examples/shaders/shadertoys/relentless.fs
Normal file
|
@ -0,0 +1,269 @@
|
|||
vec2 iResolution = iWorldScale.xz;
|
||||
vec2 iMouse = vec2(0);
|
||||
|
||||
// From https://www.shadertoy.com/view/lss3WS
|
||||
|
||||
// srtuss, 2013
|
||||
|
||||
// collecting some design ideas for a new game project.
|
||||
// no raymarching is used.
|
||||
|
||||
// if i could add a custom soundtrack, it'd use this one (essential for desired sensation)
|
||||
// http://www.youtube.com/watch?v=1uFAu65tZpo
|
||||
|
||||
//#define GREEN_VERSION
|
||||
|
||||
// ** improved camera shaking
|
||||
// ** cleaned up code
|
||||
// ** added stuff to the gates
|
||||
|
||||
// *******************************************************************************************
|
||||
// Please do NOT use this shader in your own productions/videos/games without my permission!
|
||||
// If you'd still like to do so, please drop me a mail (stral@aon.at)
|
||||
// *******************************************************************************************
|
||||
|
||||
float time = iGlobalTime;
|
||||
|
||||
vec2 rotate(vec2 p, float a) {
|
||||
return vec2(p.x * cos(a) - p.y * sin(a), p.x * sin(a) + p.y * cos(a));
|
||||
}
|
||||
float box(vec2 p, vec2 b, float r) {
|
||||
return length(max(abs(p) - b, 0.0)) - r;
|
||||
}
|
||||
|
||||
// iq's ray-plane-intersection code
|
||||
vec3 intersect(in vec3 o, in vec3 d, vec3 c, vec3 u, vec3 v)
|
||||
{
|
||||
vec3 q = o - c;
|
||||
return vec3(
|
||||
dot(cross(u, v), q),
|
||||
dot(cross(q, u), d),
|
||||
dot(cross(v, q), d)) / dot(cross(v, u), d);
|
||||
}
|
||||
|
||||
// some noise functions for fast developing
|
||||
float rand11(float p) {
|
||||
return fract(sin(p * 591.32) * 43758.5357);
|
||||
}
|
||||
float rand12(vec2 p) {
|
||||
return fract(sin(dot(p.xy, vec2(12.9898, 78.233))) * 43758.5357);
|
||||
}
|
||||
vec2 rand21(float p) {
|
||||
return fract(vec2(sin(p * 591.32), cos(p * 391.32)));
|
||||
}
|
||||
vec2 rand22(in vec2 p)
|
||||
{
|
||||
return fract(vec2(sin(p.x * 591.32 + p.y * 154.077), cos(p.x * 391.32 + p.y * 49.077)));
|
||||
}
|
||||
|
||||
float noise11(float p) {
|
||||
float fl = floor(p);
|
||||
return mix(rand11(fl), rand11(fl + 1.0), fract(p)); //smoothstep(0.0, 1.0, fract(p)));
|
||||
}
|
||||
float fbm11(float p) {
|
||||
return noise11(p) * 0.5 + noise11(p * 2.0) * 0.25 + noise11(p * 5.0) * 0.125;
|
||||
}
|
||||
vec3 noise31(float p) {
|
||||
return vec3(noise11(p), noise11(p + 18.952), noise11(p - 11.372)) * 2.0 - 1.0;
|
||||
}
|
||||
|
||||
// something that looks a bit like godrays coming from the surface
|
||||
float sky(vec3 p) {
|
||||
float a = atan(p.x, p.z);
|
||||
float t = time * 0.1;
|
||||
float v = rand11(floor(a * 4.0 + t)) * 0.5 + rand11(floor(a * 8.0 - t)) * 0.25
|
||||
+ rand11(floor(a * 16.0 + t)) * 0.125;
|
||||
return v;
|
||||
}
|
||||
|
||||
vec3 voronoi(in vec2 x)
|
||||
{
|
||||
vec2 n = floor(x); // grid cell id
|
||||
vec2 f = fract(x);// grid internal position
|
||||
vec2 mg;// shortest distance...
|
||||
vec2 mr;// ..and second shortest distance
|
||||
float md = 8.0, md2 = 8.0;
|
||||
for(int j = -1; j <= 1; j ++)
|
||||
{
|
||||
for(int i = -1; i <= 1; i ++)
|
||||
{
|
||||
vec2 g = vec2(float(i), float(j)); // cell id
|
||||
vec2 o = rand22(n + g);// offset to edge point
|
||||
vec2 r = g + o - f;
|
||||
|
||||
float d = max(abs(r.x), abs(r.y));// distance to the edge
|
||||
|
||||
if(d < md)
|
||||
{ md2 = md; md = d; mr = r; mg = g;}
|
||||
else if(d < md2)
|
||||
{ md2 = d;}
|
||||
}
|
||||
}
|
||||
return vec3(n + mg, md2 - md);
|
||||
}
|
||||
|
||||
#define A2V(a) vec2(sin((a) * 6.28318531 / 100.0), cos((a) * 6.28318531 / 100.0))
|
||||
|
||||
float circles(vec2 p) {
|
||||
float v, w, l, c;
|
||||
vec2 pp;
|
||||
l = length(p);
|
||||
|
||||
pp = rotate(p, time * 3.0);
|
||||
c = max(dot(pp, normalize(vec2(-0.2, 0.5))),
|
||||
-dot(pp, normalize(vec2(0.2, 0.5))));
|
||||
c = min(c,
|
||||
max(dot(pp, normalize(vec2(0.5, -0.5))),
|
||||
-dot(pp, normalize(vec2(0.2, -0.5)))));
|
||||
c = min(c,
|
||||
max(dot(pp, normalize(vec2(0.3, 0.5))),
|
||||
-dot(pp, normalize(vec2(0.2, 0.5)))));
|
||||
|
||||
// innerest stuff
|
||||
v = abs(l - 0.5) - 0.03;
|
||||
v = max(v, -c);
|
||||
v = min(v, abs(l - 0.54) - 0.02);
|
||||
v = min(v, abs(l - 0.64) - 0.05);
|
||||
|
||||
pp = rotate(p, time * -1.333);
|
||||
c = max(dot(pp, A2V(-5.0)), -dot(pp, A2V(5.0)));
|
||||
c = min(c, max(dot(pp, A2V(25.0 - 5.0)), -dot(pp, A2V(25.0 + 5.0))));
|
||||
c = min(c, max(dot(pp, A2V(50.0 - 5.0)), -dot(pp, A2V(50.0 + 5.0))));
|
||||
c = min(c, max(dot(pp, A2V(75.0 - 5.0)), -dot(pp, A2V(75.0 + 5.0))));
|
||||
|
||||
w = abs(l - 0.83) - 0.09;
|
||||
v = min(v, max(w, c));
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
float shade1(float d) {
|
||||
float v = 1.0 - smoothstep(0.0, mix(0.012, 0.2, 0.0), d);
|
||||
float g = exp(d * -20.0);
|
||||
return v + g * 0.5;
|
||||
}
|
||||
|
||||
void mainImage( out vec4 fragColor, in vec2 fragCoord )
|
||||
{
|
||||
vec2 uv = fragCoord.xy / iResolution.xy;
|
||||
uv = uv * 2.0 - 1.0;
|
||||
uv.x *= iResolution.x / iResolution.y;
|
||||
|
||||
// using an iq styled camera this time :)
|
||||
// ray origin
|
||||
vec3 ro = 0.7 * vec3(cos(0.2 * time), 0.0, sin(0.2 * time));
|
||||
ro.y = cos(0.6 * time) * 0.3 + 0.65;
|
||||
// camera look at
|
||||
vec3 ta = vec3(0.0, 0.2, 0.0);
|
||||
|
||||
// camera shake intensity
|
||||
float shake = clamp(3.0 * (1.0 - length(ro.yz)), 0.3, 1.0);
|
||||
float st = mod(time, 10.0) * 143.0;
|
||||
|
||||
// build camera matrix
|
||||
vec3 ww = normalize(ta - ro + noise31(st) * shake * 0.01);
|
||||
vec3 uu = normalize(cross(ww, normalize(vec3(0.0, 1.0, 0.2 * sin(time)))));
|
||||
vec3 vv = normalize(cross(uu, ww));
|
||||
// obtain ray direction
|
||||
vec3 rd = normalize(uv.x * uu + uv.y * vv + 1.0 * ww);
|
||||
|
||||
// shaking and movement
|
||||
ro += noise31(-st) * shake * 0.015;
|
||||
ro.x += time * 2.0;
|
||||
|
||||
float inten = 0.0;
|
||||
|
||||
// background
|
||||
float sd = dot(rd, vec3(0.0, 1.0, 0.0));
|
||||
inten = pow(1.0 - abs(sd), 20.0) + pow(sky(rd), 5.0) * step(0.0, rd.y) * 0.2;
|
||||
|
||||
vec3 its;
|
||||
float v, g;
|
||||
|
||||
// voronoi floor layers
|
||||
for(int i = 0; i < 4; i ++)
|
||||
{
|
||||
float layer = float(i);
|
||||
its = intersect(ro, rd, vec3(0.0, -5.0 - layer * 5.0, 0.0), vec3(1.0, 0.0, 0.0), vec3(0.0, 0.0, 1.0));
|
||||
if(its.x > 0.0)
|
||||
{
|
||||
vec3 vo = voronoi((its.yz) * 0.05 + 8.0 * rand21(float(i)));
|
||||
v = exp(-100.0 * (vo.z - 0.02));
|
||||
|
||||
float fx = 0.0;
|
||||
|
||||
// add some special fx to lowest layer
|
||||
if(i == 3)
|
||||
{
|
||||
float crd = 0.0; //fract(time * 0.2) * 50.0 - 25.0;
|
||||
float fxi = cos(vo.x * 0.2 + time * 1.5);//abs(crd - vo.x);
|
||||
fx = clamp(smoothstep(0.9, 1.0, fxi), 0.0, 0.9) * 1.0 * rand12(vo.xy);
|
||||
fx *= exp(-3.0 * vo.z) * 2.0;
|
||||
}
|
||||
inten += v * 0.1 + fx;
|
||||
}
|
||||
}
|
||||
|
||||
// draw the gates, 4 should be enough
|
||||
float gatex = floor(ro.x / 8.0 + 0.5) * 8.0 + 4.0;
|
||||
float go = -16.0;
|
||||
for(int i = 0; i < 4; i ++)
|
||||
{
|
||||
its = intersect(ro, rd, vec3(gatex + go, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(0.0, 0.0, 1.0));
|
||||
if(dot(its.yz, its.yz) < 2.0 && its.x > 0.0)
|
||||
{
|
||||
v = circles(its.yz);
|
||||
inten += shade1(v);
|
||||
}
|
||||
|
||||
go += 8.0;
|
||||
}
|
||||
|
||||
// draw the stream
|
||||
for(int j = 0; j < 20; j ++)
|
||||
{
|
||||
float id = float(j);
|
||||
|
||||
vec3 bp = vec3(0.0, (rand11(id) * 2.0 - 1.0) * 0.25, 0.0);
|
||||
vec3 its = intersect(ro, rd, bp, vec3(1.0, 0.0, 0.0), vec3(0.0, 0.0, 1.0));
|
||||
|
||||
if(its.x > 0.0)
|
||||
{
|
||||
vec2 pp = its.yz;
|
||||
float spd = (1.0 + rand11(id) * 3.0) * 2.5;
|
||||
pp.y += time * spd;
|
||||
pp += (rand21(id) * 2.0 - 1.0) * vec2(0.3, 1.0);
|
||||
float rep = rand11(id) + 1.5;
|
||||
pp.y = mod(pp.y, rep * 2.0) - rep;
|
||||
float d = box(pp, vec2(0.02, 0.3), 0.1);
|
||||
float foc = 0.0;
|
||||
float v = 1.0 - smoothstep(0.0, 0.03, abs(d) - 0.001);
|
||||
float g = min(exp(d * -20.0), 2.0);
|
||||
|
||||
inten += (v + g * 0.7) * 0.5;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
inten *= 0.4 + (sin(time) * 0.5 + 0.5) * 0.6;
|
||||
|
||||
// find a color for the computed intensity
|
||||
#ifdef GREEN_VERSION
|
||||
vec3 col = pow(vec3(inten), vec3(2.0, 0.15, 9.0));
|
||||
#else
|
||||
vec3 col = pow(vec3(inten), 1.5 * vec3(0.15, 2.0, 9.0));
|
||||
#endif
|
||||
|
||||
fragColor = vec4(col, 1.0);
|
||||
}
|
||||
|
||||
vec4 getProceduralColor() {
|
||||
vec4 result;
|
||||
vec2 position = _position.xz;
|
||||
position += 0.5;
|
||||
position.y = 1.0 - position.y;
|
||||
|
||||
mainImage(result, position * iWorldScale.xz);
|
||||
|
||||
return result;
|
||||
}
|
136
examples/shaders/shadertoys/topologica.fs
Normal file
136
examples/shaders/shadertoys/topologica.fs
Normal file
|
@ -0,0 +1,136 @@
|
|||
#line 2
|
||||
vec2 iResolution = iWorldScale.xz;
|
||||
vec2 iMouse = vec2(0);
|
||||
|
||||
// From https://www.shadertoy.com/view/4djXzz
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
License CC0 - http://creativecommons.org/publicdomain/zero/1.0/
|
||||
To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty.
|
||||
----------------------------------------------------------------------------------------
|
||||
^ This means do ANYTHING YOU WANT with this code. Because we are programmers, not lawyers.
|
||||
-Otavio Good
|
||||
*/
|
||||
|
||||
// various noise functions
|
||||
float Hash2d(vec2 uv)
|
||||
{
|
||||
float f = uv.x + uv.y * 47.0;
|
||||
return fract(cos(f*3.333)*100003.9);
|
||||
}
|
||||
float Hash3d(vec3 uv) {
|
||||
float f = uv.x + uv.y * 37.0 + uv.z * 521.0;
|
||||
return fract(cos(f * 3.333) * 100003.9);
|
||||
}
|
||||
float mixP(float f0, float f1, float a) {
|
||||
return mix(f0, f1, a * a * (3.0 - 2.0 * a));
|
||||
}
|
||||
const vec2 zeroOne = vec2(0.0, 1.0);
|
||||
float noise2d(vec2 uv) {
|
||||
vec2 fr = fract(uv.xy);
|
||||
vec2 fl = floor(uv.xy);
|
||||
float h00 = Hash2d(fl);
|
||||
float h10 = Hash2d(fl + zeroOne.yx);
|
||||
float h01 = Hash2d(fl + zeroOne);
|
||||
float h11 = Hash2d(fl + zeroOne.yy);
|
||||
return mixP(mixP(h00, h10, fr.x), mixP(h01, h11, fr.x), fr.y);
|
||||
}
|
||||
|
||||
float noise(vec3 uv) {
|
||||
vec3 fr = fract(uv.xyz);
|
||||
vec3 fl = floor(uv.xyz);
|
||||
float h000 = Hash3d(fl);
|
||||
float h100 = Hash3d(fl + zeroOne.yxx);
|
||||
float h010 = Hash3d(fl + zeroOne.xyx);
|
||||
float h110 = Hash3d(fl + zeroOne.yyx);
|
||||
float h001 = Hash3d(fl + zeroOne.xxy);
|
||||
float h101 = Hash3d(fl + zeroOne.yxy);
|
||||
float h011 = Hash3d(fl + zeroOne.xyy);
|
||||
float h111 = Hash3d(fl + zeroOne.yyy);
|
||||
return mixP(mixP(mixP(h000, h100, fr.x), mixP(h010, h110, fr.x), fr.y),
|
||||
mixP(mixP(h001, h101, fr.x), mixP(h011, h111, fr.x), fr.y), fr.z);
|
||||
}
|
||||
|
||||
float PI = 3.14159265;
|
||||
|
||||
vec3 saturate(vec3 a) {
|
||||
return clamp(a, 0.0, 1.0);
|
||||
}
|
||||
vec2 saturate(vec2 a) {
|
||||
return clamp(a, 0.0, 1.0);
|
||||
}
|
||||
float saturate(float a) {
|
||||
return clamp(a, 0.0, 1.0);
|
||||
}
|
||||
|
||||
float Density(vec3 p) {
|
||||
//float ws = 0.06125*0.125;
|
||||
//vec3 warp = vec3(noise(p*ws), noise(p*ws + 111.11), noise(p*ws + 7111.11));
|
||||
float final = noise(p * 0.06125); // + sin(iGlobalTime)*0.5-1.95 + warp.x*4.0;
|
||||
float other = noise(p * 0.06125 + 1234.567);
|
||||
other -= 0.5;
|
||||
final -= 0.5;
|
||||
final = 0.1 / (abs(final * final * other));
|
||||
final += 0.5;
|
||||
return final * 0.0001;
|
||||
}
|
||||
|
||||
void mainImage( out vec4 fragColor, in vec2 fragCoord )
|
||||
{
|
||||
// ---------------- First, set up the camera rays for ray marching ----------------
|
||||
vec2 uv = fragCoord.xy/iResolution.xy * 2.0 - 1.0;// - 0.5;
|
||||
|
||||
// Camera up vector.
|
||||
vec3 camUp=vec3(0,1,0);// vuv
|
||||
|
||||
// Camera lookat.
|
||||
vec3 camLookat=vec3(0,0.0,0);// vrp
|
||||
|
||||
float mx=iMouse.x/iResolution.x*PI*2.0 + iGlobalTime * 0.01;
|
||||
float my=-iMouse.y/iResolution.y*10.0 + sin(iGlobalTime * 0.03)*0.2+0.2;//*PI/2.01;
|
||||
vec3 camPos=vec3(cos(my)*cos(mx),sin(my),cos(my)*sin(mx))*(200.2);// prp
|
||||
|
||||
// Camera setup.
|
||||
vec3 camVec=normalize(camLookat - camPos);//vpn
|
||||
vec3 sideNorm=normalize(cross(camUp, camVec));// u
|
||||
vec3 upNorm=cross(camVec, sideNorm);//v
|
||||
vec3 worldFacing=(camPos + camVec);//vcv
|
||||
vec3 worldPix = worldFacing + uv.x * sideNorm * (iResolution.x/iResolution.y) + uv.y * upNorm;//scrCoord
|
||||
vec3 relVec = normalize(worldPix - camPos);//scp
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
float t = 0.0;
|
||||
float inc = 0.02;
|
||||
float maxDepth = 70.0;
|
||||
vec3 pos = vec3(0,0,0);
|
||||
float density = 0.0;
|
||||
// ray marching time
|
||||
for (int i = 0; i < 37; i++)// This is the count of how many times the ray actually marches.
|
||||
{
|
||||
if ((t > maxDepth)) break;
|
||||
pos = camPos + relVec * t;
|
||||
float temp = Density(pos);
|
||||
//temp *= saturate(t-1.0);
|
||||
|
||||
inc = 1.9 + temp*0.05;// add temp because this makes it look extra crazy!
|
||||
density += temp * inc;
|
||||
t += inc;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// Now that we have done our ray marching, let's put some color on this.
|
||||
vec3 finalColor = vec3(0.01,0.1,1.0)* density*0.2;
|
||||
|
||||
// output the final color with sqrt for "gamma correction"
|
||||
fragColor = vec4(sqrt(clamp(finalColor, 0.0, 1.0)),1.0);
|
||||
}
|
||||
|
||||
vec4 getProceduralColor() {
|
||||
vec4 result;
|
||||
vec2 position = _position.xz;
|
||||
position += 0.5;
|
||||
|
||||
mainImage(result, position * iWorldScale.xz);
|
||||
|
||||
return result;
|
||||
}
|
|
@ -39,16 +39,16 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
|
|||
Q_ASSERT(args->_batch);
|
||||
gpu::Batch& batch = *args->_batch;
|
||||
batch.setModelTransform(getTransformToCenter()); // we want to include the scale as well
|
||||
|
||||
glm::vec4 cubeColor(toGlm(getXColor()), getLocalRenderAlpha());
|
||||
|
||||
if (!_procedural) {
|
||||
_procedural.reset(new ProceduralInfo(this));
|
||||
}
|
||||
|
||||
if (_procedural->ready()) {
|
||||
_procedural->prepare(batch);
|
||||
DependencyManager::get<GeometryCache>()->renderUnitCube(batch);
|
||||
DependencyManager::get<GeometryCache>()->renderSolidCube(batch, 1.0f, _procedural->getColor(cubeColor));
|
||||
} else {
|
||||
glm::vec4 cubeColor(toGlm(getXColor()), getLocalRenderAlpha());
|
||||
DependencyManager::get<DeferredLightingEffect>()->renderSolidCube(batch, 1.0f, cubeColor);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,10 +8,11 @@
|
|||
|
||||
#include "RenderableProceduralItem.h"
|
||||
|
||||
#include <QtCore/QJsonObject>
|
||||
#include <QtCore/QJsonDocument>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QJsonArray>
|
||||
#include <QtCore/QJsonDocument>
|
||||
#include <QtCore/QJsonObject>
|
||||
|
||||
#include <ShaderCache.h>
|
||||
#include <EntityItem.h>
|
||||
|
@ -26,10 +27,19 @@ static const char* const UNIFORM_TIME_NAME= "iGlobalTime";
|
|||
static const char* const UNIFORM_SCALE_NAME = "iWorldScale";
|
||||
static const QString PROCEDURAL_USER_DATA_KEY = "ProceduralEntity";
|
||||
|
||||
static const QString URL_KEY = "shaderUrl";
|
||||
static const QString VERSION_KEY = "version";
|
||||
static const QString UNIFORMS_KEY = "uniforms";
|
||||
|
||||
RenderableProceduralItem::ProceduralInfo::ProceduralInfo(EntityItem* entity) : _entity(entity) {
|
||||
parse();
|
||||
}
|
||||
|
||||
void RenderableProceduralItem::ProceduralInfo::parse() {
|
||||
_enabled = false;
|
||||
QJsonObject userData;
|
||||
{
|
||||
const QString& userDataJson = entity->getUserData();
|
||||
const QString& userDataJson = _entity->getUserData();
|
||||
if (userDataJson.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -48,30 +58,51 @@ RenderableProceduralItem::ProceduralInfo::ProceduralInfo(EntityItem* entity) : _
|
|||
// "color" : "#FFFFFF"
|
||||
// }
|
||||
//}
|
||||
|
||||
auto proceduralData = userData[PROCEDURAL_USER_DATA_KEY];
|
||||
if (proceduralData.isNull()) {
|
||||
return;
|
||||
}
|
||||
auto proceduralDataObject = proceduralData.toObject();
|
||||
QString shaderUrl = proceduralDataObject["shaderUrl"].toString();
|
||||
_shaderUrl = QUrl(shaderUrl);
|
||||
if (!_shaderUrl.isValid()) {
|
||||
qWarning() << "Invalid shader URL: " << shaderUrl;
|
||||
return;
|
||||
|
||||
parse(proceduralData.toObject());
|
||||
}
|
||||
|
||||
void RenderableProceduralItem::ProceduralInfo::parse(const QJsonObject& proceduralData) {
|
||||
// grab the version number
|
||||
{
|
||||
auto version = proceduralData[VERSION_KEY];
|
||||
if (version.isDouble()) {
|
||||
_version = (uint8_t)(floor(version.toDouble()));
|
||||
}
|
||||
}
|
||||
|
||||
if (_shaderUrl.isLocalFile()) {
|
||||
_shaderPath = _shaderUrl.toLocalFile();
|
||||
qDebug() << "Shader path: " << _shaderPath;
|
||||
if (!QFile(_shaderPath).exists()) {
|
||||
// Get the path to the shader
|
||||
{
|
||||
QString shaderUrl = proceduralData[URL_KEY].toString();
|
||||
_shaderUrl = QUrl(shaderUrl);
|
||||
if (!_shaderUrl.isValid()) {
|
||||
qWarning() << "Invalid shader URL: " << shaderUrl;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Shader url: " << _shaderUrl;
|
||||
_networkShader = ShaderCache::instance().getShader(_shaderUrl);
|
||||
|
||||
if (_shaderUrl.isLocalFile()) {
|
||||
_shaderPath = _shaderUrl.toLocalFile();
|
||||
qDebug() << "Shader path: " << _shaderPath;
|
||||
if (!QFile(_shaderPath).exists()) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Shader url: " << _shaderUrl;
|
||||
_networkShader = ShaderCache::instance().getShader(_shaderUrl);
|
||||
}
|
||||
}
|
||||
|
||||
// Grab any custom uniforms
|
||||
{
|
||||
auto uniforms = proceduralData[UNIFORMS_KEY];
|
||||
if (uniforms.isObject()) {
|
||||
_uniforms = uniforms.toObject();;
|
||||
}
|
||||
}
|
||||
_enabled = true;
|
||||
}
|
||||
|
||||
|
@ -106,11 +137,21 @@ void RenderableProceduralItem::ProceduralInfo::prepare(gpu::Batch& batch) {
|
|||
}
|
||||
|
||||
if (!_pipeline || _pipelineDirty) {
|
||||
_pipelineDirty = false;
|
||||
_pipelineDirty = true;
|
||||
if (!_vertexShader) {
|
||||
_vertexShader = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(simple_vert)));
|
||||
}
|
||||
QString framentShaderSource = SHADER_TEMPLATE.arg(_shaderSource);
|
||||
QString framentShaderSource;
|
||||
switch (_version) {
|
||||
case 1:
|
||||
framentShaderSource = SHADER_TEMPLATE_V1.arg(_shaderSource);
|
||||
break;
|
||||
|
||||
default:
|
||||
case 2:
|
||||
framentShaderSource = SHADER_TEMPLATE_V2.arg(_shaderSource);
|
||||
break;
|
||||
}
|
||||
_fragmentShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(framentShaderSource.toLocal8Bit().data())));
|
||||
_shader = gpu::ShaderPointer(gpu::Shader::createProgram(_vertexShader, _fragmentShader));
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
|
@ -129,9 +170,68 @@ void RenderableProceduralItem::ProceduralInfo::prepare(gpu::Batch& batch) {
|
|||
}
|
||||
|
||||
batch.setPipeline(_pipeline);
|
||||
|
||||
if (_pipelineDirty) {
|
||||
_pipelineDirty = false;
|
||||
// Set any userdata specified uniforms
|
||||
foreach(QString key, _uniforms.keys()) {
|
||||
std::string uniformName = key.toLocal8Bit().data();
|
||||
int32_t slot = _shader->getUniforms().findLocation(uniformName);
|
||||
if (gpu::Shader::INVALID_LOCATION == slot) {
|
||||
continue;
|
||||
}
|
||||
QJsonValue value = _uniforms[key];
|
||||
if (value.isDouble()) {
|
||||
batch._glUniform1f(slot, value.toDouble());
|
||||
} else if (value.isArray()) {
|
||||
auto valueArray = value.toArray();
|
||||
switch (valueArray.size()) {
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 1:
|
||||
batch._glUniform1f(slot, valueArray[0].toDouble());
|
||||
break;
|
||||
case 2:
|
||||
batch._glUniform2f(slot,
|
||||
valueArray[0].toDouble(),
|
||||
valueArray[1].toDouble());
|
||||
break;
|
||||
case 3:
|
||||
batch._glUniform3f(slot,
|
||||
valueArray[0].toDouble(),
|
||||
valueArray[0].toDouble(),
|
||||
valueArray[1].toDouble());
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
batch._glUniform4f(slot,
|
||||
valueArray[0].toDouble(),
|
||||
valueArray[1].toDouble(),
|
||||
valueArray[2].toDouble(),
|
||||
valueArray[3].toDouble());
|
||||
break;
|
||||
|
||||
}
|
||||
valueArray.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Minimize floating point error by doing an integer division to milliseconds, before the floating point division to seconds
|
||||
float time = (float)((usecTimestampNow() - _start) / USECS_PER_MSEC) / MSECS_PER_SECOND;
|
||||
batch._glUniform1f(_timeSlot, time);
|
||||
|
||||
// FIXME move into the 'set once' section, since this doesn't change over time
|
||||
auto scale = _entity->getDimensions();
|
||||
batch._glUniform3f(_scaleSlot, scale.x, scale.y, scale.z);
|
||||
batch.setResourceTexture(DeferredLightingEffect::NORMAL_FITTING_MAP_SLOT, DependencyManager::get<TextureCache>()->getNormalFittingTexture());
|
||||
}
|
||||
|
||||
|
||||
glm::vec4 RenderableProceduralItem::ProceduralInfo::getColor(const glm::vec4& entityColor) {
|
||||
if (_version == 1) {
|
||||
return glm::vec4(1);
|
||||
}
|
||||
return entityColor;
|
||||
}
|
|
@ -10,9 +10,10 @@
|
|||
#ifndef hifi_RenderableProcedrualItem_h
|
||||
#define hifi_RenderableProcedrualItem_h
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/QJsonObject>
|
||||
|
||||
#include <ShaderCache.h>
|
||||
#include <gpu/Shader.h>
|
||||
|
@ -20,15 +21,22 @@
|
|||
#include <gpu/Batch.h>
|
||||
|
||||
class EntityItem;
|
||||
class QJsonObject;
|
||||
|
||||
class RenderableProceduralItem {
|
||||
protected:
|
||||
// FIXME better encapsulation
|
||||
// FIXME better mechanism for extending to things rendered using shaders other than simple.slv
|
||||
struct ProceduralInfo {
|
||||
ProceduralInfo(EntityItem* entity);
|
||||
void parse();
|
||||
void parse(const QJsonObject&);
|
||||
bool ready();
|
||||
void prepare(gpu::Batch& batch);
|
||||
glm::vec4 getColor(const glm::vec4& entityColor);
|
||||
|
||||
bool _enabled{ false };
|
||||
uint8_t _version{ 1 };
|
||||
gpu::PipelinePointer _pipeline;
|
||||
gpu::ShaderPointer _vertexShader;
|
||||
gpu::ShaderPointer _fragmentShader;
|
||||
|
@ -43,6 +51,7 @@ protected:
|
|||
uint64_t _start{ 0 };
|
||||
NetworkShaderPointer _networkShader;
|
||||
EntityItem* _entity;
|
||||
QJsonObject _uniforms;
|
||||
};
|
||||
|
||||
QSharedPointer<ProceduralInfo> _procedural;
|
||||
|
|
|
@ -16,17 +16,17 @@
|
|||
// Distributed under the MIT License. See LICENSE file.
|
||||
// https://github.com/ashima/webgl-noise
|
||||
//
|
||||
const QString SHADER_TEMPLATE = R"SCRIBE(#version 410 core
|
||||
|
||||
|
||||
const QString SHADER_COMMON = R"SHADER(#version 410 core
|
||||
layout(location = 0) out vec4 _fragColor0;
|
||||
layout(location = 1) out vec4 _fragColor1;
|
||||
layout(location = 2) out vec4 _fragColor2;
|
||||
|
||||
// the glow intensity
|
||||
uniform float glowIntensity;
|
||||
|
||||
// the alpha threshold
|
||||
uniform float alphaThreshold;
|
||||
|
||||
uniform sampler2D normalFittingMap;
|
||||
|
||||
vec3 bestFitNormal(vec3 normal) {
|
||||
|
@ -45,18 +45,6 @@ vec3 bestFitNormal(vec3 normal) {
|
|||
}
|
||||
|
||||
|
||||
const vec3 DEFAULT_SPECULAR = vec3(0.1);
|
||||
const float DEFAULT_SHININESS = 10;
|
||||
|
||||
void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess, vec3 emissive) {
|
||||
if (alpha != glowIntensity) {
|
||||
discard;
|
||||
}
|
||||
|
||||
_fragColor0 = vec4(diffuse.rgb, alpha);
|
||||
_fragColor1 = vec4(bestFitNormal(normal), 0.5);
|
||||
_fragColor2 = vec4(emissive, shininess / 128.0);
|
||||
}
|
||||
|
||||
float mod289(float x) {
|
||||
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
||||
|
@ -314,16 +302,62 @@ uniform vec3 iWorldScale; // the dimensions of the object being rende
|
|||
// TODO document available inputs other than the uniforms
|
||||
// TODO provide world scale in addition to the untransformed position
|
||||
|
||||
const vec3 DEFAULT_SPECULAR = vec3(0.1);
|
||||
const float DEFAULT_SHININESS = 10;
|
||||
|
||||
)SHADER";
|
||||
|
||||
// V1 shaders, only support emissive
|
||||
// vec4 getProceduralColor()
|
||||
const QString SHADER_TEMPLATE_V1 = SHADER_COMMON + R"SCRIBE(
|
||||
|
||||
#line 1001
|
||||
%1
|
||||
#line 317
|
||||
|
||||
void main(void) {
|
||||
vec4 texel = getProceduralColor();
|
||||
vec4 emissive = getProceduralColor();
|
||||
|
||||
float alpha = glowIntensity * emissive.a;
|
||||
if (alpha != glowIntensity) {
|
||||
discard;
|
||||
}
|
||||
|
||||
vec4 diffuse = vec4(_color.rgb, alpha);
|
||||
vec4 normal = vec4(normalize(bestFitNormal(_normal)), 0.5);
|
||||
|
||||
_fragColor0 = diffuse;
|
||||
_fragColor1 = normal;
|
||||
_fragColor2 = vec4(emissive.rgb, DEFAULT_SHININESS / 128.0);
|
||||
}
|
||||
|
||||
)SCRIBE";
|
||||
|
||||
// void getProceduralDiffuseAndEmissive(out vec4 diffuse, out vec4 emissive)
|
||||
const QString SHADER_TEMPLATE_V2 = SHADER_COMMON + R"SCRIBE(
|
||||
// FIXME should we be doing the swizzle here?
|
||||
vec3 iResolution = iWorldScale.xzy;
|
||||
|
||||
// FIXME Mouse X,Y coordinates, and Z,W are for the click position if clicked (not supported in High Fidelity at the moment)
|
||||
vec4 iMouse = vec4(0);
|
||||
|
||||
// FIXME We set the seconds (iDate.w) of iDate to iGlobalTime, which contains the current date in seconds
|
||||
vec4 iDate = vec4(0, 0, 0, iGlobalTime);
|
||||
|
||||
|
||||
#line 1001
|
||||
%1
|
||||
#line 351
|
||||
|
||||
void main(void) {
|
||||
vec3 diffuse = _color.rgb;
|
||||
vec3 specular = DEFAULT_SPECULAR;
|
||||
float shininess = DEFAULT_SHININESS;
|
||||
|
||||
packDeferredFragmentLightmap(
|
||||
normalize(_normal),
|
||||
glowIntensity * texel.a,
|
||||
_color.rgb,
|
||||
DEFAULT_SPECULAR, DEFAULT_SHININESS,
|
||||
texel.rgb);
|
||||
float emissiveAmount = getProceduralColors(diffuse, specular, shininess);
|
||||
|
||||
_fragColor0 = vec4(diffuse.rgb, 1.0);
|
||||
_fragColor1 = vec4(bestFitNormal(normalize(_normal.xyz)), 1.0 - (emissiveAmount / 2.0));
|
||||
_fragColor2 = vec4(specular, shininess / 128.0);
|
||||
}
|
||||
)SCRIBE";
|
||||
|
|
|
@ -50,11 +50,11 @@ void RenderableSphereEntityItem::render(RenderArgs* args) {
|
|||
_procedural.reset(new ProceduralInfo(this));
|
||||
}
|
||||
|
||||
glm::vec4 sphereColor(toGlm(getXColor()), getLocalRenderAlpha());
|
||||
if (_procedural->ready()) {
|
||||
_procedural->prepare(batch);
|
||||
DependencyManager::get<GeometryCache>()->renderSphere(batch, 0.5f, SLICES, STACKS, vec3(1));
|
||||
DependencyManager::get<GeometryCache>()->renderSphere(batch, 0.5f, SLICES, STACKS, _procedural->getColor(sphereColor));
|
||||
} else {
|
||||
glm::vec4 sphereColor(toGlm(getXColor()), getLocalRenderAlpha());
|
||||
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphere(batch, 0.5f, SLICES, STACKS, sphereColor);
|
||||
}
|
||||
|
||||
|
|
|
@ -144,6 +144,7 @@ public:
|
|||
void _glUniform1f(int location, float v0);
|
||||
void _glUniform2f(int location, float v0, float v1);
|
||||
void _glUniform3f(int location, float v0, float v1, float v2);
|
||||
void _glUniform4f(int location, float v0, float v1, float v2, float v3);
|
||||
void _glUniform3fv(int location, int count, const float* value);
|
||||
void _glUniform4fv(int location, int count, const float* value);
|
||||
void _glUniform4iv(int location, int count, const int* value);
|
||||
|
@ -192,6 +193,7 @@ public:
|
|||
COMMAND_glUniform1f,
|
||||
COMMAND_glUniform2f,
|
||||
COMMAND_glUniform3f,
|
||||
COMMAND_glUniform4f,
|
||||
COMMAND_glUniform3fv,
|
||||
COMMAND_glUniform4fv,
|
||||
COMMAND_glUniform4iv,
|
||||
|
|
|
@ -56,6 +56,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
(&::gpu::GLBackend::do_glUniform1f),
|
||||
(&::gpu::GLBackend::do_glUniform2f),
|
||||
(&::gpu::GLBackend::do_glUniform3f),
|
||||
(&::gpu::GLBackend::do_glUniform4f),
|
||||
(&::gpu::GLBackend::do_glUniform3fv),
|
||||
(&::gpu::GLBackend::do_glUniform4fv),
|
||||
(&::gpu::GLBackend::do_glUniform4iv),
|
||||
|
@ -458,6 +459,36 @@ void GLBackend::do_glUniform3f(Batch& batch, uint32 paramOffset) {
|
|||
(void) CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
|
||||
void Batch::_glUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
|
||||
ADD_COMMAND_GL(glUniform4f);
|
||||
|
||||
_params.push_back(v3);
|
||||
_params.push_back(v2);
|
||||
_params.push_back(v1);
|
||||
_params.push_back(v0);
|
||||
_params.push_back(location);
|
||||
|
||||
DO_IT_NOW(_glUniform4f, 1);
|
||||
}
|
||||
|
||||
|
||||
void GLBackend::do_glUniform4f(Batch& batch, uint32 paramOffset) {
|
||||
if (_pipeline._program == 0) {
|
||||
// We should call updatePipeline() to bind the program but we are not doing that
|
||||
// because these uniform setters are deprecated and we don;t want to create side effect
|
||||
return;
|
||||
}
|
||||
updatePipeline();
|
||||
glUniform4f(
|
||||
batch._params[paramOffset + 4]._int,
|
||||
batch._params[paramOffset + 3]._float,
|
||||
batch._params[paramOffset + 2]._float,
|
||||
batch._params[paramOffset + 1]._float,
|
||||
batch._params[paramOffset + 0]._float);
|
||||
(void)CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
void Batch::_glUniform3fv(GLint location, GLsizei count, const GLfloat* value) {
|
||||
ADD_COMMAND_GL(glUniform3fv);
|
||||
|
||||
|
|
|
@ -457,6 +457,7 @@ protected:
|
|||
void do_glUniform1f(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform2f(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform3f(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform4f(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform3fv(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform4fv(Batch& batch, uint32 paramOffset);
|
||||
void do_glUniform4iv(Batch& batch, uint32 paramOffset);
|
||||
|
|
Loading…
Reference in a new issue