diff options
author | IRIE Shinsuke <irieshinsuke@yahoo.co.jp> | 2013-11-25 15:58:23 +0400 |
---|---|---|
committer | IRIE Shinsuke <irieshinsuke@yahoo.co.jp> | 2013-11-25 17:19:47 +0400 |
commit | ab9822eff8865846d3c7ef81ff30cc35cb48ae0c (patch) | |
tree | 0955c1502f6f0327f59a3dd430c251378ba64c7c /source/blender/gpu | |
parent | 33bc6a3959b4f59f6ded304b5db06733653051cd (diff) |
Blender Internal: Add "Lamp Data" shader node that allows shaders to acquire information such as light vector from specified Lamp.
For now this provides the following outputs:
- Color
- Light Vector
- Distance
- Shadow
- Visibility Factor
Note: Color output is multiplied by the lamp energy. Multiplication of
color*max(dot(light_vector,normal_vector),0)*shadow*visibility_factor
produces the exact same result as the Lambert shader.
Many thanks to Brecht for code review and discussion!
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/GPU_material.h | 2 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_material.c | 47 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_material.glsl | 33 |
3 files changed, 82 insertions, 0 deletions
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 29da72a00fe..8c4c7d47558 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -133,6 +133,7 @@ void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double tim void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float obcol[4], float autobumpscale); void GPU_material_unbind(GPUMaterial *material); int GPU_material_bound(GPUMaterial *material); +struct Scene *GPU_material_scene(GPUMaterial *material); void GPU_material_vertex_attributes(GPUMaterial *material, struct GPUVertexAttribs *attrib); @@ -244,6 +245,7 @@ void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float ener void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2); void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend); int GPU_lamp_shadow_layer(GPULamp *lamp); +GPUNodeLink *GPU_lamp_get_data(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **col, GPUNodeLink **lv, GPUNodeLink **dist, GPUNodeLink **shadow); #ifdef __cplusplus } diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index ed7a2f4ede0..8e7194bb4a1 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -355,6 +355,11 @@ int GPU_material_bound(GPUMaterial *material) return material->bound; } +Scene *GPU_material_scene(GPUMaterial *material) +{ + return material->scene; +} + void GPU_material_vertex_attributes(GPUMaterial *material, GPUVertexAttribs *attribs) { *attribs = material->attribs; @@ -1953,6 +1958,48 @@ int GPU_lamp_shadow_layer(GPULamp *lamp) return -1; } +GPUNodeLink *GPU_lamp_get_data(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **col, GPUNodeLink **lv, GPUNodeLink **dist, GPUNodeLink **shadow) +{ + GPUNodeLink *visifac; + + *col = GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob); + visifac = lamp_get_visibility(mat, lamp, lv, dist); + shade_light_textures(mat, lamp, col); + + if (GPU_lamp_has_shadow_buffer(lamp)) { + GPUNodeLink *vn, *inp; + + GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &vn); + GPU_link(mat, "shade_inp", vn, *lv, &inp); + mat->dynproperty |= DYN_LAMP_PERSMAT; + + if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) { + GPU_link(mat, "shadows_only_vsm", + GPU_builtin(GPU_VIEW_POSITION), + GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), + GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), + GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias), + GPU_uniform(lamp->shadow_color), inp, shadow); + } + else { + GPU_link(mat, "shadows_only", + GPU_builtin(GPU_VIEW_POSITION), + GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), + GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), + GPU_uniform(&lamp->bias), GPU_uniform(lamp->shadow_color), inp, shadow); + } + } + else { + GPU_link(mat, "set_rgb_one", shadow); + } + + /* ensure shadow buffer and lamp textures will be updated */ + add_user_list(&mat->lamps, lamp); + add_user_list(&lamp->materials, mat->ma); + + return visifac; +} + /* export the GLSL shader */ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma) diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 1dd33080d94..3a4aa75aa01 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -166,6 +166,15 @@ void camera(vec3 co, out vec3 outview, out float outdepth, out float outdist) outview = normalize(co); } +void lamp(vec4 col, vec3 lv, float dist, vec3 shadow, float visifac, out vec4 outcol, out vec3 outlv, out float outdist, out vec4 outshadow, out float outvisifac) +{ + outcol = col; + outlv = lv; + outdist = dist; + outshadow = vec4(shadow, 1.0); + outvisifac = visifac; +} + void math_add(float val1, float val2, out float outval) { outval = val1 + val2; @@ -1973,6 +1982,30 @@ void test_shadowbuf_vsm(vec3 rco, sampler2D shadowmap, mat4 shadowpersmat, float } } +void shadows_only(vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat, float shadowbias, vec3 shadowcolor, float inp, out vec3 result) +{ + result = vec3(1.0); + + if(inp > 0.0) { + float shadfac; + + test_shadowbuf(rco, shadowmap, shadowpersmat, shadowbias, inp, shadfac); + result -= (1.0 - shadfac) * (vec3(1.0) - shadowcolor); + } +} + +void shadows_only_vsm(vec3 rco, sampler2D shadowmap, mat4 shadowpersmat, float shadowbias, float bleedbias, vec3 shadowcolor, float inp, out vec3 result) +{ + result = vec3(1.0); + + if(inp > 0.0) { + float shadfac; + + test_shadowbuf_vsm(rco, shadowmap, shadowpersmat, shadowbias, bleedbias, inp, shadfac); + result -= (1.0 - shadfac) * (vec3(1.0) - shadowcolor); + } +} + void shade_light_texture(vec3 rco, sampler2D cookie, mat4 shadowpersmat, out vec4 result) { |