godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.36k stars 21.25k forks source link

MODEL_MATRIX cannot be modified from the vertex stage #74568

Open QbieShay opened 1 year ago

QbieShay commented 1 year ago

Godot version

4.0 stable official

System information

Fedora, X11, RX 590

Issue description

When trying to assign anything to MODEL_MATRIX in my shader, it says "constants cannot be modified" but it's marked as inout in the documentation: https://docs.godotengine.org/en/stable/tutorials/shaders/shader_reference/spatial_shader.html

image

Steps to reproduce

Create a shader, paste this code:

// NOTE: Shader automatically converted from Godot Engine 4.0.stable's StandardMaterial3D.

shader_type spatial;
render_mode blend_mix,depth_draw_opaque,cull_back,diffuse_burley,specular_schlick_ggx;
uniform vec4 albedo : source_color;
uniform sampler2D texture_albedo : source_color,filter_linear_mipmap,repeat_enable;
uniform float point_size : hint_range(0,128);
uniform float roughness : hint_range(0,1);
uniform sampler2D texture_metallic : hint_default_white,filter_linear_mipmap,repeat_enable;
uniform vec4 metallic_texture_channel;
uniform sampler2D texture_roughness : hint_roughness_r,filter_linear_mipmap,repeat_enable;
uniform float specular;
uniform float metallic;
uniform int particles_anim_h_frames;
uniform int particles_anim_v_frames;
uniform bool particles_anim_loop;
uniform vec3 uv1_scale;
uniform vec3 uv1_offset;
uniform vec3 uv2_scale;
uniform vec3 uv2_offset;

void vertex() {
    UV=UV*uv1_scale.xy+uv1_offset.xy;

    MODEL_MATRIX = mat4(1.0);
    float h_frames = float(particles_anim_h_frames);
    float v_frames = float(particles_anim_v_frames);
    float particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);
    float particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));
    if (!particles_anim_loop) {
        particle_frame = clamp(particle_frame, 0.0, particle_total_frames - 1.0);
    } else {
        particle_frame = mod(particle_frame, particle_total_frames);
    }
    UV /= vec2(h_frames, v_frames);
    UV += vec2(mod(particle_frame, h_frames) / h_frames, floor((particle_frame + 0.5) / h_frames) / v_frames);
}

void fragment() {
    vec2 base_uv = UV;
    vec4 albedo_tex = texture(texture_albedo,base_uv);
    ALBEDO = albedo.rgb * albedo_tex.rgb;
    float metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);
    METALLIC = metallic_tex * metallic;
    vec4 roughness_texture_channel = vec4(1.0,0.0,0.0,0.0);
    float roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);
    ROUGHNESS = roughness_tex * roughness;
    SPECULAR = specular;
}

Observe the error

Minimal reproduction project

see above

clayjohn commented 1 year ago

I think this is a documentation issue. The MODEL_MATRIX isn't used after the vertex shader and it doesn't carry over to the fragment shader. So the fact that it was previously writable was pretty misleading. I ended up making it const in https://github.com/godotengine/godot/pull/66178 to avoid the issue where users right to it and their write gets ignored