Files
starruler-linux/data/shaders/source/star_anim_high_ps.txt
T
2018-07-17 14:15:37 +02:00

202 lines
5.4 KiB
Plaintext

#version 120
const float tau = 6.28318530716;
const bool parallax = #{{level:extreme}};
const bool advancedProcedurals = #{{level:high}};
// it needs special tweaks to not bleed out in overexposure
bool lightShaftsOn = #{{bGodRays}};
bool bloomOn = #{{bBloom}};
// parallax scale, bias and steps
const vec2 scaleBias = vec2(0.005, 0.0025);
uniform sampler2D texture[2];
uniform float cycles[5];
uniform float temperature;
uniform float nodeScale;
varying float distortion;
varying vec2 uvA, uvB;
varying vec3 vertCol, normal, origo;
varying vec3 v;
const float maxVariance = 0.03; //should be kept low
const float deviationCycles = 3.25; //How much variation is based on base color
const float two_pi = 6.28318531;
const float noise1Base = 0.84, noise1Range = 0.25;
const float noise2Base = 0.93, noise2Range = 0.34;
const float diffPower = 2.3;
const float tempInfluence = 0.25;
const float baseTemp = 10000.0;
const float noiseOffsetNoise = 0.1;
float mixRange(float x, float low, float hi) {
return clamp((x - low) / (hi - low), 0.0, 1.0);
}
vec3 blackBody(float temp) {
vec3 c;
c.r = mix(1.0, 0.6234, mixRange(temp, 6400.0, 29800.0));
c.b = mix(0.0, 1.0, mixRange(temp, 2800.0, 7600.0));
if(temp < 6600.0)
c.g = mix(0.22, 0.976, mixRange(temp, 1000.0, 6600.0));
else
c.g = mix(0.976, 0.75, mixRange(temp, 6600.0, 29800.0));
if(temp > 13000.0)
c += vec3(mixRange(temp, 13000.0, 29800.0));
return c;
}
vec3 dp1Calc(vec3 p)
{
return dFdx(p);
}
vec3 dp2Calc(vec3 p)
{
return dFdy(p);
}
vec4 duv1Calc(vec4 uv)
{
return dFdx(uv);
}
vec4 duv2Calc(vec4 uv)
{
return dFdy(uv);
}
float pow4(float x){
x*= x;
return x*x;
}
/*
float mip_map_level(vec2 uv)
{
vec2 dx_vtc = dFdx(uv);
vec2 dy_vtc = dFdy(uv);
float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc));
//return max(0.0, 0.5 * log2(delta_max_sqr) - 1.0); // == log2(sqrt(delta_max_sqr));
return 0.5 * log2(delta_max_sqr); // == log2(sqrt(delta_max_sqr));
}
*/
float starSampMip(vec2 uv, float mip){
vec2 noiseCoord = uv * 3.0 + (texture2D(texture[1], uv * 16.0, mip).xz - vec2(0.5)) * noiseOffsetNoise;
noiseCoord += vec2( cycles[0], cycles[1]);
vec2 noise2Coord = noiseCoord + vec2( -cycles[3], cycles[4] );
vec2 noise3Coord = noiseCoord + vec2( -cycles[2], cycles[3] * 4.0 );
vec2 noise4Coord = noiseCoord * 2.0 + vec2( cycles[4], cycles[0] * -2.0 );
noiseCoord += vec2( cycles[1], cycles[2] );
float heat = noise1Base + noise1Range *
texture2D(texture[1], uv * 4.0, mip).r;
heat *= noise2Base + noise2Range *
texture2D(texture[0], noise2Coord, mip).g;
heat *= noise2Base + noise2Range *
texture2D(texture[0], noise3Coord, mip).b;
heat *= noise1Base + noise1Range *
texture2D(texture[1], noise4Coord, mip).g;
return heat;
}
float starSamp(vec2 uv){
vec2 noiseCoord =uv * 3.0 + (texture2D(texture[1], uv * 16.0).xz - vec2(0.5)) * noiseOffsetNoise;
noiseCoord += vec2( cycles[0], cycles[1]);
vec2 noise2Coord = noiseCoord + vec2( -cycles[3], cycles[4] );
vec2 noise3Coord = noiseCoord + vec2( -cycles[2], cycles[3] * 4.0 );
vec2 noise4Coord = noiseCoord * 2.0 + vec2( cycles[4], cycles[0] * -2.0 );
noiseCoord += vec2( cycles[1], cycles[2] );
float heat = noise1Base + noise1Range *
texture2D(texture[1], uv * 4.0).r;
heat *= noise2Base + noise2Range *
texture2D(texture[0], noise2Coord).g;
heat *= noise2Base + noise2Range *
texture2D(texture[0], noise3Coord).b;
heat *= noise1Base + noise1Range *
texture2D(texture[1], noise4Coord).g;
return heat;
}
void main() {
vec4 uvP = vec4(uvA, uvB);
// do polar blend mask from world space normals
float blendMask = clamp(abs(normal.y)* 4.0 - 2.0, 0.0, 1.0);
float NdotV = max(0.0, dot(normal, v));
float heat = 0.0;
if (parallax){
// star surface to noisy to work for parallax, so sample mip-blurred for approximate softened plumes
heat = mix(starSampMip(uvB, 5.0), starSampMip(uvA, 5.0), blendMask);
// make the parallax a little more interesting
heat = pow4(abs(fract(heat) * 2.0 - 1.0));
// and smoothstep
heat *= heat * (3.0 - (2.0 * heat));
vec3 dp1 = dp1Calc(-v);
vec3 dp2 = dp2Calc(-v);
// derive for both uv's
vec4 duv1 = duv1Calc(uvP);
vec4 duv2 = duv2Calc(uvP);
vec3 dp2perp = cross(dp2, normal);
vec3 dp1perp = cross(normal, dp1);
// do parallax
float fDet = dot(dp1, dp2perp);
vec2 vProjVScr = (1.0/fDet) * vec2(dot(dp2perp, v), dot(dp1perp, v));
vec4 vProjVTex = (duv1 * vProjVScr.x + duv2 * vProjVScr.y);
float vProjVTexZ = NdotV * ((1.0 - heat - 0.5) * scaleBias.r - scaleBias.g);
uvP += (vProjVTex * vProjVTexZ);
heat = mix(starSamp(uvP.zw), starSamp(uvP.xy), blendMask);
}
else{
heat = mix(starSamp(uvB), starSamp(uvA), blendMask);
}
heat -=1.1;
if(temperature < 3500.0) {
heat += 0.05;
if(heat < 0.0)
heat *= 2.0;
else
heat *= 22.0 - (temperature / 350.0);
}
else if(temperature < 6500.0) {
heat *= 4.0;
}
else if(temperature > 20000.0) {
heat *= 5.0;
}
else {
heat += 0.05;
if(heat < 0.0)
heat *= 2.0;
else
heat *= 20.0;
}
heat = mix(heat, 0.7, pow(max(distortion,0.0), 2.8));
heat = mix(0.6, heat, NdotV) + 1.0;
gl_FragColor.rgb = blackBody(temperature * heat) * clamp(heat, min(temperature / 2500.0, 1.0), 1.0);
gl_FragColor.a = 1.0;
}