Added a weird stippling. Its kinda funny how hard this is to look like the “old” way. On the Amiga you ran a blitter co routine (yes they had one of the first gpus) and it was kinda trivial to ‘step over’ a pixel when rendering ![]()
Something to be said for pixel buffers imho.
Heres the shader as well. There are some specific constants in there for my game, read the comments ![]()
varying highp vec4 var_position;
varying mediump vec3 var_normal;
varying mediump vec2 var_texcoord0;
varying mediump vec4 var_light;
// Notes:
// This is mapped onto a 3DD cylinder made in Blender. It is 2.0 high and the texture is unwrapped so
// that the uv mapping is vertical for the height of the cylinder. The cylinder also has had its faces
// flipped becase you will be inside it :)
// The var_position is the only weird one here. In the vp I use:
// var_position = (mtx_proj * p).xyz;
// otherwise the vp is pretty std model vp.
// This is setup from the render_script with:
// x = resolution width (in my case its a RT width, but you can normally use screen/window)
// y = resolution height
// z = aspect (just divide the x by the y) I dont use it here, but I do for others :)
// w = altitude of the camera. This is needed because the plane can move up almost as far as the farplane which is 50km.
uniform mediump vec4 params;
// Colors for the top and middle of the atmospehere. Below horizonColor black is drawn
const vec4 peakColor = vec4(0.5372549, 0.545098039, 0.929411764, 1.0);
const vec4 horizonColor = vec4(0.52941176, 0.843137254, 0.98823529, 1.0);
const vec4 black = vec4(0.0,0.0,0.0, 1.0);
highp float pi = 3.141592653589793;
// These are used in pixel calcs. Because my render texture resolution can change this means
// these need to be dynamic.
mediump float pixelBandX = 1.0 / params.x;
mediump float pixelBandY = 1.0 / params.y;
// How wide to apply a blend for the hiorizon
mediump float colorBand = 1.0 / 256.0;
// How wide to apply the dithering band on the horizon
mediump float colorBandLow = (1.0 / 256.0) * 5;
// Fudge factor to get it looking ok.
const highp float factor = 0.75;
// These are 'steppers' so that the position of the pixel can be stepped. This isnt overly
// accurate because we are doing this in projected screen coords. Theres probably a better way I suspect.
highp float RESX = (params.x * factor);
highp float RESY = (params.y * factor);
highp float RESHX = (RESX * 0.5);
highp float RESHY = (RESY * 0.5);
// This creates the horizon stipple effect
vec4 stipple( vec4 color, vec2 uv, float level )
{
float xcoord = uv.x;
float valy = mod(uv.y, RESY);
if(valy > RESHY)
xcoord += RESHX;
float valx = mod(xcoord, RESX);
if(valx > RESHX)
return color * level;
else
return vec4(color.xyz, level);
}
void main()
{
// Yes horrible. Divide by our maximum alt * 2 - because this is mapped onto a cylinder
float alt = params.w / 90000;
// Work out where the horizon is using uv coord
highp float f = floor( (var_texcoord0.y + alt) / colorBand) * colorBand;
if(f < 0.5) {
gl_FragColor = black;
}
else if(f >= 0.5 && f <= 0.5 + colorBandLow) {
float level = ((f-0.5)/colorBandLow ) * 0.5 + 0.5;
gl_FragColor = stipple( mix(horizonColor, peakColor, (f-0.5)/0.05), var_position.xy, level);
}
else if(f > 0.5 + colorBandLow && f < 0.55) {
gl_FragColor = mix(horizonColor, peakColor, (f-0.5)/0.05);
}
else if(f >= 0.55){
gl_FragColor = peakColor;
}
}
