Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shadows Tutorial Continuation #99

Open
tonygoldcrest opened this issue Apr 15, 2021 · 4 comments
Open

Shadows Tutorial Continuation #99

tonygoldcrest opened this issue Apr 15, 2021 · 4 comments

Comments

@tonygoldcrest
Copy link

First of all, thank you for such an amazing resource.

Are you planning to finish this part? https://github.com/gfxfundamentals/webgl2-fundamentals/blob/master/webgl/lessons/webgl-shadows-continued.md
It's one of the most complex topics on the website and I'd like as much information about this as possible. Would be awesome if you have plans to release it since your tutorials are so easy to follow.
The first article on shadows mentions multiple techniques of rendering shadows, so would be nice to read about other options, ray tracing possibly as I've seen it done with WebGL.

In any case, thank you so much, I couldn't have done anything I've already achieved without your tutorials.

@greggman
Copy link
Member

Sorry I haven't had time to continue the shadows. Mostly I'd try to cover point lights (which is basically the same thing as the current article except you render in 6 directions instead of just one to make a shadow cubemap). Another thing to cover is trying to anti-alias the shadows. Yet another is trying to adjust the math to not waste the the resolution of the shadow map texture for far away stuff but instead use it for close up stuff.

You can read about these topics all over the net, mostly in non-WebGL articles but the ideas are usually easily translatable, especially if you made it through the tutorials to the shadow article.

This article has one example of anti-aliasing
and this article has an example of point light shadows

@Khgiikbvhkbvv
Copy link

Khgiikbvhkbvv commented Mar 22, 2024

I have added anti aliasing/pcf (percentage-closer filtering)
for the spotligt and the last samples.
Just exchange the fragment shader code with
my extended one, that's it and it should work.

happy shadowing easter, friends

point light

var fs=`#version 300 es
precision highp float;
in vec2 v_texcoord;
in vec4 v_projectedTexcoord;
in vec3 v_normal;
in vec3 v_surfaceToLight;
in vec3 v_surfaceToView;

uniform vec4 u_colorMult;
uniform sampler2D u_texture;
uniform sampler2D u_projectedTexture;
uniform float u_bias;
uniform float u_shininess;
uniform vec3 u_lightDirection;
uniform float u_innerLimit;
uniform float u_outerLimit;
//                                   no need to uniform at this sample
float u_shadowVisibility=0.5;
// to uniform -->
//uniform float u_shadowVisibility;//    shadow visibility
//                                              uniform location at init time
//var blabla=gl.getUniformLocation(program, "u_shadowVisibility");
//                                                          uniform at draw time
//gl.uniform1f(blabla, your value);//0.0-1.0    uniform <--

out vec4 outColor;
void main() 
{
  vec3 normal=normalize(v_normal);

  vec3 surfaceToLightDirection=normalize(v_surfaceToLight);
  vec3 surfaceToViewDirection=normalize(v_surfaceToView);
  vec3 halfVector=normalize(surfaceToLightDirection + surfaceToViewDirection);

  float dotFromDirection=dot(surfaceToLightDirection,-u_lightDirection);
  float limitRange=u_innerLimit - u_outerLimit;
  float inLight=clamp((dotFromDirection - u_outerLimit) / limitRange, 0.0, 1.0);
  float light=inLight * dot(normal, surfaceToLightDirection);
  float specular=inLight * pow(dot(normal, halfVector), u_shininess);

  // shadow -->
  vec3 projectedTexcoord=v_projectedTexcoord.xyz/v_projectedTexcoord.w;
  float currentDepth=projectedTexcoord.z+u_bias; 
  float projectedDepth=texture(u_projectedTexture, projectedTexcoord.xy).r; 
  bool inRange=projectedTexcoord.x>=0.0&&projectedTexcoord.x<=1.0&&projectedTexcoord.y>=0.0&&projectedTexcoord.y<=1.0;  
  //float shadowLight=(inRange&&projectedDepth<=currentDepth)?0.0:1.0;  
  float shadowLight=0.0;
  //              anti aliasing/pcf (percentage-closer filtering)
  vec2 texSize=vec2(1)/vec2(textureSize(u_projectedTexture, 0));
  int samples=6;
  for(int x=0;x<samples;++x){ for(int y=0;y<samples;++y)
  {
    float pcf=texture(u_projectedTexture, projectedTexcoord.xy+vec2(x, y)*texSize).r; 
    shadowLight+=inRange&&currentDepth>pcf?u_shadowVisibility:1.0;
  }}
  //     final scene brightnes. needs to be adjusted by the
  shadowLight/=9.0*4.0;//                  amount of samples
  //                 keep the shadow at 0.0 if outside of region
  if(projectedTexcoord.z>1.0)shadowLight=0.0;
  // shadow <--
  
  vec4 texColor=texture(u_texture, v_texcoord) * u_colorMult;
  outColor=vec4(texColor.rgb * light * shadowLight +specular * shadowLight,texColor.a);
}`;

last sample on the Website

var fs=`#version 300 es
precision highp float;
in vec2 v_texcoord;
in vec4 v_projectedTexcoord;
in vec3 v_normal;

uniform vec4 u_colorMult;
uniform sampler2D u_texture;
uniform sampler2D u_projectedTexture;
uniform float u_bias;
uniform vec3 u_reverseLightDirection;
//                                   no need to uniform at this sample
float u_shadowVisibility=0.5;
// to uniform -->
//uniform float u_shadowVisibility;//    shadow visibility
//                                              uniform location at init time
//var blabla=gl.getUniformLocation(program, "u_shadowVisibility");
//                                                          uniform at draw time
//gl.uniform1f(blabla, your value);//0.0-1.0    uniform <--

out vec4 outColor;
void main() 
{
  vec3 normal=normalize(v_normal); 
  float light=dot(normal, u_reverseLightDirection);
  
  // shadow -->
  vec3 projectedTexcoord=v_projectedTexcoord.xyz/v_projectedTexcoord.w;
  float currentDepth=projectedTexcoord.z+u_bias; 
  float projectedDepth=texture(u_projectedTexture, projectedTexcoord.xy).r; 
  bool inRange=projectedTexcoord.x>=0.0&&projectedTexcoord.x<=1.0&&projectedTexcoord.y>=0.0&&projectedTexcoord.y<=1.0;
  //float shadowLight=(inRange&&projectedDepth<=currentDepth)?0.0:1.0;  
  float shadowLight=0.0;
  //              anti aliasing/pcf (percentage-closer filtering)
  vec2 texSize=vec2(1)/vec2(textureSize(u_projectedTexture, 0));
  
  int samples=3;
  for(int x=0;x<samples;++x){ for(int y=0;y<samples;++y)
  {
    float pcf=texture(u_projectedTexture, projectedTexcoord.xy+vec2(x, y)*texSize).r; 
    shadowLight+=inRange&&currentDepth>pcf?u_shadowVisibility:1.0;
  }}
  //     final scene brightnes. needs to be adjusted by the
  shadowLight/=9.0;//                         amount of samples
  //                 keep the shadow at 0.0 if outside of region
  if(projectedTexcoord.z>1.0)shadowLight=0.0;
  // shadow <--
  
  vec4 texColor=texture(u_texture, v_texcoord)*u_colorMult;
  outColor=vec4(texColor.rgb*light*shadowLight,texColor.a);
}`;

@Khgiikbvhkbvv
Copy link

Pardon, from this website

https://webgl2fundamentals.org/webgl/lessons/webgl-shadows.html

@Khgiikbvhkbvv
Copy link

Pardon again...my bad. First code is for the spotligt sample, the second one for the sampe after.

Best regards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants