Jump to content

highlighting objects


cassius
 Share

Recommended Posts

Coincidentally I'm looking for this too right now, because I need to highlight hovered function blocks in SuperFlow.

I tried first EntityColor, but it doesn't seem to work with meshes which have a texture which is lacking the highlighted color component: for example a blue texture will be black when I try to color it red.

 

Then I tried a load the mesh_diffuse_vertexgi.frag shader and put it on the model's material, and it kinda worked: the model was much brighter.

I think next I will copy the vertexgi.frag shader and make it so that it can also highlight with a specific color, for example red.

For this it seems I need to set the shader variable fragcolor to vec4(1,0,0,1) from code.

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

Interesting. I played morrowind recently and they highlight objects when you hold the mouse pointer over them. In my case I suppose I could ise speech like"Is that a key I see lying around here?"

I have a microphone and am good at mimicking, but I would prefer highlighting.

amd quad core 4 ghz / geforce 660 ti 2gb / win 10

Blender,gimp,silo2,ac3d,,audacity,Hexagon / using c++

Link to comment
Share on other sites

It seems the mesh_diffuse_bloom.frag shader can be used for highlighting.

I made a mat file like:

texture0="mat/blue.dds"
texture2="mat/red.dds"

So the highlighting will be done using the red.dds texture.

 

Then I loaded the shader with:

shader=LoadShader("abstract::mesh_diffuse.vert","abstract::mesh_diffuse_bloom.frag");

And then I can apply the shader to any model with:

SetMaterialShader(mat,shader);

And it looks like this:

post-2-0-43529100-1318747198_thumb.png

 

EDIT: Ah damn, of course then all models with that mat will be hightlighted ;) I guess I will have to use EntityColor then, but make sure no textures are completely black on one color component. Interestestingly, if I make the texture with color 63,127,255, then a highlight with EntityColor(0.5,1,0.5,1) will be too dark green, but I can do EntityColor(0.5,2,0.5,1) and the green is bright enough.

post-2-0-69811700-1318748952_thumb.png

Ryzen 9 RX 6800M ■ 16GB XF8 Windows 11 ■
Ultra ■ LE 2.53DWS 5.6  Reaper ■ C/C++ C# ■ Fortran 2008 ■ Story ■
■ Homepage: https://canardia.com ■

Link to comment
Share on other sites

I have small objects in my game,some of which can be picked up by the player with a keypress. Whats the best way to highlight them to indicate which ones are pickupable?

Hi cassius,

For me the best way is to outiline the objects like in starcraft interface.

i did something like this in the past but it's not trivial and took me way too much time to find out how to alone ... this should be 1 command in the engine that sets an entity as selected and accepts a parameter to define selection kind.

 

program cubeoutline;

{$ifdef FPC} {$mode delphi} {$endif}
{$H+}

uses Classes, SysUtils, LeadWerks;

const
  FullScreenDefaultWidth = 800;
  FullScreenDefaultHeight = 600;
  OutLineDefaultLineWidth = 6.0;

var
  Framework: TFramework = 0;
  Lua: Pointer;
  World: Tworld;
  Camera: TCamera;
  Light: TLight;
  Material: TMaterial;
  Mesh, Mesh2: TMesh;
  MeshVector: Tvec3;
  Ground: Tmesh;
  Outline_World_Buffer: TBuffer = 0;
  Mem_buffer: TBuffer = 0;
  Post_shader: TShader = 0;
  Outline_world: Tworld = 0;
  Outline_camera: Tcamera = 0;
  OutLineWidth: Single = OutLineDefaultLineWidth;
  key: integer;

