Share a Shader!

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Wojak
Party member
Posts: 134
Joined: Tue Jan 24, 2012 7:15 pm

Re: Share a Shader!

Post by Wojak »

Jasoco wrote:It's a neat start. And it replicates the effect from later Wolf clones perfectly. But can you make it do more than one texture on the same plane? Right now it's just tiling one texture over and over.
I'm 100% sure that it's possible, but GLSL is not lua and this is my second shader ever...
I will play with this more and who knows maybe even create a 100% shader based raycaster (though the methods behind it will be more like in the old days – no quads and drawing full sprites, just checking what color should a specific pixel have)
Wojak
Party member
Posts: 134
Joined: Tue Jan 24, 2012 7:15 pm

Re: Share a Shader!

Post by Wojak »

GLSL is not lua – a true story”

Me: I want to implement tile maps so I think I should use a simple 2d array of integers.
GLSL: NO! I don't support 2d arrays :joker:
Me: How about I convert 2d array to 1d array?
GLSL: Sure go ahead ;) but I won't let You index it with floats, float 1 is not the same as int 1 :megagrin:
Me: Ok, so I convert it using the int() function then...
GLSL: Yes, You can do that, but I won't let You sue arrays anyway, because arrays can only hold vectors and only indexed with loop index and what not :joker:
Me: :huh: WTF...

Than I converted the tile map to a texture and presto:
Attachments
floorcaster3.love
(11.91 KiB) Downloaded 466 times
test.jpg
test.jpg (130.77 KiB) Viewed 12664 times
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Share a Shader!

Post by Jasoco »

Yeah, I was gonna say don't even bother trying to send all the tiles to the shader. Just put them all in one texture.

Question is, how easy is it to get the proper 2D screen X and Y locations of any given 3D point in that world?
Wojak
Party member
Posts: 134
Joined: Tue Jan 24, 2012 7:15 pm

Re: Share a Shader!

Post by Wojak »

I did this like this:
1) sent a texture set (384x64 pixels) containing 6 unique textures
2) sent 2 tile maps in the form of one 20x20 pixel image with the information about the textures id's encoded to the red and green chancels (if I would want to send a 100x100 tile map it would only be a 100x100 pixel image and you can fit 4 maps of the same size to one image if you have less then 255 unique textures)
Question is, how easy is it to get the proper 2D screen X and Y locations of any given 3D point in that world?
If the world is flat - very easy ;)
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Share a Shader!

Post by Jasoco »

Wojak wrote:
Question is, how easy is it to get the proper 2D screen X and Y locations of any given 3D point in that world?
If the world is flat - very easy ;)
I'm sure you know what I mean. If I ask for the 2D screen coordinates of a 3D point in that scene, I want to make sure it lines up correctly. Or else it's useless.
Wojak
Party member
Posts: 134
Joined: Tue Jan 24, 2012 7:15 pm

Re: Share a Shader!

Post by Wojak »

I don't know if you tried to code something in GLSL, but the screen X and Y coordinates are the things you start with and with the stuff like floorcasting, raycasting and raytracking the screen coordinates are the only unique feature of a single pixel (I do not even know if it is possible for a pixel to save some data between frames...).
So for each and every pixel you must calculate the world 3D position that corresponds to that pixel than check what color the thing on thous coordinates have, and set the pixel to that color.
And the difficulty will very with the structure of the world:
flat: floorcasting
large cubes: raycasting
like real life: raytracking

In theory in GLSL raytracking should be as hard as raycasting, but I'm not advanced enough to test it...

also (not my video):
User avatar
rmcode
Party member
Posts: 454
Joined: Tue Jul 15, 2014 12:04 pm
Location: Germany
Contact:

Re: Share a Shader!

Post by rmcode »

I turned the colour / palette - switcher of my latest game into a library which can be found here.

It uses a look-up table to change the input color to a certain output color. You don't have to change any code if you want to add more palettes, or use different palettes which use more colors. You simply can paint them into the LUT image file. Each line on the y-axis represents a palette and each pixel on the x-axis is a color which can be used by the shader to replace the original colors.
example.gif
example.gif (193.64 KiB) Viewed 12271 times
The example.love which was used to create the above .gif can be found in the repository.
NPException
Prole
Posts: 1
Joined: Mon Nov 24, 2014 3:26 pm

Re: Share a Shader!

Post by NPException »

hello everyone!

First of all, I am completely new to shaders, and don't know what I'm doing. I have stumbled across the nice "Voronoise" on Shadertoy and decided that I want it as an effect for my game. I already modified the code a bit so here is what I have now:

Code: Select all

extern float time;

vec3 hash3( vec2 p )
{
    vec3 q = vec3( dot(p,vec2(127.1,311.7)), 
				   dot(p,vec2(269.5,183.3)), 
				   dot(p,vec2(419.2,371.9)) );
	return fract(sin(q)*43758.5453);
}

vec4 effect(vec4 vcolor, Image texture, vec2 texture_coords, vec2 pixel_coords)
{
  vec2 size = vec2(800.0, 600.0); // screen size
  vec2 scaledSize = size/10.0;
	vec2 x = scaledSize * texture_coords;
  
  float u = 0.375*sin(time/2); // amount of 'voronoiification'
  vec2 p = floor(x);
  vec2 f = fract(x);
		
	float k = 64.0;
  
  float va = 0.0;
	float wt = 0.0;
    for( int j=-2; j<=2; j++ )
        for( int i=-2; i<=2; i++ )
        {
            vec2 g = vec2( (i+0.5),(j+0.5) );
            vec3 o = hash3( p + g )*vec3(u,u,1.0);
            vec2 r = g - f + o.xy;
            float d = dot(r,r);
            float ww = pow( 1.0-smoothstep(0.0,1.414,sqrt(d)), k );
            va += o.z*ww;
            wt += ww;
        }
	
  float c = va/wt;
	
  vec4 txl = Texel(texture, texture_coords);
	
  
	return vec4( c, c, c, 1.0 );
}
Now here is what I want to achieve with the shader:
Instead of rendering those distorted greyscale pixels, I want to distort the pixels of my 80x60 image that I have .
Can someone help me out? I have no idea how exactly this shader works...

