#RenderTarget.count with default materials

10 messages · Page 1 of 1 (latest)

teal crane
#

When changing renderTarget.count to > 1. What do I need to do to every default material for them to render as normally (as if there was single active write buffer). Now I get this into console:

[.WebGL-0x12c001e7300] GL_INVALID_OPERATION: glDrawArrays: Active draw buffers with missing fragment shader outputs.

The example is here:

https://stackblitz.com/edit/vitejs-vite-99xplpq8?file=src%2Fmain.ts

teal crane
#

I have just found out that: Default materials (MeshStandardMaterial, MeshPhongMaterial, etc.) are GLSL1-based. To write to multiple attachments in WebGL2 you need GLSL 3.00 ES layout(location=…) outputs; but you can’t switch a built-in material to GLSL3 via onBeforeCompile (that flag only exists on ShaderMaterial/RawShaderMaterial). So you’d be trying to graft GLSL3 features onto a GLSL1 shader, which won’t compile

worldly dune
#

You need to use glsl 3

new ShaderMaterial({
  glslVersion: THREE.GLSL3,
  ...
})

and manually define the outputs like so

layout(location = 0) out vec4 out1;
layout(location = 1) out vec4 out2;

void main() {
  out1 = vec4(...);
  out2 = vec4(...);
}
teal crane
#

Yeah, but will this won't work on default materials like MeshBasicMaterial, because it is GLSL1 based?

worldly dune
#

Correct but you should be able to override the defualts in onBeforeCompile let me see if i can modify your demo

teal crane
#

Hmm yeah that sounds promising.

worldly dune
#

Core concept - In onBeforeCompile,

Overwrite the glsl version

shader.glslVersion = THREE.GLSL3;

Define new output variables with layout

layout(location = 0) out vec4 custom_FragColor;
layout(location = 1) out vec4 custom_output2;

Replace every occurace of gl_FragColor to the the first (layout=0) output variable using string replacement

You will need to do this for evey material that is rendered to said render target

teal crane
#

Thank you so much man! I didn't know we can override glsl version on onBeforeCompile. 😄