# Fresnel Outline Shader for Picking up Items

2772 views

Subscribe to our subreddit to get all the updates from the team!

# Idea

We wanted units in our game to be able to pick up items, including the player. But how can the player know which item will be picked up when he executes that action? Traditionally, video game developers and designers do this by using an outline shader. However, in our game, we thought that it was too "normal", cartoonish and not enough A E S T H E T I C.

# Solution

The solution was to use Fresnel optics to simulate a cooler outline. The Fresnel Effect is used, approximated actually because it is extremely complex, in shaders such as a reflection shader for specular colors. In real life, this visual effect occurs on surfaces that reflect and refract light. An object that refracts light lets a fraction of the incoming light pass through its body. A good example for this is water.

## Examples and Tutorials

Here are examples and tutorials for the Fresnel Effect in computer graphics programming :

## How to Do It

Here's how I did it with the jMonkeyEngine, which is a Java 3D game engine.

Firstly, you need to create a material definition that will describe what will be the shaders and their inputs.

### Material Definition

MaterialDef Fresnel Outline {

MaterialParameters {
Color FresnelOutlineColor
Float FresnelOutlineBias
Float FresnelOutlineScale
Float FresnelOutlinePower
}

Technique {

WorldParameters {
WorldViewProjectionMatrix
WorldMatrix
CameraPosition
}
}
}

#### Material Parameters

As you can see, there are 4 uniforms that we need to specify to the shaders for them to function properly :

