Page 3 of 7

Re: a nice cavern filled with lava

Posted: Tue Jul 28, 2015 10:29 pm
by Azel
That's pretty damn hawt! Pun intended :twisted:

Re: a nice cavern filled with lava

Posted: Tue Jul 28, 2015 11:37 pm
by bongobeat
hey,

it looks nice!

Ive try with a 10x11 squares filled with fire emitter, brightness set to 7, no lag.
also can you share the texture that you use in your material definition? I have use the magma_dif.tga for the test, but this texture is too little.

for magma bubbles I have no idea, maybe you can try to use the existing forest_underwater_bubbles particle and modify it.

Also you can add eruption/explosions:
place some spawners at elevation -1, that are spawning "magma_golem_meteor_impact_ground" (big explosion), which are activated with timers.

Re: a nice cavern filled with lava

Posted: Wed Jul 29, 2015 9:06 am
by AndakRainor
Here is the texture I made (I used the ocean normals green channel as a base)

http://ge.tt/9HPTdWE2

Tonight I will show you some new scripts about lava!

Re: a nice cavern filled with lava

Posted: Wed Jul 29, 2015 8:29 pm
by AndakRainor
What do you think of this new version ?
SpoilerShow
Image
Here is the code
SpoilerShow

Code: Select all

defineObject{
  name = "lava_effects",
  components = {
    { class = "Light",
      offset = vec(0, -0.5, 0),
      range = 6,
      color = vec(2.8, 1.2, 0.7),
      brightness = 7,
      castShadow = true,
      shadowMapSize = 64,
      staticShadows = true,
      staticShadowDistance = 0,   -- use static shadows always
    },
    { class = "Particle",
      particleSystem = "lava_effects",
      offset = vec(0, -0.4, 0),
    },
    {
      class = "TileDamager",
      attackPower = 3,
      damageType = "fire",
      repeatCount = math.huge,
      repeatDelay = 1,
      onInit = function(self)
        if self.go.map:getElevation(self.go.x, self.go.y) < self.go.elevation then
          spawn("under_lava_effects", self.go.level, self.go.x, self.go.y, self.go.facing, self.go.elevation-1)
        end
      end,
    },
    { class = "Timer",
      timerInterval = 1,
      triggerOnStart = true,
      onActivate = function(self)
        spawn("magma_golem_meteor_impact_ground", self.go.level, self.go.x, self.go.y, self.go.facing, self.go.elevation-1)
        self:setTimerInterval(300*(0.1+0.9*math.random()))
      end,
      onInit = function(self)
        self:setTimerInterval(300*math.random())
      end,
    },
  },
  placement = "floor",
  editorIcon = 88,
}

defineObject{
  name = "under_lava_effects",
  components = {
    { class = "Particle",
      particleSystem = "under_lava_effects",
    },
    {
      class = "TileDamager",
      attackPower = 15,
      damageType = "fire",
      repeatCount = math.huge,
      repeatDelay = 1,
      onInit = function(self)
        if self.go.map:getElevation(self.go.x, self.go.y) < self.go.elevation then
          spawn("under_lava_effects", self.go.level, self.go.x, self.go.y, self.go.facing, self.go.elevation-1)
        end
      end,
    },
  },
  placement = "floor",
  editorIcon = 88,
}

defineObject{
  name = "lava_surface",
  components = {
    {
      class = "Model",
      model = "assets/models/env/ocean_water.fbx",
      material = "lava_surface",
      offset = vec(0, -0.4, 0),
    },
    {
      class = "WaterSurface",
      planeY = -0.4,
      reflectionColor = vec(1.5, 0.9, 0.27) * 0.9,
      refractionColor = vec(1.5,1.0,0.5),
    },
  },
  placement = "floor",
  dontAdjustHeight = true,
  editorIcon = 264,
  reflectionMode = "never",
}

