Skip to content

Commit

Permalink
sky shader
Browse files Browse the repository at this point in the history
  • Loading branch information
tritonas00 authored and ohlidalp committed Mar 2, 2024
1 parent 2915a88 commit b1e6457
Show file tree
Hide file tree
Showing 15 changed files with 425 additions and 34 deletions.
99 changes: 99 additions & 0 deletions resources/materials/SkyGLSL.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Shader ported from https://www.shadertoy.com/view/4sKGWt
// License: BSD
// by Morgan McGuire, @CasualEffects

uniform float iTime;
uniform float iResolution_x;
uniform float iResolution_y;

uniform float sky_yaw;
uniform float sky_pitch;
uniform float sky_roll;
uniform float sky_fov;
uniform float sun_size;
uniform float cloud_density;
uniform float sky_light;

varying vec4 projectionCoord;

float hash(vec2 p) { return fract(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x)))); }

float noise(vec2 x) {
float speed = iTime * 0.2;

vec2 i = floor(x+speed), f = fract(x+speed);

float a = hash(i);
float b = hash(i + vec2(1.0, 0.0));
float c = hash(i + vec2(0.0, 1.0));
float d = hash(i + vec2(1.0, 1.0));

vec2 u = f * f * (3.0 - 2.0 * f);

return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
}

float fbm(vec2 p) {
const mat2 m2 = mat2(0.8, -0.6, 0.6, 0.8);

float f = 0.5000 * noise(p); p = m2 * p * 2.02;
f += 0.2500 * noise(p); p = m2 * p * 2.03;
f += 0.1250 * noise(p); p = m2 * p * 2.01;
f += 0.0625 * noise(p);

return f / 0.9375;
}

vec3 render(in vec3 light, in vec3 ro, in vec3 rd) {
// Sky with haze
vec3 col = vec3(0.3, 0.55, 0.8) * (1.0 - 0.8 * rd.y) * sky_light;

if (rd.y >= 0.0)
{
// Sun
float sundot = clamp(dot(rd, light), 0.0, 1.0);
col += sun_size * 0.25 * vec3(1.0, 0.7, 0.4) * pow(sundot, 8.0);
col += sun_size * 0.75 * vec3(1.0, 0.8, 0.5) * pow(sundot, 64.0);

// Clouds
col = mix(col, vec3(1.0, 0.95, 1.0), 0.5 * smoothstep(0.5-cloud_density, 0.8-cloud_density, fbm((ro.xz + rd.xz * (250000.0 - ro.y) / rd.y) * 0.000008)));
}

// Horizon/atmospheric perspective
col = mix(col, vec3(0.7, 0.75, 0.8), pow(1.0 - max(abs(rd.y), 0.0), 8.0));

return col;
}

void main(void)
{
float verticalFieldOfView = sky_fov * 3.1415927 / 180.0;

vec3 cameraOrigin = vec3(-iTime, sin(iTime) + 2.1, 0.0);

vec3 ro = cameraOrigin;
vec3 rd = normalize(vec3(projectionCoord.xy * vec2(iResolution_x, iResolution_y) / 2.0, iResolution_y * 0.5 / -tan(verticalFieldOfView * 0.5)));

mat3 yawMatrix = mat3(cos(sky_yaw), 0.0, -sin(sky_yaw),
0.0, 1.0, 0.0,
sin(sky_yaw), 0.0, cos(sky_yaw));

mat3 pitchMatrix = mat3(1.0, 0.0, 0.0,
0.0, cos(sky_pitch), sin(sky_pitch),
0.0, -sin(sky_pitch), cos(sky_pitch));

mat3 rollMatrix = mat3(cos(sky_roll), sin(sky_roll), 0.0,
-sin(sky_roll), cos(sky_roll), 0.0,
0.0, 0.0, 1.0);

rd = yawMatrix * pitchMatrix * rollMatrix * rd;

vec3 light = normalize(vec3(-0.5, 0.3 - sin(0.15), -0.3));

vec3 col = render(light, ro, rd);

// Gamma encode
col = pow(col, vec3(0.4545));

gl_FragColor = vec4( col, 1.0 );
}
11 changes: 11 additions & 0 deletions resources/materials/SkyGLSL.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
attribute vec4 vertex;

uniform mat4 worldViewProj;

varying vec4 projectionCoord;

void main(void)
{
gl_Position = worldViewProj * vertex;
projectionCoord = worldViewProj * vertex;
}
101 changes: 101 additions & 0 deletions resources/materials/SkyHLSL.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Shader ported from https://www.shadertoy.com/view/4sKGWt
// License: BSD
// by Morgan McGuire, @CasualEffects

uniform float iTime;
uniform float iResolution_x;
uniform float iResolution_y;

uniform float sky_yaw;
uniform float sky_pitch;
uniform float sky_roll;
uniform float sky_fov;
uniform float sun_size;
uniform float cloud_density;
uniform float sky_light;

float hash(float2 p) { return frac(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x)))); }

float noise(float2 x) {
float speed = iTime * 0.2;

float2 i = floor(x+speed), f = frac(x+speed);

float a = hash(i);
float b = hash(i + float2(1.0, 0.0));
float c = hash(i + float2(0.0, 1.0));
float d = hash(i + float2(1.0, 1.0));

float2 u = f * f * (3.0 - 2.0 * f);

return lerp(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
}

float fbm(float2 p) {
const float2x2 m2 = float2x2(0.8, -0.6, 0.6, 0.8);

float f = 0.5000 * noise(p);
p = mul(m2, p) * 2.02;
f += 0.2500 * noise(p); p = mul(m2, p) * 2.03;
f += 0.1250 * noise(p); p = mul(m2, p) * 2.01;
f += 0.0625 * noise(p);

return f / 0.9375;
}

float3 render(in float3 light, in float3 ro, in float3 rd) {
// Sky with haze
float3 col = float3(0.3, 0.55, 0.8) * (1.0 - 0.8 * rd.y) * sky_light;

if (rd.y >= 0.0)
{
// Sun
float sundot = clamp(dot(rd, light), 0.0, 1.0);
col += sun_size * 0.25 * float3(1.0, 0.7, 0.4) * pow(sundot, 8.0);
col += sun_size * 0.75 * float3(1.0, 0.8, 0.5) * pow(sundot, 64.0);

// Clouds
col = lerp(col, float3(1.0, 0.95, 1.0), 0.5 * smoothstep(0.5-cloud_density, 0.8-cloud_density, fbm((ro.xz + rd.xz * (250000.0 - ro.y) / rd.y) * 0.000008)));
}

// Horizon/atmospheric perspective
col = lerp(col, float3(0.7, 0.75, 0.8), pow(1.0 - max(abs(rd.y), 0.0), 8.0));

return col;
}

float4 mainFP(
float4 projectionCoord : TEXCOORD0
) : COLOR
{
float verticalFieldOfView = sky_fov * 3.1415927 / 180.0;

float3 cameraOrigin = float3(-iTime, sin(iTime) + 2.1, 0.0);

float3 ro = cameraOrigin;
float3 rd = normalize(float3(projectionCoord.xy * float2(iResolution_x, iResolution_y) / 2.0, iResolution_y * 0.5 / -tan(verticalFieldOfView * 0.5)));

float3x3 yawMatrix = float3x3(cos(sky_yaw), 0.0, sin(sky_yaw),
0.0, 1.0, 0.0,
-sin(sky_yaw), 0.0, cos(sky_yaw));

float3x3 pitchMatrix = float3x3(1.0, 0.0, 0.0,
0.0, cos(sky_pitch), -sin(sky_pitch),
0.0, sin(sky_pitch), cos(sky_pitch));

float3x3 rollMatrix = float3x3(cos(sky_roll), -sin(sky_roll), 0.0,
sin(sky_roll), cos(sky_roll), 0.0,
0.0, 0.0, 1.0);

rd = mul(mul(mul(yawMatrix, pitchMatrix), rollMatrix), rd);

float3 light = normalize(float3(-0.5, 0.3 - sin(0.15), -0.3));

float3 col = render(light, ro, rd);

// Gamma encode
col = pow(col, float3(0.4545, 0.4545, 0.4545));

return float4(col, 1.0);

}
9 changes: 9 additions & 0 deletions resources/materials/SkyHLSL.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
float4 mainVP(
float4 pos : POSITION,
uniform float4x4 worldViewProj,
out float4 projectionCoord : TEXCOORD0
) : POSITION
{
projectionCoord = mul(worldViewProj, pos);
return mul(worldViewProj, pos);
}
88 changes: 72 additions & 16 deletions resources/materials/ror.material
Original file line number Diff line number Diff line change
Expand Up @@ -1901,26 +1901,82 @@ material tracks/abflame
}
}

vertex_program SkyHLSLVertex hlsl
{
source SkyHLSL.vert
entry_point mainVP
target vs_3_0

default_params
{
param_named_auto worldViewProj worldviewproj_matrix
}
}

