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

Shader issues, setting the sampler texture and visual bugs #177

Closed
DefaultV opened this issue Nov 26, 2021 · 7 comments
Closed

Shader issues, setting the sampler texture and visual bugs #177

DefaultV opened this issue Nov 26, 2021 · 7 comments

Comments

@DefaultV
Copy link

Hello! I'm currently trying to setup a shader (shaderMaterial) for my application.

The shader basically takes an image and makes it blurry and transparent. I've stored these shaders locally as *.vertex/fragment.fx files.

I can load it via the following example:

return (
    <plane name="shadow" position={position} width={width} height={height}>
      <shaderMaterial
        ref={shaderRef}
        name="artworkShadow"
        shaderPath="/shaders/shadowShader"
        options={{
          needAlphaBlending: true,
          attributes: ["position", "normal", "uv"],
          uniforms: [
            "world",
            "worldView",
            "worldViewProjection",
            "view",
            "projection",
          ],
        }}
      >
      </shaderMaterial>
    </plane>
  );

Then in a useEffect I set the sampler texture. (Bonus question, how do I set this sampler texture declaratively?)
The component is a child to other components.

The shader code works fine when used in the babylon playground.

However, the sample texture it ends up using switches between multiple others. It seems to switch depending on the angle the camera is viewing the plane from and seemingly random textures that are loaded into the scene. I hope this is enough information to go on, I cannot really share more of the sourcecode.

@brianzinn
Copy link
Owner

Can you include your useEffect code that sets the texture?

@DefaultV
Copy link
Author

Here's the useEffect, however, even if I comment out this code, the textureSampler still gets set somehow (sampler2D textureSampler in the shader code)

useEffect(() => {
    shaderRef.current.setTexture(
      "textureSampler",
      new Texture(textureUrl, scene)
    );
    console.log(textureUrl);
  }, []);

@brianzinn
Copy link
Owner

Is the "textureSampler" just an example - It's supposed to match the name of a uniform sampler as defined in the shader isn't it? Otherwise if you can share a playground example that does work and then I can work my way backwards.

Setting declaratively I do not see a good way, because there is no property to set it to without first getting a Ref.

<texture ref={textureRef ...>
...
<shaderMaterial ... setTexture{['textureSample', textureRef.current]} />

What I do is destructure that array and pass it to setTexture. It will call on every render though unfortunately, because I don't don't check equality well.

shaderMaterialInstance['setTexture'](...values);

What would work though is if you use an array from a ref because it would match the equality check. This would also mean the texture is loaded before being assigned.

const textureArrayRef = useRef(null);

// once texture is loaded
textureArrayRef.current = ['textureSample', textureRef.current];

textureArrayRef.current && {
  <shaderMaterial ... setTexture(textureArrayRef.current) />
}

@DefaultV
Copy link
Author

I've tried to replicate the bug here, however, it seems there's an issue with loading the shader from the path. The branch is here:
https://github.com/DefaultV/create-react-app-typescript-babylonjs/tree/Bug-shaderPath

I get the following error.

image

It seems to be trying to load the html file contents no matter what. Might be related.

@brianzinn
Copy link
Owner

You got it - you just need to delete the homepage in your package.json - or otherwise include that as part of the base_url if you want to deploy like I do to a sub folder (like github pages requires). In which case, you just need to add to your paths process.env.PUBLIC_URL as follows:
https://github.com/brianzinn/create-react-app-babylonjs/blob/master/src/withSkybox.js#L11

If you wanted some help with declaratively adding textures to the shader that would make a good storybook.

Also, if you want to load shaders without HTTP requests have a look at VaporWave procedural texture:
https://github.com/brianzinn/react-babylonjs/blob/master/storybook/stories/babylonjs/Integrations/pixi-demo/VaporWave.js

@DefaultV
Copy link
Author

DefaultV commented Dec 1, 2021

Thanks for the tip, alright, I think we're at the reproducible stage now, however it doesn't seem to switch between multiple textures but, it does seem to only apply the only most recent texture to the sampler even though specified otherwise.

image

The checkerboard was loaded last, the dog should be the applied sampler (Top-left is the plane with the shader material, so that should have a dog too)

Same branch, the file is planeShader.tsx
https://github.com/DefaultV/create-react-app-typescript-babylonjs/tree/Bug-shaderPath
https://github.com/DefaultV/create-react-app-typescript-babylonjs/blob/Bug-shaderPath/src/planeShader.tsx

textureArrayRef.current = ["textureSample", textureRef.current];
{textureArrayRef.current && (
<shaderMaterial
    name="artworkShadow"
    shaderPath="/shaders/shadowShader"
    setTexture={textureArrayRef.current}
    options={{
        needAlphaBlending: true,
        attributes: ["position", "normal", "uv"],
        uniforms: [
            "world",
            "worldView",
            "worldViewProjection",
            "view",
            "projection",
        ],
    }}
></shaderMaterial>
)}

@DefaultV
Copy link
Author

I got this to work in my other project. It was seemingly due to folder hierarchies.
What I did in the end was to make sure all naming conventions were correct and renamed the sampler, instead of textureSampler I put MAIN_TEXTURE. I know this doesn't seem like it should fix it, but it did somehow.

You can close the issue if you want =) Thanks for the aid!

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

2 participants