defineObject{
  name = "lava_surface_tiles",
  baseObject = "base_floor_decoration",
  components = {
    {
      -- updates global reflection and refraction maps
      class = "WaterSurface",
      planeY = -0.4,
      fogColor = math.saturation(vec(0.26, 0.09, 0.042), 0.5) * 0.5,
      fogDensity = 0.4,
      reflectionColor = vec(1.5, 0.9, 0.27) * 0.9,
      refractionColor = vec(1.5,1.0,0.5),
    },
    {
      -- builds a continuous mesh from underwater tiles
      class = "WaterSurfaceMesh",
      material = "lava_surface_tiles",
      underwaterMaterial = "water_surface_underwater",
      offset = vec(0, -0.4, 0),
    },
  },
  dontAdjustHeight = true,
  editorIcon = 264,
}

defineMaterial{
  name = "lava_surface",
  shader = "ocean_water",
  diffuseMap = "mod_assets/textures/env/lava_dif.tga",
  normalMap = "assets/textures/env/ocean_normal.tga",
  displacementMap = "assets/textures/env/ocean_disp.tga",
  doubleSided = true,
  --lighting = true,
  alphaTest = false,
  --castShadow = true,
  blendMode = "Opaque",
  textureAddressMode = "Wrap",
  glossiness = 0,
  depthBias = 0,
  texOffset = 0,
  foamOffset = 0,
  foamAmount = 0,
  waveAmplitude = 50, 
  onUpdate = function(self, time)
    self:setTexcoordScaleOffset(1, 1, math.cos(time*0.15)*0.5, math.sin(time*0.15)*0.5)
  end,
}

defineMaterial{
  name = "lava_surface_tiles",
  shader = "ocean_water",
  diffuseMap = "mod_assets/textures/env/lava_dif.tga",
  normalMap = "assets/textures/env/ocean_normal.tga",
  displacementMap = "assets/textures/env/ocean_disp.tga",
  doubleSided = false,
  --lighting = true,
  alphaTest = false,
  --castShadow = true,
  blendMode = "Opaque",
  textureAddressMode = "Wrap",
  glossiness = 0,
  depthBias = 0,
  texOffset = 0,
  foamOffset = 0,
  foamAmount = 0,
  waveAmplitude = 0.5, 
  onUpdate = function(self, time)
    self:setTexcoordScaleOffset(1, 1, math.cos(time*0.15)*0.5, math.sin(time*0.15)*0.5)
  end,
}

defineParticleSystem{
  name = "lava_effects",
  emitters = {
    -- stars
    {
      emissionRate = 40,
      emissionTime = 0,
      maxParticles = 200,
      boxMin = {-1.3, 0.0,-1.3},
      boxMax = { 1.3, 0.5, 1.3},
      sprayAngle = {0,360},
      velocity = {0,0},
      objectSpace = true,
      texture = "assets/textures/particles/firefly_dif.tga",
      lifetime = {0.5,5.0},
      color0 = {4, 0.4, 0.2},
      opacity = 1,
      fadeIn = 0.1,
      fadeOut = 1.0,
      size = {0.05, 0.1},
      gravity = {0,0.5,0},
      airResistance = 0.1,
      rotationSpeed = 5,
      blendMode = "Additive",
    },
    -- flames 1
    {
      emissionRate = 2,
      emissionTime = 0,
      maxParticles = 10,
      boxMin = {-1.5, -0.2,-1.5},
      boxMax = { 1.5, -0.0, 1.5},
      sprayAngle = {0,360},
      velocity = {0,0},
      objectSpace = false,
      texture = "assets/textures/particles/flame.tga",
      frameSize = 32,
      frameCount = 40,
      frameRate = 40,
      lifetime = {5.0,5.0},
      color0 = {4, 0.4, 0.2},
      opacity = 0.5,
      fadeIn = 0.5,
      fadeOut = 0.5,
      size = {0.5, 0.5},
      gravity = {0,0.02,0},
      airResistance = 0.1,
      rotationSpeed = 1,
      blendMode = "Additive",
    },
    -- flames 2
    {
      emissionRate = 2,
      emissionTime = 0,
      maxParticles = 10,
      boxMin = {-1.5, -0.2,-1.5},
      boxMax = { 1.5, -0.0, 1.5},
      sprayAngle = {0,360},
      velocity = {0,0},
      objectSpace = false,
      texture = "assets/textures/particles/flame.tga",
      frameSize = 32,
      frameCount = 40,
      frameRate = 40,
      lifetime = {5.0,5.0},
      color0 = {4, 0.4, 0.2},
      opacity = 0.5,
      fadeIn = 0.5,
      fadeOut = 0.5,
      size = {0.5, 0.5},
      gravity = {0,0.02,0},
      airResistance = 0.1,
      rotationSpeed = -1,
      blendMode = "Additive",
    },
    -- smoke
    {
      emissionRate = 4,
      emissionTime = 0,
      maxParticles = 40,
      boxMin = {-1.3, 0, -1.3},
      boxMax = { 1.3, 1.0, 1.3},
      sprayAngle = {0,20},
      velocity = {0.4, 0.8},
      texture = "assets/textures/particles/smoke_01.tga",
      lifetime = {1,5},
      color0 = {0.25, 0.20, 0.17},
      opacity = 0.5,
      fadeIn = 0.3,
      fadeOut = 0.9,
      size = {1.5, 2},
      gravity = {0,0.3,0},
      airResistance = 0.1,
      rotationSpeed = 0.5,
      blendMode = "Translucent",
    },
  }
}

