Sdfgeoff's Random Things Thread

sdfgeoffsdfgeoff Posts: 9Member

Me, make a game? Nah, probably not. But I'll enjoy playing around with gameplay and visual art. This will become a dumping ground for the random things I made. Some I'll post the full source for, some not. Unless otherwise mentioned, all assets are licensed CC-BY-SA-NC 4.0

This mornings creation: a rocky planet shader:

With the same shader you can do many varieties of solid-core planets, from earth-like to airless moons. It was designed for a 3d top-down game, so it's best for viewing from the sides at longish distances.

It uses a single texture which is a normal map with the elevation baked into the alpha channel. The other controls are shown below:

The surface roughness is the influence of the normal map. Small numbers = smooth surface lighting
The surface color roughness enhances the contrast of the two surface colors.
The atmosphere amount changes it between being airless and having an atmosphere. In the demo image you can see that a moon with no atmosphere is nearly invisible from the back, but if there is an atmosphere the light "wraps" around.

Possible future advances:
- Ice caps at poles to hide the texture seams
- Model the scattering separate to the transmission so the planet looks better from the front.

Demo project is attached to this post. It may need a development build of Godot.

Comments

  • SchusterSchuster Posts: 326Member

    Nice shader....like to see more stuff...Thanks for sharing

  • sdfgeoffsdfgeoff Posts: 9Member
    edited December 2018

    I wanted to make a shield for a spacecraft. I wanted it to be clearly visible, but to stay away from the "blue crackling energy" that seems to be taking over these days. So I made a distortion shader:

    The material samples from the screen texture and uses a sphere's normals to offset the sample position and mipmap level.

    The shader is reasonably short, but it took a while to figure out all the transforms and fudge the view-distance-falloff into submission. I'm pretty happy with the result

    shader_type spatial;
    render_mode unshaded;
    
    uniform float strength = 1.0;
    
    varying vec3 view_vec;
    
    void vertex () {
        vec4 normal_localspace = vec4(NORMAL, 0.0);
        vec4 position_localspace = vec4(VERTEX, 1.0);
        vec4 normal_worldspace = WORLD_MATRIX * normal_localspace;
        vec4 position_worldspace = WORLD_MATRIX * position_localspace;
        vec4 normal_camera_space = inverse(CAMERA_MATRIX) * normal_worldspace;
        vec4 position_camera_space = inverse(CAMERA_MATRIX) * position_worldspace;
        view_vec = position_camera_space.xyz;
    }
    
    void fragment() {
        float falloff = 1.0 - abs(-dot(normalize(view_vec), NORMAL));
        falloff = sin(falloff * 3.14);
        falloff = pow(falloff, 5.0) * 0.05 * strength;
        falloff *= pow(-1.0 / view_vec.z, 0.2);
        vec2 uv_distort = SCREEN_UV - NORMAL.xy*falloff;
        ALBEDO=textureLod( SCREEN_TEXTURE, uv_distort, falloff * 100.0).rgb;
    }
    
  • dpwbrowndpwbrown Posts: 2Member

    Very cool, I was looking for a way to make more realistic planets in my game.
    My planets are 2d circles that "rotate" and use light tricks to fake a 3d sphere, but I'm sure theres techniques here I can study in the shaders, even though they are vertex not frag.
    I wonder how performance intensive it'd be to randomly generate that pre-baked texture you use as a material using Godots new simplexnoise feature.... to add variety,

    Maybe it'd be better to actually have little 3d spheres in a 2d game scene, using the viewport texture tricks... it'd be easier to make a planet-looking planet that way perhaps...

    Thanks for the ideas you've given me!

  • ChristofferChristoffer Posts: 6Member

    @sdfgeoff said:
    I wanted to make a shield for a spacecraft. I wanted it to be clearly visible, but to stay away from the "blue crackling energy" that seems to be taking over these days. So I made a distortion shader:

    The material samples from the screen texture and uses a sphere's normals to offset the sample position and mipmap level.

    The shader is reasonably short, but it took a while to figure out all the transforms and fudge the view-distance-falloff into submission. I'm pretty happy with the result

    shader_type spatial;
    render_mode unshaded;
    
    uniform float strength = 1.0;
    
    varying vec3 view_vec;
    
    void vertex () {
      vec4 normal_localspace = vec4(NORMAL, 0.0);
      vec4 position_localspace = vec4(VERTEX, 1.0);
      vec4 normal_worldspace = WORLD_MATRIX * normal_localspace;
      vec4 position_worldspace = WORLD_MATRIX * position_localspace;
      vec4 normal_camera_space = inverse(CAMERA_MATRIX) * normal_worldspace;
      vec4 position_camera_space = inverse(CAMERA_MATRIX) * position_worldspace;
      view_vec = position_camera_space.xyz;
    }
    
    void fragment() {
      float falloff = 1.0 - abs(-dot(normalize(view_vec), NORMAL));
      falloff = sin(falloff * 3.14);
      falloff = pow(falloff, 5.0) * 0.05 * strength;
      falloff *= pow(-1.0 / view_vec.z, 0.2);
      vec2 uv_distort = SCREEN_UV - NORMAL.xy*falloff;
      ALBEDO=textureLod( SCREEN_TEXTURE, uv_distort, falloff * 100.0).rgb;
    }
    

    How do i get this to work with a 2d canvas or sprite ?
    Looks nice ;D

Sign In or Register to comment.