Closed DefaultV closed 2 years ago
Can you include your useEffect code that sets the texture?
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);
}, []);
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) />
}
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.
It seems to be trying to load the html file contents no matter what. Might be related.
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
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.
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>
)}
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!
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:
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.