defineParticleSystem{
  name = "under_lava_effects",
  emitters = {
    -- fog under 1
    {
      emissionRate = 1,
      emissionTime = 0,
      maxParticles = 10,
      boxMin = {-1.5, -1.0, -1.5},
      boxMax = { 1.5,  2.0,  1.5},
      sprayAngle = {0,360},
      velocity = {0,0},
      objectSpace = true,
      texture = "assets/textures/particles/fog.tga",
      lifetime = {10,10},
      color0 = {1.75,0.6,0.2},
      opacity = 1,
      fadeIn = 2.5,
      fadeOut = 2.5,
      size = {5, 5},
      gravity = {0,0,0},
      airResistance = 0.5,
      rotationSpeed = -0.3,
      blendMode = "Translucent",
    },
    -- fog under 2
    {
      emissionRate = 1,
      emissionTime = 0,
      maxParticles = 10,
      boxMin = {-1.5, -1.0, -1.5},
      boxMax = { 1.5,  2.0,  1.5},
      sprayAngle = {0,360},
      velocity = {0,0},
      objectSpace = true,
      texture = "assets/textures/particles/fog.tga",
      lifetime = {10,10},
      color0 = {1.75,0.6,0.2},
      opacity = 1,
      fadeIn = 2.5,
      fadeOut = 2.5,
      size = {5, 5},
      gravity = {0,0,0},
      airResistance = 0.5,
      rotationSpeed = 0.3,
      blendMode = "Translucent",
    },
  }
}
Now you have a definition for water tiles and another for a stand alone ocean like object. When I tried to put water and lava on the same map I realized it was not possible without using an ocean object; two WaterSurfaceMesh can't be used in a map or be swaped dynamically. So you will have to choose, only lava and no water on a level, or else use "lava_surface" object as you use the ocean one.

In both case you should put "lava_effects" objects on each lava tile at elevation 0. You will see that those objects spawn "under_lava_effects" under them down to the floor.

Don't forget the texture in the previous post. Type "lava" in the editor filter to see all objects. Now with explosions (Bubbles were really not convincing) ! Let me know what you think of it !

Re: a nice cavern filled with lava

Posted: Thu Jul 30, 2015 12:43 pm
by Komag
This new version looks like dark red satin sheets billowing around like in a music video or something. 8-) That's just how it looks to me

Re: a nice cavern filled with lava

Posted: Thu Jul 30, 2015 2:24 pm
by maneus
It looks to much like waves for me. And it should shine a little more like lava did.
I would not use blendMode = "Opaque". I would use "Additive" because of the luminescence.

Re: a nice cavern filled with lava

Posted: Thu Jul 30, 2015 7:06 pm
by minmay
Using a water surface is also really bad for performance and you presumably don't need a reflection. I would just use an animated texture with setTexcoordScaleOffset() and maybe the "wall_fire" shader.

Re: a nice cavern filled with lava

Posted: Thu Jul 30, 2015 7:32 pm
by AndakRainor
Hello! Thanks for the feedback.

Here is another try:
SpoilerShow
Image
code:
SpoilerShow

Code: Select all

defineObject{
  name = "lava_effects",
  components = {
    { class = "Light",
      offset = vec(0, -0.5, 0),
      range = 6,
      color = vec(2.8, 1.2, 0.7),
      brightness = 50,
      castShadow = true,
      shadowMapSize = 64,
      staticShadows = true,
      staticShadowDistance = 0,   -- use static shadows always
    },
    { class = "Particle",
      particleSystem = "lava_effects",
      offset = vec(0, -0.4, 0),
    },
    {
      class = "TileDamager",
      attackPower = 3,
      damageType = "fire",
      repeatCount = math.huge,
      repeatDelay = 1,
      onInit = function(self)
        if self.go.map:getElevation(self.go.x, self.go.y) < self.go.elevation then
          spawn("under_lava_effects", self.go.level, self.go.x, self.go.y, self.go.facing, self.go.elevation-1)
        end
      end,
    },
    { class = "Timer",
      timerInterval = 1,
      triggerOnStart = true,
      onActivate = function(self)
        spawn("magma_golem_meteor_impact_ground", self.go.level, self.go.x, self.go.y, self.go.facing, self.go.elevation-1)
        self:setTimerInterval(300*(0.1+0.9*math.random()))
      end,
      onInit = function(self)
        self:setTimerInterval(300*math.random())
      end,
    },
    { class = "Sound",
      sound = "fire_pit",
      volume = 0.5,
    },
  },
  placement = "floor",
  editorIcon = 88,
}

defineObject{
  name = "under_lava_effects",
  components = {
    { class = "Particle",
      particleSystem = "under_lava_effects",
    },
    {
      class = "TileDamager",
      attackPower = 15,
      damageType = "fire",
      repeatCount = math.huge,
      repeatDelay = 1,
      onInit = function(self)
        if self.go.map:getElevation(self.go.x, self.go.y) < self.go.elevation then
          spawn("under_lava_effects", self.go.level, self.go.x, self.go.y, self.go.facing, self.go.elevation-1)
        end
      end,
    },
  },
  placement = "floor",
  editorIcon = 88,
}

defineObject{
  name = "lava_surface",
  components = {
    {
      class = "Model",
      model = "assets/models/env/ocean_water.fbx",
      material = "lava_surface",
      offset = vec(0, -0.4, 0),
    },
  },
  placement = "floor",
  dontAdjustHeight = true,
  editorIcon = 264,
  reflectionMode = "never",
}

defineObject{
  name = "lava_surface_tiles",
  baseObject = "base_floor_decoration",
  components = {
    {
      -- updates global reflection and refraction maps
      class = "WaterSurface",
      planeY = -0.4,
      fogColor = math.saturation(vec(0.26, 0.09, 0.042), 0.5) * 0.5,
      fogDensity = 0.4,
      reflectionColor = vec(1.5, 0.9, 0.27) * 0.9,
      refractionColor = vec(1.5,1.0,0.5),
    },
    {
      -- builds a continuous mesh from underwater tiles
      class = "WaterSurfaceMesh",
      material = "lava_surface_tiles",
      underwaterMaterial = "water_surface_underwater",
      offset = vec(0, -0.4, 0),
    },
  },
  dontAdjustHeight = true,
  editorIcon = 264,
}

defineMaterial{
  name = "lava_surface",
  shader = "ocean_water",
  diffuseMap = "mod_assets/textures/env/lava_dif.tga",
  normalMap = "assets/textures/env/ocean_normal.tga",
  displacementMap = "assets/textures/env/ocean_disp.tga",
  doubleSided = true,
  --lighting = true,
  alphaTest = false,
  --castShadow = true,
  blendMode = "Opaque",
  textureAddressMode = "Wrap",
  glossiness = 0,
  depthBias = 0,
  texOffset = 0,
  foamOffset = 0,
  foamAmount = 0,
  waveAmplitude = 50, 
  onUpdate = function(self, time)
    self:setTexcoordScaleOffset(1, 1, math.cos(time*0.15)*0.25, math.sin(time*0.15)*0.25)
  end,
}