begin
  RegisterAbstractPath('D:\Program Files\Leadwerks Engine SDK 231');
  SetAppTitle('Exemple1');

  try
     // Set graphics mode
     if Graphics(FullScreenDefaultWidth, FullScreenDefaultHeight)=0 then Exception.Create('ERROR: Failed to create set graphics mode.');

     // Create framewerk object and set it to a global object so other scripts can access it
     Framework := CreateFramework;
     if Framework=0 then Exception.Create('ERROR: Failed to create Framework');

     if Framework<>0 then
     begin
        // Set Lua variable
        Lua := GetLuaState;
        lua_pushobject(Lua, pointer(Framework));
        lua_setglobal(Lua, 'fw');
        lua_pop(Lua, 1);
     end;

     World := GetLayerWorld(GetFrameworkLayer(0));
     Camera := GetLayerCamera(GetFrameworkLayer(0));
     PositionEntity(Camera, Vec3(0, 0, -2));

     Light := CreateSpotLight(10);
     RotateEntity(Light, Vec3(45, 55, 0), 0);
     PositionEntity(Light, Vec3(5, 5, -5), 0);

     Light := CreateDirectionalLight(0);
     RotateEntity(Light, Vec3(45, 45, 45), 0);

     Material := LoadMaterial('abstract::cobblestones.mat');
     Mesh := CreateCube;
     PaintEntity(Mesh, Material, 0);

     Ground := CreateCube;
     ScaleEntity(Ground, Vec3(10, 1, 10));
     PositionEntity(Ground, Vec3(0, -2, 0), 0);
     PaintEntity(Ground, Material, 0);

     // Activate Framework Postfilter Effects if needed
     //SetAntialias(2);
     //SetDistanceFog(1);
     SetStats(2);
     //SetHDR(1);
     SetGodRays(1);
     SetBloom(1);
     //SetSSAO(1);

     //SetShadowQuality(3);

     Outline_world := CreateWorld;
     SetWorld(Outline_world);
     Outline_camera := CreateCamera;
     PositionEntity(Outline_camera, Vec3(0, 0, -2));
     Mesh2 := CreateCube;

     Outline_World_Buffer := createbuffer(GraphicsWidth, GraphicsHeight, BUFFER_COLOR or BUFFER_DEPTH);
     if Outline_world=0 then Exception.Create('ERROR: Failed to create Outline_World_Buffer');

     Post_shader := loadshader('', 'outline.frag');
     if Post_shader=0 then Exception.Create('ERROR: Failed to create Post_shader');

     SetWorld(World);
     Mem_buffer := currentBuffer;
     while (KeyHit(KEY_ESCAPE)=0) and (AppTerminate=0) do
     begin
        if AppSuspended=1 then UpdateApptime
        else
        begin
           TurnEntity(Mesh, Vec3(AppSpeed*0.5, AppSpeed*0.5, AppSpeed*0.5), 0);
           UpdateFramework;
           RenderFramework;
           MeshVector := EntityRotation(Mesh);

           SetWorld(Outline_world);
           SetBuffer(Outline_World_Buffer);
           RotateEntity(Mesh2, MeshVector);
           UpdateWorld;
           RenderWorld(ENTITY_MESH);
           SetWorld(World);

           key := GetChar;
           if keyhit(KEY_UP)=1 then
           begin
              freeBuffer(Outline_World_Buffer);
              if Graphics(round(GraphicsWidth * 1.1), round(GraphicsHeight * 1.1))=0 then Exception.Create('ERROR: Failed to create set graphics mode.');
              Outline_World_Buffer := createbuffer(GraphicsWidth, GraphicsHeight, BUFFER_COLOR or BUFFER_DEPTH);
              if Outline_world=0 then Exception.Create('ERROR: Failed to create Outline_World_Buffer');
              OutLineWidth := round(OutLineDefaultLineWidth * (GraphicsWidth/FullScreenDefaultWidth));
           end
           else if keyhit(KEY_DOWN)=1 then
           begin
              freeBuffer(Outline_World_Buffer);
              if Graphics(round(GraphicsWidth / 1.1), round(GraphicsHeight / 1.1))=0 then Exception.Create('ERROR: Failed to create set graphics mode.');
              Outline_World_Buffer := createbuffer(GraphicsWidth, GraphicsHeight, BUFFER_COLOR or BUFFER_DEPTH);
              if Outline_world=0 then Exception.Create('ERROR: Failed to create Outline_World_Buffer');
              OutLineWidth := round(OutLineDefaultLineWidth * (GraphicsWidth/FullScreenDefaultWidth));
           end
           else Leadwerks.DrawText(100, 100, chr(lo(key)));

           SetBuffer(backbuffer);
           SetShader(Post_shader);
           BindTexture(GetDepthBuffer(Outline_World_Buffer), 1);
           SetShaderVec4(Post_shader, 'color', Vec4(1,0,0,1));
           SetShaderVec4(Post_shader, 'alphacolor', Vec4(1,0,1,0));
           SetShaderFloat(Post_shader, 'linewidth', OutLineWidth);
           SetBlend(BLEND_ALPHA);
           DrawImage(GetColorBuffer(Outline_World_Buffer), 0, GraphicsHeight, GraphicsWidth, -GraphicsHeight);
           SetBlend(0);
           SetShader(0);

           SetBuffer(Mem_buffer);

           Flip(1);
        end;
     end;
  except
     on E: exception do
     begin
        Applog(PAnsiChar(' Exception occured ! '+E.message));
     end;
  end;
end.

 

and the shader code

uniform vec2 buffersize;

void main( void ) {

vec2 _texcoord = gl_FragCoord.xy/buffersize;

vec2 _pixelsize = linewidth/buffersize;

       float _depth = texture2D( texture0, _texcoord ).x/2;
       if (_depth != 0)
       {
          gl_FragColor = alphacolor;
       }
       else
       {
      	   float tl = texture2D(texture0, _texcoord + vec2(-_pixelsize.x, -_pixelsize.y)).x;
          float tm = texture2D(texture0, _texcoord + vec2(0.0, -_pixelsize.y)).x;
          float tr = texture2D(texture0, _texcoord + vec2(+_pixelsize.x, -_pixelsize.y)).x;
          float ml = texture2D(texture0, _texcoord + vec2(-_pixelsize.x, 0.0)).x;
          float mm = 0; //texture2D(texture0, _texcoord).x;
          float mr = texture2D(texture0, _texcoord + vec2(+_pixelsize.x, 0.0)).x;
          float bl = texture2D(texture0, _texcoord + vec2(-_pixelsize.x, +_pixelsize.y)).x;
          float bm = texture2D(texture0, _texcoord + vec2(0.0, +_pixelsize.y)).x;
          float br = texture2D(texture0, _texcoord + vec2(+_pixelsize.x, +_pixelsize.y)).x;

          float dpt  = tl+tm+tr+ml+mm+mr+bl+bm+br;
          if (dpt != 0)
          {
             gl_FragColor = color;
          }
          else
          {
             gl_FragColor = alphacolor;
          }
}
}

 

post-44-0-41316900-1318759932_thumb.jpg

 

Notice you'll have to resize the outline buffer manually if you change screen resolution.

 

also with this method, if you want to select an animated entity, you'll have to animate it twice.

 

But i'm pretty sure there's a way to do this without worlds, only with a shader. and even with a glow efect. but my shader knowledge is not good enought.

 

Cheers

Chris

Windows 7 home - 32 bits

Intel Quad Q6600 - nVidia GTX 460 1GB - 2 GB RAM

Link to comment
Share on other sites

Chris's method above is certainly widely used in games these days although walking into a room where objects are highlighted or glow at you I've personally found annoying as it takes any skill out of the game (a bit like playing a game with a walk through guide in your hand). An alternative is to either highlight the object only when your cursor is over it, as you suggested, or in my pick/inventory interface I simply enable inspect and pick icons when the cursor (a hand in my case) is over a pickable/inspectable item as show below:

 

post-51-0-91264900-1318787818_thumb.jpg

Intel Core i5 2.66 GHz, Asus P7P55D, 8Gb DDR3 RAM, GTX460 1Gb DDR5, Windows 7 (x64), LE Editor, GMax, 3DWS, UU3D Pro, Texture Maker Pro, Shader Map Pro. Development language: C/C++

Link to comment
Share on other sites

Thanks for the interesting answers.I don't want to make puzzles too easy as pixel said and I don't want to make this a big deal so I may just use a spotlight that comes on when player gets near an object.But only for the first object. the player comes across.

amd quad core 4 ghz / geforce 660 ti 2gb / win 10

Blender,gimp,silo2,ac3d,,audacity,Hexagon / using c++

Link to comment
Share on other sites

Another play with the hightlighting using lighting could be to have the object in another world. When you mouse over it you hide the one in the base world and show the one in the highlighted world. You can then have a high ambient light in that world and it would stand out then.

 

If you went this route creating a system to automatically do all of that on special objects would be ideal. This is sort of a world of warcraft deal as when you highlight things the lighting changes on the object to show it's highlighted.

Link to comment
Share on other sites

using the fullbright shader would probably give the same results as that and wouldnt require an additional world and doubling of the objects.

 

and nice one wchris... nice idea with alpha in the shader... works nice.

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

using the fullbright shader would probably give the same results as that and wouldnt require an additional world and doubling of the objects.

 

Good call. If you had multiple instances of the model you wanted highlighted and applied the shader at run-time to one instance would they all get that shader applied? If so a possible side effect to the shader based methods.

Link to comment
Share on other sites

true but as always it depends on what it is required in the game and the circumstances... personally i like the postprocess effect that wchris is showing as its been something i have tried in the past but could never figure out how to merge the post process toon shader of one world with another world together without issues...

 

another thing that is done alot is to put particles or a corona flash on the object to bring attention to it... but it depends on the game and the intentions... for pixel's game it would make sense to not make it too easy for them to find the items they need to inspect, but for a game where you just want to highlight money dropped or weapons, a common effect across all instances would work fine.

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...