Jump to content

Grid Material lacks receiveShadows


Nockawa
 Share

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 !

 

Link to comment
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.

 

 

Link to comment
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

Link to comment
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!

Link to comment
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.. :)

Link to comment
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

Link to comment
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
 
Link to comment
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.;
}
 
 
`);
 
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...