fragment_program SkyHLSLFragment hlsl
{
source SkyHLSL.frag
entry_point mainFP
target ps_3_0
}

vertex_program SkyGLSLVertex glsl
{
source SkyGLSL.vert

default_params
{
param_named_auto worldViewProj worldviewproj_matrix
}
}

fragment_program SkyGLSLFragment glsl
{
source SkyGLSL.frag
}

vertex_program SkyVS unified
{
delegate SkyHLSLVertex
delegate SkyGLSLVertex
}

fragment_program SkyFS unified
{
delegate SkyHLSLFragment
delegate SkyGLSLFragment
}

material tracks/skyboxcol
{
receive_shadows off
technique
{
pass
{
fog_override true
lighting off
depth_write off
// depth_check off
technique
{
pass
{
receive_shadows off
lighting off
depth_write off
depth_check off

texture_unit
{
cubic_texture cloudy_noon.dds separateUV
tex_address_mode clamp
}
}
}
vertex_program_ref SkyVS
{
}
fragment_program_ref SkyFS
{
param_named_auto iTime time
param_named_auto iResolution_x viewport_width
param_named_auto iResolution_y viewport_height

param_named sun_size float 1.0
param_named sky_yaw float 1.0
param_named sky_pitch float 1.0
param_named sky_roll float 1.0
param_named sky_fov float 60.0
param_named cloud_density float 0.0
param_named sky_light float 0.7
}
}
}
}

material Sky/EarlyMorning
Expand Down
2 changes: 1 addition & 1 deletion source/main/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ std::string ToLocalizedString(GfxSkyMode e)
{
switch (e)
{
case GfxSkyMode::SANDSTORM: return _LC("GfxSkyMode", "Sandstorm (fastest)");
case GfxSkyMode::BASIC: return _LC("GfxSkyMode", "Basic (fastest)");
case GfxSkyMode::CAELUM: return _LC("GfxSkyMode", "Caelum (best looking, slower)");
case GfxSkyMode::SKYX: return _LC("GfxSkyMode", "SkyX (best looking, slower)");
default: return "";
Expand Down
2 changes: 1 addition & 1 deletion source/main/Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ std::string ToLocalizedString(GfxWaterMode e);

enum class GfxSkyMode
{
SANDSTORM, //!< Sandstorm (fastest)
BASIC, //!< Basic (fastest)
CAELUM, //!< Caelum (best looking, slower)
SKYX, //!< SkyX (best looking, slower)
};
Expand Down
33 changes: 33 additions & 0 deletions source/main/GameContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,39 @@ void GameContext::UpdateSimInputEvents(float dt)

void GameContext::UpdateSkyInputEvents(float dt)
{
if (App::gfx_sky_mode->getEnum<GfxSkyMode>() == GfxSkyMode::BASIC)
{
float light = App::GetGuiManager()->TopMenubar.sky_light;
Ogre::MaterialPtr sky_material = Ogre::MaterialManager::getSingleton().getByName("tracks/skyboxcol", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
Ogre::GpuProgramParametersSharedPtr sky_params = sky_material->getTechnique(0)->getPass(0)->getFragmentProgramParameters();

if (RoR::App::GetInputEngine()->getEventBoolValue(EV_SKY_INCREASE_TIME))
{
light += 0.001;
}
else if (RoR::App::GetInputEngine()->getEventBoolValue(EV_SKY_DECREASE_TIME))
{
light -= 0.001;
}
if (RoR::App::GetInputEngine()->getEventBoolValue(EV_SKY_INCREASE_TIME_FAST))
{
light += 0.01;
}
else if (RoR::App::GetInputEngine()->getEventBoolValue(EV_SKY_DECREASE_TIME_FAST))
{
light -= 0.01;
}

if (App::GetGuiManager()->TopMenubar.sky_light != light && light >= 0.0 && light <= 1.0)
{
App::GetGuiManager()->TopMenubar.sky_light = light;
sky_params->setNamedConstant("sky_light", light);
sky_material->getTechnique(0)->getPass(0)->setFragmentProgramParameters(sky_params);
App::GetGfxScene()->GetSceneManager()->setAmbientLight(Ogre::ColourValue(light, light, light));
App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, fmt::format("Ambient light set to {:.1f}", light), "lightbulb.png");
}
}

#ifdef USE_CAELUM
if (App::gfx_sky_mode->getEnum<GfxSkyMode>() == GfxSkyMode::CAELUM &&
m_terrain->getSkyManager())
Expand Down
Loading

0 comments on commit b1e6457

Please sign in to comment.