Nockawa

Grid Material lacks receiveShadows

Recommended Posts

This one is for @Sebavan, I use this material (a lot) and I would really appreciate if it could receive cast shadows. Currently I'm creating two surfaces displayed alpha blended, a second one with a standard material to display the shadows but Depth Fight occurs a lot and it's not something I can solve by tweaking as I have many different scales in many different objects.

Could you tell me if it's something that can be done without much trouble and could be in future (beta, near ? :) ) releases? Or if it's too much work that I have to lost hope on it?

Maybe you have a more tangible workaround in the meantime? I'm playing with zOffset in the Material and the scale of the second surface, but it's not working 100%...

Thanks !

 

Share this post


Link to post
Share on other sites

Hello 🙂

This could be added to the material by taking example on the shadow only material. basically mixing the shadowonlymaterial code in the gridmaterial.

The main issue would then be to support lights in the material cause shadows without lit area might give weird results.

 

 

Share this post


Link to post
Share on other sites

I have no way of validating this script but I figured id post it for someone with more time then me at this moment.

 

#extension GL_OES_standard_derivatives : enable

#define SQRT2 1.41421356
#define PI 3.14159

precision highp float;

uniform vec3 mainColor;
uniform vec3 lineColor;
uniform vec4 gridControl;
uniform vec3 gridOffset;

uniform vec3 vEyePosition;
uniform float alpha;

// Varying
#ifdef TRANSPARENT
varying vec4 vCameraSpacePosition;
#endif
varying vec3 vPosition;
varying vec3 vNormal;

#include<__decl__lightFragment>[0..maxSimultaneousLights]
#include<lightsFragmentFunctions>
#include<shadowsFragmentFunctions>
#include<clipPlaneFragmentDeclaration>

#include<fogFragmentDeclaration>

float getVisibility(float position) {
    // Major grid line every Frequency defined in material.
    float majorGridFrequency = gridControl.y;
    if (floor(position + 0.5) == floor(position / majorGridFrequency + 0.5) * majorGridFrequency)
    {
        return 1.0;
    }  

    return gridControl.z;
}

float getAnisotropicAttenuation(float differentialLength) {
    const float maxNumberOfLines = 10.0;
    return clamp(1.0 / (differentialLength + 1.0) - 1.0 / maxNumberOfLines, 0.0, 1.0);
}

float isPointOnLine(float position, float differentialLength) {
    float fractionPartOfPosition = position - floor(position + 0.5); // fract part around unit [-0.5; 0.5]
    fractionPartOfPosition /= differentialLength; // adapt to the screen space size it takes
    fractionPartOfPosition = clamp(fractionPartOfPosition, -1., 1.);
    
    float result = 0.5 + 0.5 * cos(fractionPartOfPosition * PI); // Convert to 0-1 for antialiasing.
    return result;    
}

float contributionOnAxis(float position) {
    float differentialLength = length(vec2(dFdx(position), dFdy(position)));
    differentialLength *= SQRT2;  // Multiply by SQRT2 for diagonal length
    
    // Is the point on the line.
    float result = isPointOnLine(position, differentialLength);

    // Add dynamic visibility.
    float visibility = getVisibility(position);
    result *= visibility;
    
    // Anisotropic filtering.
    float anisotropicAttenuation = getAnisotropicAttenuation(differentialLength);
    result *= anisotropicAttenuation;
    
    return result;
}

float normalImpactOnAxis(float x) {
    float normalImpact = clamp(1.0 - 3.0 * abs(x * x * x), 0.0, 1.0);
    return normalImpact;
}

void main(void) {
    #include<clipPlaneFragment>
    vec3 viewDirectionW=normalize(vEyePosition-vPositionW);
    
    #ifdef NORMAL
        vec3 normalW=normalize(vNormalW);
    #else
        vec3 normalW=vec3(1.0,1.0,1.0);
    #endif

    // Scale position to the requested ratio.
    float gridRatio = gridControl.x;
    vec3 gridPos = (vPosition + gridOffset) / gridRatio;
    
    // Find the contribution of each coords.
    float x = contributionOnAxis(gridPos.x);
    float y = contributionOnAxis(gridPos.y);
    float z = contributionOnAxis(gridPos.z);
    
    // Find the normal contribution.
    vec3 normal = normalize(vNormal);
    x *= normalImpactOnAxis(normal.x);
    y *= normalImpactOnAxis(normal.y);
    z *= normalImpactOnAxis(normal.z);
    
    // Create the grid value by combining axis.
    float grid = clamp(x + y + z, 0., 1.);
    
    // Create the color.
    vec3 color = mix(mainColor, lineColor, grid);

#ifdef FOG
    #include<fogFragment>
#endif

#ifdef TRANSPARENT
    float distanceToFragment = length(vCameraSpacePosition.xyz);
    float cameraPassThrough = clamp(distanceToFragment - 0.25, 0.0, 1.0);

    float opacity = clamp(grid, 0.08, cameraPassThrough * gridControl.w * grid);
   
    vec3 diffuseBase=vec3(0.,0.,0.);
    lightingInfo info;
    float shadow=1.;
    float glossiness=0.;
    #include<lightFragment>[0..1];
    
    float sVal = (1.0-clamp(shadow,0.,1.))*alpha;    

    gl_FragColor = vec4(mix(color.rgb, vec3(0.), sVal), opacity);

    #ifdef PREMULTIPLYALPHA
        gl_FragColor.rgb *= opacity;
    #endif
#else
    // Apply the color.
    gl_FragColor = vec4(color.rgb, 1.0);
#endif
}



