Jump to content
  • Advertisement

Design Idea: Iridescent shader

jb-dev

3018 views

In our brainstorming, we had the idea of a type of item dropped by enemies that will have a very particular look: it will reproduce bismuth and, in particular, its iridescence.

What is Iridescence?

Remember CD? The under side of CDs had some trippy colors that changed based on which angle you're looking at.

CD

That type of effect is called iridescence.

Many other things has that kind of effect. Things like bubbles, some metals and even some bugs (especially beetles).

Wikipedia defines iridescence as:

Quote

Iridescence (also known as goniochromism) is the phenomenon of certain surfaces that appear to gradually change colour as the angle of view or the angle of illumination changes. Examples of iridescence include soap bubbles, butterfly wings and seashells, as well as certain minerals. It is often created by structural coloration (microstructures that interfere with light).

In order to reproduce the visual qualities of bismuth, we must find how to recreate this effect in a shader.

One of my hypotheses is that we could do it with the normals and the viewing angle. I'm not an expert in shader writing but I'm sure that's possible ...



4 Comments


Recommended Comments

I've done it in Blender. You can also do it in UE4, but it's not great. Substance Designer might have a solution. I think I saw someone doing it in Unity.

Search online and you'll also find solutions for both GLSL and HLSL.

Share this comment


Link to comment
On 4/30/2018 at 12:45 PM, swiftcoder said:

There's a great shader tutorial series on iridescence, if you are looking for inspiration. I'll link you right to the one on CD-ROMS.

I've tried the link and tried to translate the Unity shader into GLSL and it did this:
iridescent.png.ad7b35270d5ca40fd4e7d9d4c852d6ee.png It sure looks pretty...

Share this comment


Link to comment

You forgot to mention that it should be a vertex shader, not a fragment shader.

Also, I love doing shaders ;)  wink wink Let me do some shaders too.

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
  • Advertisement
  • Blog Entries

  • Similar Content

    • By Ed Welch
      I am having a problem loading DXT5 textures. Everything works fine, unless I use a texture which has a height greater than the width and I enable mipmaps (i.e GL_LINEAR_MIPMAP_LINEAR)
      The textures are created using Compressonator and the code to load the textures is here: https://github.com/paroj/nv_dds/blob/master/nv_dds.cpp
    • By phil67rpg
      I have a very simple question, I am trying to rotate some vertex's around an arbitrary axis. basically I want to use glRotatef and glTranslatef to rotate a space ship I have drawn on the screen. here is my code of my  ship. what it does do is rotate around the origin when I  use the arrow keys left and right.
      void drawShip() { glPushMatrix(); glColor3f(255.0f, 0.0f, 0.0f); glTranslatef(-50.0f, 0.0f, 0.0f); glRotatef(rotateship, 0.0f, 0.0f, 1.0f); glBegin(GL_LINE_LOOP); glVertex3f(50.0f, 0.0f, 0.0f); glVertex3f(45.0f, -5.0f, 0.0f); glVertex3f(50.0f, 10.0f, 0.0f); glVertex3f(55.0f, -5.0f, 0.0f); glEnd(); glTranslatef(50.0f, 0.0f, 0.0f); glPopMatrix(); }  
    • By DiligentDev
      Hello!
      I am trying to find efficient map-write-discard implementation in OpenGL, but with no luck so far. Following suggestions on this page, I tried both buffer orphaning with glBufferData(NULL) as well as glMapBufferRange(GL_MAP_INVALIDATE_BUFFER_BIT), both with depressing performance (approximately 40x slower than similar implementation in Direct3D). The method should ideally be suitable for OpenGL4.2 / GLES3.0 API, so glBufferStorage is not desirable, though initializing the buffer with glBufferStorage(GL_DYNAMIC_STORAGE_BIT|GL_MAP_WRITE_BIT) makes no difference. As an experiment I also tried mapping with GL_MAP_UNSYNCHRONIZED_BIT flag with no difference either. Various usage hints (I use GL_DYNAMIC_DRAW) also have zero effect as well.
      In my benchmark I render 32K objects with individual draw calls and map/unmap constant buffer before every call. On my 970GTX, this benchmark runs at ~4 ms/frame in D3D11 mode and 140 ms/frame in OpenGL.
      Here is what my map/unmap functions look like:
       
      void BufferGLImpl :: Map(MAP_TYPE MapType, Uint32 MapFlags, PVoid &pMappedData) { m_uiMapTarget = ( MapType == MAP_READ ) ? GL_COPY_READ_BUFFER : GL_COPY_WRITE_BUFFER; glBindBuffer(m_uiMapTarget, m_GlBuffer); GLbitfield Access = 0; switch(MapType) { case MAP_READ: Access |= GL_MAP_READ_BIT; break; case MAP_WRITE: Access |= GL_MAP_WRITE_BIT; if (MapFlags & MAP_FLAG_DISCARD) { if (m_bUseMapWriteDiscardBugWA) { glBufferData(m_uiMapTarget, m_Desc.uiSizeInBytes, nullptr, m_GLUsageHint); Access |= GL_MAP_WRITE_BIT; } else { Access |= GL_MAP_INVALIDATE_BUFFER_BIT; } } if (MapFlags & MAP_FLAG_DO_NOT_SYNCHRONIZE) { Access |= GL_MAP_UNSYNCHRONIZED_BIT; } break; case MAP_READ_WRITE: Access |= GL_MAP_WRITE_BIT | GL_MAP_READ_BIT; break; } pMappedData = glMapBufferRange(m_uiMapTarget, 0, m_Desc.uiSizeInBytes, Access); glBindBuffer(m_uiMapTarget, 0); } void BufferGLImpl::Unmap() { glBindBuffer(m_uiMapTarget, m_GlBuffer); glUnmapBuffer(m_uiMapTarget); glBindBuffer(m_uiMapTarget, 0); m_uiMapTarget = 0; } Am I doing something obviously wrong here? Is there a clear way to tell OpenGL that I want to discard all previous contents of the buffer?
    • By mujina
      What could be a way of avoiding using inheritance and virtual methods when designing components for an entity-component-system?
      I'll be more specific about my design issue:
      I currently have different classes for different kinds of colliders (let's say, CircleCollider and LineCollider).
      My system that checks for collisions and updates the positions and/or velocities of my entities should be something like:
      for entity_i in alive_entities { collider_i = get_collider_of_entity(entity_i) // components of same kind are stored contiguously in separate arrays transform_i = get_transform_of_entity(entity_i) for entity_j in alive_entities { collider_j = get_collider_of_entity(entity_j) transform_j = get_transform_of_entity(entity_j) if check_collision(collider_i, collider_j) { update(transform_i) update(transform_j) } } } my problem is that I don't have a generic `get_collider_of_entity` function, but rather a function `get_circle_collider_of_entity` and a separate one `get_line_collider_of_entity`, and so on. (This happens because under the hood I am keeping a mapping (entity_id -> [transform_id, sprite_id, circle_collider_id, line_collider_id, ...]) that tells me whether an entity is using certain kinds of components and which are the indices of those components in the arrays containing the actual components instances. As you can see, each component class is corresponding to a unique index, namely the index position of the array of the mapping described above. For example, transforms are 0, sprites are 1, circle colliders are 2, line colliders are 3, and so on.)
      I am in need to write a system as the one in the snippet above. I can write several overloaded `check_collision` functions that implement the logic for collision detection between different kinds of geometric primitives, but my problem is that I am not sure how to obtain a generic `get_collider_of_entity` function. I would need something that would get me the collider of an entity, regardless of whether the entity has a circle collider, a line collider, a square collider, etc.
      One solution could be to write a function that checks whether in my internal entity_id -> [components_ids] mapping a certain entity has a collider at any of the indices that correspond to colliders. For example, say that the indices related to the collider classes are indices 10 to 20, then my function would do
      get_collider_of_entity (entity_id) { for comp_type_id in 10..20{ if mapping[entity_id][comp_type_id] not null { return components_arrays[comp_type_id][entity_id] } } return null } This could turn out to be pretty slow, since I have to do a small search for every collider of every entity. Also, it may not be straightforward to handle returned types here. (I'm working with C++, and the first solution - that is not involving inheritance in any way - would be returning a std::variant<CircleCollider, LineCollider, ... all kinds of components>, since I would need to return something that could be of different types).
      Another solution could be having some inheritance among components, e.g. all specific component classes inherit from a base Collider, and overrride some virtual `collide_with(const Collider& other)` method. Then I would redesign my mapping to probably reserve just one index for colliders, and then I would actual colliders in a polymorphic array of pointers to colliders, instead of having a separate array for CircleColliders, another for LineColliders, and so on. But this would destroy any attempt to be cache-friendly in my design, wouldn't it? That's why I am looking for alternatives.
      A third alternative would be to just have a single, only, Collider class. That would internally store the "actual type" ( aka what kind of collider it is ) with dynamic information (like an enum ColliderType). Then I would have all colliders have all members needed by any kind of colliders, and specific collision detection functions which I can dispatch dynamically that only use some of that data. (Practical example: a "Collider" would have a radius, and the coordinate for 2 points, and in case its type was "circle" it would only make use of the radius and of one of the 2 points - used as the center -, while if it was a "segment" it would only make use of the 2 points). My gut feeling is that this would bloat all colliders, and, even if the bloat could be reduced - using unions in some smart way for storing members? I wouldn't know how -, then still the design would be pretty brittle.
      I'm clueless and open for ideas and advice! How do you handle in general situations in which you have components that can be naturally modeled as subclasses of a more generic component class? Inheritance? Smart hacks with variants, templates, macros, custom indexing? Dynamic "internal" type?
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!