-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
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
World_vertex_coords flag required in canvas_item shaders #19800
Comments
I don't fully understand matrix multiplication BUT... it looks like this is working except that It seems like you should be able to do something to An alternative is to just pass in
...and in your
|
This almost works but it seems to ignore camera position and zoom:
|
thanks @jotson for trying to solve this! I also ended up trying very matrix combo I could think of, but couldn't solve it. I think it is because it is missing the camera and inverse camera matrices that the spatial shader has. My knowledge of matrix math is very limited, so I am not sure. I also had tried feeding in the player position as a uniform. It does work , but it means you need a separate shader for each object that uses it, that is why I need a pure shader approach. I am trying to use it on my seaweed so that it would distort more and change colour as the player touched it. Btw, I did try the same idea in 3d with spatial shader and it works easily since it has the world vertex coords flag builtin. Am hoping that a smart dev sees this issue and adds this to canvas shader so that we don't have to worry about all the matrix math ourselves :) |
I started working on this today. It shouldn't be too big of a problem (famous last words). However, I ran into a bug (#23976) and ended up spending all my time on that. I want to document a few things in case I don't end up finishing this and someone takes over:
|
@clayjohn thanks so much for working on this! |
Here is my WIP branch implementing world_vertex_coords in canvas_item shaders. It is currently working in gles3. It was even more simple than I thought. It should not take much to add it to the gles2 branch. I am just going to move the matrix calculations out of the drivers. However, I am not sure that once I make a PR it will be merged into 3.1 as they have paused adding features, it may not even be merged for 3.2 as we work towards a new renderer. Accordingly, a work around for those of you that really want the functionality is to pass the global transform from the node into the shader as a uniform (this doesn't work now due to a bug, but is fixed with #23976).
Then, in your vertex shader:
|
Thanks @clayjohn . Looks very promising, so I hope that at least that bugfix will be added to 3.1. It would explain the strange results I was getting when passing in shader parameters. |
Just wanted to thank @clayjohn and also to bump this issue. Not to sing a sob story but I just spent several hours bug chasing before realizing that WORLD_MATRIX doesn't properly account for camera transforms in canvas shaders. At least this issue was easy to find. |
I'm sorry that happened to you! I also updated the docs to explain it as well http://docs.godotengine.org/en/latest/tutorials/shading/shading_reference/canvas_item_shader.html#vertex-built-ins. |
@clayjohn Thanks as well for the work-around! A bit of a pity that this has been dropped from 3.2. Here's a slight extension of the work-around: What makes the work-around tedious at first is that the shader preview in the editor doesn't work, and that duplicating any object requires a "make unique" on the material. It looks like this can be automated by a small variation: tool
extends Sprite
func _ready():
print("Duplicating material")
material = material.duplicate()
func _process(_delta):
material.set_shader_param("global_transform", get_global_transform()) |
Feature and improvement proposals for the Godot Engine are now being discussed and reviewed in a dedicated Godot Improvement Proposals (GIP) (godotengine/godot-proposals) issue tracker. The GIP tracker has a detailed issue template designed so that proposals include all the relevant information to start a productive discussion and help the community assess the validity of the proposal for the engine. The main (godotengine/godot) tracker is now solely dedicated to bug reports and Pull Requests, enabling contributors to have a better focus on bug fixing work. Therefore, we are now closing all older feature proposals on the main issue tracker. If you are interested in this feature proposal, please open a new proposal on the GIP tracker following the given issue template (after checking that it doesn't exist already). Be sure to reference this closed issue if it includes any relevant discussion (which you are also encouraged to summarize in the new proposal). Thanks in advance! |
Any status updates on this? It has been closed but no solution has been provided as far as I can see. |
There is a ugly solution "Duplicating material" "Passing global transform every frame" |
|
Very very good.Can not wait any longer. Thanks the Godot members~ |
sorry, I don't seem to get it work. I try to draw a SDF for a polygon, based on screen coordinates. func _ready() -> void:
print("Duplicating material")
material = matFrame.duplicate()
func _process(delta) -> void:
if is_inside_tree():
var vx = [];
for v in polygon:
vx.append(get_global_transform().xform_inv(v));
material.set_shader_param('v0', vx[0])
material.set_shader_param('v1', vx[1])
material.set_shader_param('v2', vx[2])
material.set_shader_param('v3', vx[3]) and a canvas shader with: uniform vec2 v0;
uniform vec2 v1;
uniform vec2 v2;
uniform vec2 v3;
float distToLine(vec2 p, vec2 q, vec2 a) {
vec2 pq = q - p;
vec2 n = normalize(vec2(pq.y, -pq.x));
vec2 pa = a - p;
return abs(dot(n, pa));
}
void fragment() {
vec2 fx = FRAGCOORD.xy;
float d = distToLine(v0, v1, fx);
d = min(d, distToLine(v1, v2, fx));
d = min(d, distToLine(v2, v3, fx));
d = min(d, distToLine(v3, v0, fx));
COLOR.rgb = vec3( d / 250.0);
} but somehow it's still dependent on the position in the screen: https://i.imgur.com/ldVlPSV.mp4 any hints? (apart from the fact that the SDF is actually unsigned and wrong :-) |
oof this is still very annoying, as its not feasible to pass the Global transform to every tile in a tilemap this makes it basically impossible to sample textures bigger than the individual tiles, based on world position. it's fine, you guys are doing amazing work, i'm just malding yk |
I came here looking for a way to get world position in the fragment function. I've found a simple solution here by using a shader_type spatial;
render_mode specular_schlick_ggx;
varying vec3 worldPos;
void vertex() {
vec4 worldPos4 = WORLD_MATRIX * vec4(VERTEX, 1);
worldPos = worldPos4.xyz / worldPos4.w;
}
void fragment() {
// use `worldPos` here
} |
As far as I understand, you don't have to. Multiplying with Here is how to pass the correct matrix:
Here how the transformation in the shader should look like:
Note, that I declared the I think |
Sorry to resurrect the old issue that is closed, I am unsure how global uniform in Godot 4 actually resolves the issue here with the camera. Or is it any other feature added that helps with the issue here. Are there any examples in the documentation on how to do that ? I could not find any. |
Implemented by #81160. |
Godot version:
3.0.3/3.0.4
OS/device including version:
Issue description:
After many attempts to get world space coordinates for the vertex and fragment shaders in a canvas item shader, I have come to the conclusion that it is not possible, without resorting to shader parameter hacks.(If I am wrong then please let me know!).
With spatial shaders it is very easy to do by turning on the render_mode "world_vertex_coords" and it works perfectly without having to play around with multiplying matrices.
Would be great to have this option for canvas_item shaders as well. After much googling and asking the community, there seems to be a lot of confusion on this matter and it is a much needed option.
Steps to reproduce:
Minimal reproduction project:
world_pos_canvas.zip
The text was updated successfully, but these errors were encountered: