Godot Version
4.2.2
Question
I am trying to add a Texture2D (a moon) to my Visual Sky Shader utilizing the SkyImageUV shader found here: Add a SkyImageUV node to render texture in a sky shader · Issue #3534 · godotengine/godot-proposals · GitHub
That shader on its own works exactly as intended and is perfect for my needs. However, I am having difficulty integrating it with my existing Visual Shader.
I played around a little with Expression and Global Expression nodes, but I’m not sure if that’s the right path. The Visual Shader Custom Node seems well-suited for this task, but I’m struggling at the finish line, specifically the syntax for _get_code for which I’m not finding a whole lot of examples to guide me, and the proposal itself from which I obtained the shader code is still open two years later.
Here is what I have so far, and would appreciate any pointers on how to complete OR how best to implement the SkyImageUV shader code if this is not even the right path:
@tool
extends VisualShaderNodeCustom
class_name VisualShaderNodeSkyImageUV
func _get_name():
return "SkyImageUV"
func _get_category():
return "VisualShaderExtras"
func _get_description():
return "Projects a 2D image into the skybox (by Ansraer)"
func _get_return_icon_type():
return VisualShaderNode.PORT_TYPE_VECTOR_4D
func _get_input_port_count():
return 4
func _get_input_port_name(port):
match port:
0:
return "rotation"
1:
return "altitude"
2:
return "imageSize"
3:
return "imageTexture"
func _get_input_port_type(port):
match port:
0:
return VisualShaderNode.PORT_TYPE_SCALAR
1:
return VisualShaderNode.PORT_TYPE_SCALAR
2:
return VisualShaderNode.PORT_TYPE_SCALAR
3:
return VisualShaderNode.PORT_TYPE_SAMPLER
func _get_outport_port_count():
return 1
func _get_output_port_name(port):
return "finalImage"
func _get_output_port_type(port):
return VisualShaderNode.PORT_TYPE_VECTOR_3D
func _get_global_code(mode):
return """
float map(float value, float srcMin, float srcMax, float destMin, float destMax){
return destMin + (value-srcMin) * (destMax-destMin) / (srcMax-srcMin);
}
mat3 rotation3dY(float angle) {
float s = sin(angle);
float c = cos(angle);
return mat3(
vec3(c, 0.0, -s),
vec3(0.0, 1.0, 0.0),
vec3(s, 0.0, c)
);
}
vec4 projImage(float _altitude, float _rot_x, float _viewVec_x, float _imageSize, sampler2D _image) {
if(_rot_x > _altitude-_imageSize && _rot_x < _altitude+_imageSize){
float xSizeFactor = 2.0*PI;
if(_viewVec_x > -_imageSize*xSizeFactor && _viewVec_x < _imageSize*xSizeFactor){
float v = map(_rot_x-_altitude, -_imageSize, _imageSize, 1.0, 0.0);
float u = map(_viewVec_x, -_imageSize*xSizeFactor, _imageSize*xSizeFactor, 0.0, 1.0);
return texture(_image, vec2(u, v));
}
}
return vec4(0.0);
}
vec4 skyImageProj(vec3 viewVec, float _rotation, float _altitude, float _imageSize, sampler2D _imageSampler) {
_altitude = fract(_altitude);
vec3 _EYEDIR = rotation3dY(_rotation) * viewVec;
//Since we applied the rotation directly to the viewVec we can just ingore it from now on.
//float rot_z = atan(_EYEDIR.y, _EYEDIR.x)/(2.0*PI)+0.5;
float rot_x = atan(_EYEDIR.y, _EYEDIR.z)/(2.0*PI)+0.5;
//float rot_y = atan(_EYEDIR.z, _EYEDIR.x)/(2.0*PI)+0.5;
vec4 result = projImage(_altitude, rot_x, _EYEDIR.x, _imageSize, _imageSampler);
//make sure the image isn't clipped when altitude approaches the max/min values
if(_altitude > 0.75) {
result = max(result, projImage(_altitude-1.0, rot_x, _EYEDIR.x, _imageSize, _imageSampler));
} else if (_altitude < 0.25) {
result = max(result, projImage(_altitude+1.0, rot_x, _EYEDIR.x, _imageSize, _imageSampler));
}
return result;
}
vec4 finalImage = skyImageProj(EYEDIR, rotation, altitude, imageSize, imageTexture);
"""
func _get_code(input_vars, output_vars, mode, type):
return output_vars[0] + " = vec4(0,0,0,0)" //This vec4 is just temporary to prevent errors
I have basically no idea what syntax is expected at the end to get the output. I can’t even get an output port to show up, let alone a functioning one.
I found another post that refers to converting input_ and output_vars to strings, but I’m still not quite wrapping my head around how to accomplish that.
Anyway, any pointers or corrections in my way of thinking would be much appreciated! Happy to do more reading, I just…don’t know what I don’t know?