I overlayed the effect with an image underneath, so you can imagine what I have in mind:
Image
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Share a Shader!

Post by s-ol »

NPException wrote:hello everyone!
-snip-
Now here is what I want to achieve with the shader:
Instead of rendering those distorted greyscale pixels, I want to distort the pixels of my 80x60 image that I have .
Can someone help me out? I have no idea how exactly this shader works...

I overlayed the effect with an image underneath, so you can imagine what I have in mind:
It should be enough to replace the return call in the frag function with this:

Code: Select all

    return vec4( c, c, c, 1.0 ) * txl;

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
drunken_thor
Citizen
Posts: 75
Joined: Wed Oct 01, 2014 12:14 am
Location: Toronto, Canada
Contact:

Re: Share a Shader!

Post by drunken_thor »

Hey everyone I am working on a rewrite (again) of the light_world.lua library found here: viewtopic.php?f=5&t=78998 and I managed to compile my normal shading, shadow shading and shine shading all into one shader, and one draw call per light. I am pretty proud of this so check it out! It has sped up the library quite a bit and make the library (at least visually) function exactly the same. (I have not merged this branch yet with the master though I will let you know when I do)

I would also love some crits if you see any problem points, I am still fairly new at the whole shading thing.

Thanks!

Code: Select all

/*
The MIT License (MIT)

Copyright (c) 2014 Tim Anema
Light Shadow, Shine and Normal shader all in one

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#define PI 3.1415926535897932384626433832795

extern vec2 screenResolution; //size of the screen
extern Image shadowMap;       //a canvas containing shadow data only
extern vec3 lightPosition;    //the light position on the screen(not global)
extern vec3 lightColor;       //the rgb color of the light
extern float lightRange;      //the range of the light
extern float lightSmooth;     //smoothing of the lights attenuation
extern vec2 lightGlow;        //how brightly the light bulb part glows
extern float lightAngle;      //if set, the light becomes directional to a slice lightAngle degrees wide
extern float lightDirection;  //which direction to shine the light in if directional in degrees 
extern bool  invert_normal;   //if the light should invert normals

//calculate if a pixel is within the light slice
bool not_in_slice(vec2 pixel_coords){
  float angle = atan(lightPosition.x - pixel_coords.x, pixel_coords.y - lightPosition.y) + PI;
  bool pastRightSide = angle < mod(lightDirection + lightAngle, PI * 2);
  bool pastLeftSide  = angle > mod(lightDirection - lightAngle, PI * 2);
  bool lightUp = lightDirection - lightAngle > 0 && lightDirection + lightAngle < PI * 2;
  return (lightUp && (pastRightSide && pastLeftSide)) || (!lightUp && (pastRightSide || pastLeftSide));
}

vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {
  vec4 pixelColor = Texel(texture, texture_coords);
  vec4 shadowColor = Texel(shadowMap, texture_coords);

  //if the light is a slice and the pixel is not inside
  if(lightAngle > 0.0 && not_in_slice(pixel_coords)) {
    return vec4(0.0, 0.0, 0.0, 1.0);
  }

  vec3 normal;
	if(pixelColor.a > 0.0) {
    //if on the normal map ie there is normal map data
    //so get the normal data
    if(invert_normal) {
      normal = normalize(vec3(pixelColor.r, 1 - pixelColor.g, pixelColor.b) * 2.0 - 1.0); 
    } else {
      normal = normalize(pixelColor.rgb * 2.0 - 1.0);
    }
  } else {
    // not on the normal map so it is the floor with a normal point strait up
    normal = vec3(0.0, 0.0, 1.0);
  }
  float dist = distance(lightPosition, vec3(pixel_coords, normal.b));
  //if the pixel is within this lights range
  if(dist < lightRange) {
    //calculater attenuation of light based on the distance
    float att = clamp((1.0 - dist / lightRange) / lightSmooth, 0.0, 1.0);
    // if not on the normal map draw attenuated shadows
    if(pixelColor.a == 0.0) {
      //start with a dark color and add in the light color and shadow color
      vec4 pixel = vec4(0.0, 0.0, 0.0, 1.0);
      if (lightGlow.x < 1.0 && lightGlow.y > 0.0) {
        pixel.rgb = clamp(lightColor * pow(att, lightSmooth) + pow(smoothstep(lightGlow.x, 1.0, att), lightSmooth) * lightGlow.y, 0.0, 1.0);
      } else {
        pixel.rgb = lightColor * pow(att, lightSmooth);
      }
      //If on the shadow map add the shadow color
      if(shadowColor.a > 0.0) {
        pixel.rgb = pixel.rgb * shadowColor.rgb;
      }
      return pixel;
    } else {
      //on the normal map, draw normal shadows
      vec3 dir = vec3((lightPosition.xy - pixel_coords.xy) / screenResolution.xy, lightPosition.z);
      dir.x *= screenResolution.x / screenResolution.y;
      vec3 diff = lightColor * max(dot(normalize(normal), normalize(dir)), 0.0);
      //return the light that is effected by the normal and attenuation
      return vec4(diff * att, 1.0);
    }
  } else {
    //not in range draw in shadows
    return vec4(0.0, 0.0, 0.0, 1.0);
  }
}
Light_world.lua for all your lighting needs
Talkies for all dialog needs
Github
twitter
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 15 guests