Debugging glsl? Or what am I missing?

I have setup a TEffectNode and initialized with all the field data that is used in CastleTerrain… The effect is added to the appearance node for my terrain mesh and setup texture layers paralleling the layers in CastleTerrain.

function TTerrainMesh.InitAppearance : TAppearanceNode;
 var Effect : TEffectNode;
     VertexPart, FragmentPart: TEffectPartNode;
     i : integer;
 begin
   Result := inherited;
   Effect := TEffectNode.Create;
   Effect.Language := slGLSL;
   Effect.UniformMissing := umIgnore;
   Result.SetEffects([effect]);

   Effect.AddCustomField( TSFVec4f.Create(Effect, true, 'uv_scale', Vector4( 1, 1, 1, 1)));
   Effect.AddCustomField(TSFVec4f.Create(Effect, true, 'metallic', Vector4( 1, 1, 1, 1)));
   Effect.AddCustomField(TSFVec4f.Create(Effect, true, 'roughness', Vector4( 1, 1, 1, 1)));

   Effect.AddCustomField(TSFFloat.Create(Effect, true, 'height_1', 4));
   Effect.AddCustomField(TSFFloat.Create(Effect, true, 'height_2', 8));

   TTextureLayer.CreateForTerrain( self, 1, 'castle-data:/terrain/textures/island_sand2_d.jpg', effect );
   TTextureLayer.CreateForTerrain( self, 2, 'castle-data:/terrain/textures/ground_mud2_d.jpg', effect );
   TTextureLayer.CreateForTerrain( self, 3, 'castle-data:/terrain/textures/mntn_green_d.jpg', effect );
   TTextureLayer.CreateForTerrain( self, 4, 'castle-data:/terrain/textures/moss_ground_d.jpg', effect );

   Effect.AddCustomField(TSFFloat.Create(Effect, true, 'layers_influence', 1.0));
   Effect.AddCustomField(TSFFloat.Create(Effect, true, 'steep_emphasize', 2.0));

   { initialize 2 EffectPart nodes (one for vertex shader, one for fragment shader) }
   FragmentPart := TEffectPartNode.Create;
   FragmentPart.ShaderType := stFragment;
   FragmentPart.Contents := {$I terrain.fs.inc};

   VertexPart := TEffectPartNode.Create;
   VertexPart.ShaderType := stVertex;
   VertexPart.Contents := {$I terrain.vs.inc};

   Effect.SetParts([FragmentPart, VertexPart]);


//   result.Texture := initTexture( 'castle-data:/grid2.png' );
 end;                                   

But the terrain ends up just being the untextured phong shaded white. I am not sure if the glsl is running correctly or getting an error. Is there a way to see?

Or perhaps I am missing a connection somewhere to make the effect apply?

I needed the equivilent to the layer’s SetTexture call to ChangeAll. Now it is working! The jpg texture are mapped differently than in castleterrain… I just picked them real quick to test. It is super cool that the silhouette lines change color!

1 Like

It is also cool how the texturing masks the low resolution tiles making it look like more detail than is there. Only the very middle few tiles are the full 121x121 vertex grid. The whole area is 11x11 tiles.

1 Like

So if I wanted to combine this with my grid texture that maps to different scales and works as grid and contour map… how would I achieve that? Would I have to add a 5th layer to the glsl and send it and compute the mix in the glsl?

Depends on what you want to achieve. Using GLSL, you can mix any number of textures using any algorithm (including using weights from a splatmap). I don’t know your exact goal, but in general, yes – extend this shader code as much as you need, add more textures as you need.

Remember to not overload the shader if it’s not necessary. If you need e.g. 5 texture inputs to calculate the terrain at each point, pass 5. But if you know that some shape, as a whole, never needs one of them… then maybe you can optimize it, and pass less textures to it.

My goal is ultimately something like the splatmap where I can maintain data about each location … sand dirt rock whatever and then texture appropriately, perhaps mixing if there are neighbors of different types. Maybe as many as 16? I would handle vegetation in another mesh (my water/vegetation/snow mesh). I would then want to overlay stuff on that, like the grid, toggled from the interface. I could probably optimize by tile… if a tile only has a few layers in its data then just pass those few. And only pass the grid if it is turned on. The glsl scares me… but it looks easy enough to add another layer copying from what is there. Can I use the same TEffectNode for all tiles? Right now there is one per tile, which maybe gets expensive?

You can reuse the same TEffectNode. But it’s also not very expensive to have multiple. Different TEffectNode → just means that shapes have different shaders. Does it hurt? Depends on how many tiles do you plan. But it likely doesn’t matter, you don’t plan millions of tiles :slight_smile:

101x101 is likely sufficient for a seamless huge world. But separate shaders is probably more versatile and then you can have different areas have different look, for different biomes.