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

Lack of MRT support in ShaderLab #2373

Open
Sway007 opened this issue Sep 10, 2024 · 8 comments · Fixed by #2452
Open

Lack of MRT support in ShaderLab #2373

Sway007 opened this issue Sep 10, 2024 · 8 comments · Fixed by #2452
Assignees
Labels
enhancement New feature or request high priority High priority issue Rendering Rendering related functions shader Shader related functions
Milestone

Comments

@Sway007
Copy link
Member

Sway007 commented Sep 10, 2024

Is your feature request related to a problem? Please describe.

Currently developer can only specify multiple render target using gl_FragData with glsl100 syntax, but gl_FragData is not supported in WebGL2.

In Unity ShaderLab, you specify mrt by sematic keywords SV_Target, SV_Target0, SV_Target1, ...

fixed4 frag (v2f i) : SV_Target
{
    return fixed4(i.uv, 0, 0);
}

// or wrapped in struct
struct fragOutput {
    fixed4 color : SV_Target;
    fixed4 color1 : SV_Target1;
};
fragOutput frag (v2f i)
{
    fragOutput o;
    o.color = fixed4(i.uv, 0, 0);
    o.color1 = fixed4(i.uv, 1, 0);
    return o;
}

Describe the solution you'd like

A complete MRT support in WebGL1 and Webgl2

Syntax

...
// webgl1
void main(v2f input) {
   // mrt
  gl_FragData[0] = vec4(1.,2.,3.,4.);
  gl_FragData[1] = vec4(1.,2.,3.,4.);

  // normal
  gl_FragColor = vec4(1.0);
}

// webgl2
// normal
vec4 main(v2f input) {
  vec4 color = vec4(1.0);
  return color;
}

// mrt
struct mrt {
  layout(location = 0) vec4 fragColor0;
  layout(location = 1) vec4 fragColor1;
}

mrt main(v2f input) {
  mrt output;
  output.fragColor0= xxx;
  output.fragColor1 = xxxx;
  return output;
}
...

All syntax above are supported.

the properties of output struct in fragment shader must all be vec4 property qualified by layout and location.

@Sway007 Sway007 added enhancement New feature or request shader Shader related functions high priority High priority issue labels Sep 10, 2024
@Sway007 Sway007 added this to the 1.4 milestone Sep 10, 2024
@Sway007 Sway007 self-assigned this Sep 10, 2024
@Sway007 Sway007 added the Rendering Rendering related functions label Sep 10, 2024
@zhuxudong
Copy link
Member

zhuxudong commented Sep 10, 2024

得指定 layout, 你这里 struct 是无序的,webgl 里面是有序的
image

参考下 WebGL2:

layout(location=${index})

WebGPU:

@group(0) @binding(0)

@Sway007
Copy link
Member Author

Sway007 commented Sep 10, 2024

默认第一个属性layout location就是0,剩下的索引依次递增不行吗?如果要加索引这里mrt的struct语法就要变,跟常用的struct语法不一致,没必要增加语法复杂度啊

@zhuxudong
Copy link
Member

默认第一个属性layout location就是0,剩下的索引依次递增不行吗?如果要加索引这里mrt的struct语法就要变,跟常用的struct语法不一致,没必要增加语法复杂度啊

那照你这个设计应该是数组,不是 struct

@zhuxudong
Copy link
Member

mrt 的指定可以是缺省的,比如只绑定 1 和 3, 我不用2

@Sway007
Copy link
Member Author

Sway007 commented Sep 10, 2024

默认第一个属性layout location就是0,剩下的索引依次递增不行吗?如果要加索引这里mrt的struct语法就要变,跟常用的struct语法不一致,没必要增加语法复杂度啊

那照你这个设计应该是数组,不是 struct

根据glsl300的标准,fragment shader的输出除了vec4类型用作mrt,还可以是 uint,数组没法满足这些场景场景
image

@Sway007
Copy link
Member Author

Sway007 commented Sep 10, 2024

mrt 的指定可以是缺省的,比如只绑定 1 和 3, 我不用2

第2个属性你不赋值操作就好了呀

@Sway007
Copy link
Member Author

Sway007 commented Sep 12, 2024

核实了下,glsl300标准里确实没有明确说明MRT的场景下layout location的指定可以省略,实际测试会编译报错提示,之前受ChatGPT误导了
image
image

@Sway007 Sway007 mentioned this issue Dec 5, 2024
3 tasks
@Sway007 Sway007 linked a pull request Dec 5, 2024 that will close this issue
3 tasks
@zhuxudong
Copy link
Member

zhuxudong commented Dec 12, 2024

WebGL 1.0

// fragData 和 FragColor 不能混用
gl_FragColor = ***;
gl_FragData[0] = ***;

image

WebGL 2.0

// 必须强制指定或者只有一个 out
layout(location = 0) out vec4 fragColor;
void main(){}
out vec4 color;
// 必须同时指定,否则报错
out vec4;
layout(location = 1) out vec4;

ShaderLab

struct mrt {
  layout(location = 0) vec4 fragColor0;
  layout(location = 1) vec4 fragColor1;
}

mrt main(){
 	mrt output;
  // 警告 + 编译报错:只能针对 MRT
  output.fragColor0 = xxx;
  output.fragColor1 = xxxx;
  
 	// gl_FragColor = ***;
  // gl_FragData[1] = ***;  
  
  return output;
}

vec4 main(){
  // 警告 + 编译报错: 只能针对 color
	// gl_FragColor = ***;
   gl_FragData[0] = ***;
   return color;
}

void main(){
   // 组合情况会 警告 + 编译报错:不能混用
   // @todo: 组合情况下, 编译到 glsl 是否需要报错?
	 gl_FragColor = ***;
   gl_FragData[0] = ***;  
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request high priority High priority issue Rendering Rendering related functions shader Shader related functions
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants