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

Add basic support to evaluate operator value in shader language #93822

Merged
merged 1 commit into from
Sep 9, 2024

Conversation

Chaosus
Copy link
Member

@Chaosus Chaosus commented Jul 1, 2024

This PR adds a basic set of evaluator functions to the shader language. This might be needed in some places, like an array initialization. After this PR got merged, user may define and use basic constant expression like:

shader_type spatial;

const int ARRAY_SIZE = 1 + (9 / 3); // evaluates to 4

void fragment() { 
	int array[ARRAY_SIZE] = {0, 0, 0, 0}; // correct
}

Also, I've fixed parse_array_size function to allow declaring expression inside it:

shader_type spatial;

void fragment() {
	int array[1 + 2 / 2] = {0, 0}; // correct
}

Also, constant may be used like this:

shader_type spatial;

const int SIZE = 3;

void fragment() {
	int array[SIZE + SIZE] = {0, 0, 0, 0, 0, 0}; // correctly evaluates to 6
}

Besides array size, the expressions can now be passed to specific built-in functions:

const int SIZE = 1;

textureGather(sampler, vec2(0.0), SIZE + 1); // OK
textureGather(sampler, vec2(0.0), SIZE + 4); // FAILED (must be within 0..3 range)

Note, the advanced constant constructions like:

const int ARRAY_SIZE = ivec2(1, 0).x;

void fragment() {
	int array[ARRAY_SIZE] = {0};
}

still doesn't work, I may improve it lately.

PS: Yes, I renamed ShaderLanguage::ConstantNode::Value to ShaderLanguage::Scalar because it fits better and other nodes may use it, not only constant node (currently an OperatorNode will also start to use it).

@Chaosus Chaosus requested a review from a team as a code owner July 1, 2024 16:33
@Chaosus Chaosus added this to the 4.4 milestone Jul 1, 2024
@Chaosus Chaosus force-pushed the shader_constant_parsing branch 21 times, most recently from 0351bae to 775917a Compare July 8, 2024 16:19
@Chaosus Chaosus force-pushed the shader_constant_parsing branch 5 times, most recently from 421b199 to 619642d Compare July 9, 2024 12:32
Copy link
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally, it works as expected in all rendering methods. Thanks for improving the error reporting on mismatched array sizes too 🙂

image

shader_type canvas_item;

void fragment() {
	const int SIZE = 1 + 2;
	int items[SIZE] = { 1, 2, 3 };

	int items2[SIZE + 1] = { 1, 2, 3, 4 };
	int items3[SIZE * 2] = { 1, 2, 3, 4, 5, 6 };

	COLOR.gb *= float(items3[5]) * 0.1;

	// Not valid, as it needs to be a constant.
	//int dyn = 3;
	//int items_dyn[SIZE + dyn] = { 1, 2, 3, 4, 5, 6 };
}

@Chaosus Chaosus force-pushed the shader_constant_parsing branch from 0ecd207 to af92fdb Compare September 9, 2024 12:12
@akien-mga akien-mga merged commit 9fa3226 into godotengine:master Sep 9, 2024
20 checks passed
@akien-mga
Copy link
Member

Thanks!

@geekley
Copy link

geekley commented Sep 21, 2024

If I understand correctly, I assume the code in this PR may be useful to solve #96504 as well... can I get a confirmation?

@Chaosus
Copy link
Member Author

Chaosus commented Sep 23, 2024

@geekley Well, technically preprocessor and shader language are in separate files and in order to work together they need to use a single header and all that evaluations needs to be done in it. Need to spend another several hours for that..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Can't use calculated constant as array size in shader
4 participants