|
|
|
|
Reply From: |
SIsilicon |
It could about an hour to come up with the answer. So if there’s a bug, let me know.
The Script
tool
extends Node
var mat
var light
func _ready():
mat = $MeshInstance.get_surface_material(0)
light = $SpotLight
func _process(delta):
var trans = light.global_transform
var fov = light.spot_angle
var far = light.spot_range
var proj = Vector3(1/tan(fov/2 * PI/180), 0.01, far)
mat.set_shader_param("lightMatrix", trans)
mat.set_shader_param("projvals", proj)
Put this in as a GDscript in some node. Preferably the scene’s root node.
The Shader
shader_type spatial;
render_mode world_vertex_coords;
uniform sampler2D tex;
uniform mat4 lightMatrix;
uniform vec3 projvals;
uniform float scale = 2.0;
varying vec4 UVtex;
varying float facing;
void vertex() {
float n = projvals.y;
float f = projvals.z;
mat4 projection = mat4(vec4(projvals.x, 0, 0, 0),
vec4(0, projvals.x, 0, 0),
vec4(0, 0, -f/(f-n), -1),
vec4(0, 0, -(f*n)/(f-n), 0));
UVtex = projection * inverse(lightMatrix) * vec4(VERTEX,1.0);
vec3 lightpos = lightMatrix[3].xyz;
facing = max(dot(normalize(lightpos - VERTEX), NORMAL), 0.0);
}
void light() {
vec4 proj = UVtex.xyzw / UVtex.w;
bool outofbounds = proj.z <= -1.0 || proj.z >= 1.0;
if( !outofbounds ) {
proj.xy = proj.xy * 0.25 + 0.5;
proj.y = 1.0 - proj.y;
proj.xy *= scale;
vec4 texproj = textureProj(tex, proj);
DIFFUSE_LIGHT += LIGHT_COLOR * ATTENUATION * ALBEDO * texproj.rgb*texproj.a * facing;
}
}
Put this in as a shader in a shader material. The shader material shall be the material of your mesh that’ll be illuminated.
How to use
You will now need to change some stuff so that these will work for your project.
In the script, change the node reference of the light variable to that of yours. Has to be a spotlight. Also change the material reference of the mat variable. Just like the light var, but you not only must assign the node reference, but you must also retrieve the material from that mesh instance. Eg: $MeshInstance.get_surface_material(0)
Save your scene then revert it so that the script runs in the editor.
Then you can change the tex parameter in the shader material to the texture of your choice. And the scale parameter for how much of the texture you see.
WARNING!!! THE THE SYSTEM WILL BREAK WITH MORE THAN ONE LIGHT SOURCE!