1. FresnelOutlineColor - The color of the Fresnel Effect. Usually, it is an environment map that deals with that.
2. FresnelOutlineBias - Acts like a diffuse color for the specular component.
3. FresnelOutlineScale - How far the Fresnel Effect affects the model. The smaller the angle between I and N (the surface's normal), the less Fresnel Effect there is and the more scale is needed for that surface to be lit by it.
4. FresnelOutlinePower - Exponentially increases the Fresnel Effect's color but decreases the scale.

We will need to either set them in the material or in the code. You'll see about that later in the article.

#### Technique

The technique describes what shaders to execute and their engine's uniforms.

There's no need to use a recent version of OpenGL / GLSL for this shader. The first GLSL version will do.

For the Fresnel shader, we need to the following uniforms to be supplied by the game engine :

1. WorldViewProjectionMatrix - The MVP matrix is needed to compute each vertex' position
2. WorldMatrix - The world matrix is needed to compute the position and normal for each vertex in world coordinates
3. CameraPosition - The camera position is needed to calculate the I (incident) vector

### Material

The material uses a material definition and then applies render states and parameters to it. It is instantiable codewise.

Material Fresnel Outline : material_definition/fresnel_outline/fresnel_outline_material_definition.j3md {
MaterialParameters {
FresnelOutlineColor : 1.0 0.0 0.0 1.0
FresnelOutlineBias : 0.17
FresnelOutlineScale : 2.0
FresnelOutlinePower : 1.0
}
}

As you can see, we can set the uniforms right here instead of doing so in the code, which saves us programmers from dealing with design components.

#import "Common/ShaderLib/GLSLCompat.glsllib"

uniform vec3 g_CameraPosition;
uniform mat4 g_WorldMatrix;
uniform mat4 g_WorldViewProjectionMatrix;

uniform float m_FresnelOutlineBias;
uniform float m_FresnelOutlineScale;
uniform float m_FresnelOutlinePower;

attribute vec3 inPosition;
attribute vec3 inNormal;

varying float fresnelOutlineR;

void main() {
vec3 worldPosition = (g_WorldMatrix * vec4(inPosition, 1.0)).xyz;
vec4 worldNormal = normalize(g_WorldMatrix * vec4(inNormal, 0.0));

vec3 fresnelI = normalize(worldPosition - g_CameraPosition);

fresnelOutlineR = m_FresnelOutlineBias + m_FresnelOutlineScale * pow(1.0 + dot(fresnelI, worldNormal.xyz), m_FresnelOutlinePower);

gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
}

This is how each vertex position, normal, color, texture coordinates [...] are transferred into the vertex shader by the jMonkeyEngine.

attribute vec3 inPosition

The same procedure is applied onto g_ and m_ variables. g_ variables are definied by the engine, whilst m_ variables are defined by the material definition.

Here's how to do the Fresnel outline shader on the vertex side :

1. Compute the world position and normal
2. Compute the eye to vertex direction
3. Compute the Fresnel Effect R variable (description reference
Quote

R is a Fresnel term describing how strong the Fresnel effect is at a specific point

#import "Common/ShaderLib/GLSLCompat.glsllib"

uniform vec4 m_FresnelOutlineColor;

varying float fresnelOutlineR;

void main() {
gl_FragColor = mix(vec4(0.0, 0.0, 0.0, 1.0), m_FresnelOutlineColor, fresnelOutlineR);
}

All that's left to do is a linear interpolation between the black color and the desired color with R being the interpolation value between the two.

Because this is a simple tutorial, it only shows how to compute the Fresnel outline specular color.

### Result

And with a bias of 1.0.

Teal!

Tested on a pickable item

So what exactly is this game going to be about anyways?

3 hours ago, Awoken said:

So what exactly is this game going to be about anyways?

That's a good question actually ahah!

We weren't exactly sure and the game design has changed since we started. Originally (and still today), we wanted a 3D rogue-lite procedural vaporwave game.

The game consists of different worlds which will have randomly generated levels that consist of semi-random rooms and totally random rooms.

For example, we had two worlds in mind : the savanna and the jungle.

1. The savanna is outdoor and there is no direct path to the end. We didn't define what is the end. We had a zone planned for that with a giant rock with a tons of lions.
2. The jungle is a classic dungeon crawler level.

The savanna was discarded because it wasn't enough rogue-lite (I actually wanted it to be included in the game, sad reacts only 😢 ). It was just too open.

As of how it will look like, think of Heavy Bullets.

Anyway, here's the gameplay

• Attack enemies, which will be the fauna, the flora, mobs, mini-bosses, bosses and legendary bosses, with your weapon.
• There's a stats mechanic similar to The Binding of Isaac.
• Equip items : armor, charms, weapons and relics. Those have stats modifiers.
• Gain money and equipment from killing enemies.
• Gain relics from killing bosses. They offer permanent effects like in The Binding of Isaac.
• Beware of traps!
• And much more! Like a secret gameplay mechanic that we're not ready to announce just yet

vapour wave, Heavy Bullets, The Binding of Isaac.  Very interesting indeed.

## Create an account

Register a new account

• ### Similar Content

• My project started in 2014 but recently ended due to no funds.  AltarisNine was a Minecraft project based on RPG. The conc﻿ept was nine islands that you explore at a time to follow an in depth lore based on our own production team. This is where the 'Nine' comes in. With skepticism of future success we hope to make this tale into chapters. Such as the first one introducing Nine islands at time.
It wasn't always the same though, my world did evolve over time and now I have a better idea of what it is better than ever. In the first island, Main Isle, is themed around jungles and wilderness. There's lore that stretches throughout the chapter which will engage the player. There would also be kinds of characters you can be such as any other RPG which could be talked about (because i'm still  about what I have lol)
My former team was designing a world players would get into interact with in various ways. Boss battles would be minigames and the RPG lore would be engaged in and something indie platforms would enjoy and talk about beyond platforms.
In the minecraft varient I was a builder, the leader, and the story director which everyone respected. I led my own team of builders and story writers. While I chose certain individuals to be the head department of development and art design.
The reason I am here is to find a new team to help take this away from minecraft and hope we can be successful about it. I'll happily commute each and every person that volunteers and will be accommodated down the line with promotions, wages, and definitely praised for helping start my dream up.

Here are some questions that were frequently asked and that I can thoroughly answer:
What is the goal of the game? If you've ever heard of Wizard101. I got inspired by that game a little. I like the concept of making yourself in this world of mystery and impressing people with new mechanics and events that they enjoy. I'd like for the game to be successful and be mostly on PC but if this keeps up we could reach out to other consoles. But for now, PC, one platform at a time lol. My goal personally is to give people the entertainment and enjoyment I think they'll deserve. Something thats not cheesy, not cliche, something new to keep evolving the gaming community Is this in first-person or third-person? This will be a third person game. We can play around with the camera angles but I kind of want it from a aerial pov I saw RPG in the post so can I assume that the game will have generic RPG elements, e.g. quests, npcs, story-line, items? Yes this will have generic RPG elements. But with a few surprises that make the game different. Such as making boss fights some type of minigame. I don't know how the audience will like or even if it'll flow with game play. But I'd still like to take the idea on for now. Will there be combats, e.g. vs. monsters, vs. players(?) ? There will be tons of concepts. As i've said before the 'Nine' comes in the Nine isles of this world we haven't named yet lol. Each nine islands we come up with will not only give players plenty of content to play, but something we break up into story chapters. Each island will have its on set monsters tied to the story or even monsters that are just natural in their environment. There will also be a PvP aspect which can't be brought up too much because its difficult to try to come up with a player style culture that isn't too predictable or generic or even cliche. I was wondering if it should be an initiated fight or a head on duel like world of warcraft. Is this a single player game or a multiplayer one? Definitely multiplayer. Will the game look like Minecraft? like a voxel/blocks game? I imagined it not looking like minecraft but maybe that can be a concept of its own down the line (like an island concept). I was thinking along the lines of a 3D style and not like minecraft. What are the core mechanics to be included, e.g. player movement, enemy movement, enemy AI? This question is more technical but there will be interactive things in the world, things to collect, natural occurring crafting supplies to make new loot and weapons with. There will be NPC's and thats a broad topic enough lol. I'd even a imagine a pet, housing, and gardening system. But thats for accessories in coding and to give more content in the game for later polishing. Is there a storyline already made? There is an indirect storyline. We've made a script for voice actors (and just what to make the NPC's say in general) in A9 v1. Are there goals already planned out? There are many goals to set out. One each at a time for separate upcoming departments The first 8 pictures were of our hub, the other 9 was our factions world. The factions world doesn't retain to this project I wanted you to see how dedicated I was to making this project. I built everything in the hub myself except for the giant pagodas. The last two photos were all the ones I could find of the RPG world

• I want to render an ocean where players can change waves’ amplitude in real-time. Initially, I would render rolling waves (see picture). As the amplitude increases, I need to transition the rolling waves into breaking waves (see picture). For now, I am not going to show the shoreline onscreen so I don’t need to render breaking waves interacting with the shoreline; I only need breaking waves on the open ocean.

I’ve tried three different approaches so far and I’ve only had success with rolling waves using approach 1. Breaking waves have been impossible so far with all three approaches.

Approach 1: Mesh deformation

a.     I can create smooth rolling waves using the Sine and Gerstner equations.

b.     Since I can’t use these equations for breaking waves, I tried to implement them by using this free plugin whose output is similar to this paid mesh deformation plugin. But there are 2 problems with this plugin approach:

·      There is no smooth transition between rolling waves generated by approach 1a and the breaking waves generated by the Deform plugin

·      The output of the plugin does not look similar to real breaking ocean waves in three different ways:

i.     No smooth blending with the ocean surface

ii.     A large depression is created below the crest

iii.     The entire wave is the same height (rather than with more realistic variations)

c.      I considered using vertex shaders but this approach seems similar to mesh deformation.

Approach 2: Fluid dynamics + metaballs

1.     To render an ocean I will need thousands of particles which will be too expensive in terms of performance (especially for mobile devices).

Approach 3: Using mesh files

1.     I can create breaking waves using some 3D software like in this post but then I can’t modify the ocean in real-time. It will be more like a pre-rendered simulation.

To summarize, I am looking for an approach where I can vary ocean waves’ amplitude for a smooth transition between rolling waves and breaking waves. Please let me know if you have more questions.

• By Cacks
Hi,
I'd like to get & set the OpenGL View Port Matrix but it doesn't work
I'm using the "GL_VIEWPORT" parameter
any ideas?

• Is there a way to set up the projection matrix (in OpenGL) so that the vanishing point is not at the center of the screen?
Let me explain what I mean in more detail.  Imagine that I am rendering a 3D scene with a standard perspective projection matrix to a 1000x1000 window.  There is no camera matrix, so planes of constant z are parallel to the screen, and objects move toward the center of the window as their z coordinate approaches infinity.  Now, I want to only render the bottom half of this window.  Planes of constant z are still parallel to the screen, but now objects move to a point at the top of the window as their z approaches infinity.
• By bandages
So, in real life, incoming dot normal at the silhouette is always 0.  With smooth shaded meshes, it never is, not naturally, not outside of contrived situations.  (Not with flat shaded meshes either, I guess.)
And incoming dot normal is one of the bedrocks of CG.  Probably the equal of 4x4 matrix multiplication.  Problems with silhouette normals show up in Fresnel, in diffuse lighting, in environment mapping....  everywhere.  But I can't really find anybody talking about it.  (Maybe I'm not Googling the right terms.)
Obviously, the problem decreases as poly count goes up, eventually reaching a point where it's dwarfed by other silhouette problems (like translucency or micro-occlusion) that CG doesn't handle well either.  But, if I'm reasoning correctly, normal maps don't improve the problem-- they're as likely to exacerbate it as improve it, and the exacerbations are, aesthetically speaking, probably worse than the improvements are better.
I've tried playing with crude fixes-- basically, rotating normals toward incoming by a percentage, or of course clamping incoming dot normal (like we all have to do) to prevent it from bending behind the mesh.  Nothing I've tried looks good.  I suppose the best option might be to rotate normals to perpendicular to incoming at the silhouette and then interpolate to the nearest inflection point  of something like screen space depth to preserve curvature, but the math for how to do that is beyond me, and I'm not sure it would look any better.  Or maybe, instead, somehow, adjust the drawn silhouette to match the silhouette defined by incoming dot normal?  Not even sure how that would work, not if the normal was pointing away from incoming.
I don't know-- is this a solvable problem?  Has anyone tried other stuff and given up, pursued anything that was promising but too expensive, anything like that?  Are there any papers I'm missing?  It's really surprising to me that I can't find anyone else talking about this.
(Apologies if I chose the wrong subforum for this.  I considered art forums, but I felt that people frequenting the programming forums would have more to say on the subject.)