defineMaterial{
  name = "lava_surface_tiles",
  shader = "ocean_water",
  diffuseMap = "mod_assets/textures/env/lava_dif.tga",
  normalMap = "assets/textures/env/ocean_normal.tga",
  displacementMap = "assets/textures/env/ocean_disp.tga",
  doubleSided = false,
  --lighting = true,
  alphaTest = false,
  --castShadow = true,
  blendMode = "Opaque",
  textureAddressMode = "Wrap",
  glossiness = 0,
  depthBias = 0,
  texOffset = 0,
  foamOffset = 0,
  foamAmount = 0,
  waveAmplitude = 0.5, 
  onUpdate = function(self, time)
    self:setTexcoordScaleOffset(1, 1, math.cos(time*0.15)*0.25, math.sin(time*0.15)*0.25)
  end,
}

defineParticleSystem{
  name = "lava_effects",
  emitters = {
    -- stars
    {
      emissionRate = 40,
      emissionTime = 0,
      maxParticles = 200,
      boxMin = {-1.3, 0.0,-1.3},
      boxMax = { 1.3, 0.5, 1.3},
      sprayAngle = {0,360},
      velocity = {0,0},
      objectSpace = true,
      texture = "assets/textures/particles/firefly_dif.tga",
      lifetime = {0.5,5.0},
      color0 = {4, 0.4, 0.2},
      opacity = 1,
      fadeIn = 0.1,
      fadeOut = 1.0,
      size = {0.05, 0.1},
      gravity = {0,0.5,0},
      airResistance = 0.1,
      rotationSpeed = 5,
      blendMode = "Additive",
    },
    -- flames 1
    {
      emissionRate = 5,
      emissionTime = 0,
      maxParticles = 5,
      boxMin = {-1.5, -0.2,-1.5},
      boxMax = { 1.5, -0.0, 1.5},
      sprayAngle = {0,360},
      velocity = {0,0},
      objectSpace = false,
      texture = "assets/textures/particles/flame.tga",
      frameSize = 32,
      frameCount = 40,
      frameRate = 60,
      lifetime = {0.5,1.0},
      color0 = {4, 0.4, 0.2},
      opacity = 0.5,
      fadeIn = 0.5,
      fadeOut = 0.5,
      size = {0.5, 0.5},
      gravity = {0,0.02,0},
      airResistance = 0.1,
      rotationSpeed = 1,
      blendMode = "Additive",
    },
    -- flames 2
    {
      emissionRate = 5,
      emissionTime = 0,
      maxParticles = 5,
      boxMin = {-1.5, -0.2,-1.5},
      boxMax = { 1.5, -0.0, 1.5},
      sprayAngle = {0,360},
      velocity = {0,0},
      objectSpace = false,
      texture = "assets/textures/particles/flame.tga",
      frameSize = 32,
      frameCount = 40,
      frameRate = 60,
      lifetime = {0.5,1.0},
      color0 = {4, 0.4, 0.2},
      opacity = 0.5,
      fadeIn = 0.5,
      fadeOut = 0.5,
      size = {0.5, 0.5},
      gravity = {0,0.02,0},
      airResistance = 0.1,
      rotationSpeed = -1,
      blendMode = "Additive",
    },
    -- smoke
    {
      emissionRate = 4,
      emissionTime = 0,
      maxParticles = 40,
      boxMin = {-1.3, 0, -1.3},
      boxMax = { 1.3, 1.0, 1.3},
      sprayAngle = {0,20},
      velocity = {0.4, 0.8},
      texture = "assets/textures/particles/smoke_01.tga",
      lifetime = {1,5},
      color0 = {0.25, 0.20, 0.17},
      opacity = 0.5,
      fadeIn = 0.3,
      fadeOut = 0.9,
      size = {1.5, 2},
      gravity = {0,0.3,0},
      airResistance = 0.1,
      rotationSpeed = 0.5,
      blendMode = "Translucent",
    },
  }
}