-------------------------------------

precision highp float;

// Attributes
attribute vec3 position;
attribute vec3 normal;

// Uniforms
uniform mat4 projection;
uniform mat4 world;
uniform mat4 view;
uniform mat4 worldView;

// Varying
#ifdef TRANSPARENT
    varying vec4 vCameraSpacePosition;
#endif
varying vec3 vPosition;
varying vec3 vNormal;

#include<fogVertexDeclaration>

void main(void) {

    #ifdef FOG
    vec4 worldPos = world * vec4(position, 1.0);
    #endif

    #include<fogVertex>
    #include<shadowsVertex>[0..maxSimultaneousLights]

    vec4 cameraSpacePosition = worldView * vec4(position, 1.0);
    gl_Position = projection * cameraSpacePosition;

    #ifdef TRANSPARENT
        vCameraSpacePosition = cameraSpacePosition;
    #endif

    vPosition = position;
    vNormal = normal;
}


If it is valid then here is the PR:
https://github.com/BabylonJS/Babylon.js/pull/4684

Share this post


Link to post
Share on other sites

Ideally I'd like the surface area where there's no line not to be transparent at all, but be able to set an opacity level and have shadow casted there. I didn't have time to check your progress, I really have to go to bed right now, I'll check tomorrow first in the morning.

Thanks all for your help!

Share this post


Link to post
Share on other sites

Wow @NasimiAsl I just saw your last PG, it looks awesome ! I believe I going to try and import your shader code directly in my project and see if it works so well (no reason it shouldn't), many thanks to you! It just would take 1 to 2 days, currently the code path using the grid material with shadow is being rewritten and I need to finish it to get result on screen.

I couldn't take time to go down in customizing shaders again, I've not done that for a moment, it got GC out of my brain since a while.. :)

Share this post


Link to post
Share on other sites

@NasimiAsl thanks again for your help, I've tried your version of the Grid Material and apparently the lighting is not behaving the same.

You can take a look at this modified version of your PG: https://www.babylonjs-playground.com/#UXCB15#52, comment line 167 to enable your material. I took a quick look but couldn't find why there's a difference..

Thanks

Share this post


Link to post
Share on other sites
mm you most check this parameter
 
material.getEffect().setVector3('mainColor',
new BABYLON.Vector3(1,0.5,0.));
material.getEffect().setVector3('lineColor',
new BABYLON.Vector3(0,0.5,1.));
material.getEffect().setVector4('gridControl',new BABYLON.Vector4(0.5,0.0,1.,0.));
material.getEffect().setVector3('gridOffset',new BABYLON.Vector3(1,0.5,0.));
 
gridControl is important setting 
but for correct answer i most ping @Sebavan
 

Share this post


Link to post
Share on other sites

yes, I did, I look at the Material's implementation on GitHub to know how to set the gridControl parameter, and in the PG I gave the settings of both your custom material and the Grid Material are the same (at least for the grid settings).

Share this post


Link to post
Share on other sites

These are the settings to change the Grid line spacing.

I'm talking about the color of the material, look at the screenshot below

image.thumb.png.670add1d81a82449fbf51380e407f0fb.png

Left part is your shader, right part is the GridMaterial, it's much brighter.v

Share this post


Link to post
Share on other sites

dear @Nockawa

that is result with out light and shadow https://www.babylonjs-playground.com/#UXCB15#57 use with customMaterial

so i think the light change that same as standard material

but you can channage it before fragcolor too 

material.Fragment_Before_FragColor(`
float f1 = 1.2;
if(vPositionW.x > 0.){
color.x = pow(color.x,f1)*f1;
color.y = pow(color.y,f1)*f1;
color.z = pow(color.z,f1)*f1;
color.w = 1.;
}
 
 
`);
 

Share this post


Link to post
Share on other sites

ok thank you, I now understand better. I think the GridMaterial's implementation has a different lighting model, more simple than Standard/Custom material.

I'll try take a closer look at how I could emulate the same result.

Thanks again for you help, time and patience!

Share this post


Link to post
Share on other sites

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

  • Recently Browsing   0 members

    No registered users viewing this page.