Fix #113235: Voronoi GLSL Shaders On Legacy Intel
When using Voronoi shader nodes on legacy Intel platforms (HD4400) Blender would crash due to a driver bug. The bug is related to generating the `fractal_voronoi_x_fx` functions. It doesn't effect all drivers, but mainly from vendors that don't allow installing the official intel drivers. We have tried several approaches including using unique function names and unroll only the function of the body. But none worked on the failing platform. In the future we could solve this by including our own GLSL compiler, but that is still very experimental and requires a lot of testing.#113938 Pull Request: https://projects.blender.org/blender/blender/pulls/113834
This commit is contained in:
parent
cdbde7d941
commit
ea2746d468
|
@ -6,69 +6,9 @@
|
|||
#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl)
|
||||
#pragma BLENDER_REQUIRE(gpu_shader_material_voronoi.glsl)
|
||||
|
||||
/* The fractalization logic is the same as for fBM Noise, except that some additions are replaced
|
||||
* by lerps. */
|
||||
#define FRACTAL_VORONOI_X_FX(T) \
|
||||
VoronoiOutput fractal_voronoi_x_fx(VoronoiParams params, T coord) \
|
||||
{ \
|
||||
float amplitude = 1.0; \
|
||||
float max_amplitude = 0.0; \
|
||||
float scale = 1.0; \
|
||||
\
|
||||
VoronoiOutput Output; \
|
||||
Output.Distance = 0.0; \
|
||||
Output.Color = vec3(0.0, 0.0, 0.0); \
|
||||
Output.Position = vec4(0.0, 0.0, 0.0, 0.0); \
|
||||
bool zero_input = params.detail == 0.0 || params.roughness == 0.0; \
|
||||
\
|
||||
for (int i = 0; i <= ceil(params.detail); ++i) { \
|
||||
VoronoiOutput octave; \
|
||||
if (params.feature == SHD_VORONOI_F2) { \
|
||||
octave = voronoi_f2(params, coord * scale); \
|
||||
} \
|
||||
else if (params.feature == SHD_VORONOI_SMOOTH_F1 && params.smoothness != 0.0) { \
|
||||
octave = voronoi_smooth_f1(params, coord * scale); \
|
||||
} \
|
||||
else { \
|
||||
octave = voronoi_f1(params, coord * scale); \
|
||||
} \
|
||||
\
|
||||
if (zero_input) { \
|
||||
max_amplitude = 1.0; \
|
||||
Output = octave; \
|
||||
break; \
|
||||
} \
|
||||
else if (i <= params.detail) { \
|
||||
max_amplitude += amplitude; \
|
||||
Output.Distance += octave.Distance * amplitude; \
|
||||
Output.Color += octave.Color * amplitude; \
|
||||
Output.Position = mix(Output.Position, octave.Position / scale, amplitude); \
|
||||
scale *= params.lacunarity; \
|
||||
amplitude *= params.roughness; \
|
||||
} \
|
||||
else { \
|
||||
float remainder = params.detail - floor(params.detail); \
|
||||
if (remainder != 0.0) { \
|
||||
max_amplitude = mix(max_amplitude, max_amplitude + amplitude, remainder); \
|
||||
Output.Distance = mix( \
|
||||
Output.Distance, Output.Distance + octave.Distance * amplitude, remainder); \
|
||||
Output.Color = mix(Output.Color, Output.Color + octave.Color * amplitude, remainder); \
|
||||
Output.Position = mix(Output.Position, \
|
||||
mix(Output.Position, octave.Position / scale, amplitude), \
|
||||
remainder); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if (params.normalize) { \
|
||||
Output.Distance /= max_amplitude * params.max_distance; \
|
||||
Output.Color /= max_amplitude; \
|
||||
} \
|
||||
\
|
||||
Output.Position = safe_divide(Output.Position, params.scale); \
|
||||
\
|
||||
return Output; \
|
||||
}
|
||||
/* TODO(jbakker): Deduplicate code when OpenGL backend has been removed.
|
||||
* `fractal_voronoi_x_fx` functions are identical, except for the input parameter.
|
||||
* It used to be a macro, but didn't work on legacy drivers. */
|
||||
|
||||
/* The fractalization logic is the same as for fBM Noise, except that some additions are replaced
|
||||
* by lerps. */
|
||||
|
@ -115,24 +55,264 @@
|
|||
|
||||
/* **** 1D Fractal Voronoi **** */
|
||||
|
||||
FRACTAL_VORONOI_X_FX(float)
|
||||
/* The fractalization logic is the same as for fBM Noise, except that some additions are replaced
|
||||
* by lerps. */
|
||||
VoronoiOutput fractal_voronoi_x_fx(VoronoiParams params, float coord)
|
||||
{
|
||||
float amplitude = 1.0;
|
||||
float max_amplitude = 0.0;
|
||||
float scale = 1.0;
|
||||
|
||||
VoronoiOutput Output;
|
||||
Output.Distance = 0.0;
|
||||
Output.Color = vec3(0.0, 0.0, 0.0);
|
||||
Output.Position = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
bool zero_input = params.detail == 0.0 || params.roughness == 0.0;
|
||||
|
||||
for (int i = 0; i <= ceil(params.detail); ++i) {
|
||||
VoronoiOutput octave;
|
||||
if (params.feature == SHD_VORONOI_F2) {
|
||||
octave = voronoi_f2(params, coord * scale);
|
||||
}
|
||||
else if (params.feature == SHD_VORONOI_SMOOTH_F1 && params.smoothness != 0.0) {
|
||||
octave = voronoi_smooth_f1(params, coord * scale);
|
||||
}
|
||||
else {
|
||||
octave = voronoi_f1(params, coord * scale);
|
||||
}
|
||||
|
||||
if (zero_input) {
|
||||
max_amplitude = 1.0;
|
||||
Output = octave;
|
||||
break;
|
||||
}
|
||||
else if (i <= params.detail) {
|
||||
max_amplitude += amplitude;
|
||||
Output.Distance += octave.Distance * amplitude;
|
||||
Output.Color += octave.Color * amplitude;
|
||||
Output.Position = mix(Output.Position, octave.Position / scale, amplitude);
|
||||
scale *= params.lacunarity;
|
||||
amplitude *= params.roughness;
|
||||
}
|
||||
else {
|
||||
float remainder = params.detail - floor(params.detail);
|
||||
if (remainder != 0.0) {
|
||||
max_amplitude = mix(max_amplitude, max_amplitude + amplitude, remainder);
|
||||
Output.Distance = mix(
|
||||
Output.Distance, Output.Distance + octave.Distance * amplitude, remainder);
|
||||
Output.Color = mix(Output.Color, Output.Color + octave.Color * amplitude, remainder);
|
||||
Output.Position = mix(
|
||||
Output.Position, mix(Output.Position, octave.Position / scale, amplitude), remainder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.normalize) {
|
||||
Output.Distance /= max_amplitude * params.max_distance;
|
||||
Output.Color /= max_amplitude;
|
||||
}
|
||||
|
||||
Output.Position = safe_divide(Output.Position, params.scale);
|
||||
|
||||
return Output;
|
||||
}
|
||||
|
||||
FRACTAL_VORONOI_DISTANCE_TO_EDGE_FUNCTION(float)
|
||||
|
||||
/* **** 2D Fractal Voronoi **** */
|
||||
|
||||
FRACTAL_VORONOI_X_FX(vec2)
|
||||
/* The fractalization logic is the same as for fBM Noise, except that some additions are replaced
|
||||
* by lerps. */
|
||||
VoronoiOutput fractal_voronoi_x_fx(VoronoiParams params, vec2 coord)
|
||||
{
|
||||
float amplitude = 1.0;
|
||||
float max_amplitude = 0.0;
|
||||
float scale = 1.0;
|
||||
|
||||
VoronoiOutput Output;
|
||||
Output.Distance = 0.0;
|
||||
Output.Color = vec3(0.0, 0.0, 0.0);
|
||||
Output.Position = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
bool zero_input = params.detail == 0.0 || params.roughness == 0.0;
|
||||
|
||||
for (int i = 0; i <= ceil(params.detail); ++i) {
|
||||
VoronoiOutput octave;
|
||||
if (params.feature == SHD_VORONOI_F2) {
|
||||
octave = voronoi_f2(params, coord * scale);
|
||||
}
|
||||
else if (params.feature == SHD_VORONOI_SMOOTH_F1 && params.smoothness != 0.0) {
|
||||
octave = voronoi_smooth_f1(params, coord * scale);
|
||||
}
|
||||
else {
|
||||
octave = voronoi_f1(params, coord * scale);
|
||||
}
|
||||
|
||||
if (zero_input) {
|
||||
max_amplitude = 1.0;
|
||||
Output = octave;
|
||||
break;
|
||||
}
|
||||
else if (i <= params.detail) {
|
||||
max_amplitude += amplitude;
|
||||
Output.Distance += octave.Distance * amplitude;
|
||||
Output.Color += octave.Color * amplitude;
|
||||
Output.Position = mix(Output.Position, octave.Position / scale, amplitude);
|
||||
scale *= params.lacunarity;
|
||||
amplitude *= params.roughness;
|
||||
}
|
||||
else {
|
||||
float remainder = params.detail - floor(params.detail);
|
||||
if (remainder != 0.0) {
|
||||
max_amplitude = mix(max_amplitude, max_amplitude + amplitude, remainder);
|
||||
Output.Distance = mix(
|
||||
Output.Distance, Output.Distance + octave.Distance * amplitude, remainder);
|
||||
Output.Color = mix(Output.Color, Output.Color + octave.Color * amplitude, remainder);
|
||||
Output.Position = mix(
|
||||
Output.Position, mix(Output.Position, octave.Position / scale, amplitude), remainder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.normalize) {
|
||||
Output.Distance /= max_amplitude * params.max_distance;
|
||||
Output.Color /= max_amplitude;
|
||||
}
|
||||
|
||||
Output.Position = safe_divide(Output.Position, params.scale);
|
||||
|
||||
return Output;
|
||||
}
|
||||
|
||||
FRACTAL_VORONOI_DISTANCE_TO_EDGE_FUNCTION(vec2)
|
||||
|
||||
/* **** 3D Fractal Voronoi **** */
|
||||
|
||||
FRACTAL_VORONOI_X_FX(vec3)
|
||||
/* The fractalization logic is the same as for fBM Noise, except that some additions are replaced
|
||||
* by lerps. */
|
||||
VoronoiOutput fractal_voronoi_x_fx(VoronoiParams params, vec3 coord)
|
||||
{
|
||||
float amplitude = 1.0;
|
||||
float max_amplitude = 0.0;
|
||||
float scale = 1.0;
|
||||
|
||||
VoronoiOutput Output;
|
||||
Output.Distance = 0.0;
|
||||
Output.Color = vec3(0.0, 0.0, 0.0);
|
||||
Output.Position = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
bool zero_input = params.detail == 0.0 || params.roughness == 0.0;
|
||||
|
||||
for (int i = 0; i <= ceil(params.detail); ++i) {
|
||||
VoronoiOutput octave;
|
||||
if (params.feature == SHD_VORONOI_F2) {
|
||||
octave = voronoi_f2(params, coord * scale);
|
||||
}
|
||||
else if (params.feature == SHD_VORONOI_SMOOTH_F1 && params.smoothness != 0.0) {
|
||||
octave = voronoi_smooth_f1(params, coord * scale);
|
||||
}
|
||||
else {
|
||||
octave = voronoi_f1(params, coord * scale);
|
||||
}
|
||||
|
||||
if (zero_input) {
|
||||
max_amplitude = 1.0;
|
||||
Output = octave;
|
||||
break;
|
||||
}
|
||||
else if (i <= params.detail) {
|
||||
max_amplitude += amplitude;
|
||||
Output.Distance += octave.Distance * amplitude;
|
||||
Output.Color += octave.Color * amplitude;
|
||||
Output.Position = mix(Output.Position, octave.Position / scale, amplitude);
|
||||
scale *= params.lacunarity;
|
||||
amplitude *= params.roughness;
|
||||
}
|
||||
else {
|
||||
float remainder = params.detail - floor(params.detail);
|
||||
if (remainder != 0.0) {
|
||||
max_amplitude = mix(max_amplitude, max_amplitude + amplitude, remainder);
|
||||
Output.Distance = mix(
|
||||
Output.Distance, Output.Distance + octave.Distance * amplitude, remainder);
|
||||
Output.Color = mix(Output.Color, Output.Color + octave.Color * amplitude, remainder);
|
||||
Output.Position = mix(
|
||||
Output.Position, mix(Output.Position, octave.Position / scale, amplitude), remainder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.normalize) {
|
||||
Output.Distance /= max_amplitude * params.max_distance;
|
||||
Output.Color /= max_amplitude;
|
||||
}
|
||||
|
||||
Output.Position = safe_divide(Output.Position, params.scale);
|
||||
|
||||
return Output;
|
||||
}
|
||||
|
||||
FRACTAL_VORONOI_DISTANCE_TO_EDGE_FUNCTION(vec3)
|
||||
|
||||
/* **** 4D Fractal Voronoi **** */
|
||||
|
||||
FRACTAL_VORONOI_X_FX(vec4)
|
||||
/* The fractalization logic is the same as for fBM Noise, except that some additions are replaced
|
||||
* by lerps. */
|
||||
VoronoiOutput fractal_voronoi_x_fx(VoronoiParams params, vec4 coord)
|
||||
{
|
||||
float amplitude = 1.0;
|
||||
float max_amplitude = 0.0;
|
||||
float scale = 1.0;
|
||||
|
||||
VoronoiOutput Output;
|
||||
Output.Distance = 0.0;
|
||||
Output.Color = vec3(0.0, 0.0, 0.0);
|
||||
Output.Position = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
bool zero_input = params.detail == 0.0 || params.roughness == 0.0;
|
||||
|
||||
for (int i = 0; i <= ceil(params.detail); ++i) {
|
||||
VoronoiOutput octave;
|
||||
if (params.feature == SHD_VORONOI_F2) {
|
||||
octave = voronoi_f2(params, coord * scale);
|
||||
}
|
||||
else if (params.feature == SHD_VORONOI_SMOOTH_F1 && params.smoothness != 0.0) {
|
||||
octave = voronoi_smooth_f1(params, coord * scale);
|
||||
}
|
||||
else {
|
||||
octave = voronoi_f1(params, coord * scale);
|
||||
}
|
||||
|
||||
if (zero_input) {
|
||||
max_amplitude = 1.0;
|
||||
Output = octave;
|
||||
break;
|
||||
}
|
||||
else if (i <= params.detail) {
|
||||
max_amplitude += amplitude;
|
||||
Output.Distance += octave.Distance * amplitude;
|
||||
Output.Color += octave.Color * amplitude;
|
||||
Output.Position = mix(Output.Position, octave.Position / scale, amplitude);
|
||||
scale *= params.lacunarity;
|
||||
amplitude *= params.roughness;
|
||||
}
|
||||
else {
|
||||
float remainder = params.detail - floor(params.detail);
|
||||
if (remainder != 0.0) {
|
||||
max_amplitude = mix(max_amplitude, max_amplitude + amplitude, remainder);
|
||||
Output.Distance = mix(
|
||||
Output.Distance, Output.Distance + octave.Distance * amplitude, remainder);
|
||||
Output.Color = mix(Output.Color, Output.Color + octave.Color * amplitude, remainder);
|
||||
Output.Position = mix(
|
||||
Output.Position, mix(Output.Position, octave.Position / scale, amplitude), remainder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.normalize) {
|
||||
Output.Distance /= max_amplitude * params.max_distance;
|
||||
Output.Color /= max_amplitude;
|
||||
}
|
||||
|
||||
Output.Position = safe_divide(Output.Position, params.scale);
|
||||
|
||||
return Output;
|
||||
}
|
||||
|
||||
FRACTAL_VORONOI_DISTANCE_TO_EDGE_FUNCTION(vec4)
|
||||
|
|
Loading…
Reference in New Issue