defineParticleSystem{
  name = "under_lava_effects",
  emitters = {
    -- fog under 1
    {
      emissionRate = 1,
      emissionTime = 0,
      maxParticles = 10,
      boxMin = {-1.5, -0.5, -1.5},
      boxMax = { 1.5,  2.5,  1.5},
      sprayAngle = {0,360},
      velocity = {0,0},
      objectSpace = true,
      texture = "assets/textures/particles/fog.tga",
      lifetime = {10,10},
      color0 = {1.75,0.6,0.2},
      opacity = 1,
      fadeIn = 2.5,
      fadeOut = 2.5,
      size = {5, 5},
      gravity = {0,0,0},
      airResistance = 0.5,
      rotationSpeed = -0.3,
      blendMode = "Translucent",
    },
    -- fog under 2
    {
      emissionRate = 1,
      emissionTime = 0,
      maxParticles = 10,
      boxMin = {-1.5, -0.5, -1.5},
      boxMax = { 1.5,  2.5,  1.5},
      sprayAngle = {0,360},
      velocity = {0,0},
      objectSpace = true,
      texture = "assets/textures/particles/fog.tga",
      lifetime = {10,10},
      color0 = {1.75,0.6,0.2},
      opacity = 1,
      fadeIn = 2.5,
      fadeOut = 2.5,
      size = {5, 5},
      gravity = {0,0,0},
      airResistance = 0.5,
      rotationSpeed = 0.3,
      blendMode = "Translucent",
    },
  }
}
This time with more bright light, less dancing flames, less texture movements. I think it is hard to fake a higher viscosity, may be with higher waveAmplitude and a lower planeY.

I tried all the other blendMode like "additive" but alas it does not work fine with the ocean shader. Those modes make the surface nearly invisible or totally white with a bright light. Is it possible to write our own shader ? :)

Do you use lava in your mods ? Don't you think the wall_fire model is a little too static and makes tiles too visible ?

Minmay, how could I keep the waves animation without using the ocean_water shader ? Is the only solution creating a new model (seems a lot of work I'm not very familiar with 3D modeling tools like blender) ?

Edit: okay, I removed the WaterSurface component from the lava_surface object, as it does nothing except consume resources ! Is there something similar I could do for the lava_surface_tiles object ?

Re: a nice cavern filled with lava

Posted: Thu Jul 30, 2015 10:59 pm
by minmay
I didn't know you wanted to keep the waves animation. Molten lava isn't Kool-Aid. It's extremely viscous and doesn't make ocean-like waves in real life. I was thinking of just using setTexcoordScaleOffset() to slowly move the texture and the wall_fire shader to slightly distort it, to make it look like it's flowing.
AndakRainor wrote:Do you use lava in your mods ? Don't you think the wall_fire model is a little too static and makes tiles too visible ?
I am talking about the SHADER called "wall_fire". It takes a displacement map and a "time" parameter (look at the wall_fire material definition), and causes a rippling effect. You can't write your own shaders but you can make your own displacement map and control the speed in the onUpdate hook.

Re: a nice cavern filled with lava

Posted: Fri Jul 31, 2015 12:43 am
by AndakRainor
Okay lava is not red water, I know ! (but I rarely approach it in real life). I would be very happy to find the ideal way to make it work, but I feel all things tried before are lacking something.

When I wrote about the wall_fire model it was not directed at you, but it was the solution proposed in the original post. I think this model lacks animation when used as lava, and makes tiles too visible. That's why I tried something else.

Even if lava is not water, it should move a little. What makes water feel like water in the game is by far the way the texture is moved quickly. Not so much the animation of the mesh from my point of view. So a texture moving less with a mesh slowly moving up and down makes sens. Even if waves are not appropriate, I don't think the surface should stay static with only a moving texture, but I could be wrong.

As for the wall_fire shader, i don't know what it does exactly, I will try it. With a first test, it seems it does nothing to the mesh itself.