Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/engines/workbench')
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl64
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl8
-rw-r--r--source/blender/draw/engines/workbench/workbench_deferred.c4
-rw-r--r--source/blender/draw/engines/workbench/workbench_forward.c4
-rw-r--r--source/blender/draw/engines/workbench/workbench_volume.c87
5 files changed, 112 insertions, 55 deletions
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
index 1f14e506dcf..5b949a6d952 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
@@ -3,9 +3,15 @@ uniform mat4 ProjectionMatrix;
uniform mat4 ModelMatrixInverse;
uniform mat4 ModelViewMatrixInverse;
uniform mat4 ModelMatrix;
+uniform vec3 OrcoTexCoFactors[2];
uniform sampler2D depthBuffer;
+
uniform sampler3D densityTexture;
+uniform sampler3D shadowTexture;
+uniform sampler3D flameTexture;
+uniform sampler1D flameColorTexture;
+uniform sampler1D transferTexture;
uniform int samplesLen = 256;
uniform float stepLength; /* Step length in local space. */
@@ -62,15 +68,35 @@ float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection)
void volume_properties(vec3 ls_pos, out vec3 scattering, out float extinction)
{
- scattering = vec3(0.0);
- extinction = 1e-8;
+ vec3 co = ls_pos * 0.5 + 0.5;
+#ifdef USE_COBA
+ float val = texture(densityTexture, co).r;
+ vec4 tval = texture(transferTexture, val) * densityScale;
+ tval.rgb = pow(tval.rgb, vec3(2.2));
+ scattering = tval.rgb * 1500.0;
+ extinction = max(1e-4, tval.a * 50.0);
+#else
+ float flame = texture(flameTexture, co).r;
+ vec4 emission = texture(flameColorTexture, flame);
+ float shadows = texture(shadowTexture, co).r;
+ vec4 density = texture(densityTexture, co); /* rgb: color, a: density */
+
+ scattering = density.rgb * density.a * densityScale;
+ extinction = max(1e-4, dot(scattering, vec3(0.33333)));
- vec4 density = texture(densityTexture, ls_pos * 0.5 + 0.5);
- density.rgb /= density.a;
- density *= densityScale;
+ scattering *= shadows * M_PI;
+ /* 800 is arbitrary and here to mimic old viewport. TODO make it a parameter */
+ scattering += pow(emission.rgb, vec3(2.2)) * emission.a * 800.0;
+#endif
+}
- scattering = density.rgb;
- extinction = max(1e-8, density.a);
+void eval_volume_step(inout vec3 Lscat, float extinction, float step_len, out float Tr)
+{
+ Lscat *= phase_function_isotropic();
+ /* Evaluate Scattering */
+ Tr = exp(-extinction * step_len);
+ /* integrate along the current step segment */
+ Lscat = (Lscat - Lscat * Tr) / extinction;
}
#define P(x) ((x + 0.5) * (1.0 / 16.0))
@@ -96,18 +122,15 @@ vec4 volume_integration(
vec3 ls_pos = ray_ori + ray_dir * ray_len;
vec3 Lscat;
- float s_extinction;
+ float s_extinction, Tr;
volume_properties(ls_pos, Lscat, s_extinction);
- /* Evaluate Scattering */
- float Tr = exp(-s_extinction * step_len);
- /* integrate along the current step segment */
- Lscat = (Lscat - Lscat * Tr) / s_extinction;
+ eval_volume_step(Lscat, s_extinction, step_len, Tr);
/* accumulate and also take into account the transmittance from previous steps */
final_scattering += final_transmittance * Lscat;
final_transmittance *= Tr;
}
- return vec4(final_scattering, 1.0 - final_transmittance);
+ return vec4(final_scattering, final_transmittance);
}
void main()
@@ -134,15 +157,11 @@ void main()
step_len = 1.0 / step_len;
vec3 Lscat;
- float s_extinction;
+ float s_extinction, Tr;
volume_properties(localPos, Lscat, s_extinction);
- /* Evaluate Scattering */
- float Tr = exp(-s_extinction * step_len);
- /* integrate along the current step segment */
- Lscat = (Lscat - Lscat * Tr) / s_extinction;
-
- fragColor = vec4(Lscat, 1.0 - Tr);
+ eval_volume_step(Lscat, s_extinction, step_len, Tr);
+ fragColor = vec4(Lscat, Tr);
#else
vec2 screen_uv = gl_FragCoord.xy / vec2(textureSize(depthBuffer, 0).xy);
bool is_persp = ProjectionMatrix[3][3] == 0.0;
@@ -156,10 +175,13 @@ void main()
vec3 vs_ray_dir = (is_persp) ? (vs_ray_end - vs_ray_ori) : vec3(0.0, 0.0, -1.0);
vs_ray_dir /= abs(vs_ray_dir.z);
- vec3 ls_ray_dir = mat3(ModelViewMatrixInverse) * vs_ray_dir;
+ vec3 ls_ray_dir = mat3(ModelViewMatrixInverse) * vs_ray_dir * OrcoTexCoFactors[1] * 2.0;
vec3 ls_ray_ori = (ModelViewMatrixInverse * vec4(vs_ray_ori, 1.0)).xyz;
vec3 ls_ray_end = (ModelViewMatrixInverse * vec4(vs_ray_end, 1.0)).xyz;
+ ls_ray_ori = (OrcoTexCoFactors[0] + ls_ray_ori * OrcoTexCoFactors[1]) * 2.0 - 1.0;
+ ls_ray_end = (OrcoTexCoFactors[0] + ls_ray_end * OrcoTexCoFactors[1]) * 2.0 - 1.0;
+
/* TODO: Align rays to volume center so that it mimics old behaviour of slicing the volume. */
float dist = line_unit_box_intersect_dist(ls_ray_ori, ls_ray_dir);
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
index 90a22d9d02f..7ce21c3d5ca 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
@@ -1,5 +1,6 @@
uniform mat4 ModelViewProjectionMatrix;
+uniform vec3 OrcoTexCoFactors[2];
uniform float slicePosition;
uniform int sliceAxis; /* -1 is no slice, 0 is X, 1 is Y, 2 is Z. */
@@ -23,9 +24,10 @@ void main()
else {
localPos = vec3(pos.xy, slicePosition * 2.0 - 1.0);
}
-
- gl_Position = ModelViewProjectionMatrix * vec4(localPos, 1.0);
+ vec3 final_pos = localPos;
#else
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ vec3 final_pos = pos;
#endif
+ final_pos = ((final_pos * 0.5 + 0.5) - OrcoTexCoFactors[0]) / OrcoTexCoFactors[1];
+ gl_Position = ModelViewProjectionMatrix * vec4(final_pos, 1.0);
}
diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c
index 7fbe928d29e..a1345afcf11 100644
--- a/source/blender/draw/engines/workbench/workbench_deferred.c
+++ b/source/blender/draw/engines/workbench/workbench_deferred.c
@@ -649,7 +649,7 @@ static void workbench_cache_populate_particles(WORKBENCH_Data *vedata, Object *o
if (!psys_check_enabled(ob, psys, false)) {
continue;
}
- if (!DRW_check_psys_visible_within_active_context(ob, psys)) {
+ if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
continue;
}
ParticleSettings *part = psys->part;
@@ -701,7 +701,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
return; /* Do not draw solid in this case. */
}
- if (!DRW_check_object_visible_within_active_context(ob)) {
+ if (!DRW_object_is_visible_in_active_context(ob) || (ob->dt < OB_SOLID)) {
return;
}
diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c
index 0d4329c9699..cb11864df54 100644
--- a/source/blender/draw/engines/workbench/workbench_forward.c
+++ b/source/blender/draw/engines/workbench/workbench_forward.c
@@ -420,7 +420,7 @@ static void workbench_forward_cache_populate_particles(WORKBENCH_Data *vedata, O
if (!psys_check_enabled(ob, psys, false)) {
continue;
}
- if (!DRW_check_psys_visible_within_active_context(ob, psys)) {
+ if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
continue;
}
ParticleSettings *part = psys->part;
@@ -487,7 +487,7 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
return; /* Do not draw solid in this case. */
}
- if (!DRW_check_object_visible_within_active_context(ob)) {
+ if (!DRW_object_is_visible_in_active_context(ob) || (ob->dt < OB_SOLID)) {
return;
}
diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c
index ea4152486af..b0c08a2dc28 100644
--- a/source/blender/draw/engines/workbench/workbench_volume.c
+++ b/source/blender/draw/engines/workbench/workbench_volume.c
@@ -35,7 +35,11 @@
static struct {
struct GPUShader *volume_sh;
+ struct GPUShader *volume_coba_sh;
struct GPUShader *volume_slice_sh;
+ struct GPUShader *volume_slice_coba_sh;
+ struct GPUTexture *dummy_tex;
+ struct GPUTexture *dummy_coba_tex;
} e_data = {NULL};
extern char datatoc_workbench_volume_vert_glsl[];
@@ -47,21 +51,39 @@ void workbench_volume_engine_init(void)
e_data.volume_sh = DRW_shader_create(
datatoc_workbench_volume_vert_glsl, NULL,
datatoc_workbench_volume_frag_glsl, NULL);
+ e_data.volume_coba_sh = DRW_shader_create(
+ datatoc_workbench_volume_vert_glsl, NULL,
+ datatoc_workbench_volume_frag_glsl,
+ "#define USE_COBA\n");
e_data.volume_slice_sh = DRW_shader_create(
datatoc_workbench_volume_vert_glsl, NULL,
- datatoc_workbench_volume_frag_glsl, "#define VOLUME_SLICE");
+ datatoc_workbench_volume_frag_glsl,
+ "#define VOLUME_SLICE\n");
+ e_data.volume_slice_coba_sh = DRW_shader_create(
+ datatoc_workbench_volume_vert_glsl, NULL,
+ datatoc_workbench_volume_frag_glsl,
+ "#define VOLUME_SLICE\n"
+ "#define USE_COBA\n");
+
+ float pixel[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ e_data.dummy_tex = GPU_texture_create_3D(1, 1, 1, GPU_RGBA8, pixel, NULL);
+ e_data.dummy_coba_tex = GPU_texture_create_1D(1, GPU_RGBA8, pixel, NULL);
}
}
void workbench_volume_engine_free(void)
{
DRW_SHADER_FREE_SAFE(e_data.volume_sh);
+ DRW_SHADER_FREE_SAFE(e_data.volume_coba_sh);
DRW_SHADER_FREE_SAFE(e_data.volume_slice_sh);
+ DRW_SHADER_FREE_SAFE(e_data.volume_slice_coba_sh);
+ DRW_TEXTURE_FREE_SAFE(e_data.dummy_tex);
+ DRW_TEXTURE_FREE_SAFE(e_data.dummy_coba_tex);
}
void workbench_volume_cache_init(WORKBENCH_Data *vedata)
{
- vedata->psl->volume_pass = DRW_pass_create("Volumes", DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_PREMUL | DRW_STATE_CULL_FRONT);
+ vedata->psl->volume_pass = DRW_pass_create("Volumes", DRW_STATE_WRITE_COLOR | DRW_STATE_TRANSMISSION | DRW_STATE_CULL_FRONT);
}
void workbench_volume_cache_populate(WORKBENCH_Data *vedata, Scene *scene, Object *ob, ModifierData *md)
@@ -70,6 +92,7 @@ void workbench_volume_cache_populate(WORKBENCH_Data *vedata, Scene *scene, Objec
SmokeDomainSettings *sds = smd->domain;
WORKBENCH_PrivateData *wpd = vedata->stl->g_data;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ DRWShadingGroup *grp = NULL;
/* Don't show smoke before simulation starts, this could be made an option in the future. */
if (!sds->fluid || CFRA < sds->point_cache[0]->startframe) {
@@ -77,21 +100,26 @@ void workbench_volume_cache_populate(WORKBENCH_Data *vedata, Scene *scene, Objec
}
wpd->volumes_do = true;
-
- if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
+ if (sds->use_coba) {
+ GPU_create_smoke_coba_field(smd);
+ }
+ else if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
GPU_create_smoke(smd, 0);
}
else if (sds->wt && (sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
GPU_create_smoke(smd, 1);
}
- if (sds->tex == NULL) {
+ if ((!sds->use_coba && sds->tex == NULL) ||
+ (sds->use_coba && sds->tex_field == NULL))
+ {
return;
}
- if (sds->slice_method == MOD_SMOKE_SLICE_AXIS_ALIGNED &&
- sds->axis_slice_method == AXIS_SLICE_SINGLE)
- {
+ const bool use_slice = (sds->slice_method == MOD_SMOKE_SLICE_AXIS_ALIGNED &&
+ sds->axis_slice_method == AXIS_SLICE_SINGLE);
+
+ if (use_slice) {
float invviewmat[4][4];
DRW_viewport_matrix_get(invviewmat, DRW_MAT_VIEWINV);
@@ -99,41 +127,46 @@ void workbench_volume_cache_populate(WORKBENCH_Data *vedata, Scene *scene, Objec
? axis_dominant_v3_single(invviewmat[2])
: sds->slice_axis - 1;
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.volume_slice_sh, vedata->psl->volume_pass);
- DRW_shgroup_uniform_texture(grp, "densityTexture", sds->tex);
- DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
- DRW_shgroup_uniform_float_copy(grp, "densityScale", 10.0f * sds->display_thickness);
+ GPUShader *sh = (sds->use_coba) ? e_data.volume_slice_coba_sh : e_data.volume_slice_sh;
+ grp = DRW_shgroup_create(sh, vedata->psl->volume_pass);
DRW_shgroup_uniform_float_copy(grp, "slicePosition", sds->slice_depth);
DRW_shgroup_uniform_int_copy(grp, "sliceAxis", axis);
- DRW_shgroup_state_disable(grp, DRW_STATE_CULL_FRONT);
- BLI_addtail(&wpd->smoke_domains, BLI_genericNodeN(smd));
-
- /* TODO Flame rendering */
- /* TODO COBA Rendering */
-
- DRW_shgroup_call_object_add(grp, DRW_cache_quad_get(), ob);
}
else {
int max_slices = max_iii(sds->res[0], sds->res[1], sds->res[2]) * sds->slice_per_voxel;
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.volume_sh, vedata->psl->volume_pass);
+ GPUShader *sh = (sds->use_coba) ? e_data.volume_coba_sh : e_data.volume_sh;
+ grp = DRW_shgroup_create(sh, vedata->psl->volume_pass);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
- DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
- DRW_shgroup_uniform_texture(grp, "densityTexture", sds->tex);
- DRW_shgroup_uniform_float_copy(grp, "densityScale", 10.0f * sds->display_thickness);
DRW_shgroup_uniform_int_copy(grp, "samplesLen", max_slices);
/* TODO FIXME : This step size is in object space but the ray itself
* is NOT unit length in object space so the required number of subdivisions
* is tricky to get. */
DRW_shgroup_uniform_float_copy(grp, "stepLength", 8.0f / max_slices);
- DRW_shgroup_state_enable(grp, DRW_STATE_CULL_FRONT);
- BLI_addtail(&wpd->smoke_domains, BLI_genericNodeN(smd));
+ }
- /* TODO Flame rendering */
- /* TODO COBA Rendering */
+ if (sds->use_coba) {
+ DRW_shgroup_uniform_texture(grp, "densityTexture", sds->tex_field);
+ DRW_shgroup_uniform_texture(grp, "transferTexture", sds->tex_coba);
+ }
+ else {
+ DRW_shgroup_uniform_texture(grp, "densityTexture", sds->tex);
+ DRW_shgroup_uniform_texture(grp, "shadowTexture", sds->tex_shadow);
+ DRW_shgroup_uniform_texture(grp, "flameTexture", (sds->tex_flame) ? sds->tex_flame : e_data.dummy_tex);
+ DRW_shgroup_uniform_texture(grp, "flameColorTexture", (sds->tex_flame) ? sds->tex_flame_coba : e_data.dummy_coba_tex);
+ }
+ DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
+ DRW_shgroup_uniform_float_copy(grp, "densityScale", 10.0f * sds->display_thickness);
+ DRW_shgroup_state_disable(grp, DRW_STATE_CULL_FRONT);
+ if (use_slice) {
+ DRW_shgroup_call_object_add(grp, DRW_cache_quad_get(), ob);
+ }
+ else {
DRW_shgroup_call_object_add(grp, DRW_cache_cube_get(), ob);
}
+
+ BLI_addtail(&wpd->smoke_domains, BLI_genericNodeN(smd));
}
void workbench_volume_smoke_textures_free(WORKBENCH_PrivateData *wpd)