Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
understanding normal map shader - Page 2 — Gideros Forum

understanding normal map shader

2»

Comments

  • @pie, Hey man, maybe you have any tips for noticing before creating a map like in here: https://www.youtube.com/watch?time_continue=1&v=E9FSkY8MEkg?
  • @tytadas no specific tips, it's a tilemap :) and I am not sure I did it in the best possible way. I have 2 tilesets, 1 with "classic" textures and the other with normalmap textures.
    Inside Tiled I use 2 layers to hand-draw normalmaps upon my "classic map" (2 layers because I may have a bridge or coast overlapping water - or other map elements overlapping a generic "ground").

    The "hard part" (where I suppose I waste a lot of resources) is rendering classic map and normal map aside in a big texture (power of 2 using hgy29 snippet http://giderosmobile.com/forum/discussion/comment/47547#Comment_47547, which then I send to the shader for the light effect).
    Since objects(buildings) in my game have a different size from the ground grid (and Tiled is not able to handle together grids with different sizes) I place them later (along with their normalmap) on an additional Sprite-layer when I render the "big texture".


    Normal map textures are drawn with Sprite Illuminator, I choose normals directions based on the isometric tilemap (ie. "ground" normal is at "12 hours").
  • @hgy29, can you tell me how can i access vertex color array in a shader? thanks
  • hgy29hgy29 Maintainer
    @keszegh, you need to define color attribute when creating your shader, then reference it in your vertex shader and pass it along down to the fragment shader through a 'varying'.
  • ookay, i understand this in principle. could you help how to do the varying, at least? with cpp i have almost no experience. (if it's easier for you, you can modify our terrain3d example and then i will understand what happens).

    don't worry, i'm about to finish my questions. i realized that what i imagined as a polygonal 3d brush in my animation app, at the end it does not look as good as i wanted. still, i've learnt a lot about shaders and 3d in gideros in the last days, for which i'm glad, so thanks.
  • hgy29hgy29 Maintainer
    edited February 2017
    I am posting a modified version of lighting.lua (which can be found in 3D-Horse demo), here in case someone else is interested.
    lua
    lua
    lighting.lua
    6K
  • thanks, perfect.
    (the spec=0; was added by me and probably could be misleading if others want to use your code as a sample).
    i'm pretty sure that this lighting class would be necessary to add to the tools and/or examples, it's quite capable as it is now.
  • olegoleg Member
    edited November 2019
    hgy29 said:

    Hi @pie, below is how I would have wrote the ps shader (tested on my computer);

    uniform lowp sampler2D g_Texture;
    uniform lowp vec4 g_Color;
     
    #define NUM_LIGHTS	2 
    uniform mediump vec4 lightPos[NUM_LIGHTS];
     
    varying highp vec2 texCoord;
    varying mediump vec2 position; 
     
    void main()
    {
    	//Common data
    	//Grab the main pixel color from the classic texture
    	lowp vec3 color0 = texture2D(g_Texture, texCoord).rgb;
     
    	//Set the specular (i.e. "shine") color to 30% gray
    	lowp vec3 color1 = vec3(0.3, 0.3, 0.3);
     
    	//Grab the normal vector from the right part of the texture:
    	//-Displace by 0.5 to the right in normalized coordinates (1=full texture width)
    	//-Convert RGB (range 0->1) to XYZ (range -1 -> 1)
    	mediump vec3 normal = texture2D(g_Texture, texCoord + vec2(0.5, 0.0)).rgb * 2.0 - 1.0; 
     
    	lowp vec3 lightContributions=vec3(0,0,0);	
    	int index;
    	for (index = 0; index <= NUM_LIGHTS; index++) // for all light sources 
    	{ 
    		//Compute light direction, assuming light distance of 150 units
    		mediump vec3 lightDir = normalize(vec3(lightPos[index].xy, 150) - vec3(position.xy, 0)); 
     
    		//Compute the light direction as if light was two times further (for specular)
    		mediump vec3 halfdir = normalize(normalize(lightDir) + vec3(0, 0, 1));
     
    		//Compute diffuse factor: normal and lightDir colinear -> 1, perpendicular -> 0
    		lowp float diff = max(0.0, dot(normal, lightDir));
     
    		//Compute specular factor the same way, but with exponential scale
    		mediump float nh = max(0.0, dot(normal, halfdir));
    		mediump float spec = pow(nh, 10.0); 
     
    		lightContributions=lightContributions+ (color0 * diff + color1 * spec);
    	} 
    	gl_FragColor = g_Color * vec4(lightContributions.rgb, 1); 
    }
    And lua init/setup:
    local effect = Shader.new("vs","ps",0,
    {
    {name="g_MVPMatrix",type=Shader.CMATRIX,sys=Shader.SYS_WVP, vertex=true},
    {name="g_Color",type=Shader.CFLOAT4,mult=1,sys=Shader.SYS_COLOR},
    {name="lightPos",type=Shader.CFLOAT4,mult=2,vertex=false}, --Two lights
    {name="g_Texture",type=Shader.CTEXTURE,mult=1,vertex=false}
    },
    {
    {name="POSITION0",type=Shader.DFLOAT,mult=3,slot=0,offset=0},
    {name="vColor",type=Shader.DUBYTE,mult=0,slot=1,offset=0},
    {name="TEXCOORD0",type=Shader.DFLOAT,mult=2,slot=2,offset=0}
    })
     
    effect:setConstant("lightPos", Shader.CFLOAT4, 2, x, y,0,0, x2,y2,0,0) //Two lightPos
    Help me understand how to remove the light source in the corner?
    I have listed only 2 sources:
    effect:setConstant("lightPos", Shader.CFLOAT4, 2, 200, 50,0,0,400, 50,0,0) --//Two lightPos


    image.png
    527 x 520 - 408K
    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
  • hgy29hgy29 Maintainer
    I see "index <= NUM_LIGHTS" in the for loop, it should be "index < NUM_LIGHTS"

    Likes: oleg

    +1 -1 (+1 / -0 )Share on Facebook
  • hgy29 said:

    I see "index <= NUM_LIGHTS" in the for loop, it should be "index < NUM_LIGHTS"</p>

    Yes it is, thank you
    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
  • olegoleg Member
    edited November 2019
    hgy29 said:

    I see "index <= NUM_LIGHTS" in the for loop, it should be "index < NUM_LIGHTS"</p>

    I have another problem, I can't create 3 light sources, the program displays only 2

    What am i doing wrong?
    effect:setConstant("lightPos", Shader.CFLOAT4, 3, 50, 50,0,0,100,50,0,0,150,150,0,0) --//Two lightPos

    I figured it out myself
    #define NUM_LIGHTS 3

    Likes: MoKaLux

    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
    +1 -1 (+1 / -0 )Share on Facebook
  • How to set this parameter with Lua programmatically?
    #define NUM_LIGHTS 2

    Can lua change the color and size of the light source?
    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
  • hgy29hgy29 Maintainer
    You cn create your shader from the code contained in a lua string, that way you can change the #define and recompile the shader.

    To change the light color and size (specular ?) you'll need to declare more uniforms and use setShaderConstant() from lua

    Likes: oleg

    +1 -1 (+1 / -0 )Share on Facebook
  • hgy29 said:



    To change the light color and size (specular ?) you'll need to declare more uniforms and use setShaderConstant() from lua

    I tried to change with lua these 2 parameters,
    //Set the specular (i.e. "shine") color to 30% gray
    	lowp vec3 color1 = vec3(0.3, 0.3, 0.3);
    //Compute light direction, assuming light distance of 150 units
    		mediump vec3 lightDir = normalize(vec3(lightPos[index].xy, 150) - vec3(position.xy, 0
    I tried setShaderConstant () and i dont understand how it all works ..
    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
  • rrraptorrrraptor Member
    edited November 2019
    oleg said:

    I tried setShaderConstant () and i dont understand how it all works ..

    It is used to pass values from LUA to shader. Its absolutly the same as Shader:setConstant(...). The only difference is that setShaderConstant operates on a shader that is assigned to a sprite, and setConstant applyies directly to the shader object.

    For example, if you have this In your shader
    uniform mediump vec2 fTexelSize;
    mediump - accuracy of floating point value
    vec2 - 2d vector type


    Then you use
    Shader:setConstant("fTexelSize",Shader.CFLOAT2,1,{0,1/self.h})
    to set "fTexelSize" value in shader.

    You cant change non uniform values in sahder from LUA.

    P.S. As a starting point read The Book of Shaders by Patricio Gonzalez Vivo & Jen Lowe

    Likes: oleg, SinisterSoft

    +1 -1 (+2 / -0 )Share on Facebook
  • rrraptor said:
    Unfortunately the 'Textures' section is not active there
    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
  • hgy29 said:

    Hi @pie, below is how I would have wrote the ps shader (tested on my computer);

    uniform lowp sampler2D g_Texture;
    uniform lowp vec4 g_Color;
     
    #define NUM_LIGHTS	2 
    uniform mediump vec4 lightPos[NUM_LIGHTS];
     
    varying highp vec2 texCoord;
    varying mediump vec2 position; 
     
    void main()
    {
    	//Common data
    	//Grab the main pixel color from the classic texture
    	lowp vec3 color0 = texture2D(g_Texture, texCoord).rgb;
     
    	//Set the specular (i.e. "shine") color to 30% gray
    	lowp vec3 color1 = vec3(0.3, 0.3, 0.3);
     
    	//Grab the normal vector from the right part of the texture:
    	//-Displace by 0.5 to the right in normalized coordinates (1=full texture width)
    	//-Convert RGB (range 0->1) to XYZ (range -1 -> 1)
    	mediump vec3 normal = texture2D(g_Texture, texCoord + vec2(0.5, 0.0)).rgb * 2.0 - 1.0; 
     
    	lowp vec3 lightContributions=vec3(0,0,0);	
    	int index;
    	for (index = 0; index <= NUM_LIGHTS; index++) // for all light sources 
    	{ 
    		//Compute light direction, assuming light distance of 150 units
    		mediump vec3 lightDir = normalize(vec3(lightPos[index].xy, 150) - vec3(position.xy, 0)); 
     
    		//Compute the light direction as if light was two times further (for specular)
    		mediump vec3 halfdir = normalize(normalize(lightDir) + vec3(0, 0, 1));
     
    		//Compute diffuse factor: normal and lightDir colinear -> 1, perpendicular -> 0
    		lowp float diff = max(0.0, dot(normal, lightDir));
     
    		//Compute specular factor the same way, but with exponential scale
    		mediump float nh = max(0.0, dot(normal, halfdir));
    		mediump float spec = pow(nh, 10.0); 
     
    		lightContributions=lightContributions+ (color0 * diff + color1 * spec);
    	} 
    	gl_FragColor = g_Color * vec4(lightContributions.rgb, 1); 
    }
    And lua init/setup:
    local effect = Shader.new("vs","ps",0,
    {
    {name="g_MVPMatrix",type=Shader.CMATRIX,sys=Shader.SYS_WVP, vertex=true},
    {name="g_Color",type=Shader.CFLOAT4,mult=1,sys=Shader.SYS_COLOR},
    {name="lightPos",type=Shader.CFLOAT4,mult=2,vertex=false}, --Two lights
    {name="g_Texture",type=Shader.CTEXTURE,mult=1,vertex=false}
    },
    {
    {name="POSITION0",type=Shader.DFLOAT,mult=3,slot=0,offset=0},
    {name="vColor",type=Shader.DUBYTE,mult=0,slot=1,offset=0},
    {name="TEXCOORD0",type=Shader.DFLOAT,mult=2,slot=2,offset=0}
    })
     
    effect:setConstant("lightPos", Shader.CFLOAT4, 2, x, y,0,0, x2,y2,0,0) //Two lightPos
    I created the following texture:

    But for some reason the normal.map coordinates are out of place

    I have to shift the texture by 0.3467 instead of 0.5
    Why is that so?
    mediump vec3 normal = texture2D(g_Texture, texCoord + vec2(0.3467, 0.0)).rgb * 2.0 - 1;
    image.png
    522 x 288 - 73K
    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
  • hgy29hgy29 Maintainer
    Is your texture power of two sized ?

    Likes: oleg

    +1 -1 (+1 / -0 )Share on Facebook
  • hgy29 said:

    Is your texture power of two sized ?

    Yes, my texture is 50% of the image size
    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
  • olegoleg Member
    edited November 2019
    @hgy29 Here is the texture, test it for yourself:

    ps//Set the tile size 71 * 71
    rar
    rar
    tile6.rar
    156K
    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
  • rrraptorrrraptor Member
    edited November 2019
    oleg said:

    hgy29 said:

    Is your texture power of two sized ?

    Yes, my texture is 50% of the image size
    I guess @hgy29 mean that your texture should be POWER OF 2 size. Like 512x512 (2^9) or 2048x2048 (2^11) etc
    But yours is 710x568

    Likes: oleg, hgy29, MoKaLux

    +1 -1 (+3 / -0 )Share on Facebook
  • olegoleg Member
    edited November 2019
    rrraptor said:

    oleg said:

    hgy29 said:

    Is your texture power of two sized ?

    Yes, my texture is 50% of the image size
    I guess @hgy29 mean that your texture should be POWER OF 2 size. Like 512x512 (2^9) or 2048x2048 (2^11) etc
    But yours is 710x568
    You're right, the problem was this

    710/2048=0,3466796875 --Now i know the correct value of texture offset B)

    Likes: antix, MoKaLux

    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
    +1 -1 (+2 / -0 )Share on Facebook
  • hgy29hgy29 Maintainer
    rrraptor said:


    I guess @hgy29 mean that your texture should be POWER OF 2 size. Like 512x512 (2^9) or 2048x2048 (2^11) etc
    But yours is 710x568

    Yes that's what I meant. Actually your texture doesn't need to have the same width and height, it can be 512x256, as long as each dimension is a power of two, all is fine.

    +1 -1 (+3 / -0 )Share on Facebook
  • When opengl es 3 is used will them being a power of 2 matter? (I think it may have removed this restriction)

    Likes: MoKaLux

    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
    +1 -1 (+1 / -0 )Share on Facebook
  • Apollo14Apollo14 Member
    edited November 2019
    Folks use visual shader editors nowadays.
    I didn't dive into it yet, but if I will, I'd check visual editors.
    > Newcomers roadmap: from where to start learning Gideros
    "What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
    “The more you do coding stuff, the better you get at it.” - Aristotle (322 BC)
  • if more than 3 light sources are added, the gideros player crashes when restarted.

    an error occurs when the game screen loses focus. On the tablet the same way. :'(

    Likes: MoKaLux

    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
    +1 -1 (+1 / -0 )Share on Facebook
Sign In or Register to comment.